diff --git a/CMakeLists.txt b/CMakeLists.txt index 66226eb..dc6d4a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,7 @@ add_library(bliss OBJECT ${CMAKE_SOURCE_DIR}/src/bliss/bench_lipp.h ${CMAKE_SOURCE_DIR}/src/bliss/bench_alex.h ${CMAKE_SOURCE_DIR}/src/bliss/bench_btree.h + ${CMAKE_SOURCE_DIR}/src/bliss/bench_skiplist.h ) target_compile_features(bliss PUBLIC @@ -63,6 +64,7 @@ target_link_libraries(bliss PUBLIC alex lipp tlx + skiplist ) target_include_directories(bliss PUBLIC diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 3531b2f..15aed48 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -33,7 +33,7 @@ FetchContent_MakeAvailable(cxxopts) FetchContent_Declare( alex - GIT_REPOSITORY https://github.com/microsoft/ALEX.git + GIT_REPOSITORY https://github.com/microsoft/ALEX GIT_TAG master ) FetchContent_GetProperties(alex) @@ -70,4 +70,18 @@ if (NOT tlx_POPULATED) endif() add_library(tlx INTERFACE) -target_include_directories(tlx INTERFACE ${tlx_SOURCE_DIR}/) \ No newline at end of file +target_include_directories(tlx INTERFACE ${tlx_SOURCE_DIR}/) + + +FetchContent_Declare( + skiplist + GIT_REPOSITORY https://github.com/Samyak2/skip-list.git + GIT_TAG main +) +FetchContent_GetProperties(skiplist) +if (NOT skiplist_POPULATED) + FetchContent_Populate(skiplist) +endif() + +add_library(skiplist INTERFACE) +target_include_directories(skiplist INTERFACE ${skiplist_SOURCE_DIR}/skiplist) \ No newline at end of file diff --git a/src/bliss/bench_skiplist.h b/src/bliss/bench_skiplist.h new file mode 100644 index 0000000..5579d0a --- /dev/null +++ b/src/bliss/bench_skiplist.h @@ -0,0 +1,33 @@ +#ifndef BLISS_BENCH_SKIPLIST +#define BLISS_BENCH_SKIPLIST + +#include + +#include "bliss/bliss_index.h" +#include "skiplist_map.hpp" + +namespace bliss { + +template +class BlissSkipListIndex : public BlissIndex { + public: + skiplist _index; + BlissSkipListIndex() : _index(){}; + + void bulkload( + std::vector> values) override { + for (const auto& pair : values) { + _index.insert(pair.first, pair.second); + } + } + + bool get(KEY_TYPE key) override { return _index.find(key) != _index.end(); } + + void put(KEY_TYPE key, VALUE_TYPE value) override { _index.insert(key, value); } + + void end_routine() override {} +}; + +} // namespace bliss + +#endif // !BLISS_BENCH_SKIPLIST diff --git a/src/bliss_bench.cpp b/src/bliss_bench.cpp index 97b8e32..752f832 100644 --- a/src/bliss_bench.cpp +++ b/src/bliss_bench.cpp @@ -1,5 +1,6 @@ #include #include +#include "skiplist_map.hpp" #include #include @@ -9,6 +10,7 @@ #include "bliss/bench_alex.h" #include "bliss/bench_btree.h" #include "bliss/bench_lipp.h" +#include "bliss/bench_skiplist.h" #include "bliss/bliss_index.h" #include "bliss/util/args.h" #include "bliss/util/config.h" @@ -168,6 +170,8 @@ int main(int argc, char *argv[]) { index.reset(new bliss::BlissLippIndex()); } else if (config.index == "btree") { index.reset(new bliss::BlissBTreeIndex()); + } else if (config.index == "skiplist") { + index.reset(new bliss::BlissSkipListIndex()); } else { spdlog::error(config.index + " not implemented yet", 1); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e916e4f..a61ec72 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -16,4 +16,5 @@ target_include_directories(bliss_test_infra PUBLIC add_subdirectory(test_alex) add_subdirectory(test_lipp) -add_subdirectory(test_btree) \ No newline at end of file +add_subdirectory(test_btree) +add_subdirectory(test_skiplist) diff --git a/tests/bliss_index_tests.h b/tests/bliss_index_tests.h index edb14fa..b666a4d 100644 --- a/tests/bliss_index_tests.h +++ b/tests/bliss_index_tests.h @@ -8,10 +8,13 @@ #include #include #include +#include +#include #include "bliss/bench_alex.h" #include "bliss/bench_btree.h" #include "bliss/bench_lipp.h" +#include "bliss/bench_skiplist.h" #include "bliss/bliss_index.h" #include "bliss/util/args.h" #include "bliss/util/config.h" @@ -27,7 +30,7 @@ using value_type = unsigned long; class BlissIndexTest : public testing::Test { protected: std::unique_ptr> index; - std::string indexes[3] = {"alex", "lipp", "btree"}; + std::string indexes[4] = {"alex", "lipp", "btree", "skiplist"}; int num_keys = 100000; void SetUp() {} @@ -38,7 +41,9 @@ class BlissIndexTest : public testing::Test { data.push_back(i); } if (!sorted) { - std::random_shuffle(data.begin(), data.end()); + std::random_device rd; + std::mt19937 g(rd()); + std::shuffle(data.begin(), data.end(), g); } } }; diff --git a/tests/test_lipp/lipp_tests.cpp b/tests/test_lipp/lipp_tests.cpp index 78750a8..146a842 100644 --- a/tests/test_lipp/lipp_tests.cpp +++ b/tests/test_lipp/lipp_tests.cpp @@ -17,7 +17,7 @@ TEST_F(LippTest, TestLipp_Sorted) { } TEST_F(LippTest, TestLipp_Random) { - index.reset(new bliss::BlissAlexIndex()); + index.reset(new bliss::BlissLippIndex()); std::vector data; GenerateData(data, num_keys, false); diff --git a/tests/test_skiplist/CMakeLists.txt b/tests/test_skiplist/CMakeLists.txt new file mode 100644 index 0000000..b44a9ac --- /dev/null +++ b/tests/test_skiplist/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_skiplist/skiplist_tests.cpp b/tests/test_skiplist/skiplist_tests.cpp new file mode 100644 index 0000000..adcc72b --- /dev/null +++ b/tests/test_skiplist/skiplist_tests.cpp @@ -0,0 +1,31 @@ +#include "bliss_index_tests.h" + +class SkipListTest : public BlissIndexTest {}; + +TEST_F(SkipListTest, TestSkipList_Sorted) { + index.reset(new bliss::BlissSkipListIndex()); + 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(SkipListTest, TestSkipList_Random) { + index.reset(new bliss::BlissSkipListIndex()); + 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