内容纲要

Constant Database PlusPlus(CDB ++)是散列数据库的 C ++ 实现,专门用于序列化和检索键与其值之间的静态关联。该数据库提供了几个功能:

  • 快速查找。该库实现了 Daniel J.Bernstein 提出的常量数据库的数据结构。
  • 占地面积小。CDB ++ 数据库由一个块头(16 个字节),散列表(每个记录 2048 个字节和 16 个字节)和实际记录(8 个字节加上每个记录的键 / 值大小)组成。
  • 快速哈希函数。CDB ++ 整合了 Austin Appleby 实现的字符串(MurmurHash 2.0)的快速和抗碰撞散列函数。
  • 块格式。CDB ++ 的结构被设计为将数据存储在文件的块中; CDB ++ 数据库可以嵌入到其他任意数据的文件中。
  • 简单的写入界面。CDB ++ 可以将散列数据库序列化为 C ++ 输出流(std::ostream)。
  • 简单的阅读界面。CDB ++ 可以从输入流(std::istream)或从文件中读取或存储映射数据库映像的内存块中准备散列数据库。
  • 跨平台。源代码可以在 Microsoft Visual Studio 2008,GNU C 编译器(gcc)等上编译。
  • 非常简单的 API。CDB ++ API 只提供一些功能; 只需查看示例代码即可使用该库。
  • 单 C ++ 头部实现。CDB ++ 在单个头文件(cdbpp.h)中实现; 只能通过在源代码中包含 cdbpp.h 来使用 CDB ++ API 。

为简单起见,CDB ++ 不支持这些:

  • 修改关联
  • 检查密钥中的冲突
  • 数据库格式在不同字节顺序体系结构上的兼容性

示例代码

此示例代码构建一个具有 100,000 个字符串 / 整数关联 “000000”/ 0,“000001”/ 1,…,“100000”/ 100000(在构建函数中)的数据库 “test.cdb”。然后代码发出字符串查询 “000000”,…,“100000”,并检查值是否正确(在读函数中)。

[cpp]
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>

#include <cdbpp.h>

#define N 100000
#define DBNAME "sample.cdb"

// Convert an integer to its string representation.
std::string int2str(int i)
{
std::stringstream ss;
ss << std::setfill(‘0’) << std::setw(6) << i;
return ss.str();
}

bool build()
{
// Open a database file for writing (with binary mode).
std::ofstream ofs(DBNAME, std::ios_base::binary);
if (ofs.fail()) {
std::cerr << "ERROR: Failed to open a database file." << std::endl;
return false;
}

try {
// Create an instance of CDB++ writer.
cdbpp::builder dbw(ofs);

// Insert key/value pairs to the CDB++ writer.
for (int i = 0;i < N;++i) {
std::string key = int2str(i);
dbw.put(key.c_str(), key.length(), &i, sizeof(i));
}

// Destructing the CDB++ writer flushes the database to the stream.

} catch (const cdbpp::builder_exception& e) {
// Abort if something went wrong…
std::cerr << "ERROR: " << e.what() << std::endl;
return false;
}

return true;
}

bool read()
{
// Open the database file for reading (with binary mode).
std::ifstream ifs(DBNAME, std::ios_base::binary);
if (ifs.fail()) {
std::cerr << "ERROR: Failed to open a database file." << std::endl;
return false;
}

try {
// Open the database from the input stream.
cdbpp::cdbpp dbr(ifs);
if (!dbr.is_open()) {
std::cerr << "ERROR: Failed to read a database file." << std::endl;
return false;
}

// Issue queries to the database.
for (int i = 0;i < N;++i) {
size_t vsize;
std::string key = int2str(i);
const int *value = (const int*)dbr.get(key.c_str(), key.length(), &vsize);
if (value == NULL) {
std::cerr << "ERROR: The key is not found." << std::endl;
return false;
}

if (vsize != sizeof(int) || *value != i) {
std::cerr << "ERROR: The key value is wrong." << std::endl;
return false;
}
}

} catch (const cdbpp::cdbpp_exception& e) {
// Abort if something went wrong…
std::cerr << "ERROR: " << e.what() << std::endl;
return false;
}

return true;
}

int main(int argc, char *argv[])
{
// Build a sample database and test it.
bool b = build() && read();
std::cout << (b ? "OK" : "FAIL") << std::endl;
return b ? 0 : 1;
}
[/cpp]

http://www.chokkan.org/software/cdbpp/

发表评论

电子邮件地址不会被公开。 必填项已用*标注