【问题标题】:BerkeleyDB Db->get not working when using custom comparison functionBerkeleyDB Db->使用自定义比较功能时无法正常工作
【发布时间】:2018-07-13 23:21:32
【问题描述】:

在一个 C++ 程序中,我尝试使用 Db::set_bt_function 成员函数为 Berkeley DB 设置自定义比较函数(DB 作为 BTREE 类型打开)。当我不更改比较功能时,我的代码工作正常;我可以使用Db::putDb::get 来放置和获取键/值。

为了尝试set_bt_function 方法,我将自己的“字典比较”定义如下:

int compkeys(Db *db, const Dbt *dbt1, const Dbt *dbt2, size_t *locp) {
        size_t s = dbt1->get_size() > dbt2->get_size() ? dbt2->get_size() : dbt1->get_size();
        int c = std::memcmp(dbt1->get_data(), dbt2->get_data(), s);
        if(c != 0) return c;
        if(dbt1->get_size() < dbt2->get_size()) return -1;
        if(dbt1->get_size() > dbt2->get_size()) return 1;
        return 0;
}

因此,当比较函数未更改时,这应该会导致与我的参考代码完全相同的行为,因为默认情况下,Berkeley DB 使用字典顺序。

然而,当使用这个比较功能时,Db::get 不再起作用了。它返回 -30999 (DB_BUFFER_SMALL)。

这是我为获取与给定键关联的值所做的工作:

Db* _dbm = ... /* DB is open */
std::vector<char> mykey;
... /* mykey is set to some content */
Dbt db_key((void*)(mykey.data()), uint32_t(mykey.size()));
Dbt db_data;
db_key.set_flags(DB_DBT_USERMEM);
db_data.set_flags(DB_DBT_MALLOC);
int status = _dbm->get(NULL, &db_key, &db_data, 0);
... /* check status, do something with db_data */
free(db_data.get_data());

知道为什么这段代码在我不设置比较函数时有效,而在我设置比较函数时无效吗?

注意:如果我使用光标 (Dbc::get) 访问键/值,则没有此问题。

【问题讨论】:

    标签: c++ berkeley-db


    【解决方案1】:

    在这种情况下,DB_BUFFER_SMALL 错误是在抱怨您的db_key Dbt。您需要致电db_key.set_ulen(uint32_t(mykey.size())) 告诉BDB 您分配了多少空间来保存来自数据库的密钥。

    当您使用自定义比较功能时,事情会变得有些奇怪。您可以在不属于比较的键中包含数据,而不是在您传递给get() 的键中。出于这个原因,BDB 会在您的 db_key 中返回它在数据库中找到的键。

    设置ulen 时,使其足够大以容纳可以从数据库返回的任何密钥。您可能会发现在堆栈中保留一个 char 数组来处理此键输入/输出行为更为明智。

    【讨论】:

    • 太好了,成功了! (为什么没有记录在任何地方......?)谢谢!
    • 我不知道! BDB 文档表面上看起来不错。但他们似乎总是缺少你需要的东西!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-22
    • 1970-01-01
    • 1970-01-01
    • 2017-09-23
    • 2016-08-06
    相关资源
    最近更新 更多