ready to write full split in put
This commit is contained in:
@ -1,6 +1,8 @@
|
|||||||
#ifndef BPT_HPP
|
#ifndef BPT_HPP
|
||||||
#define BPT_HPP
|
#define BPT_HPP
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <shared_mutex>
|
#include <shared_mutex>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -18,7 +20,7 @@ class BPlusTreeIndexer {
|
|||||||
typedef BPlusTreePage<KeyType> PageType;
|
typedef BPlusTreePage<KeyType> PageType;
|
||||||
typedef ActualDataType<KeyType> _ActualDataType;
|
typedef ActualDataType<KeyType> _ActualDataType;
|
||||||
typedef std::pair<KeyType, default_numeric_index_t> key_index_pair_t;
|
typedef std::pair<KeyType, default_numeric_index_t> key_index_pair_t;
|
||||||
typedef std::pair<KeyType, b_plus_tree_value_index_t> value_type;
|
// typedef std::pair<KeyType, b_plus_tree_value_index_t> value_type;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct PositionSignType {
|
struct PositionSignType {
|
||||||
@ -44,7 +46,7 @@ class BPlusTreeIndexer {
|
|||||||
while ((res.path.back().first.template As<PageType>()->data.page_status & PageStatusType::LEAF) == 0) {
|
while ((res.path.back().first.template As<PageType>()->data.page_status & PageStatusType::LEAF) == 0) {
|
||||||
default_numeric_index_t nxt_page_id;
|
default_numeric_index_t nxt_page_id;
|
||||||
in_page_key_count_t internal_id = res.path.back().second;
|
in_page_key_count_t internal_id = res.path.back().second;
|
||||||
if (internal_id < res.path.back().first.template As<PageType>()->data.key_count)
|
if (internal_id < _ActualDataType::kMaxKeyCount)
|
||||||
nxt_page_id = res.path.back().first.template As<PageType>()->data.p_data[internal_id].second;
|
nxt_page_id = res.path.back().first.template As<PageType>()->data.p_data[internal_id].second;
|
||||||
else
|
else
|
||||||
nxt_page_id = res.path.back().first.template As<PageType>()->data.p_n;
|
nxt_page_id = res.path.back().first.template As<PageType>()->data.p_n;
|
||||||
@ -56,10 +58,14 @@ class BPlusTreeIndexer {
|
|||||||
next_page_guard.As<PageType>()->data.p_data;
|
next_page_guard.As<PageType>()->data.p_data;
|
||||||
res.path.push_back(std::make_pair(std::move(next_page_guard), nxt));
|
res.path.push_back(std::make_pair(std::move(next_page_guard), nxt));
|
||||||
}
|
}
|
||||||
if (nxt == res.path.back().first.template As<PageType>()->data.key_count) res.is_end = true;
|
if (nxt == res.path.back().first.template As<PageType>()->data.key_count)
|
||||||
|
res.is_end = true;
|
||||||
|
else
|
||||||
|
res.is_end = false;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
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) {
|
||||||
|
fprintf(stderr, "_ActualDataType::kMaxKeyCount = %d\n", (int)_ActualDataType::kMaxKeyCount);
|
||||||
if (siz == 0) {
|
if (siz == 0) {
|
||||||
// special case for the first entry
|
// special case for the first entry
|
||||||
BasicPageGuard new_page_guard = bpm->NewPageGuarded(&root_page_id);
|
BasicPageGuard new_page_guard = bpm->NewPageGuarded(&root_page_id);
|
||||||
@ -75,14 +81,71 @@ class BPlusTreeIndexer {
|
|||||||
// case 1: the page has enough space
|
// case 1: the page has enough space
|
||||||
memmove(page_guard.template AsMut<PageType>()->data.p_data + pos.path.back().second + 1,
|
memmove(page_guard.template AsMut<PageType>()->data.p_data + pos.path.back().second + 1,
|
||||||
page_guard.template As<PageType>()->data.p_data + pos.path.back().second,
|
page_guard.template As<PageType>()->data.p_data + pos.path.back().second,
|
||||||
(page_guard.template As<PageType>()->data.key_count - pos.path.back().second) * sizeof(value_type));
|
(page_guard.template As<PageType>()->data.key_count - pos.path.back().second) * sizeof(key_index_pair_t));
|
||||||
page_guard.template AsMut<PageType>()->data.p_data[pos.path.back().second] = std::make_pair(key, value);
|
page_guard.template AsMut<PageType>()->data.p_data[pos.path.back().second] = std::make_pair(key, value);
|
||||||
page_guard.template AsMut<PageType>()->data.key_count++;
|
page_guard.template AsMut<PageType>()->data.key_count++;
|
||||||
|
fprintf(stderr, "page_guard.template As<PageType>()->data.key_count = %d\n",
|
||||||
|
(int)page_guard.template As<PageType>()->data.key_count);
|
||||||
++siz;
|
++siz;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// In our case, the tree is not too high, so we do not consider borrowing from siblings, we just split the page.
|
||||||
|
// We first construct a new page, and then move half of the keys to the new page.
|
||||||
|
// The check if we split the root page, we just handle it.
|
||||||
|
// Otherwise, what we need to do is modify the parent page, then "insert" a new key to the parent page
|
||||||
|
page_id_t new_page_id;
|
||||||
|
BasicPageGuard new_page_guard = bpm->NewPageGuarded(&new_page_id);
|
||||||
|
// Then move the last kMinNumberOfKeysForLeaf keys(including newly inserted) to the new page
|
||||||
|
new_page_guard.AsMut<PageType>()->data.page_status = PageStatusType::LEAF;
|
||||||
|
new_page_guard.AsMut<PageType>()->data.key_count = _ActualDataType::kMinNumberOfKeysForLeaf;
|
||||||
|
page_guard.template AsMut<PageType>()->data.key_count -= _ActualDataType::kMinNumberOfKeysForLeaf;
|
||||||
|
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 (pos.path.back().second <= _ActualDataType::kMaxKeyCount - _ActualDataType::kMinNumberOfKeysForLeaf) {
|
||||||
|
// the new key is in the first half
|
||||||
|
memmove(new_page_guard.template AsMut<PageType>()->data.p_data,
|
||||||
|
page_guard.template As<PageType>()->data.p_data + _ActualDataType::kMaxKeyCount -
|
||||||
|
_ActualDataType::kMinNumberOfKeysForLeaf,
|
||||||
|
_ActualDataType::kMinNumberOfKeysForLeaf * sizeof(key_index_pair_t));
|
||||||
|
memmove(page_guard.template AsMut<PageType>()->data.p_data + pos.path.back().second + 1,
|
||||||
|
page_guard.template As<PageType>()->data.p_data + pos.path.back().second,
|
||||||
|
(page_guard.template As<PageType>()->data.key_count - pos.path.back().second) * sizeof(key_index_pair_t));
|
||||||
|
page_guard.template AsMut<PageType>()->data.p_data[pos.path.back().second] = std::make_pair(key, value);
|
||||||
|
page_guard.template AsMut<PageType>()->data.key_count++;
|
||||||
|
} else {
|
||||||
|
// the new key is in the second half
|
||||||
|
memmove(
|
||||||
|
new_page_guard.template AsMut<PageType>()->data.p_data,
|
||||||
|
page_guard.template As<PageType>()->data.p_data + _ActualDataType::kMaxKeyCount -
|
||||||
|
_ActualDataType::kMinNumberOfKeysForLeaf + 1,
|
||||||
|
(pos.path.back().second - (_ActualDataType::kMaxKeyCount - _ActualDataType::kMinNumberOfKeysForLeaf + 1)) *
|
||||||
|
sizeof(key_index_pair_t));
|
||||||
|
new_page_guard.template AsMut<PageType>()
|
||||||
|
->data.p_data[pos.path.back().second -
|
||||||
|
(_ActualDataType::kMaxKeyCount - _ActualDataType::kMinNumberOfKeysForLeaf + 1)] =
|
||||||
|
std::make_pair(key, value);
|
||||||
|
memmove(new_page_guard.template AsMut<PageType>()->data.p_data + pos.path.back().second -
|
||||||
|
(_ActualDataType::kMaxKeyCount - _ActualDataType::kMinNumberOfKeysForLeaf + 1) + 1,
|
||||||
|
page_guard.template As<PageType>()->data.p_data + pos.path.back().second,
|
||||||
|
(_ActualDataType::kMaxKeyCount - pos.path.back().second) * sizeof(key_index_pair_t));
|
||||||
|
page_guard.template AsMut<PageType>()->data.key_count++;
|
||||||
|
}
|
||||||
|
if (page_guard.template As<PageType>()->data.page_status & PageStatusType::ROOT) {
|
||||||
|
// special case for the root page
|
||||||
|
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);
|
||||||
|
++siz;
|
||||||
|
fprintf(stderr, "new_page_guard.AsMut<PageType>()->data.key_count = %d\n",
|
||||||
|
(int)new_page_guard.AsMut<PageType>()->data.key_count);
|
||||||
|
return;
|
||||||
|
}
|
||||||
throw std::runtime_error("Not implemented yet: InsertEntryAt");
|
throw std::runtime_error("Not implemented yet: InsertEntryAt");
|
||||||
// TODO
|
|
||||||
}
|
}
|
||||||
void RemoveEntryAt(PositionSignType &pos) {
|
void RemoveEntryAt(PositionSignType &pos) {
|
||||||
if (siz == 1) {
|
if (siz == 1) {
|
||||||
@ -96,9 +159,10 @@ class BPlusTreeIndexer {
|
|||||||
if (page_guard.template As<PageType>()->data.key_count > _ActualDataType::kMinNumberOfKeysForLeaf ||
|
if (page_guard.template As<PageType>()->data.key_count > _ActualDataType::kMinNumberOfKeysForLeaf ||
|
||||||
(page_guard.template As<PageType>()->data.page_status & PageStatusType::ROOT) != 0) {
|
(page_guard.template As<PageType>()->data.page_status & PageStatusType::ROOT) != 0) {
|
||||||
// case 1: the page has enough keys
|
// case 1: the page has enough keys
|
||||||
memmove(page_guard.template AsMut<PageType>()->data.p_data + pos.path.back().second,
|
memmove(
|
||||||
page_guard.template As<PageType>()->data.p_data + pos.path.back().second + 1,
|
page_guard.template AsMut<PageType>()->data.p_data + pos.path.back().second,
|
||||||
(page_guard.template As<PageType>()->data.key_count - pos.path.back().second - 1) * sizeof(value_type));
|
page_guard.template As<PageType>()->data.p_data + pos.path.back().second + 1,
|
||||||
|
(page_guard.template As<PageType>()->data.key_count - pos.path.back().second - 1) * sizeof(key_index_pair_t));
|
||||||
page_guard.template AsMut<PageType>()->data.key_count--;
|
page_guard.template AsMut<PageType>()->data.key_count--;
|
||||||
--siz;
|
--siz;
|
||||||
return;
|
return;
|
||||||
|
@ -10,6 +10,6 @@ target_link_libraries(buffer_pool_manager_test bpt GTest::gtest_main spdlog::spd
|
|||||||
add_executable(page_guard_test page_guard_test.cpp)
|
add_executable(page_guard_test page_guard_test.cpp)
|
||||||
target_link_libraries(page_guard_test bpt GTest::gtest_main)
|
target_link_libraries(page_guard_test bpt GTest::gtest_main)
|
||||||
add_executable(bpt_basic_test bpt_basic_test.cpp)
|
add_executable(bpt_basic_test bpt_basic_test.cpp)
|
||||||
target_link_libraries(bpt_basic_test bpt GTest::gtest_main)
|
target_link_libraries(bpt_basic_test bpt GTest::gtest_main spdlog::spdlog)
|
||||||
add_executable(buffer_pool_manager_extreme_test buffer_pool_manager_extreme_test.cpp)
|
add_executable(buffer_pool_manager_extreme_test buffer_pool_manager_extreme_test.cpp)
|
||||||
target_link_libraries(buffer_pool_manager_extreme_test bpt)
|
target_link_libraries(buffer_pool_manager_extreme_test bpt)
|
@ -1,5 +1,10 @@
|
|||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
#include <spdlog/async.h>
|
||||||
|
#include <spdlog/sinks/basic_file_sink.h>
|
||||||
|
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <random>
|
||||||
#include "bpt/bpt.hpp"
|
#include "bpt/bpt.hpp"
|
||||||
#include "bpt/buffer_pool_manager.h"
|
#include "bpt/buffer_pool_manager.h"
|
||||||
#include "bpt/config.h"
|
#include "bpt/config.h"
|
||||||
@ -9,6 +14,13 @@ template <size_t length>
|
|||||||
class FixLengthString {
|
class FixLengthString {
|
||||||
public:
|
public:
|
||||||
char data[length];
|
char data[length];
|
||||||
|
bool operator<(const FixLengthString<length> &that) const {
|
||||||
|
for (size_t i = 0; i < length; i++) {
|
||||||
|
if (data[i] < that.data[i]) return true;
|
||||||
|
if (data[i] > that.data[i]) return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
} // namespace bpt_basic_test
|
} // namespace bpt_basic_test
|
||||||
TEST(BasicTest, Compile) { // This Test only test the compile of the code
|
TEST(BasicTest, Compile) { // This Test only test the compile of the code
|
||||||
@ -135,4 +147,198 @@ TEST(BasicTest, Put_Get_Remove) {
|
|||||||
}
|
}
|
||||||
delete bpm;
|
delete bpm;
|
||||||
delete dm;
|
delete dm;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(BasicTest, Split_in_Put_Simple_1) {
|
||||||
|
remove("/tmp/bpt4.db");
|
||||||
|
DiskManager *dm = new DiskManager("/tmp/bpt4.db");
|
||||||
|
BufferPoolManager *bpm = new BufferPoolManager(20, 3, dm);
|
||||||
|
{
|
||||||
|
BPlusTreeIndexer<long long, std::less<long long>> bpt(bpm);
|
||||||
|
for (int i = 1; i <= 383; i++) {
|
||||||
|
bpt.Put(i, i + 3);
|
||||||
|
ASSERT_EQ(bpt.Get(i), i + 3);
|
||||||
|
}
|
||||||
|
for (int i = 1; i <= 383; i++) {
|
||||||
|
ASSERT_EQ(bpt.Get(i), i + 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete bpm;
|
||||||
|
delete dm;
|
||||||
|
dm = new DiskManager("/tmp/bpt4.db");
|
||||||
|
bpm = new BufferPoolManager(20, 3, dm);
|
||||||
|
{
|
||||||
|
BPlusTreeIndexer<long long, std::less<long long>> bpt(bpm);
|
||||||
|
for (int i = 1; i <= 383; i++) {
|
||||||
|
ASSERT_EQ(bpt.Get(i), i + 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete bpm;
|
||||||
|
delete dm;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(BasicTest, Split_in_Put_Simple_2) {
|
||||||
|
std::vector<int> keys;
|
||||||
|
const int kNumberOfKeys = 383;
|
||||||
|
for (int i = 1; i <= kNumberOfKeys; i++) keys.push_back(i);
|
||||||
|
const unsigned int RndSeed = testing::GTEST_FLAG(random_seed);
|
||||||
|
std::mt19937 rnd(RndSeed);
|
||||||
|
std::shuffle(keys.begin(), keys.end(), rnd);
|
||||||
|
remove("/tmp/bpt5.db");
|
||||||
|
DiskManager *dm = new DiskManager("/tmp/bpt5.db");
|
||||||
|
BufferPoolManager *bpm = new BufferPoolManager(20, 3, dm);
|
||||||
|
{
|
||||||
|
BPlusTreeIndexer<long long, std::less<long long>> bpt(bpm);
|
||||||
|
for (int i = 1; i <= kNumberOfKeys; i++) {
|
||||||
|
bpt.Put(keys[i - 1], i + 3);
|
||||||
|
ASSERT_EQ(bpt.Get(keys[i - 1]), i + 3);
|
||||||
|
}
|
||||||
|
for (int i = 1; i <= kNumberOfKeys; i++) {
|
||||||
|
ASSERT_EQ(bpt.Get(keys[i - 1]), i + 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete bpm;
|
||||||
|
delete dm;
|
||||||
|
dm = new DiskManager("/tmp/bpt5.db");
|
||||||
|
bpm = new BufferPoolManager(20, 3, dm);
|
||||||
|
{
|
||||||
|
BPlusTreeIndexer<long long, std::less<long long>> bpt(bpm);
|
||||||
|
for (int i = 1; i <= kNumberOfKeys; i++) {
|
||||||
|
ASSERT_EQ(bpt.Get(keys[i - 1]), i + 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete bpm;
|
||||||
|
delete dm;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(BasicTest, Split_in_Put_Simple_3) {
|
||||||
|
const unsigned int RndSeed = testing::GTEST_FLAG(random_seed);
|
||||||
|
std::mt19937 rnd(RndSeed);
|
||||||
|
const int str_len = 16;
|
||||||
|
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>));
|
||||||
|
remove("/tmp/bpt5.db");
|
||||||
|
DiskManager *dm = new DiskManager("/tmp/bpt5.db");
|
||||||
|
BufferPoolManager *bpm = new BufferPoolManager(20, 3, dm);
|
||||||
|
std::vector<KeyType> keys;
|
||||||
|
const int ops = 307;
|
||||||
|
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[15] = '\0';
|
||||||
|
keys.push_back(key);
|
||||||
|
}
|
||||||
|
// sort(keys.begin(), keys.end());
|
||||||
|
std::shuffle(keys.begin(), keys.end(), rnd);
|
||||||
|
{
|
||||||
|
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("/tmp/bpt5.db");
|
||||||
|
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_1) {
|
||||||
|
const unsigned int RndSeed = testing::GTEST_FLAG(random_seed);
|
||||||
|
std::mt19937 rnd(RndSeed);
|
||||||
|
const int str_len = 1360 - 4;
|
||||||
|
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>));
|
||||||
|
remove("/tmp/bpt6.db");
|
||||||
|
DiskManager *dm = new DiskManager("/tmp/bpt6.db");
|
||||||
|
BufferPoolManager *bpm = new BufferPoolManager(20, 3, dm);
|
||||||
|
std::vector<KeyType> keys;
|
||||||
|
const int ops = 5;
|
||||||
|
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[15] = '\0';
|
||||||
|
keys.push_back(key);
|
||||||
|
}
|
||||||
|
// sort(keys.begin(), keys.end());
|
||||||
|
std::shuffle(keys.begin(), keys.end(), rnd);
|
||||||
|
{
|
||||||
|
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("/tmp/bpt6.db");
|
||||||
|
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_2) {
|
||||||
|
const unsigned int RndSeed = testing::GTEST_FLAG(random_seed);
|
||||||
|
std::mt19937 rnd(RndSeed);
|
||||||
|
const int str_len = 2030;
|
||||||
|
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>));
|
||||||
|
remove("/tmp/bpt7.db");
|
||||||
|
DiskManager *dm = new DiskManager("/tmp/bpt7.db");
|
||||||
|
BufferPoolManager *bpm = new BufferPoolManager(20, 3, dm);
|
||||||
|
std::vector<KeyType> keys;
|
||||||
|
const int ops = 4;
|
||||||
|
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[15] = '\0';
|
||||||
|
keys.push_back(key);
|
||||||
|
}
|
||||||
|
sort(keys.begin(), keys.end());
|
||||||
|
// std::shuffle(keys.begin(), keys.end(), rnd);
|
||||||
|
{
|
||||||
|
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("/tmp/bpt7.db");
|
||||||
|
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;
|
||||||
}
|
}
|
Reference in New Issue
Block a user