-
Notifications
You must be signed in to change notification settings - Fork 6.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a new interface method SecondaryIndex::NewIterator to enable querying the index #13257
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
// 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, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see that ReadOptions are not being passed here yet. I assume that will come in the later PRs? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, this implementation doesn't use any read options; however, for example, the index iterator for vector similarity search will |
||
std::unique_ptr<Iterator>&& underlying_it) | ||
: index_(index), underlying_it_(std::move(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_; | ||
std::unique_ptr<Iterator> underlying_it_; | ||
Status status_; | ||
std::string prefix_; | ||
}; | ||
|
||
} // namespace ROCKSDB_NAMESPACE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we'd want to add EXPERIMENTAL tag
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The entire secondary indexing functionality (including this class) is currently marked as being "under construction" but hopefully will graduate to "experimental" soon ;)