在RocksDB中存储任意字节

时间:2015-07-22 14:10:11

标签: rocksdb

RocksDB声明它可以存储任意数据,但API仅支持std::string类型。我想存储std::vector<T>值,如果我想这样做,那么我必须将其转换为std::string

存储任意类型的方法是否不那么脆弱?

2 个答案:

答案 0 :(得分:2)

作为键值存储,RocksDB可以存储“任意字节数组”。对于您的用例,您需要有一些方法将std::vector<T>序列化为字节数组,以便将其放入std::string。请注意,输入std::string不需要以零终止。

答案 1 :(得分:1)

我倾向于使用以下命令将结构/类打包/解压缩到std :: string,使用模板自动调整它们的大小。

template <typename T>
std::string Pack(const T* data)
{
    std::string d(sizeof(T), L'\0');
    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] = '\0';

    // 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");
    }