在 RocksDB 中存储任意字节
Storing arbitrary bytes in RocksDB
RocksDB 声明它可以存储任意数据,但 API 仅支持 std::string
类型。我想存储 std::vector<T>
值,如果我想这样做,我必须将其转换为 std::string
。
是否有更安全的方式来存储任意类型?
作为键值存储,RocksDB 可以存储"arbitrary byte array"。对于您的用例,您需要通过某种方式将 std::vector<T>
序列化为字节数组,以便将其放入 std::string
中。请注意,输入 std::string
不需要以零结尾。
我倾向于使用下面的pack/unpackstructures/classes到std::string使用模板来自动调整自己的大小
template <typename T>
std::string Pack(const T* data)
{
std::string d(sizeof(T), L'[=10=]');
memcpy(&d[0], data, d.size());
return d;
}
template <typename T>
std::unique_ptr<T> Unpack(const std::string& data)
{
if (data.size() != sizeof(T))
return nullptr;
auto d = std::make_unique<T>();
memcpy(d.get(), data.data(), data.size());
return d;
}
因此以下客户端代码可以将结构打包和解包到数据库中:
// Test structure
BOB b = {};
b.a = 12;
b.b = 144;
b.c[0] = 's';
b.c[1] = '[=11=]';
// Write to the db
status = pDb->Put(rocksdb::WriteOptions(), key, Pack(&b));
// Read from db with same key
std::string result;
status = pDb->Get(rocksdb::ReadOptions(), key, &result);
std::unique_ptr<BOB> pBob = Unpack<BOB>(result);
if (b.a == pBob->a && b.b == pBob->b && b.c[0] == pBob->c[0])
{
printf("Structure matches!\n");
}
else
{
printf("Structure doesn't match!\n");
}
RocksDB 声明它可以存储任意数据,但 API 仅支持 std::string
类型。我想存储 std::vector<T>
值,如果我想这样做,我必须将其转换为 std::string
。
是否有更安全的方式来存储任意类型?
作为键值存储,RocksDB 可以存储"arbitrary byte array"。对于您的用例,您需要通过某种方式将 std::vector<T>
序列化为字节数组,以便将其放入 std::string
中。请注意,输入 std::string
不需要以零结尾。
我倾向于使用下面的pack/unpackstructures/classes到std::string使用模板来自动调整自己的大小
template <typename T>
std::string Pack(const T* data)
{
std::string d(sizeof(T), L'[=10=]');
memcpy(&d[0], data, d.size());
return d;
}
template <typename T>
std::unique_ptr<T> Unpack(const std::string& data)
{
if (data.size() != sizeof(T))
return nullptr;
auto d = std::make_unique<T>();
memcpy(d.get(), data.data(), data.size());
return d;
}
因此以下客户端代码可以将结构打包和解包到数据库中:
// Test structure
BOB b = {};
b.a = 12;
b.b = 144;
b.c[0] = 's';
b.c[1] = '[=11=]';
// Write to the db
status = pDb->Put(rocksdb::WriteOptions(), key, Pack(&b));
// Read from db with same key
std::string result;
status = pDb->Get(rocksdb::ReadOptions(), key, &result);
std::unique_ptr<BOB> pBob = Unpack<BOB>(result);
if (b.a == pBob->a && b.b == pBob->b && b.c[0] == pBob->c[0])
{
printf("Structure matches!\n");
}
else
{
printf("Structure doesn't match!\n");
}