Skip to content

Commit 3300ca0

Browse files
committed
Add rocksdb.iterator.internal-key property
Summary: Added a new iterator property: `rocksdb.iterator.internal-key` to get the internal-key (converted to user key) at which the iterator stopped. Closes #3525 Differential Revision: D7033694 Pulled By: sagar0 fbshipit-source-id: d51e6c00f5e9d766c6276ef79774b81c6c5216f8
1 parent aa3b8bb commit 3300ca0

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed

db/db_iter.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,9 @@ class DBIter final: public Iterator {
217217
*prop = "Iterator is not valid.";
218218
}
219219
return Status::OK();
220+
} else if (prop_name == "rocksdb.iterator.internal-key") {
221+
*prop = saved_key_.GetUserKey().ToString();
222+
return Status::OK();
220223
}
221224
return Status::InvalidArgument("Undentified property.");
222225
}

db/db_iterator_test.cc

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ TEST_F(DBIteratorTest, IteratorProperty) {
5555
Options options = CurrentOptions();
5656
CreateAndReopenWithCF({"pikachu"}, options);
5757
Put(1, "1", "2");
58+
Delete(1, "2");
5859
ReadOptions ropt;
5960
ropt.pin_data = false;
6061
{
@@ -64,9 +65,15 @@ TEST_F(DBIteratorTest, IteratorProperty) {
6465
ASSERT_NOK(iter->GetProperty("non_existing.value", &prop_value));
6566
ASSERT_OK(iter->GetProperty("rocksdb.iterator.is-key-pinned", &prop_value));
6667
ASSERT_EQ("0", prop_value);
68+
ASSERT_OK(iter->GetProperty("rocksdb.iterator.internal-key", &prop_value));
69+
ASSERT_EQ("1", prop_value);
6770
iter->Next();
6871
ASSERT_OK(iter->GetProperty("rocksdb.iterator.is-key-pinned", &prop_value));
6972
ASSERT_EQ("Iterator is not valid.", prop_value);
73+
74+
// Get internal key at which the iteration stopped (tombstone in this case).
75+
ASSERT_OK(iter->GetProperty("rocksdb.iterator.internal-key", &prop_value));
76+
ASSERT_EQ("2", prop_value);
7077
}
7178
Close();
7279
}
@@ -2157,6 +2164,48 @@ TEST_F(DBIteratorTest, SkipStatistics) {
21572164
ASSERT_EQ(skip_count, TestGetTickerCount(options, NUMBER_ITER_SKIP));
21582165
}
21592166

2167+
TEST_F(DBIteratorTest, SeekAfterHittingManyInternalKeys) {
2168+
Options options = CurrentOptions();
2169+
DestroyAndReopen(options);
2170+
ReadOptions ropts;
2171+
ropts.max_skippable_internal_keys = 2;
2172+
2173+
Put("1", "val_1");
2174+
// Add more tombstones than max_skippable_internal_keys so that Next() fails.
2175+
Delete("2");
2176+
Delete("3");
2177+
Delete("4");
2178+
Delete("5");
2179+
Put("6", "val_6");
2180+
2181+
unique_ptr<Iterator> iter(db_->NewIterator(ropts));
2182+
iter->SeekToFirst();
2183+
2184+
ASSERT_TRUE(iter->Valid());
2185+
ASSERT_EQ(iter->key().ToString(), "1");
2186+
ASSERT_EQ(iter->value().ToString(), "val_1");
2187+
2188+
// This should fail as incomplete due to too many non-visible internal keys on
2189+
// the way to the next valid user key.
2190+
iter->Next();
2191+
ASSERT_TRUE(!iter->Valid());
2192+
ASSERT_TRUE(iter->status().IsIncomplete());
2193+
2194+
// Get the internal key at which Next() failed.
2195+
std::string prop_value;
2196+
ASSERT_OK(iter->GetProperty("rocksdb.iterator.internal-key", &prop_value));
2197+
ASSERT_EQ("4", prop_value);
2198+
2199+
// Create a new iterator to seek to the internal key.
2200+
unique_ptr<Iterator> iter2(db_->NewIterator(ropts));
2201+
iter2->Seek(prop_value);
2202+
ASSERT_TRUE(iter2->Valid());
2203+
ASSERT_OK(iter2->status());
2204+
2205+
ASSERT_EQ(iter2->key().ToString(), "6");
2206+
ASSERT_EQ(iter2->value().ToString(), "val_6");
2207+
}
2208+
21602209
} // namespace rocksdb
21612210

21622211
int main(int argc, char** argv) {

include/rocksdb/iterator.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ class Iterator : public Cleanable {
9797
// Property "rocksdb.iterator.super-version-number":
9898
// LSM version used by the iterator. The same format as DB Property
9999
// kCurrentSuperVersionNumber. See its comment for more information.
100+
// Property "rocksdb.iterator.internal-key":
101+
// Get the user-key portion of the internal key at which the iteration
102+
// stopped.
100103
virtual Status GetProperty(std::string prop_name, std::string* prop);
101104

102105
private:

0 commit comments

Comments
 (0)