如何在RocksDbSharp的read_options中设置prefix_same_as_start

时间:2018-09-22 17:06:31

标签: c# rocksdb

我正在使用RocksDbSharp库,该库是C#中来自Facebook的RocksDb的实现。我想通过一个键来过滤我的记录,但是不幸的是,我没有看到如何执行此操作的选项。这是示例代码:

static void Main(string[] args)
{
    string directory = @"C:\Path\To\RocksDB\Storage";

    DbOptions options = new DbOptions().SetCreateIfMissing(true);

    using (RocksDb rocksDb = RocksDb.Open(options, directory))
    {
        rocksDb.Put("AAAAB", "Test 1");
        rocksDb.Put("AAABB", "Test 2");
        rocksDb.Put("AABBB", "Test 3");
        rocksDb.Put("ABBBB", "Test 4");
        rocksDb.Put("BBBBB", "Test 5");

        List<string> keys = new List<string>();

        using (Iterator iterator = rocksDb.NewIterator())
        {
            iterator.Seek("AAB");

            while (iterator.Valid())
            {
                keys.Add(iterator.StringKey());

                iterator.Next();
            }
        }

        Console.WriteLine(string.Join(", ", keys));
        Console.ReadLine();
    }
}

输出为:

  

AABBB,ABBBB,BBBBB

如何更改它,因此输出仅为AABBB?我读了Iterator wikiPrefix Seek API,可以将prefix_same_as_start设置为true

  

如果前缀的键没有等于或大于lookup_key,或者在调用一个或多个Next()之后,我们完成了该前缀的所有键,则可能返回Valid()= false或任何大于上一个键,具体取决于ReadOptions.prefix_same_as_start = true。

此外,对此ticket进行了解释:

  

如果只希望键以前缀002开头,请使用read_options.prefix_same_as_start,该键仅显示与查找时具有相同前缀的键。

如何将该属性设置为true?如果检查ReadOptions class的实现,将找不到设置此属性的任何内容。我还有其他过滤键的选项吗?

1 个答案:

答案 0 :(得分:0)

要通过前缀检索,应首先创建一个前缀提取器。

Options options;
options.prefix_extractor.reset(NewFixedPrefixTransform(<Length of the prefix>));

并使用这些选项打开数据库。

在ReadOptions中将prefix_same_as_start设置为true。

以下代码段可能会帮助您(尽管使用C ++编写)

int main()
{
    DB *db;
    Options options;
    options.IncreaseParallelism();
    options.OptimizeLevelStyleCompaction();
    options.create_if_missing = true;
    options.prefix_extractor.reset(NewFixedPrefixTransform(3));

    Status s = DB::Open(options, kDBPath, &db);
    assert(s.ok());

    s = db->Put(WriteOptions(), "AAAAB", "value1");
    assert(s.ok());    
    s = db->Put(WriteOptions(), "AAABB", "value2");
    assert(s.ok());
    s = db->Put(WriteOptions(), "AABBB", "value3");
    assert(s.ok());
    s = db->Put(WriteOptions(), "ABBBB", "value4");
    assert(s.ok());
    s = db->Put(WriteOptions(), "BBBBB", "value5");
    assert(s.ok());

    ReadOptions read_options;
    read_options.prefix_same_as_start = true;

    Iterator *iter = db->NewIterator(read_options);
    iter->Seek("AAB");

    while (iter->Valid())
    {
        printf("key %s\n", iter->key().ToString().c_str());
        iter->Next();
    }

    delete iter;
    delete db;
    return 0;
}

由于rocksdb是用c ++编写的,因此如果不存在,则将you might want to write a wrapper function用于prefix_same_as_start并将其包括在内。 对于包装函数示例,在rocksdb本机代码中,有文件c.cc/c.h用C语言为各种rocksdb选项编写包装函数。您可以用C#编写一个以满足您的要求。 :)