日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 综合教程 >内容正文

综合教程

内存映射文件原理_开源内存数据库

發(fā)布時(shí)間:2023/12/15 综合教程 39 生活家
生活随笔 收集整理的這篇文章主要介紹了 内存映射文件原理_开源内存数据库 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

在前文LMDB簡(jiǎn)介的基礎(chǔ)上,本文介紹LMDB數(shù)據(jù)庫(kù)的基本用法,包括環(huán)境environment創(chuàng)建、數(shù)據(jù)存儲(chǔ)put、數(shù)據(jù)讀取get等;

源碼

ULONG cvtest_Test4_Lmdb()
{   
    INT iRet;
    MDB_txn *pstTxn = NULL;
    MDB_dbi stDbi;
    UINT uiKey = 1;
    UINT uiData = 100;
    
    iRet = mdb_env_create(&g_pstMdbEnv);
    if (0 != iRet)
    {
        return ERROR_FAILED;
    }
    mdb_env_set_maxreaders(g_pstMdbEnv, 1);
    mdb_env_set_mapsize(g_pstMdbEnv, 4096 * 4096);
    
    if (ERROR_SUCCESS != Lib_CreateDir(CVTEST_LMDB_PATH))
    {
        mdb_env_close(g_pstMdbEnv);
        return ERROR_FAILED;
    }
    iRet = mdb_env_open(g_pstMdbEnv, CVTEST_LMDB_PATH, MDB_WRITEMAP, 0);
    E(iRet, "Env open failed...");
    
    iRet += mdb_txn_begin(g_pstMdbEnv, NULL, 0, &pstTxn);
    E(iRet, "Txm begin open failed...");
    
    iRet += mdb_dbi_open(pstTxn, NULL, MDB_CREATE, &stDbi);
    E(iRet, "dbi_open failed...");
    
    MDB_val stKey;
    MDB_val stData;
    stKey.mv_size = sizeof(UINT);
    stKey.mv_data = (VOID *)&uiKey;

    /* mdb_put  存數(shù)據(jù) */
    stData.mv_size = sizeof(UINT);
    stData.mv_data = (VOID *)&uiData;
    iRet = mdb_put(pstTxn, stDbi, &stKey, &stData, 0);
    if (iRet != MDB_SUCCESS)
    {
        printf("mdb_put failed : %s\n", mdb_strerror(iRet));
        mdb_env_close(g_pstMdbEnv);
        return ERROR_FAILED;
    }
    mdb_txn_commit(pstTxn);

    /* 重新begin一個(gè)事務(wù)---進(jìn)行讀 */
    MDB_txn *pstReadTxn = NULL;
    MDB_dbi stDbiRead;
    MDB_val stReadValue;    
    CHAR szBuf[BUF_LEN_100] = {0, };
    
    stReadValue.mv_size = BUF_LEN_100;
    stReadValue.mv_data = (VOID *)szBuf;
    mdb_txn_begin(g_pstMdbEnv, NULL, MDB_RDONLY, &pstReadTxn);
    iRet = mdb_dbi_open(pstReadTxn, NULL, 0, &stDbiRead);

    iRet += mdb_get(pstReadTxn, stDbiRead, &stKey, &stReadValue);
    if (iRet != MDB_SUCCESS)
    {
        printf("mdb_get failed : %s\n", mdb_strerror(iRet));
        return ERROR_FAILED;
    }
    printf("stReadValue.data is %d \n", *(UINT *)stReadValue.mv_data);
    return ERROR_SUCCESS;
}

源碼解讀

  1. 按照LMDB官方介紹文檔,先通過(guò)mdb_env_create創(chuàng)建env,后續(xù)mdb_env_set_maxreaders、mdb_env_set_mapsize設(shè)置環(huán)境相關(guān)參數(shù);
  2. Lib_CreateDir用于創(chuàng)建數(shù)據(jù)庫(kù)的目錄,官方文檔有提及:mdb_env_open參數(shù)2并不會(huì)為用戶(hù)創(chuàng)建相關(guān)目錄,因而需要提前創(chuàng)建;
  3. mdb_env_open、mdb_txn_begin、mdb_dbi_open分別用于打開(kāi)environment、打開(kāi)一個(gè)事務(wù)、打開(kāi)一個(gè)數(shù)據(jù)庫(kù)instance。其中mdb_dbi_open通過(guò)不同的數(shù)據(jù)庫(kù)名(param 2)支持多實(shí)例
  4. mdb_put用于存入相關(guān)數(shù)據(jù):key/value對(duì),key/value都是MDB_val結(jié)構(gòu);
  5. 后續(xù)mdb_get用戶(hù)獲取數(shù)據(jù),key與put時(shí)的key相同,get成功后,我們通過(guò)強(qiáng)制類(lèi)型轉(zhuǎn)換取得數(shù)據(jù)庫(kù)內(nèi)的值并打印;
  6. E是筆者封裝的一個(gè)宏定義,用于檢查API的返回結(jié)果,如下:
#define E(Rest, expr) LMDB_CHECK((Rest) == MDB_SUCCESS, #expr)
#define LMDB_CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \
 "%s:%d: %s: %s\n", __FILE__, __LINE__, msg, mdb_strerror(test)), abort()))

測(cè)試結(jié)果

最后,我們將程序編譯/得到,得到如下結(jié)果。

在相關(guān)目錄產(chǎn)生數(shù)據(jù)文件和鎖文件。

zglinux cvtest # ls -lrth /home/zhaogang/code_my/lmdb/
total 32K
---------- 1 root root 192 5月 27 21:29 lock.mdb
---------- 1 root root 16M 5月 27 21:29 data.mdb
zglinux cvtest #

結(jié)果表明:測(cè)試正確。

擴(kuò)展說(shuō)明

  1. LMDB通過(guò)DBI區(qū)分不同的數(shù)據(jù)庫(kù)實(shí)例,支持在一個(gè)數(shù)據(jù)文件中存儲(chǔ)多個(gè)數(shù)據(jù)庫(kù)實(shí)例;
  2. LMDB是一個(gè)輕量級(jí)的開(kāi)源數(shù)據(jù)庫(kù)library,常用在硬件受限的嵌入式環(huán)境,不支持SQL語(yǔ)句
  3. LMDB通過(guò)mmap將文件映射到進(jìn)程的虛擬地址空間,可加速數(shù)據(jù)庫(kù)的訪(fǎng)問(wèn);
  4. LMDB采用B+樹(shù)算法存儲(chǔ)數(shù)據(jù),通過(guò)游標(biāo)cursor可方便的訪(fǎng)問(wèn)不同位置的數(shù)據(jù);
  5. LMDB的數(shù)據(jù)存/取都采用c語(yǔ)言中通用的void類(lèi)型,其類(lèi)型解析由程序員自行處理,提供更大的靈活性

總結(jié)

LMDB全部源碼12K行,想要進(jìn)一步了解其實(shí)現(xiàn)的讀者可以參閱其源碼。源碼中也提供mtest、mtest2~mtest6等多個(gè)測(cè)試案例供參閱。

總結(jié)

以上是生活随笔為你收集整理的内存映射文件原理_开源内存数据库的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。