Skip to content
This repository was archived by the owner on Sep 27, 2019. It is now read-only.

Commit 93743bf

Browse files
authored
Merge pull request #1276 from wangziqi2013/non-unique-key-fix
BwTree non-unique key insert fix
2 parents a9d83a0 + 09cf612 commit 93743bf

File tree

5 files changed

+60
-32
lines changed

5 files changed

+60
-32
lines changed

src/include/index/bwtree.h

100644100755
Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2986,7 +2986,8 @@ class BwTree : public BwTreeBase {
29862986
* If both are nullptr then we just traverse and do not do anything
29872987
*/
29882988
const KeyValuePair *Traverse(Context *context_p, const ValueType *value_p,
2989-
std::pair<int, bool> *index_pair_p) {
2989+
std::pair<int, bool> *index_pair_p,
2990+
bool unique_key=false) {
29902991
// For value collection it always returns nullptr
29912992
const KeyValuePair *found_pair_p = nullptr;
29922993

@@ -3072,7 +3073,7 @@ class BwTree : public BwTreeBase {
30723073
} else {
30733074
// If a value is given then use this value to Traverse down leaf
30743075
// page to find whether the value exists or not
3075-
found_pair_p = NavigateLeafNode(context_p, *value_p, index_pair_p);
3076+
found_pair_p = NavigateLeafNode(context_p, *value_p, index_pair_p, unique_key);
30763077
}
30773078

30783079
if (context_p->abort_flag == true) {
@@ -4172,7 +4173,8 @@ class BwTree : public BwTreeBase {
41724173
*/
41734174
const KeyValuePair *NavigateLeafNode(Context *context_p,
41744175
const ValueType &search_value,
4175-
std::pair<int, bool> *index_pair_p) {
4176+
std::pair<int, bool> *index_pair_p,
4177+
bool unique_key=false) {
41764178
// This will go to the right sibling until we have seen
41774179
// a node whose range match the search key
41784180
NavigateSiblingChain(context_p);
@@ -4217,7 +4219,7 @@ class BwTree : public BwTreeBase {
42174219
// We do not need to check any delete set here, since if the
42184220
// value has been deleted earlier then this function would
42194221
// already have returned
4220-
if (ValueCmpEqual(scan_start_it->second, search_value)) {
4222+
if (unique_key == true || ValueCmpEqual(scan_start_it->second, search_value)) {
42214223
// Since only Delete() will use this piece of information
42224224
// we set exist flag to false to indicate that the value
42234225
// has been invalidated
@@ -4245,7 +4247,7 @@ class BwTree : public BwTreeBase {
42454247
static_cast<const LeafInsertNode *>(node_p);
42464248

42474249
if (KeyCmpEqual(search_key, insert_node_p->item.first)) {
4248-
if (ValueCmpEqual(insert_node_p->item.second, search_value)) {
4250+
if (unique_key == true || ValueCmpEqual(insert_node_p->item.second, search_value)) {
42494251
// Only Delete() will use this
42504252
// We just simply inherit from the first node
42514253
*index_pair_p = insert_node_p->GetIndexPair();
@@ -4264,7 +4266,7 @@ class BwTree : public BwTreeBase {
42644266

42654267
// If the value was deleted then return false
42664268
if (KeyCmpEqual(search_key, delete_node_p->item.first)) {
4267-
if (ValueCmpEqual(delete_node_p->item.second, search_value)) {
4269+
if (unique_key == true || ValueCmpEqual(delete_node_p->item.second, search_value)) {
42684270
// Only Insert() will use this
42694271
// We just simply inherit from the first node
42704272
*index_pair_p = delete_node_p->GetIndexPair();
@@ -6993,8 +6995,12 @@ class BwTree : public BwTreeBase {
69936995
*
69946996
* This function returns false if value already exists
69956997
* If CAS fails this function retries until it succeeds
6998+
*
6999+
* Note that this function also takes a unique_key argument, to indicate whether
7000+
* we allow the same key with different values. For a primary key index this
7001+
* should be set true. By default we allow non-unique key
69967002
*/
6997-
bool Insert(const KeyType &key, const ValueType &value) {
7003+
bool Insert(const KeyType &key, const ValueType &value, bool unique_key=false) {
69987004
LOG_TRACE("Insert called");
69997005

70007006
#ifdef BWTREE_DEBUG
@@ -7011,7 +7017,7 @@ class BwTree : public BwTreeBase {
70117017
// Also if the key previously exists in the delta chain
70127018
// then return the position of the node using next_key_p
70137019
// if there is none then return nullptr
7014-
const KeyValuePair *item_p = Traverse(&context, &value, &index_pair);
7020+
const KeyValuePair *item_p = Traverse(&context, &value, &index_pair, unique_key);
70157021

70167022
// If the key-value pair already exists then return false
70177023
if (item_p != nullptr) {

src/index/bwtree_index.cpp

100644100755
Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ BWTREE_INDEX_TYPE::BWTreeIndex(IndexMetadata *metadata)
3838
container{false, comparator, equals, hash_func} {
3939
return;
4040
}
41-
41+
4242
BWTREE_TEMPLATE_ARGUMENTS
4343
BWTREE_INDEX_TYPE::~BWTreeIndex() {}
4444

@@ -53,15 +53,20 @@ bool BWTREE_INDEX_TYPE::InsertEntry(const storage::Tuple *key,
5353
KeyType index_key;
5454
index_key.SetFromKey(key);
5555

56-
bool ret = container.Insert(index_key, value);
56+
bool ret;
57+
if(HasUniqueKeys() == true) {
58+
ret = container.Insert(index_key, value, true);
59+
} else {
60+
ret = container.Insert(index_key, value, false);
61+
}
5762

58-
if (static_cast<StatsType>(settings::SettingsManager::GetInt(
59-
settings::SettingId::stats_mode)) != StatsType::INVALID) {
63+
if (static_cast<StatsType>(settings::SettingsManager::GetInt(settings::SettingId::stats_mode)) != StatsType::INVALID) {
6064
stats::BackendStatsContext::GetInstance()->IncrementIndexInserts(metadata);
6165
}
6266

67+
// NOTE: If I use index_key.GetInfo() here, I always get an empty key?
6368
LOG_TRACE("InsertEntry(key=%s, val=%s) [%s]",
64-
index_key.GetInfo().c_str(),
69+
key->GetInfo().c_str(),
6570
IndexUtil::GetInfo(value).c_str(),
6671
(ret ? "SUCCESS" : "FAIL"));
6772

@@ -85,14 +90,13 @@ bool BWTREE_INDEX_TYPE::DeleteEntry(const storage::Tuple *key,
8590
// it is unnecessary for us to allocate memory
8691
bool ret = container.Delete(index_key, value);
8792

88-
if (static_cast<StatsType>(settings::SettingsManager::GetInt(
89-
settings::SettingId::stats_mode)) != StatsType::INVALID) {
93+
if (static_cast<StatsType>(settings::SettingsManager::GetInt(settings::SettingId::stats_mode)) != StatsType::INVALID) {
9094
stats::BackendStatsContext::GetInstance()->IncrementIndexDeletes(
9195
delete_count, metadata);
9296
}
9397

9498
LOG_TRACE("DeleteEntry(key=%s, val=%s) [%s]",
95-
index_key.GetInfo().c_str(),
99+
key->GetInfo().c_str(),
96100
IndexUtil::GetInfo(value).c_str(),
97101
(ret ? "SUCCESS" : "FAIL"));
98102

@@ -122,8 +126,7 @@ bool BWTREE_INDEX_TYPE::CondInsertEntry(
122126
assert(ret == false);
123127
}
124128

125-
if (static_cast<StatsType>(settings::SettingsManager::GetInt(
126-
settings::SettingId::stats_mode)) != StatsType::INVALID) {
129+
if (static_cast<StatsType>(settings::SettingsManager::GetInt(settings::SettingId::stats_mode)) != StatsType::INVALID) {
127130
stats::BackendStatsContext::GetInstance()->IncrementIndexInserts(metadata);
128131
}
129132

@@ -197,8 +200,7 @@ void BWTREE_INDEX_TYPE::Scan(
197200
}
198201
} // if is full scan
199202

200-
if (static_cast<StatsType>(settings::SettingsManager::GetInt(
201-
settings::SettingId::stats_mode)) != StatsType::INVALID) {
203+
if (static_cast<StatsType>(settings::SettingsManager::GetInt(settings::SettingId::stats_mode)) != StatsType::INVALID) {
202204
stats::BackendStatsContext::GetInstance()->IncrementIndexReads(
203205
result.size(), metadata);
204206
}
@@ -222,6 +224,7 @@ void BWTREE_INDEX_TYPE::ScanLimit(
222224
const std::vector<ExpressionType> &expr_list,
223225
ScanDirectionType scan_direction, std::vector<ValueType> &result,
224226
const ConjunctionScanPredicate *csp_p, uint64_t limit, uint64_t offset) {
227+
225228
// Only work with limit == 1 and offset == 0
226229
// Because that gets translated to "min"
227230
// But still since we could not access tuples in the table
@@ -243,6 +246,7 @@ void BWTREE_INDEX_TYPE::ScanLimit(
243246
auto scan_itr = container.Begin(index_low_key);
244247
if ((scan_itr.IsEnd() == false) &&
245248
(container.KeyCmpLessEqual(scan_itr->first, index_high_key))) {
249+
246250
result.push_back(scan_itr->second);
247251
}
248252
} else {
@@ -263,8 +267,7 @@ void BWTREE_INDEX_TYPE::ScanAllKeys(std::vector<ValueType> &result) {
263267
it++;
264268
}
265269

266-
if (static_cast<StatsType>(settings::SettingsManager::GetInt(
267-
settings::SettingId::stats_mode)) != StatsType::INVALID) {
270+
if (static_cast<StatsType>(settings::SettingsManager::GetInt(settings::SettingId::stats_mode)) != StatsType::INVALID) {
268271
stats::BackendStatsContext::GetInstance()->IncrementIndexReads(
269272
result.size(), metadata);
270273
}
@@ -280,8 +283,7 @@ void BWTREE_INDEX_TYPE::ScanKey(const storage::Tuple *key,
280283
// This function in BwTree fills a given vector
281284
container.GetValue(index_key, result);
282285

283-
if (static_cast<StatsType>(settings::SettingsManager::GetInt(
284-
settings::SettingId::stats_mode)) != StatsType::INVALID) {
286+
if (static_cast<StatsType>(settings::SettingsManager::GetInt(settings::SettingId::stats_mode)) != StatsType::INVALID) {
285287
stats::BackendStatsContext::GetInstance()->IncrementIndexReads(
286288
result.size(), metadata);
287289
}

test/include/index/testing_index_util.h

100644100755
File mode changed.

test/index/bwtree_index_test.cpp

100644100755
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ TEST_F(BwTreeIndexTests, UniqueKeyInsertTest) {
3737
TestingIndexUtil::UniqueKeyInsertTest(IndexType::BWTREE);
3838
}
3939

40-
//TEST_F(BwTreeIndexTests, UniqueKeyDeleteTest) {
41-
// TestingIndexUtil::UniqueKeyDeleteTest(IndexType::BWTREE);
42-
//}
40+
TEST_F(BwTreeIndexTests, UniqueKeyDeleteTest) {
41+
TestingIndexUtil::UniqueKeyDeleteTest(IndexType::BWTREE);
42+
}
4343

4444
TEST_F(BwTreeIndexTests, NonUniqueKeyDeleteTest) {
4545
TestingIndexUtil::NonUniqueKeyDeleteTest(IndexType::BWTREE);

test/index/testing_index_util.cpp

100644100755
Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,27 @@ void TestingIndexUtil::UniqueKeyInsertTest(const IndexType index_type) {
112112
LaunchParallelTest(1, TestingIndexUtil::InsertHelper, index.get(), pool,
113113
scale_factor);
114114

115-
// Checks
115+
// Check basic insert (key0 only has 1 value, so it is not sufficient)
116116
std::unique_ptr<storage::Tuple> key0(new storage::Tuple(key_schema, true));
117117
key0->SetValue(0, type::ValueFactory::GetIntegerValue(100), pool);
118118
key0->SetValue(1, type::ValueFactory::GetVarcharValue("a"), pool);
119119

120120
index->ScanKey(key0.get(), location_ptrs);
121+
LOG_DEBUG("Checking key0's value: %lu", location_ptrs.size());
122+
EXPECT_EQ(1, location_ptrs.size());
123+
location_ptrs.clear();
124+
125+
// This tests non-unqie key. If scan returns more than 1 then it should fail
126+
std::unique_ptr<storage::Tuple> key1(new storage::Tuple(key_schema, true));
127+
key1->SetValue(0, type::ValueFactory::GetIntegerValue(100), pool);
128+
key1->SetValue(1, type::ValueFactory::GetVarcharValue("b"), pool);
129+
130+
index->ScanKey(key1.get(), location_ptrs);
131+
LOG_DEBUG("Checking key1's value: %lu", location_ptrs.size());
121132
EXPECT_EQ(1, location_ptrs.size());
122133
location_ptrs.clear();
134+
135+
return;
123136
}
124137

125138
void TestingIndexUtil::UniqueKeyDeleteTest(const IndexType index_type) {
@@ -163,32 +176,37 @@ void TestingIndexUtil::UniqueKeyDeleteTest(const IndexType index_type) {
163176
index->ScanKey(key0.get(), location_ptrs);
164177
#ifdef LOG_DEBUG_ENABLED
165178
for (auto ptr : location_ptrs) {
166-
LOG_DEBUG(" FOUND: %s", index::IndexUtil::GetInfo(ptr).c_str());
179+
LOG_DEBUG("key0 FOUND: %s", index::IndexUtil::GetInfo(ptr).c_str());
167180
}
168181
#endif
182+
LOG_DEBUG("key0 size: %lu", location_ptrs.size());
169183
EXPECT_EQ(0, location_ptrs.size());
170184
location_ptrs.clear();
171185

172186
LOG_DEBUG("ScanKey(key1=%s)", key1->GetInfo().c_str());
173187
index->ScanKey(key1.get(), location_ptrs);
174188
#ifdef LOG_DEBUG_ENABLED
175189
for (auto ptr : location_ptrs) {
176-
LOG_DEBUG(" FOUND: %s", index::IndexUtil::GetInfo(ptr).c_str());
190+
LOG_DEBUG("key1 FOUND: %s", index::IndexUtil::GetInfo(ptr).c_str());
177191
}
178192
#endif
193+
LOG_DEBUG("key1 size: %lu", location_ptrs.size());
179194
EXPECT_EQ(0, location_ptrs.size());
180195
location_ptrs.clear();
181196

182197
LOG_DEBUG("ScanKey(key2=%s)", key2->GetInfo().c_str());
183198
index->ScanKey(key2.get(), location_ptrs);
184199
#ifdef LOG_DEBUG_ENABLED
185200
for (auto ptr : location_ptrs) {
186-
LOG_DEBUG(" FOUND: %s", index::IndexUtil::GetInfo(ptr).c_str());
201+
LOG_DEBUG("key2 FOUND: %s", index::IndexUtil::GetInfo(ptr).c_str());
187202
}
188203
#endif
204+
LOG_DEBUG("key2 size: %lu", location_ptrs.size());
189205
EXPECT_EQ(1, location_ptrs.size());
190206
EXPECT_EQ(TestingIndexUtil::item1->block, location_ptrs[0]->block);
191207
location_ptrs.clear();
208+
209+
return;
192210
}
193211

194212
void TestingIndexUtil::NonUniqueKeyDeleteTest(const IndexType index_type) {
@@ -843,11 +861,13 @@ void TestingIndexUtil::DeleteHelper(index::Index *index,
843861
index->DeleteEntry(key3.get(), TestingIndexUtil::item1.get());
844862
index->DeleteEntry(key4.get(), TestingIndexUtil::item1.get());
845863

846-
// should be no key0
864+
// For non-unique key should be no key0
847865
// key1 item 0 1 2
848866
// key2 item 1
849867
// no key3
850868
// no key4
869+
870+
// For unique key should be only key2
851871
}
852872
}
853873

0 commit comments

Comments
 (0)