c++ 按前缀RocksDb索引的反向迭代

v1l68za4  于 2023-06-07  发布在  其他
关注(0)|答案(2)|浏览(171)

我目前正在使用一个RocksDB数据库的个人项目,我试图得到所有的内容在我的数据库是由一个前缀索引的逆序。但是我没有找到适合我的循环的代码。我觉得我错过了什么。下面是我的代码:

//My iterator is already created with the rocksdb::ReadOptions()
    rocksdb::Slice key{reinterpret_cast<const char *>(indexToFind), sizeof(indexToFind};
    std::vector<int> ids;

    it->SeekForPrev(key);
    auto currentKey = it->key();
    while(it->Valid() && it->key().starts_with(key)) {

        /* Some custom treatment here */

        it->SeekForPrev(it->key());
        it->Prev();
        currentKey = it->key();
    }

    if (!it->status().ok()) {
        std::cout << it->status().ToString() << std::endl;
    }
    assert(it->status().ok()); // Check for any errors found during the scan

先谢谢你了,克莱芒。

xesrikrc

xesrikrc1#

我认为原生rocksdb还不支持使用Prefix的反向迭代。你可以很好地从他们的wiki中找到Prefix Seek API。以下是维基中PrefixSeekAPI的限制:
SeekToLast()不支持前缀迭代。SeekToFirst()仅受某些配置支持。如果要对迭代器执行这些类型的查询,则应该使用总顺序模式。
使用前缀迭代的一个常见错误是使用前缀模式以逆序进行迭代。但目前还不支持。如果反向迭代是常见的查询模式,则可以对数据重新排序,将迭代顺序改为正向。你可以通过实现一个定制的比较器来实现它,或者以不同的方式编码你的密钥。
请参阅此处的wiki

ulydmbyx

ulydmbyx2#

public List<byte[]> reverseList(int limit, byte[] prefixKey, byte[] startKey, byte[] endKey) {
    ReadOptions options = new ReadOptions();
    options.setPrefixSameAsStart(true);
    options.setTotalOrderSeek(true);
    RocksIterator iterator = rocksDB.newIterator(options);
    List<byte[]> result = new ArrayList<>();
    for(iterator.seekForPrev(getNextByteArray(prefixKey));iterator.isValid(); iterator.prev()){
        byte[] key = iterator.key();
        result.add(key);
    }
    iterator.close();
    return result;
}

public static byte[] getNextByteArray(byte[] bytes) {
    byte[] result = new byte[bytes.length];
    int carry = 1;
    for (int i = bytes.length - 1; i >= 0; i--) {
        int sum = (bytes[i] & 0xff) + carry;
        result[i] = (byte) sum;
        carry = (sum >> 8) & 0xff;
    }
    return result;
}

相关问题