diff --git a/CMakeLists.txt b/CMakeLists.txt index 15c6af7..86c7e37 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,6 +59,7 @@ add_library(bliss OBJECT ${CMAKE_SOURCE_DIR}/src/bliss/bench_pgm.h ${CMAKE_SOURCE_DIR}/src/bliss/bench_art.h ${CMAKE_SOURCE_DIR}/src/bliss/bench_leveldb.h + ${CMAKE_SOURCE_DIR}/src/bliss/bench_csbtree.h ) target_compile_features(bliss PUBLIC @@ -74,6 +75,7 @@ target_link_libraries(bliss PUBLIC skiplist pgm art + csbtree ) target_include_directories(bliss PUBLIC diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 1c6cccf..5b34f0d 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -114,4 +114,19 @@ if (NOT pgm_POPULATED) endif() add_library(pgm INTERFACE) -target_include_directories(pgm INTERFACE ${pgm_SOURCE_DIR}) \ No newline at end of file +target_include_directories(pgm INTERFACE ${pgm_SOURCE_DIR}) + + + +FetchContent_Declare( + csbtree + GIT_REPOSITORY https://github.com/Arjunbala/CSBTreesConcurrency + GIT_TAG master +) +FetchContent_GetProperties(csbtree) +if (NOT csbtree_POPULATED) + FetchContent_Populate(csbtree) +endif() + +add_library(csbtree INTERFACE) +target_include_directories(csbtree INTERFACE ${csbtree_SOURCE_DIR}) \ No newline at end of file diff --git a/src/bliss/bench_csbtree.h b/src/bliss/bench_csbtree.h new file mode 100644 index 0000000..c74cd21 --- /dev/null +++ b/src/bliss/bench_csbtree.h @@ -0,0 +1,62 @@ +#ifndef BLISS_BENCH_CSBTREE_H +#define BLISS_BENCH_CSBTREE_H + +#include +#include "bliss/bliss_index.h" +#include "src/vanilla_implementation/csbtree.h" + +namespace bliss { + +// Concrete implementation of CSBTree +class ConcreteCSBTree : public CSBTree { +public: + ConcreteCSBTree(int order) : CSBTree(order) { + root = new CSBNode(order); + } + + int insert(uint64_t key) override { + if (!root->checkPresenceOfKey(key)) { + int index = root->getIndex(key); + return root->addKeyToNode(key, index); + } + return 0; + } + + int del(uint64_t key) override { + return root->deleteKeyFromNode(key); + } +}; + +template +class BlissCSBTreeIndex : public BlissIndex { +public: + BlissCSBTreeIndex() : _index(16) {} + + void bulkload(std::vector> values) override { + for (const auto& kv : values) { + put(kv.first, 0); + } + } + + bool get(KEY_TYPE key) override { + uint64_t k = static_cast(key); + return _index.root->checkPresenceOfKey(k); + } + + bool get(KEY_TYPE start, KEY_TYPE end) override { + throw std::runtime_error("Not implemented"); + } + + void put(KEY_TYPE key, VALUE_TYPE) override { + uint64_t k = static_cast(key); + _index.insert(k); + } + + void end_routine() override {} + +private: + ConcreteCSBTree _index; +}; + +} // namespace bliss +#endif // BLISS_BENCH_CSBTREE_H diff --git a/src/bliss_bench.cpp b/src/bliss_bench.cpp index 5dcb9fc..e08e233 100644 --- a/src/bliss_bench.cpp +++ b/src/bliss_bench.cpp @@ -13,6 +13,7 @@ #include "bliss/bench_lipp.h" #include "bliss/bench_pgm.h" #include "bliss/bench_skiplist.h" +#include "bliss/bench_csbtree.h" #include "bliss/bliss_index.h" #include "bliss/util/args.h" #include "bliss/util/config.h" @@ -182,6 +183,8 @@ int main(int argc, char *argv[]) { index.reset(new bliss::BlissPGMIndex()); } else if (config.index == "leveldb") { index.reset(new bliss::BlissLevelDBIndex()); + } else if (config.index == "csbtree") { + index.reset(new bliss::BlissLevelDBIndex()); } else { spdlog::error(config.index + " not implemented yet", 1); } diff --git a/tests/bliss_index_tests.h b/tests/bliss_index_tests.h index 9def1a7..98f908b 100644 --- a/tests/bliss_index_tests.h +++ b/tests/bliss_index_tests.h @@ -18,6 +18,7 @@ #include "bliss/bench_lipp.h" #include "bliss/bench_pgm.h" #include "bliss/bench_skiplist.h" +#include "bliss/bench_csbtree.h" #include "bliss/bliss_index.h" #include "bliss/util/args.h" #include "bliss/util/config.h" @@ -34,8 +35,8 @@ using value_type = unsigned long; class BlissIndexTest : public testing::Test { protected: std::unique_ptr> index; - std::string indexes[7] = {"alex", "lipp", "btree", "skiplist", - "pgm", "art", "leveldb"}; + std::string indexes[8] = {"alex", "lipp", "btree", "skiplist", + "pgm", "art", "leveldb", "csbtree"}; int num_keys = 100000; diff --git a/tests/test_csbtree/CMakeLists.txt b/tests/test_csbtree/CMakeLists.txt new file mode 100644 index 0000000..b44a9ac --- /dev/null +++ b/tests/test_csbtree/CMakeLists.txt @@ -0,0 +1,9 @@ +get_filename_component(EXEC ${CMAKE_CURRENT_SOURCE_DIR} NAME) +file(GLOB_RECURSE CPP_TESTS "*_tests.cpp") +add_executable(${EXEC} ${CPP_TESTS}) +target_link_libraries(${EXEC} PRIVATE +bliss +bliss_test_infra +GTest::gtest_main) +include(GoogleTest) +gtest_discover_tests(${EXEC}) \ No newline at end of file diff --git a/tests/test_csbtree/csbtree_tests.cpp b/tests/test_csbtree/csbtree_tests.cpp new file mode 100644 index 0000000..dd32b6f --- /dev/null +++ b/tests/test_csbtree/csbtree_tests.cpp @@ -0,0 +1,40 @@ +#include "bliss_index_tests.h" + +class CSBTreeTest : public BlissIndexTest {}; + +TEST_F(CSBTreeTest, TestCSBTree_Sanity) { + index.reset(new bliss::BlissCSBTreeIndex()); + std::vector data; + int key = 100'000; + int value = 123'456; + index->put(key, value); + EXPECT_TRUE(index->get(key)); +} + +TEST_F(CSBTreeTest, TestCSBTree_Sorted) { + index.reset(new bliss::BlissCSBTreeIndex()); + std::vector data; + GenerateData(data, num_keys); + + auto insert_start = data.begin(); + auto insert_end = data.end(); + executor::execute_inserts(*index, insert_start, insert_end); + + for (auto key : data) { + EXPECT_TRUE(index->get(key)); + } +} + +TEST_F(CSBTreeTest, TestCSBTree_Random) { + index.reset(new bliss::BlissCSBTreeIndex()); + std::vector data; + GenerateData(data, num_keys, false); + + auto insert_start = data.begin(); + auto insert_end = data.end(); + executor::execute_inserts(*index, insert_start, insert_end); + + for (auto key : data) { + EXPECT_TRUE(index->get(key)); + } +} \ No newline at end of file