在C ++程序中,我尝试使用<span>
成员函数(DB作为BTREE类型打开)为Berkeley DB设置自定义比较函数。当我不更改比较功能时,我的代码工作正常;我可以使用Db::set_bt_function
和Db::put
来放置和获取键/值。
为了尝试Db::get
方法,我将自己的“词典比较”定义如下:
set_bt_function
因此,当比较函数未更改时,这应该导致与我的参考代码完全相同的行为,因为默认情况下Berkeley DB使用字典顺序。
然而,当使用此比较功能时,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;
}
不再起作用。它返回-30999(DB_BUFFER_SMALL)。
我正在做的是获取与给定密钥相关联的值:
Db::get
当我没有设置比较功能时,知道为什么这段代码有效,而当我没有这样做时,我知道吗?
注意:如果我使用游标(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());
)访问键/值,我没有这个问题。
答案 0 :(得分:2)
此案例中的DB_BUFFER_SMALL
错误是抱怨您的db_key Dbt
。您需要调用db_key.set_ulen(uint32_t(mykey.size()))
告诉BDB您已分配多少空间来保存数据库中出来的密钥。
当您使用自定义比较功能时,事情会变得更加怪异。您可以在密钥中包含不属于比较的数据 - 而不是您传入get()
的密钥。因此,BDB返回它在db_key中的数据库中找到的密钥。
设置ulen
时,请将其设置为足以容纳可从数据库返回的任何密钥。您可能会发现,只需在堆栈中保留char
数组即可处理此键入/换行为。