basically write and test insert
This commit is contained in:
@ -64,6 +64,139 @@ class BPlusTreeIndexer {
|
|||||||
res.is_end = false;
|
res.is_end = false;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
void InsertFixUpLookPartA(PositionSignType &pos, BasicPageGuard &parent_page_guard, BasicPageGuard &new_page_guard,
|
||||||
|
BasicPageGuard &page_guard, default_numeric_index_t new_page_id) {
|
||||||
|
pos.path[pos.path.size() - 2].second++;
|
||||||
|
// now check we are able to "insert" (new_page_guard.template
|
||||||
|
// As<PageType>()->data.p_data[new_page_guard.template As<PageType>()->data.key_count - 1].first, new_page_id)
|
||||||
|
// at pos
|
||||||
|
if (parent_page_guard.template As<PageType>()->data.key_count < _ActualDataType::kMaxKeyCount) {
|
||||||
|
// Has enough space, reach end, just insert it
|
||||||
|
// first, manually move the last pointer
|
||||||
|
parent_page_guard.template AsMut<PageType>()->data.p_data[pos.path[pos.path.size() - 2].second - 1].first =
|
||||||
|
page_guard.template As<PageType>()->data.p_data[page_guard.template As<PageType>()->data.key_count - 1].first;
|
||||||
|
if (parent_page_guard.template As<PageType>()->data.key_count == _ActualDataType::kMaxKeyCount - 1) {
|
||||||
|
parent_page_guard.template AsMut<PageType>()->data.p_n =
|
||||||
|
parent_page_guard.template As<PageType>()
|
||||||
|
->data.p_data[parent_page_guard.template As<PageType>()->data.key_count]
|
||||||
|
.second;
|
||||||
|
} else {
|
||||||
|
parent_page_guard.template AsMut<PageType>()
|
||||||
|
->data.p_data[parent_page_guard.template As<PageType>()->data.key_count + 1]
|
||||||
|
.second = parent_page_guard.template As<PageType>()
|
||||||
|
->data.p_data[parent_page_guard.template As<PageType>()->data.key_count]
|
||||||
|
.second;
|
||||||
|
}
|
||||||
|
// Then, use memmove to move the key_point pairs
|
||||||
|
fprintf(stderr, "parent_page_guard.template As<PageType>()->data.key_count = %d\n",
|
||||||
|
(int)parent_page_guard.template As<PageType>()->data.key_count);
|
||||||
|
if (pos.path[pos.path.size() - 2].second < parent_page_guard.template As<PageType>()->data.key_count) {
|
||||||
|
memmove(parent_page_guard.template AsMut<PageType>()->data.p_data + pos.path[pos.path.size() - 2].second + 1,
|
||||||
|
parent_page_guard.template As<PageType>()->data.p_data + pos.path[pos.path.size() - 2].second,
|
||||||
|
(parent_page_guard.template As<PageType>()->data.key_count - pos.path[pos.path.size() - 2].second) *
|
||||||
|
sizeof(key_index_pair_t));
|
||||||
|
}
|
||||||
|
// Then Set the key_point pair
|
||||||
|
if (pos.path[pos.path.size() - 2].second < _ActualDataType::kMaxKeyCount) {
|
||||||
|
parent_page_guard.template AsMut<PageType>()->data.p_data[pos.path[pos.path.size() - 2].second] =
|
||||||
|
std::make_pair(new_page_guard.template As<PageType>()
|
||||||
|
->data.p_data[new_page_guard.template As<PageType>()->data.key_count - 1]
|
||||||
|
.first,
|
||||||
|
new_page_id);
|
||||||
|
} else {
|
||||||
|
// just set p_n
|
||||||
|
parent_page_guard.template AsMut<PageType>()->data.p_n = new_page_id;
|
||||||
|
}
|
||||||
|
parent_page_guard.template AsMut<PageType>()->data.key_count++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// TODO: process and prepare for next round
|
||||||
|
assert((pos.path.size() == 2) ==
|
||||||
|
((parent_page_guard.template As<PageType>()->data.page_status & PageStatusType::ROOT) != 0));
|
||||||
|
/**
|
||||||
|
* Step 1: split current page
|
||||||
|
* Step 2: Check if current page is root. If current page is root, create a new root, update and exit
|
||||||
|
* Step 3: Otherwise, update parent page, and continue the loop
|
||||||
|
*/
|
||||||
|
key_index_pair_t new_entry_backup =
|
||||||
|
std::make_pair(new_page_guard.template As<PageType>()
|
||||||
|
->data.p_data[new_page_guard.template As<PageType>()->data.key_count - 1]
|
||||||
|
.first,
|
||||||
|
new_page_id);
|
||||||
|
KeyType key_to_update_backup =
|
||||||
|
page_guard.template As<PageType>()->data.p_data[page_guard.template As<PageType>()->data.key_count - 1].first;
|
||||||
|
InsertFixUpLookPartB(pos, parent_page_guard, new_entry_backup, key_to_update_backup);
|
||||||
|
}
|
||||||
|
void InsertFixUpLookPartB(PositionSignType &pos, BasicPageGuard &page_guard, const key_index_pair_t &new_entry_backup,
|
||||||
|
const KeyType &key_to_update_backup) {
|
||||||
|
default_numeric_index_t new_page_id;
|
||||||
|
auto new_page_guard = std::move(bpm->NewPageGuarded(&new_page_id));
|
||||||
|
new_page_guard.template AsMut<PageType>()->data.page_status = PageStatusType::INTERNAL;
|
||||||
|
// Now begin spliting. It is expected that the new page has _ActualDataType::kMinNumberOfKeysForLeaf keys
|
||||||
|
if (pos.path[pos.path.size() - 2].second - 1 == _ActualDataType::kMaxKeyCount) {
|
||||||
|
// In this case, first, move the last _ActualDataType::kMinNumberOfKeysForLeaf-1 keys to the new page
|
||||||
|
memmove(new_page_guard.template AsMut<PageType>()->data.p_data,
|
||||||
|
page_guard.template As<PageType>()->data.p_data + _ActualDataType::kMaxKeyCount -
|
||||||
|
(_ActualDataType::kMinNumberOfKeysForLeaf - 1),
|
||||||
|
(_ActualDataType::kMinNumberOfKeysForLeaf - 1) * sizeof(key_index_pair_t));
|
||||||
|
new_page_guard.template AsMut<PageType>()->data.p_data[_ActualDataType::kMinNumberOfKeysForLeaf - 1].second =
|
||||||
|
page_guard.template As<PageType>()->data.p_n;
|
||||||
|
new_page_guard.template AsMut<PageType>()->data.p_data[_ActualDataType::kMinNumberOfKeysForLeaf - 1].first =
|
||||||
|
key_to_update_backup;
|
||||||
|
new_page_guard.template AsMut<PageType>()->data.p_data[_ActualDataType::kMinNumberOfKeysForLeaf].second =
|
||||||
|
new_entry_backup.second;
|
||||||
|
new_page_guard.template AsMut<PageType>()->data.key_count = _ActualDataType::kMinNumberOfKeysForLeaf;
|
||||||
|
page_guard.template AsMut<PageType>()->data.key_count -= _ActualDataType::kMinNumberOfKeysForLeaf - 1;
|
||||||
|
} else {
|
||||||
|
page_guard.template AsMut<PageType>()->data.p_data[pos.path[pos.path.size() - 2].second - 1].first =
|
||||||
|
key_to_update_backup;
|
||||||
|
// now, we need to "insert" the new_entry_backup to position pos.path[pos.path.size() - 2].second
|
||||||
|
new_page_guard.template AsMut<PageType>()->data.p_data[_ActualDataType::kMinNumberOfKeysForLeaf].second =
|
||||||
|
page_guard.template As<PageType>()->data.p_n;
|
||||||
|
default_numeric_index_t it_dest = _ActualDataType::kMinNumberOfKeysForLeaf - 1;
|
||||||
|
default_numeric_index_t it_src = _ActualDataType::kMaxKeyCount - 1;
|
||||||
|
bool has_processed = false;
|
||||||
|
for (; it_dest != kInvalidNumericIndex; --it_dest) {
|
||||||
|
if (!has_processed && pos.path[pos.path.size() - 2].second == it_src + 1) {
|
||||||
|
new_page_guard.template AsMut<PageType>()->data.p_data[it_dest] = new_entry_backup;
|
||||||
|
has_processed = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
new_page_guard.template AsMut<PageType>()->data.p_data[it_dest] =
|
||||||
|
page_guard.template As<PageType>()->data.p_data[it_src];
|
||||||
|
--it_src;
|
||||||
|
}
|
||||||
|
if (pos.path[pos.path.size() - 2].second <=
|
||||||
|
_ActualDataType::kMaxKeyCount - _ActualDataType::kMinNumberOfKeysForLeaf) {
|
||||||
|
memmove(page_guard.template AsMut<PageType>()->data.p_data + pos.path[pos.path.size() - 2].second + 1,
|
||||||
|
page_guard.template As<PageType>()->data.p_data + pos.path[pos.path.size() - 2].second,
|
||||||
|
((_ActualDataType::kMaxKeyCount - _ActualDataType::kMinNumberOfKeysForLeaf) -
|
||||||
|
pos.path[pos.path.size() - 2].second) *
|
||||||
|
sizeof(key_index_pair_t));
|
||||||
|
page_guard.template AsMut<PageType>()->data.p_data[pos.path[pos.path.size() - 2].second] = new_entry_backup;
|
||||||
|
}
|
||||||
|
new_page_guard.template AsMut<PageType>()->data.key_count = _ActualDataType::kMinNumberOfKeysForLeaf;
|
||||||
|
page_guard.template AsMut<PageType>()->data.key_count -= _ActualDataType::kMinNumberOfKeysForLeaf - 1;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "Evicting page %d\n", (int)pos.path.back().first.PageId());
|
||||||
|
fprintf(stderr, "page id of page_guard = %d\n", (int)page_guard.PageId());
|
||||||
|
pos.path.pop_back();
|
||||||
|
fprintf(stderr, "the page id of the res page in pos %d\n", (int)pos.path.back().first.PageId());
|
||||||
|
if (pos.path.size() == 1) {
|
||||||
|
// we have split the root page, update and quit
|
||||||
|
page_guard.template AsMut<PageType>()->data.page_status &= ~PageStatusType::ROOT;
|
||||||
|
BasicPageGuard new_root_page_guard = bpm->NewPageGuarded(&root_page_id);
|
||||||
|
new_root_page_guard.AsMut<PageType>()->data.page_status = PageStatusType::ROOT;
|
||||||
|
new_root_page_guard.AsMut<PageType>()->data.key_count = 1;
|
||||||
|
new_root_page_guard.AsMut<PageType>()->data.p_data[0] = std::make_pair(
|
||||||
|
page_guard.template As<PageType>()->data.p_data[page_guard.template As<PageType>()->data.key_count - 1].first,
|
||||||
|
page_guard.PageId());
|
||||||
|
new_root_page_guard.AsMut<PageType>()->data.p_data[1] = std::make_pair(KeyType(), new_page_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto &parent_page_guard = pos.path[pos.path.size() - 2].first;
|
||||||
|
InsertFixUpLookPartA(pos, parent_page_guard, new_page_guard, page_guard, new_page_id);
|
||||||
|
}
|
||||||
void InsertEntryAt(PositionSignType &pos, const KeyType &key, b_plus_tree_value_index_t value,
|
void InsertEntryAt(PositionSignType &pos, const KeyType &key, b_plus_tree_value_index_t value,
|
||||||
bool is_fixing_up_recursive = false) {
|
bool is_fixing_up_recursive = false) {
|
||||||
fprintf(stderr, "_ActualDataType::kMaxKeyCount = %d\n", (int)_ActualDataType::kMaxKeyCount);
|
fprintf(stderr, "_ActualDataType::kMaxKeyCount = %d\n", (int)_ActualDataType::kMaxKeyCount);
|
||||||
@ -103,8 +236,9 @@ class BPlusTreeIndexer {
|
|||||||
new_page_guard.AsMut<PageType>()->data.page_status = 0; // PageStatusType::INTERNAL;
|
new_page_guard.AsMut<PageType>()->data.page_status = 0; // PageStatusType::INTERNAL;
|
||||||
new_page_guard.AsMut<PageType>()->data.key_count = _ActualDataType::kMinNumberOfKeysForLeaf;
|
new_page_guard.AsMut<PageType>()->data.key_count = _ActualDataType::kMinNumberOfKeysForLeaf;
|
||||||
page_guard.template AsMut<PageType>()->data.key_count -= _ActualDataType::kMinNumberOfKeysForLeaf;
|
page_guard.template AsMut<PageType>()->data.key_count -= _ActualDataType::kMinNumberOfKeysForLeaf;
|
||||||
|
if (!is_fixing_up_recursive)
|
||||||
new_page_guard.AsMut<PageType>()->data.p_n = page_guard.template As<PageType>()->data.p_n;
|
new_page_guard.AsMut<PageType>()->data.p_n = page_guard.template As<PageType>()->data.p_n;
|
||||||
page_guard.template AsMut<PageType>()->data.p_n = new_page_id;
|
if (!is_fixing_up_recursive) page_guard.template AsMut<PageType>()->data.p_n = new_page_id;
|
||||||
if (pos.path.back().second <= _ActualDataType::kMaxKeyCount - _ActualDataType::kMinNumberOfKeysForLeaf) {
|
if (pos.path.back().second <= _ActualDataType::kMaxKeyCount - _ActualDataType::kMinNumberOfKeysForLeaf) {
|
||||||
// the new key is in the first half
|
// the new key is in the first half
|
||||||
memmove(new_page_guard.template AsMut<PageType>()->data.p_data,
|
memmove(new_page_guard.template AsMut<PageType>()->data.p_data,
|
||||||
@ -160,57 +294,7 @@ class BPlusTreeIndexer {
|
|||||||
is_in_right_skew_path = true;
|
is_in_right_skew_path = true;
|
||||||
}
|
}
|
||||||
if (is_in_right_skew_path) {
|
if (is_in_right_skew_path) {
|
||||||
do {
|
InsertFixUpLookPartA(pos, parent_page_guard, new_page_guard, page_guard, new_page_id);
|
||||||
parent_page_guard.template AsMut<PageType>()->data.p_data[pos.path[pos.path.size() - 2].second].first =
|
|
||||||
page_guard.template As<PageType>()
|
|
||||||
->data.p_data[page_guard.template As<PageType>()->data.key_count - 1]
|
|
||||||
.first;
|
|
||||||
pos.path[pos.path.size() - 2].second++;
|
|
||||||
// now check we are able to "insert" (new_page_guard.template
|
|
||||||
// As<PageType>()->data.p_data[new_page_guard.template As<PageType>()->data.key_count - 1].first, new_page_id)
|
|
||||||
// at pos
|
|
||||||
if (parent_page_guard.template As<PageType>()->data.key_count < _ActualDataType::kMaxKeyCount) {
|
|
||||||
// Has enough space, reach end, just insert it
|
|
||||||
// first, manually move the last pointer
|
|
||||||
if (parent_page_guard.template As<PageType>()->data.key_count == _ActualDataType::kMaxKeyCount - 1) {
|
|
||||||
parent_page_guard.template AsMut<PageType>()->data.p_n =
|
|
||||||
parent_page_guard.template As<PageType>()
|
|
||||||
->data.p_data[parent_page_guard.template As<PageType>()->data.key_count]
|
|
||||||
.second;
|
|
||||||
} else {
|
|
||||||
parent_page_guard.template AsMut<PageType>()
|
|
||||||
->data.p_data[parent_page_guard.template As<PageType>()->data.key_count + 1]
|
|
||||||
.second = parent_page_guard.template As<PageType>()
|
|
||||||
->data.p_data[parent_page_guard.template As<PageType>()->data.key_count]
|
|
||||||
.second;
|
|
||||||
}
|
|
||||||
// Then, use memmove to move the key_point pairs
|
|
||||||
fprintf(stderr, "parent_page_guard.template As<PageType>()->data.key_count = %d\n",
|
|
||||||
(int)parent_page_guard.template As<PageType>()->data.key_count);
|
|
||||||
if (pos.path[pos.path.size() - 2].second < parent_page_guard.template As<PageType>()->data.key_count) {
|
|
||||||
memmove(
|
|
||||||
parent_page_guard.template AsMut<PageType>()->data.p_data + pos.path[pos.path.size() - 2].second + 1,
|
|
||||||
parent_page_guard.template As<PageType>()->data.p_data + pos.path[pos.path.size() - 2].second,
|
|
||||||
(parent_page_guard.template As<PageType>()->data.key_count - pos.path[pos.path.size() - 2].second) *
|
|
||||||
sizeof(key_index_pair_t));
|
|
||||||
}
|
|
||||||
// Then Set the key_point pair
|
|
||||||
if (pos.path[pos.path.size() - 2].second < _ActualDataType::kMaxKeyCount) {
|
|
||||||
parent_page_guard.template AsMut<PageType>()->data.p_data[pos.path[pos.path.size() - 2].second] =
|
|
||||||
std::make_pair(new_page_guard.template As<PageType>()
|
|
||||||
->data.p_data[new_page_guard.template As<PageType>()->data.key_count - 1]
|
|
||||||
.first,
|
|
||||||
new_page_id);
|
|
||||||
} else {
|
|
||||||
// just set p_n
|
|
||||||
parent_page_guard.template AsMut<PageType>()->data.p_n = new_page_id;
|
|
||||||
}
|
|
||||||
parent_page_guard.template AsMut<PageType>()->data.key_count++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// TODO: process and prepare for next round
|
|
||||||
throw std::runtime_error("Not implemented yet: InsertEntryAt");
|
|
||||||
} while (true);
|
|
||||||
if (!is_fixing_up_recursive) ++siz;
|
if (!is_fixing_up_recursive) ++siz;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ typedef uint32_t default_numeric_index_t;
|
|||||||
typedef default_numeric_index_t page_id_t;
|
typedef default_numeric_index_t page_id_t;
|
||||||
typedef default_numeric_index_t frame_id_t;
|
typedef default_numeric_index_t frame_id_t;
|
||||||
typedef default_numeric_index_t b_plus_tree_value_index_t;
|
typedef default_numeric_index_t b_plus_tree_value_index_t;
|
||||||
|
extern const default_numeric_index_t kInvalidNumericIndex;
|
||||||
extern const b_plus_tree_value_index_t kInvalidValueIndex;
|
extern const b_plus_tree_value_index_t kInvalidValueIndex;
|
||||||
typedef uint8_t page_status_t;
|
typedef uint8_t page_status_t;
|
||||||
typedef uint16_t in_page_key_count_t;
|
typedef uint16_t in_page_key_count_t;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
#include "bpt/bpt.hpp"
|
#include "bpt/bpt.hpp"
|
||||||
#include "bpt/config.h"
|
#include "bpt/config.h"
|
||||||
const b_plus_tree_value_index_t kInvalidValueIndex = -1;
|
const b_plus_tree_value_index_t kInvalidValueIndex = -1;
|
||||||
|
const default_numeric_index_t kInvalidNumericIndex = -1;
|
@ -251,11 +251,13 @@ auto BufferPoolManager::DeletePage(page_id_t page_id) -> bool {
|
|||||||
|
|
||||||
auto BufferPoolManager::FetchPageBasic(page_id_t page_id) -> BasicPageGuard {
|
auto BufferPoolManager::FetchPageBasic(page_id_t page_id) -> BasicPageGuard {
|
||||||
Page *page = FetchPage(page_id);
|
Page *page = FetchPage(page_id);
|
||||||
|
if (page == nullptr) throw std::runtime_error("Buffer Pool is full!");
|
||||||
return {this, page};
|
return {this, page};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto BufferPoolManager::FetchPageRead(page_id_t page_id) -> ReadPageGuard {
|
auto BufferPoolManager::FetchPageRead(page_id_t page_id) -> ReadPageGuard {
|
||||||
Page *page = FetchPage(page_id);
|
Page *page = FetchPage(page_id);
|
||||||
|
if (page == nullptr) throw std::runtime_error("Buffer Pool is full!");
|
||||||
if (page != nullptr) {
|
if (page != nullptr) {
|
||||||
page->RLatch();
|
page->RLatch();
|
||||||
}
|
}
|
||||||
@ -264,6 +266,7 @@ auto BufferPoolManager::FetchPageRead(page_id_t page_id) -> ReadPageGuard {
|
|||||||
|
|
||||||
auto BufferPoolManager::FetchPageWrite(page_id_t page_id) -> WritePageGuard {
|
auto BufferPoolManager::FetchPageWrite(page_id_t page_id) -> WritePageGuard {
|
||||||
Page *page = FetchPage(page_id);
|
Page *page = FetchPage(page_id);
|
||||||
|
if (page == nullptr) throw std::runtime_error("Buffer Pool is full!");
|
||||||
if (page != nullptr) {
|
if (page != nullptr) {
|
||||||
page->WLatch();
|
page->WLatch();
|
||||||
}
|
}
|
||||||
@ -272,5 +275,6 @@ auto BufferPoolManager::FetchPageWrite(page_id_t page_id) -> WritePageGuard {
|
|||||||
|
|
||||||
auto BufferPoolManager::NewPageGuarded(page_id_t *page_id) -> BasicPageGuard {
|
auto BufferPoolManager::NewPageGuarded(page_id_t *page_id) -> BasicPageGuard {
|
||||||
Page *page = NewPage(page_id);
|
Page *page = NewPage(page_id);
|
||||||
|
if (page == nullptr) throw std::runtime_error("Buffer Pool is full!");
|
||||||
return {this, page};
|
return {this, page};
|
||||||
}
|
}
|
@ -352,7 +352,7 @@ TEST(HarderTest, Split_in_Put_Harder_3) {
|
|||||||
sizeof(std::pair<KeyType, default_numeric_index_t>));
|
sizeof(std::pair<KeyType, default_numeric_index_t>));
|
||||||
const std::string db_file_name = "/tmp/bpt8.db";
|
const std::string db_file_name = "/tmp/bpt8.db";
|
||||||
std::vector<KeyType> keys;
|
std::vector<KeyType> keys;
|
||||||
const int ops = 20;
|
const int ops = 1000;
|
||||||
remove(db_file_name.c_str());
|
remove(db_file_name.c_str());
|
||||||
DiskManager *dm = new DiskManager(db_file_name.c_str());
|
DiskManager *dm = new DiskManager(db_file_name.c_str());
|
||||||
BufferPoolManager *bpm = new BufferPoolManager(20, 3, dm);
|
BufferPoolManager *bpm = new BufferPoolManager(20, 3, dm);
|
||||||
@ -364,6 +364,237 @@ TEST(HarderTest, Split_in_Put_Harder_3) {
|
|||||||
}
|
}
|
||||||
// sort(keys.begin(), keys.end());
|
// sort(keys.begin(), keys.end());
|
||||||
std::shuffle(keys.begin(), keys.end(), rnd);
|
std::shuffle(keys.begin(), keys.end(), rnd);
|
||||||
|
for (int i = 1; i <= ops; i++) fprintf(stderr, "key[%d]=%s\n", i - 1, keys[i - 1].data);
|
||||||
|
{
|
||||||
|
BPlusTreeIndexer<KeyType, std::less<KeyType>> bpt(bpm);
|
||||||
|
for (int i = 1; i <= ops; i++) {
|
||||||
|
bpt.Put(keys[i - 1], i + 3);
|
||||||
|
ASSERT_EQ(bpt.Get(keys[i - 1]), i + 3);
|
||||||
|
}
|
||||||
|
for (int i = 1; i <= ops; i++) {
|
||||||
|
ASSERT_EQ(bpt.Get(keys[i - 1]), i + 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete bpm;
|
||||||
|
delete dm;
|
||||||
|
dm = new DiskManager(db_file_name.c_str());
|
||||||
|
bpm = new BufferPoolManager(20, 3, dm);
|
||||||
|
{
|
||||||
|
BPlusTreeIndexer<KeyType, std::less<KeyType>> bpt(bpm);
|
||||||
|
for (int i = 1; i <= ops; i++) {
|
||||||
|
ASSERT_EQ(bpt.Get(keys[i - 1]), i + 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete bpm;
|
||||||
|
delete dm;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(HarderTest, Split_in_Put_Harder_4) {
|
||||||
|
const unsigned int RndSeed = testing::GTEST_FLAG(random_seed);
|
||||||
|
std::mt19937 rnd(RndSeed);
|
||||||
|
const int str_len = 800;
|
||||||
|
typedef bpt_basic_test::FixLengthString<str_len> KeyType;
|
||||||
|
fprintf(stderr, "sizeof(std::pair<KeyType, default_numeric_index_t>)=%lu\n",
|
||||||
|
sizeof(std::pair<KeyType, default_numeric_index_t>));
|
||||||
|
const std::string db_file_name = "/tmp/bpt9.db";
|
||||||
|
std::vector<KeyType> keys;
|
||||||
|
const int ops = 1000;
|
||||||
|
remove(db_file_name.c_str());
|
||||||
|
DiskManager *dm = new DiskManager(db_file_name.c_str());
|
||||||
|
BufferPoolManager *bpm = new BufferPoolManager(20, 3, dm);
|
||||||
|
for (int i = 1; i <= ops; i++) {
|
||||||
|
KeyType key;
|
||||||
|
for (size_t j = 0; j < str_len; j++) key.data[j] = 'a' + rnd() % 26;
|
||||||
|
key.data[str_len - 1] = '\0';
|
||||||
|
keys.push_back(key);
|
||||||
|
}
|
||||||
|
sort(keys.begin(), keys.end());
|
||||||
|
// std::shuffle(keys.begin(), keys.end(), rnd);
|
||||||
|
for (int i = 1; i <= ops; i++) fprintf(stderr, "key[%d]=%s\n", i - 1, keys[i - 1].data);
|
||||||
|
{
|
||||||
|
BPlusTreeIndexer<KeyType, std::less<KeyType>> bpt(bpm);
|
||||||
|
for (int i = 1; i <= ops; i++) {
|
||||||
|
bpt.Put(keys[i - 1], i + 3);
|
||||||
|
ASSERT_EQ(bpt.Get(keys[i - 1]), i + 3);
|
||||||
|
}
|
||||||
|
for (int i = 1; i <= ops; i++) {
|
||||||
|
ASSERT_EQ(bpt.Get(keys[i - 1]), i + 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete bpm;
|
||||||
|
delete dm;
|
||||||
|
dm = new DiskManager(db_file_name.c_str());
|
||||||
|
bpm = new BufferPoolManager(20, 3, dm);
|
||||||
|
{
|
||||||
|
BPlusTreeIndexer<KeyType, std::less<KeyType>> bpt(bpm);
|
||||||
|
for (int i = 1; i <= ops; i++) {
|
||||||
|
ASSERT_EQ(bpt.Get(keys[i - 1]), i + 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete bpm;
|
||||||
|
delete dm;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(HarderTest, Split_in_Put_Harder_5) {
|
||||||
|
const unsigned int RndSeed = testing::GTEST_FLAG(random_seed);
|
||||||
|
std::mt19937 rnd(RndSeed);
|
||||||
|
const int str_len = 800;
|
||||||
|
typedef bpt_basic_test::FixLengthString<str_len> KeyType;
|
||||||
|
fprintf(stderr, "sizeof(std::pair<KeyType, default_numeric_index_t>)=%lu\n",
|
||||||
|
sizeof(std::pair<KeyType, default_numeric_index_t>));
|
||||||
|
const std::string db_file_name = "/tmp/bpt10.db";
|
||||||
|
std::vector<KeyType> keys;
|
||||||
|
const int ops = 15 + rnd() % 20;
|
||||||
|
remove(db_file_name.c_str());
|
||||||
|
DiskManager *dm = new DiskManager(db_file_name.c_str());
|
||||||
|
BufferPoolManager *bpm = new BufferPoolManager(20, 3, dm);
|
||||||
|
for (int i = 1; i <= ops; i++) {
|
||||||
|
KeyType key;
|
||||||
|
for (size_t j = 0; j < str_len; j++) key.data[j] = 'a' + rnd() % 26;
|
||||||
|
key.data[str_len - 1] = '\0';
|
||||||
|
keys.push_back(key);
|
||||||
|
}
|
||||||
|
// sort(keys.begin(), keys.end());
|
||||||
|
std::shuffle(keys.begin(), keys.end(), rnd);
|
||||||
|
for (int i = 1; i <= ops; i++) fprintf(stderr, "key[%d]=%s\n", i - 1, keys[i - 1].data);
|
||||||
|
{
|
||||||
|
BPlusTreeIndexer<KeyType, std::less<KeyType>> bpt(bpm);
|
||||||
|
for (int i = 1; i <= ops; i++) {
|
||||||
|
bpt.Put(keys[i - 1], i + 3);
|
||||||
|
ASSERT_EQ(bpt.Get(keys[i - 1]), i + 3);
|
||||||
|
}
|
||||||
|
for (int i = 1; i <= ops; i++) {
|
||||||
|
ASSERT_EQ(bpt.Get(keys[i - 1]), i + 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete bpm;
|
||||||
|
delete dm;
|
||||||
|
dm = new DiskManager(db_file_name.c_str());
|
||||||
|
bpm = new BufferPoolManager(20, 3, dm);
|
||||||
|
{
|
||||||
|
BPlusTreeIndexer<KeyType, std::less<KeyType>> bpt(bpm);
|
||||||
|
for (int i = 1; i <= ops; i++) {
|
||||||
|
ASSERT_EQ(bpt.Get(keys[i - 1]), i + 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete bpm;
|
||||||
|
delete dm;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(HarderTest, Split_in_Put_Harder_6) {
|
||||||
|
const unsigned int RndSeed = testing::GTEST_FLAG(random_seed);
|
||||||
|
std::mt19937 rnd(RndSeed);
|
||||||
|
const int str_len = 1000;
|
||||||
|
typedef bpt_basic_test::FixLengthString<str_len> KeyType;
|
||||||
|
fprintf(stderr, "sizeof(std::pair<KeyType, default_numeric_index_t>)=%lu\n",
|
||||||
|
sizeof(std::pair<KeyType, default_numeric_index_t>));
|
||||||
|
const std::string db_file_name = "/tmp/bpt11.db";
|
||||||
|
std::vector<KeyType> keys;
|
||||||
|
const int ops = 15 + rnd() % 20;
|
||||||
|
remove(db_file_name.c_str());
|
||||||
|
DiskManager *dm = new DiskManager(db_file_name.c_str());
|
||||||
|
BufferPoolManager *bpm = new BufferPoolManager(20, 3, dm);
|
||||||
|
for (int i = 1; i <= ops; i++) {
|
||||||
|
KeyType key;
|
||||||
|
for (size_t j = 0; j < str_len; j++) key.data[j] = 'a' + rnd() % 26;
|
||||||
|
key.data[str_len - 1] = '\0';
|
||||||
|
keys.push_back(key);
|
||||||
|
}
|
||||||
|
// sort(keys.begin(), keys.end());
|
||||||
|
std::shuffle(keys.begin(), keys.end(), rnd);
|
||||||
|
for (int i = 1; i <= ops; i++) fprintf(stderr, "key[%d]=%s\n", i - 1, keys[i - 1].data);
|
||||||
|
{
|
||||||
|
BPlusTreeIndexer<KeyType, std::less<KeyType>> bpt(bpm);
|
||||||
|
for (int i = 1; i <= ops; i++) {
|
||||||
|
bpt.Put(keys[i - 1], i + 3);
|
||||||
|
ASSERT_EQ(bpt.Get(keys[i - 1]), i + 3);
|
||||||
|
}
|
||||||
|
for (int i = 1; i <= ops; i++) {
|
||||||
|
ASSERT_EQ(bpt.Get(keys[i - 1]), i + 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete bpm;
|
||||||
|
delete dm;
|
||||||
|
dm = new DiskManager(db_file_name.c_str());
|
||||||
|
bpm = new BufferPoolManager(20, 3, dm);
|
||||||
|
{
|
||||||
|
BPlusTreeIndexer<KeyType, std::less<KeyType>> bpt(bpm);
|
||||||
|
for (int i = 1; i <= ops; i++) {
|
||||||
|
ASSERT_EQ(bpt.Get(keys[i - 1]), i + 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete bpm;
|
||||||
|
delete dm;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(HarderTest, Split_in_Put_Harder_7) {
|
||||||
|
const unsigned int RndSeed = testing::GTEST_FLAG(random_seed);
|
||||||
|
std::mt19937 rnd(RndSeed);
|
||||||
|
const int str_len = 2000;
|
||||||
|
typedef bpt_basic_test::FixLengthString<str_len> KeyType;
|
||||||
|
fprintf(stderr, "sizeof(std::pair<KeyType, default_numeric_index_t>)=%lu\n",
|
||||||
|
sizeof(std::pair<KeyType, default_numeric_index_t>));
|
||||||
|
const std::string db_file_name = "/tmp/bpt12.db";
|
||||||
|
std::vector<KeyType> keys;
|
||||||
|
const int ops = 15 + rnd() % 20;
|
||||||
|
remove(db_file_name.c_str());
|
||||||
|
DiskManager *dm = new DiskManager(db_file_name.c_str());
|
||||||
|
BufferPoolManager *bpm = new BufferPoolManager(20, 3, dm);
|
||||||
|
for (int i = 1; i <= ops; i++) {
|
||||||
|
KeyType key;
|
||||||
|
for (size_t j = 0; j < str_len; j++) key.data[j] = 'a' + rnd() % 26;
|
||||||
|
key.data[str_len - 1] = '\0';
|
||||||
|
keys.push_back(key);
|
||||||
|
}
|
||||||
|
// sort(keys.begin(), keys.end());
|
||||||
|
std::shuffle(keys.begin(), keys.end(), rnd);
|
||||||
|
for (int i = 1; i <= ops; i++) fprintf(stderr, "key[%d]=%s\n", i - 1, keys[i - 1].data);
|
||||||
|
{
|
||||||
|
BPlusTreeIndexer<KeyType, std::less<KeyType>> bpt(bpm);
|
||||||
|
for (int i = 1; i <= ops; i++) {
|
||||||
|
bpt.Put(keys[i - 1], i + 3);
|
||||||
|
ASSERT_EQ(bpt.Get(keys[i - 1]), i + 3);
|
||||||
|
}
|
||||||
|
for (int i = 1; i <= ops; i++) {
|
||||||
|
ASSERT_EQ(bpt.Get(keys[i - 1]), i + 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete bpm;
|
||||||
|
delete dm;
|
||||||
|
dm = new DiskManager(db_file_name.c_str());
|
||||||
|
bpm = new BufferPoolManager(20, 3, dm);
|
||||||
|
{
|
||||||
|
BPlusTreeIndexer<KeyType, std::less<KeyType>> bpt(bpm);
|
||||||
|
for (int i = 1; i <= ops; i++) {
|
||||||
|
ASSERT_EQ(bpt.Get(keys[i - 1]), i + 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete bpm;
|
||||||
|
delete dm;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(HarderTest, Split_in_Put_Harder_8) {
|
||||||
|
const unsigned int RndSeed = testing::GTEST_FLAG(random_seed);
|
||||||
|
std::mt19937 rnd(RndSeed);
|
||||||
|
const int str_len = 1300;
|
||||||
|
typedef bpt_basic_test::FixLengthString<str_len> KeyType;
|
||||||
|
fprintf(stderr, "sizeof(std::pair<KeyType, default_numeric_index_t>)=%lu\n",
|
||||||
|
sizeof(std::pair<KeyType, default_numeric_index_t>));
|
||||||
|
const std::string db_file_name = "/tmp/bpt13.db";
|
||||||
|
std::vector<KeyType> keys;
|
||||||
|
const int ops = 15 + rnd() % 20;
|
||||||
|
remove(db_file_name.c_str());
|
||||||
|
DiskManager *dm = new DiskManager(db_file_name.c_str());
|
||||||
|
BufferPoolManager *bpm = new BufferPoolManager(20, 3, dm);
|
||||||
|
for (int i = 1; i <= ops; i++) {
|
||||||
|
KeyType key;
|
||||||
|
for (size_t j = 0; j < str_len; j++) key.data[j] = 'a' + rnd() % 26;
|
||||||
|
key.data[str_len - 1] = '\0';
|
||||||
|
keys.push_back(key);
|
||||||
|
}
|
||||||
|
// sort(keys.begin(), keys.end());
|
||||||
|
std::shuffle(keys.begin(), keys.end(), rnd);
|
||||||
|
for (int i = 1; i <= ops; i++) fprintf(stderr, "key[%d]=%s\n", i - 1, keys[i - 1].data);
|
||||||
{
|
{
|
||||||
BPlusTreeIndexer<KeyType, std::less<KeyType>> bpt(bpm);
|
BPlusTreeIndexer<KeyType, std::less<KeyType>> bpt(bpm);
|
||||||
for (int i = 1; i <= ops; i++) {
|
for (int i = 1; i <= ops; i++) {
|
||||||
|
Reference in New Issue
Block a user