lmdbxx, LMDB嵌入式B+树数据库库的C++11包装器

分享于 

15分钟阅读

GitHub

  繁體 雙語
C++11 wrapper for the LMDB embedded B+ tree database library.
  • 源代码名称:lmdbxx
  • 源代码网址:http://www.github.com/bendiken/lmdbxx
  • lmdbxx源代码文档
  • lmdbxx源代码下载
  • Git URL:
    git://www.github.com/bendiken/lmdbxx.git
    Git Clone代码到本地:
    git clone http://www.github.com/bendiken/lmdbxx
    Subversion代码到本地:
    $ svn co --depth empty http://www.github.com/bendiken/lmdbxx
    Checked out revision 1.
    $ cd repo
    $ svn up trunk
    
    lmdb++: LMDB 的C++11包装器Travis CI build statusCoverity Scan build status

    这是面向 LMDB 嵌入式数据库库的全面 C++ 包装,同时提供了错误检查的过程接口和面向对象的面向对象的资源接口,带有 RAII。

    示例

    下面是一个简单的激发示例的例子,演示了面向对象的资源接口的基本用法:

    #include <cstdio>
    #include <cstdlib>
    #include <lmdb++.h>
    int main() {
    /* Create and open the LMDB environment: */
     auto env = lmdb::env::create();
     env.set_mapsize(1UL * 1024UL * 1024UL * 1024UL);/* 1 GiB */
     env.open("./example.mdb", 0, 0664);
    /* Insert some key/value pairs in a write transaction: */
     auto wtxn = lmdb::txn::begin(env);
     auto dbi = lmdb::dbi::open(wtxn, nullptr);
     dbi.put(wtxn,"username","jhacker");
     dbi.put(wtxn,"email","jhacker@example.org");
     dbi.put(wtxn,"fullname","J. Random Hacker");
     wtxn.commit();
    /* Fetch key/value pairs in a read-only transaction: */
     auto rtxn = lmdb::txn::begin(env, nullptr, MDB_RDONLY);
     auto cursor = lmdb::cursor::open(rtxn, dbi);
     std::string key, value;
     while (cursor.get(key, value, MDB_NEXT)) {
     std::printf("key: '%s', value: '%s'n", key.c_str(), value.c_str());
     }
     cursor.close();
     rtxn.abort();
    /* The enviroment is closed automatically. */
     return EXIT_SUCCESS;
    }

    如果上面的任何操作都失败,则会引发 lmdb::error 异常,因为我们不指定异常处理程序。 所有资源都将因dc语义自动清理而自动清除。

    便笺

    为了运行这个示例,你必须首先手动创建 ./example.mdb 目录。 这是LMDB的基本特性: 给定环境路径必须已经存在,因为LMDB不会尝试自动创建它。

    特性

    • 设计为完全自包含作为单个 <lmdb++.h> 头文件,可以将它的放入项目中。
    • 实现从C 到 C++的直接映射,并具有一致的命名。
    • 提供程序接口和面向对象的变电站接口。
    • 将错误代码转换为 C++ 异常简化错误处理。
    • 仔细区分逻辑错误,运行时错误和致命错误。
    • 异常字符串包含失败的LMDB函数的NAME。
    • 与其他对象很好:所有符号都放置在 lmdb 命名空间中。
    • 100%免费和不受限制的public 域软件,在任何上下文中使用,用于任何目的。

    要求

    <lmdb++.h> 头文件需要C++11编译器和标准库。 最近发布的或者的最新版本可以很好的工作。

    此外,为了让你的应用程序构建和运行,你必须在预处理程序路径的包含中提供附带的底层 <lmdb.h> 头文件,并且必须与本地库链接。 在Ubuntu上,通过安装包可以满足这些先决条件。

    概述

    这个包装器提供了一个错误检查的程序接口和一个面向对象的面向对象的资源接口。 前者将对现有使用原始C 接口的项目很有用,但由于由于by语义所提供的异常,我们推荐后者。

    资源接口

    高级资源接口将LMDB句柄封装在一个喜爱的页面中。 这样,你可以确保 比如 在退出词法范围时自动中止事务,无论是否正常发生或者引发异常。

    C 处理 C++ 包装类
    MDB_env*lmdb::env
    MDB_txn*lmdb::txn
    MDB_dbilmdb::dbi
    MDB_cursor*lmdb::cursor
    MDB_vallmdb::val

    这些 C++ 类上可以用的方法与过程接口一致地命名为过程接口,与省略的类前缀一致。

    程序接口

    低级程序接口将LMDB函数包装为错误检查代码,在出现故障时将抛出相应 C++ 异常类的实例。 这个接口不提供任何方便的重载,而参数类型与LMDB本身提供的原始C 接口完全相同。 返回类型通常为 void,因为包装器取消了基础C 函数返回的错误代码,否则返回相同的输出参数。

    这个接口完全是使用 static 内联函数实现的,因这里只要有一个合适的编译器,就没有隐藏的。

    C 函数 C++ 包装函数
    mdb_version()n/a
    mdb_strerror()n/a
    mdb_env_create()lmdb::env_create()
    mdb_env_open()lmdb::env_open()
    mdb_env_copy()lmdb::env_copy()[1]
    mdb_env_copyfd()lmdb::env_copy_fd()[1]
    mdb_env_copy2()lmdb::env_copy()[1]
    mdb_env_copyfd2()lmdb::env_copy_fd()[1]
    mdb_env_stat()lmdb::env_stat()
    mdb_env_info()lmdb::env_info()
    mdb_env_sync()lmdb::env_sync()
    mdb_env_close()lmdb::env_close()
    mdb_env_set_flags()lmdb::env_set_flags()
    mdb_env_get_flags()lmdb::env_get_flags()
    mdb_env_get_path()lmdb::env_get_path()
    mdb_env_get_fd()lmdb::env_get_fd()
    mdb_env_set_mapsize()lmdb::env_set_mapsize()
    mdb_env_set_maxreaders()lmdb::env_set_max_readers()
    mdb_env_get_maxreaders()lmdb::env_get_max_readers()
    mdb_env_set_maxdbs()lmdb::env_set_max_dbs()
    mdb_env_get_maxkeysize()lmdb::env_get_max_keysize()
    mdb_env_set_userctx()lmdb::env_set_userctx()[2]
    mdb_env_get_userctx()lmdb::env_get_userctx()[2]
    mdb_env_set_assert()n/a
    mdb_txn_begin()lmdb::txn_begin()
    mdb_txn_env()lmdb::txn_env()
    mdb_txn_id()lmdb::txn_id()[3]
    mdb_txn_commit()lmdb::txn_commit()
    mdb_txn_abort()lmdb::txn_abort()
    mdb_txn_reset()lmdb::txn_reset()
    mdb_txn_renew()lmdb::txn_renew()
    mdb_dbi_open()lmdb::dbi_open()
    mdb_stat()lmdb::dbi_stat()[4] _
    mdb_dbi_flags()lmdb::dbi_flags()
    mdb_dbi_close()lmdb::dbi_close()
    mdb_drop()lmdb::dbi_drop()[4] _
    mdb_set_compare()lmdb::dbi_set_compare()[4] _
    mdb_set_dupsort()lmdb::dbi_set_dupsort()[4] _
    mdb_set_relfunc()lmdb::dbi_set_relfunc()[4] _
    mdb_set_relctx()lmdb::dbi_set_relctx()[4] _
    mdb_get()lmdb::dbi_get()[4] _
    mdb_put()lmdb::dbi_put()[4] _
    mdb_del()lmdb::dbi_del()[4] _
    mdb_cursor_open()lmdb::cursor_open()
    mdb_cursor_close()lmdb::cursor_close()
    mdb_cursor_renew()lmdb::cursor_renew()
    mdb_cursor_txn()lmdb::cursor_txn()
    mdb_cursor_dbi()lmdb::cursor_dbi()
    mdb_cursor_get()lmdb::cursor_get()
    mdb_cursor_put()lmdb::cursor_put()
    mdb_cursor_del()lmdb::cursor_del()
    mdb_cursor_count()lmdb::cursor_count()
    mdb_cmp()n/a
    mdb_dcmp()n/a
    mdb_reader_list()待办事项
    mdb_reader_check()待办事项

    脚注

    [1 ]( ,。) LMDB 0.9.14 ( 2014/09/20 ) 之后可用的三个参数签名。
    [2 ](。12 ) 仅在 LMDB 0.9.11 ( 2014/01/15 ) 之后可用。
    [3]仅在 LMDB HEAD中可用,但还没有在任何 0.9. x 版本( 从 0.9.16开始) 中。 定义 LMDBXX_TXN_ID 预处理器符号以取消隐藏这里属性。
    [4 ]注意命名的区别。 ( 请看下面。)
    警告
    • 通过句柄类型,C++ 过程接口比LMDB本机接口更加严格且一致。 例如 mdb_put() 被包装为 C++ 函数 lmdb::dbi_put(),而不是 lmdb::put()。 在数据库句柄中,这些differences--a少于number--all关注操作。
    • C++ 接口对输入仅适用于输入参数有一定的正确性,原始C 接口大大忽略了。 因此,在包装代码库中偶尔使用 const_cast
    • 如果LMDB返回 MDB_KEYEXIST 错误代码,lmdb::dbi_put() 不会抛出异常;它只是返回 false。 这是为了简化常见的使用模式。
    • 如果LMDB返回 MDB_NOTFOUND 错误代码,lmdb::dbi_get()lmdb::dbi_del()lmdb::cursor_get() 不会引发异常;它们只是返回 false。 这是为了简化常见的使用模式。
    • lmdb::env_get_max_keysize() 返回无符号整数,而不是以有符号整数作为基础 mdb_env_get_maxkeysize() 函数。 这里转换是在返回值不能为负的情况下完成的。

    错误句柄

    这里包装程序对三种不同的可能的LMDB错误条件类别进行了仔细的区分:

    • 逻辑错误,由 lmdb::logic_error 表示。 由于使用了函数接口与文档的先决条件冲突,引发了这里类的错误。 处理这类错误条件的一个常见策略是使用核心转储中止程序,方便自省查找和补救 Bug。
    • lmdb::fatal_error 表示的致命错误。 由于关键系统资源耗尽,特别是可以用内存( ENOMEM ),或者由于尝试超出适用的系统资源限制,引发错误。 处理此类错误条件的典型策略是使用描述性错误消息终止程序。 更强大的程序和共享库可以能需要实现另一个策略,比如在首先让调用堆栈放大。
    • 运行时错误,由 lmdb::runtime_error 表示。 这个类的错误当然会被抛出,以指示各种异常条件。 这些条件通常是可以恢复的,健壮的程序会小心地处理它们。

    便笺

    在C++11标准库中找到逻辑错误和运行时错误镜像,<stdexcept> 头定义标准异常基类 std::logic_errorstd::runtime_error。 另一方面标准异常类 std::bad_alloc 是一个致命错误的典型示例。

    错误代码异常类异常类型
    MDB_KEYEXISTlmdb::key_exist_error运行时
    MDB_NOTFOUNDlmdb::not_found_error运行时
    MDB_CORRUPTEDlmdb::corrupted_error致命
    MDB_PANIClmdb::panic_error致命
    MDB_VERSION_MISMATCHlmdb::version_mismatch_error致命
    MDB_MAP_FULLlmdb::map_full_error运行时
    MDB_BAD_DBIlmdb::bad_dbi_error运行时 [4] _
    ( 其他)lmdb::runtime_error运行时

    脚注

    [4 ]自 LMDB 0.9.14 ( 2014/09/20 ) 后可用。

    便笺

    MDB_KEYEXISTMDB_NOTFOUND 由一些函数特别处理。

    版本控制策略

    lmdb++版本跟踪它与之兼容的upstream LMDB发布( x.y.z ),并附加一个sub-patch-level版本( x.y. z。n ) 来指示对包装程序本身的更改。

    例如 0.9.14.2的lmdb++版本表示它是为了与 LMDB 0.9.14兼容而设计的,并且是第三个针对该 upstream 目标的包装版本( 第一个是. 0,第二个. 1 )。

    便笺

    在使用预处理器的早期版本时,包装器应该使用预处理程序来处理较旧版本的包装,而包装器的更新版本通常可以使用新版本的可见性,例如预处理器。

    安装

    lmdb++目前可以作为软件包/端口在以下操作系统发行版和软件包管理系统中使用:

    分发软件包 NAME 安装提示
    Arch Linuxliblmdb+ +yaourt -Sa liblmdb++
    lmdb+ +sudo fink install lmdb++
    MacPortslmdbxxsudo port install lmdbxx
    Portagelmdb+ +sudo emerge --ask lmdb++

    脚注

    [5]仍在等待审核。
    [6]兼容 Gentoo Linux,Funtoo Linux和 Sabayon Linux。

    支持

    要报告 Bug 或者提交补丁,请在GitHub的问题追踪器中提交问题。

    关于LMDB本身的问题和讨论应该直接指向 OpenLDAP邮件列表。

    在其他地方运行

    Find,,,,,。

    API文档在以下位置发布: http://lmdbxx.sourceforge.net/

    作者

    Arto Bendikenhttp://ar.to/

    许可证

    这是免费和不受限制的public 域软件。 有关更多信息,请参见 http://unlicense.org/ 或者附带的UNLICENSE 文件。


    数据  WRAP  换行    lmdb  
    相关文章