DeleteRange causes put then iterate to fail on WBWI
- Dominant language
- C++
- Stars
- 32.1k
- Forks
- 6.9k
- Avg merge
- 32m
- Merged PRs (30d)
- 1
Description
Putting the following 3 key/value pairs into a `WBWI` (`WriteBatchWithIndex`), i.e.:
```c++
batch.Put(&cf1, "a1", "some value");
batch.Put(&cf1, "a2", "some value");
batch.Put(&cf1, "a3", "some value");
```
With respect to `batch.NewIteratorWithBase`, iterating returns just those 3 key/value pairs correctly. So far so good!
---
However, if I call `batch.DeleteRange("a", "b")` before putting the values into the WBWI, then subsequently iterating the WBWI incorrectly returns 4 key/value pairs and not 3, i.e. the following code appears to cause false data to appear:
```c++
batch.DeleteRange("a", "b")
batch.Put(&cf1, "a1", "some value");
batch.Put(&cf1, "a2", "some value");
batch.Put(&cf1, "a3", "some value");
```
The first key/value pair returned by `NewIteratorWithBase` seems to be an error as its key has the value `a`, yet we never stored any such key!
I have created a reproducible test case showing the problem that fits into `utilities/write_batch_with_index/write_batch_with_index_test.cc`:
```c++
TEST_F(WriteBatchWithIndexTest, TestIteraratorWithBaseDeleteRange) {
ColumnFamilyHandleImplDummy cf1(6, BytewiseComparator());
WriteBatchWithIndex batch(BytewiseComparator(), 0, true);
std::string key1("a1");
std::string key2("a2");
std::string key3("a3");
const std::string fixed_value("some value");
// delete a range (NOTE: the line below erroneously causes the test to fail!!!)
batch.DeleteRange(&cf1, "a", "b");
// put keys in the range we just deleted
batch.Put(&cf1, key1, fixed_value);
batch.Put(&cf1, key2, fixed_value);
batch.Put(&cf1, key3, fixed_value);
// retrieve keys using iterator
KVMap empty_map;
std::unique_ptr iter(
batch.NewIteratorWithBase(&cf1, new KVIter(&empty_map)));
iter->Seek("a");
// check key1
ASSERT_OK(iter->status());
ASSERT_TRUE(iter->Valid());
ASSERT_EQ(key1, iter->key().ToString());
ASSERT_EQ(fixed_value, iter->value().ToString());
iter->Next();
// check key2
ASSERT_OK(iter->status());
ASSERT_TRUE(iter->Valid());
ASSERT_EQ(key2, iter->key().ToString());
ASSERT_EQ(fixed_value, iter->value().ToString());
iter->Next();
// check key3
ASSERT_OK(iter->status());
ASSERT_TRUE(iter->Valid());
ASSERT_EQ(key3, iter->key().ToString());
ASSERT_EQ(fixed_value, iter->value().ToString());
// should have reached the end of iterator
iter->Next();
ASSERT_OK(iter->status());
ASSERT_FALSE(iter->Valid());
}
```
Commenting out the `batch.DeleteRange(&cf1, "a", "b");` above causes the test to pass, but I don't think it should actually have an impact on the iterator produced from `WriteBatchWithIndex::NewIteratorWithBase`.
Can someone please confirm that this is indeed an issue... and that I am not doing something blindly stupid ;-)
Contributor guide
Assessment
This issue has not been assessed yet.