forked from facebook/rocksdb
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a new interface method SecondaryIndex::NewIterator to enable quer…
…ying the index (facebook#13257) Summary: The patch adds a new API `NewIterator` to `SecondaryIndex`, which should return an iterator that can be used by applications to query the index. This method takes a `ReadOptions` structure, which can be used by applications to provide (implementation-specific) query parameters to the index, and an underlying iterator, which should be an iterator over the index's secondary column family, and is expected to be leveraged by the returned iterator to read the actual secondary index entries. (Providing the underlying iterator this way enables querying the index as of a specific point in time for example.) Querying the index can be performed by calling the returned iterator's `Seek` API with a search target, and then using `Next` (and potentially `Prev`) to iterate through the matching index entries. `SeekToFirst`, `SeekToLast`, and `SeekForPrev` are not expected to be supported by the iterator. The iterator should expose primary keys, that is, the secondary key prefix should be stripped from the index entries. The exact semantics of the returned iterator depend on the index and are implementation-specific. For simple indices, the search target might be a primary column value, and the iterator might return all primary keys that have the given column value. (This behavior can be achieved using the new class `SecondaryIndexIterator`.) However, other semantics are also possible: for vector indices, the search target might be a vector, and the iterator might return similar vectors from the index. (This will be implemented for `FaissIVFIndex` in a subsequent patch.) Differential Revision: D67684777
- Loading branch information
1 parent
3570e4f
commit 8f3e75f
Showing
5 changed files
with
275 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
// Copyright (c) Meta Platforms, Inc. and affiliates. | ||
// | ||
// This source code is licensed under both the GPLv2 (found in the | ||
// COPYING file in the root directory) and Apache 2.0 License | ||
// (found in the LICENSE.Apache file in the root directory). | ||
|
||
#pragma once | ||
|
||
#include <cassert> | ||
#include <string> | ||
|
||
#include "rocksdb/iterator.h" | ||
#include "rocksdb/status.h" | ||
#include "rocksdb/utilities/secondary_index.h" | ||
#include "util/overload.h" | ||
|
||
namespace ROCKSDB_NAMESPACE { | ||
|
||
// A simple iterator that can be used to query a secondary index (that is, find | ||
// the primary keys for a given search target). Can be used as-is or as a | ||
// building block for more complex iterators. | ||
class SecondaryIndexIterator : public Iterator { | ||
public: | ||
SecondaryIndexIterator(const SecondaryIndex* index, Iterator* underlying_it) | ||
: index_(index), underlying_it_(underlying_it) { | ||
assert(index_); | ||
assert(underlying_it_); | ||
} | ||
|
||
bool Valid() const override { | ||
return status_.ok() && underlying_it_->Valid() && | ||
underlying_it_->key().starts_with(prefix_); | ||
} | ||
|
||
void SeekToFirst() override { | ||
status_ = Status::NotSupported( | ||
"SeekToFirst is not supported for secondary index iterators"); | ||
} | ||
|
||
void SeekToLast() override { | ||
status_ = Status::NotSupported( | ||
"SeekToLast is not supported for secondary index iterators"); | ||
} | ||
|
||
void Seek(const Slice& target) override { | ||
status_ = Status::OK(); | ||
|
||
std::variant<Slice, std::string> prefix; | ||
|
||
const Status s = index_->GetSecondaryKeyPrefix(target, &prefix); | ||
if (!s.ok()) { | ||
status_ = s; | ||
return; | ||
} | ||
|
||
prefix_ = std::visit( | ||
overload{ | ||
[](const Slice& value) -> std::string { return value.ToString(); }, | ||
[](const std::string& value) -> std::string { return value; }}, | ||
prefix); | ||
|
||
// FIXME: this works for BytewiseComparator but not for all comparators in | ||
// general | ||
underlying_it_->Seek(prefix_); | ||
} | ||
|
||
void SeekForPrev(const Slice& /* target */) override { | ||
status_ = Status::NotSupported( | ||
"SeekForPrev is not supported for secondary index iterators"); | ||
} | ||
|
||
void Next() override { | ||
assert(Valid()); | ||
|
||
underlying_it_->Next(); | ||
} | ||
|
||
void Prev() override { | ||
assert(Valid()); | ||
|
||
underlying_it_->Prev(); | ||
} | ||
|
||
bool PrepareValue() override { | ||
assert(Valid()); | ||
|
||
return underlying_it_->PrepareValue(); | ||
} | ||
|
||
Status status() const override { | ||
if (!status_.ok()) { | ||
return status_; | ||
} | ||
|
||
return underlying_it_->status(); | ||
} | ||
|
||
Slice key() const override { | ||
assert(Valid()); | ||
|
||
Slice key = underlying_it_->key(); | ||
key.remove_prefix(prefix_.size()); | ||
|
||
return key; | ||
} | ||
|
||
Slice value() const override { | ||
assert(Valid()); | ||
|
||
return underlying_it_->value(); | ||
} | ||
|
||
const WideColumns& columns() const override { | ||
assert(Valid()); | ||
|
||
return underlying_it_->columns(); | ||
} | ||
|
||
Slice timestamp() const override { | ||
assert(Valid()); | ||
|
||
return underlying_it_->timestamp(); | ||
} | ||
|
||
Status GetProperty(std::string prop_name, std::string* prop) override { | ||
return underlying_it_->GetProperty(std::move(prop_name), prop); | ||
} | ||
|
||
private: | ||
const SecondaryIndex* index_; | ||
Iterator* underlying_it_; | ||
Status status_; | ||
std::string prefix_; | ||
}; | ||
|
||
} // namespace ROCKSDB_NAMESPACE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters