BerkeleyDB Db->使用自定义比较函数时无法工作

BerkeleyDB Db->get not working when using custom comparison function

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

放置和获取 keys/values

为了尝试 set_bt_function 方法,我定义了自己的 "lexicographic comparison" 如下:

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 不再起作用。它returns-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) 访问 key/values,则不会出现此问题。

本例中的 DB_BUFFER_SMALL 错误是在抱怨您的 db_key Dbt。您需要调用 db_key.set_ulen(uint32_t(mykey.size())) 来告诉 BDB 您分配了多少 space 来保存从数据库中出来的密钥。

当您使用自定义比较函数时,事情会变得有点奇怪。您可以在不属于比较的键中包含数据 - 而不是在您传递给 get() 的键中。因此,BDB returns 它在您的 db_key.

数据库中找到的密钥

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