diff --git a/libmdtrie/CMakeLists.txt b/libmdtrie/CMakeLists.txt index 10c13a0f..cdd07124 100644 --- a/libmdtrie/CMakeLists.txt +++ b/libmdtrie/CMakeLists.txt @@ -10,5 +10,11 @@ add_executable(microbench add_executable(example bench/example.cpp) +add_executable(insert_test + bench/insert_test.cpp) + +add_executable(search_test + bench/search_test.cpp) + target_link_libraries(microbench ${MDTRIE_LIBS}) target_link_libraries(example ${MDTRIE_LIBS}) diff --git a/libmdtrie/bench/benchmark.hpp b/libmdtrie/bench/benchmark.hpp index fc010751..80a8f5f0 100644 --- a/libmdtrie/bench/benchmark.hpp +++ b/libmdtrie/bench/benchmark.hpp @@ -26,6 +26,7 @@ class MdTrieBench TimeStamp start = 0, diff = 0; point_t n_points = 0; point_t has_skipped = 0; + // data_point leaf_point(mdtrie_->get_width()); data_point leaf_point; /** @@ -106,6 +107,8 @@ class MdTrieBench { std::vector found_points; + // data_point start_range(mdtrie_->get_width()); + // data_point end_range(mdtrie_->get_width()); data_point start_range; data_point end_range; @@ -140,6 +143,8 @@ class MdTrieBench { std::vector found_points; + // data_point start_range(mdtrie_->get_width()); + // data_point end_range(mdtrie_->get_width()); data_point start_range; data_point end_range; diff --git a/libmdtrie/bench/common.hpp b/libmdtrie/bench/common.hpp index dfe2d5c5..d94c1244 100644 --- a/libmdtrie/bench/common.hpp +++ b/libmdtrie/bench/common.hpp @@ -34,7 +34,7 @@ enum NYC = 3, }; -std::string ROOT_DIR = "/proj/trinity-PG0/Trinity/"; +std::string ROOT_DIR = "/proj/trinitys25-PG0/Trinity/"; std::string TPCH_DATA_ADDR = ROOT_DIR + "datasets/tpch_dataset.csv"; std::string GITHUB_DATA_ADDR = ROOT_DIR + "datasets/github_dataset.csv"; std::string NYC_DATA_ADDR = ROOT_DIR + "datasets/nyc_dataset.csv"; @@ -64,10 +64,11 @@ enum level_t max_depth = 32; level_t trie_depth = 6; +dimension_t trie_width = -1; preorder_t max_tree_node = 512; point_t points_to_insert = 1000; point_t points_to_lookup = 1000; -std::string results_folder_addr = "/proj/trinity-PG0/Trinity/results/"; +std::string results_folder_addr = "/proj/trinitys25-PG0/Trinity/results/"; std::string identification_string = ""; int optimization_code = OPTIMIZATION_SM; std::string optimization = "SM"; @@ -147,10 +148,22 @@ void use_nyc_setting(int dimensions, int _total_points_count) bit_widths.resize(dimensions); trie_depth = 6; - max_depth = 28; no_dynamic_sizing = true; - create_level_to_num_children(bit_widths, start_bits, max_depth); + // calculate max_depth + uint16_t total_bits = 0; + int bit_widths_size = sizeof(bit_widths) / sizeof(bit_widths[0]); + for (int i = 0; i < bit_widths_size; i++) { + total_bits += bit_widths[i] - start_bits[i]; + } + max_depth = total_bits / trie_width; + if (total_bits % trie_width != 0) { + max_depth++; + } + + // add one to depth if there's a remainder + + create_level_to_num_children(bit_widths, start_bits, max_depth, trie_width); } void use_github_setting(int dimensions, int _total_points_count) @@ -195,11 +208,20 @@ void use_github_setting(int dimensions, int _total_points_count) bit_widths.resize(dimensions); trie_depth = 6; - max_depth = 24; no_dynamic_sizing = true; - max_tree_node = 512; - create_level_to_num_children(bit_widths, start_bits, max_depth); + // calculate max_depth + uint16_t total_bits = 0; + int bit_widths_size = sizeof(bit_widths) / sizeof(bit_widths[0]); + for (int i = 0; i < bit_widths_size; i++) { + total_bits += bit_widths[i] - start_bits[i]; + } + max_depth = total_bits / trie_width; + if (total_bits % trie_width != 0) { + max_depth++; + } + + create_level_to_num_children(bit_widths, start_bits, max_depth, trie_width); } void use_tpch_setting(int dimensions, int _total_points_count) @@ -256,9 +278,20 @@ void use_tpch_setting(int dimensions, int _total_points_count) } trie_depth = 6; - max_depth = 32; no_dynamic_sizing = true; - create_level_to_num_children(bit_widths, start_bits, max_depth); + + // calculate max_depth + uint16_t total_bits = 0; + int bit_widths_size = sizeof(bit_widths) / sizeof(bit_widths[0]); + for (int i = 0; i < bit_widths_size; i++) { + total_bits += bit_widths[i] - start_bits[i]; + } + max_depth = total_bits / trie_width; + if (total_bits % trie_width != 0) { + max_depth++; + } + + create_level_to_num_children(bit_widths, start_bits, max_depth, trie_width); } void flush_vector_to_file(std::vector vect, std::string filename) diff --git a/libmdtrie/bench/example_flex.cpp b/libmdtrie/bench/example_flex.cpp new file mode 100644 index 00000000..bda93f36 --- /dev/null +++ b/libmdtrie/bench/example_flex.cpp @@ -0,0 +1,140 @@ +#include "benchmark.hpp" +#include "common.hpp" +#include "parser.hpp" +#include "trie.h" +#include +#include +#include +#include +#include +#include + +// Template function that accepts a reference to an array of any type and size. +template +void printArray(const T* arr, std::size_t N) { + std::cout << "["; + for (std::size_t i = 0; i < N; ++i) { + std::cout << arr[i]; + if (i != N - 1) { + std::cout << ", "; + } + } + std::cout << "]" << std::endl; +} + +// Function to generate a random integer in the range [min, max] +int random_int(int min, int max) +{ + static std::random_device rd; + static std::mt19937 gen(rd()); + std::uniform_int_distribution<> distrib(min, max); + return distrib(gen); +} + +int main(int argc, char *argv[]) +{ + int arg; + dimension_t width; + + while ((arg = getopt(argc, argv, "w:")) != -1) + switch (arg) + { + case 'w': + width = atoi(optarg); + break; + default: + break; + } + + dimension_t num_dimensions = 10; + int total_count = 10; + trie_depth = 6; + max_depth = (32 * num_dimensions) / width; + no_dynamic_sizing = true; + md_trie<10> mdtrie(max_depth, trie_depth, max_tree_node, true, width); + // md_trie<10> mdtrie(max_depth, trie_depth, max_tree_node); + bitmap::CompactPtrVector primary_key_to_treeblock_mapping(total_count); + + /* ---------- Initialization ------------ */ + std::vector bit_widths = { + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}; + std::vector start_bits = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + create_level_to_num_children_flex(bit_widths, start_bits, max_depth, width); + // create_level_to_num_children(bit_widths, start_bits, max_depth); + + // debug + point_t point0[10] = {0, 7, 1, 8, 5, 6, 1, 6, 3, 2}; + point_t point1[10] = {1, 8, 2, 4, 4, 7, 6, 3, 8, 7}; + + /* ----------- INSERT ----------- */ + TimeStamp start = 0, cumulative = 0; + + for (int primary_key = 0; primary_key < total_count; primary_key++) + { + data_point_flex<10> point(width); + // data_point<10> point; + // For lookup correctness checking. + point.set_coordinate(0, primary_key); + for (dimension_t i = 1; i < num_dimensions; ++i) + { + if (primary_key == 0) + point.set_coordinate(i, point0[i]); + else if (primary_key == 1) + point.set_coordinate(i, point1[i]); + else + point.set_coordinate(i, random_int(1, (int)1 << 16)); + } + + std::cout << "Point " << std::to_string(primary_key) << " coordinate: "; + printArray(point.get(), num_dimensions); + + start = GetTimestamp(); + mdtrie.insert_trie(&point, primary_key, &primary_key_to_treeblock_mapping); + cumulative += GetTimestamp() - start; + } + std::cout << "Insertion Latency: " << (float)cumulative / total_count << " us" << std::endl; + + /* ---------- LOOKUP ------------ */ + cumulative = 0; + for (int primary_key = 0; primary_key < total_count; primary_key++) + { + start = GetTimestamp(); + data_point_flex<10> *pt = mdtrie.lookup_trie_flex(primary_key, &primary_key_to_treeblock_mapping, num_dimensions); + // data_point<10> *pt = mdtrie.lookup_trie(primary_key, &primary_key_to_treeblock_mapping, num_dimensions); + if ((int)pt->get_coordinate(0) != primary_key) + { + std::cerr << "Wrong point retrieved!" << std::endl; + } + cumulative += GetTimestamp() - start; + } + std::cout << "Lookup Latency: " << (float)cumulative / total_count << " us" << std::endl; + + /* ---------- RANGE QUERY ------------ */ + cumulative = 0; + int num_queries = 10; + for (int c = 0; c < num_queries; c++) + { + data_point_flex<10> start_range(width); + data_point_flex<10> end_range(width); + // data_point<10> start_range; + // data_point<10> end_range; + std::vector found_points; + for (dimension_t i = 0; i < 10; i++) + { + start_range.set_coordinate(i, 0); + end_range.set_coordinate(i, (int)1 << 16); + } + + start = GetTimestamp(); + mdtrie.range_search_trie(&start_range, &end_range, mdtrie.root(), 0, found_points); + // Coordinates are flattened into one vector. + if ((int)(found_points.size() / num_dimensions) != total_count) + { + std::cerr << "Wrong number of points found!" << std::endl; + } + cumulative += GetTimestamp() - start; + } + std::cout << "Query Latency: " << (float)cumulative / num_queries << " us" << std::endl; + return 0; +} \ No newline at end of file diff --git a/libmdtrie/bench/insert_test.cpp b/libmdtrie/bench/insert_test.cpp new file mode 100644 index 00000000..e2592b99 --- /dev/null +++ b/libmdtrie/bench/insert_test.cpp @@ -0,0 +1,130 @@ +#include "benchmark.hpp" +#include "common.hpp" +#include "parser.hpp" +#include "trie.h" +#include +#include +#include +#include +#include +#include + +bool check_size = false; + +// Function to generate a random integer in the range [min, max] +int random_int(int min, int max) +{ + static std::random_device rd; + static std::mt19937 gen(rd()); + std::uniform_int_distribution<> distrib(min, max); + return distrib(gen); +} + +void run_example(std::vector bit_widths, std::vector start_bits, int total_count, dimension_t width) { + + max_depth = (24 * 10) / width; + if ((24 * 10) % width != 0) { + max_depth++; + } + + create_level_to_num_children(bit_widths, start_bits, max_depth, width); + + md_trie<10> mdtrie(width, max_depth, trie_depth, max_tree_node); + // md_trie<10> mdtrie(max_depth, trie_depth, max_tree_node); + bitmap::CompactPtrVector primary_key_to_treeblock_mapping(total_count); + + // Reserve space in a vector for total_count data_point<10> objects + std::vector> points; + points.reserve(total_count); + + for (int primary_key = 0; primary_key < total_count; primary_key++) { + // data_point<10> point(width); + data_point<10> point; + // Use primary_key as the first coordinate (for lookup correctness checking) + point.set_coordinate(0, primary_key); + // For the remaining dimensions, assign random values + for (dimension_t i = 1; i < 10; ++i) { + point.set_coordinate(i, random_int(1, (int)1 << 16)); + } + // Push the generated point into the vector + points.push_back(point); + } + + /* ----------- INSERT ----------- */ + TimeStamp start = 0, cumulative = 0; + for (int primary_key = 0; primary_key < total_count; primary_key++) { + // Insert each point from the vector into the trie. + start = GetTimestamp(); + mdtrie.insert_trie(&points[primary_key], primary_key, &primary_key_to_treeblock_mapping); + cumulative += GetTimestamp() - start; + } + std::cout << "Insertion Latency: " << (float)cumulative / total_count << " us" << std::endl; + if (check_size) + std::cout << "Size after insertion: " << mdtrie.size(&primary_key_to_treeblock_mapping) << std::endl; + + /* ---------- LOOKUP ------------ */ + for (int primary_key = 0; primary_key < total_count; primary_key++) + { + data_point<10> *pt = mdtrie.lookup_trie(primary_key, &primary_key_to_treeblock_mapping); + for (int i = 0; i < 10; i++) { + if ((int) pt->get_coordinate(i) != (int) points[primary_key].get_coordinate(i)) { + std::cerr << "Wrong point retrieved!" << std::endl; + break; + } + } + } +} + +int main(int argc, char *argv[]) +{ + int total_count = 100; + trie_depth = 6; + no_dynamic_sizing = true; + + // defaults + max_tree_node = 512; + optimization_code = OPTIMIZATION_SM; + + int arg; + + while ((arg = getopt(argc, argv, "o:t:s:")) != -1) + switch (arg) + { + case 't': + max_tree_node = atoi(optarg); + break; + case 'o': + optimization = std::string(optarg); + if (optimization == "SM") + optimization_code = OPTIMIZATION_SM; + if (optimization == "B") + optimization_code = OPTIMIZATION_B; + if (optimization == "CN") + optimization_code = OPTIMIZATION_CN; + if (optimization == "GM") + optimization_code = OPTIMIZATION_GM; + break; + case 's': + check_size = true; + break; + default: + abort(); + } + + /* ---------- Initialization ------------ */ + std::vector bit_widths = { + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24}; + std::vector start_bits = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + run_example(bit_widths, start_bits, total_count, 6); + run_example(bit_widths, start_bits, total_count, 8); + run_example(bit_widths, start_bits, total_count, 10); + run_example(bit_widths, start_bits, total_count, 12); + run_example(bit_widths, start_bits, total_count, 14); + run_example(bit_widths, start_bits, total_count, 16); + run_example(bit_widths, start_bits, total_count, 18); + run_example(bit_widths, start_bits, total_count, 20); + + return 0; +} \ No newline at end of file diff --git a/libmdtrie/bench/microbench.cpp b/libmdtrie/bench/microbench.cpp index 6489ab45..61f166bf 100644 --- a/libmdtrie/bench/microbench.cpp +++ b/libmdtrie/bench/microbench.cpp @@ -12,7 +12,15 @@ void github_bench(void) { use_github_setting(GITHUB_DIMENSION, micro_github_size); - md_trie mdtrie(max_depth, trie_depth, max_tree_node); + + if (trie_width == (dimension_t) -1) { + trie_width = (dimension_t) GITHUB_DIMENSION; + } + else { + identification_string += "_FLEX_" + std::to_string(trie_width) + "_" + std::to_string(max_tree_node); + } + + md_trie mdtrie(trie_width, max_depth, trie_depth, max_tree_node); MdTrieBench bench(&mdtrie); p_key_to_treeblock_compact = new bitmap::CompactPtrVector(total_points_count); std::string folder_name = "microbenchmark/"; @@ -35,7 +43,15 @@ void nyc_bench(void) { use_nyc_setting(NYC_DIMENSION, micro_nyc_size); - md_trie mdtrie(max_depth, trie_depth, max_tree_node); + + if (trie_width == (dimension_t) -1) { + trie_width = NYC_DIMENSION; + } + else { + identification_string += "_FLEX_" + std::to_string(trie_width) + "_" + std::to_string(max_tree_node); + } + + md_trie mdtrie(trie_width, max_depth, trie_depth, max_tree_node); MdTrieBench bench(&mdtrie); p_key_to_treeblock_compact = new bitmap::CompactPtrVector(total_points_count); std::string folder_name = "microbenchmark/"; @@ -58,7 +74,15 @@ void tpch_bench(void) { use_tpch_setting(TPCH_DIMENSION, micro_tpch_size); - md_trie mdtrie(max_depth, trie_depth, max_tree_node); + + if (trie_width == (dimension_t) -1) { + trie_width = TPCH_DIMENSION; + } + else { + identification_string += "_FLEX_" + std::to_string(trie_width) + "_" + std::to_string(max_tree_node); + } + + md_trie mdtrie(trie_width, max_depth, trie_depth, max_tree_node); MdTrieBench bench(&mdtrie); p_key_to_treeblock_compact = new bitmap::CompactPtrVector(total_points_count); std::string folder_name = "microbenchmark/"; @@ -81,7 +105,7 @@ void sensitivity_num_dimensions_9(void) { use_tpch_setting(9, micro_tpch_size); - md_trie<9> mdtrie(max_depth, trie_depth, max_tree_node); + md_trie<9> mdtrie(9, max_depth, trie_depth, max_tree_node); MdTrieBench<9> bench(&mdtrie); p_key_to_treeblock_compact = new bitmap::CompactPtrVector(total_points_count); @@ -103,7 +127,7 @@ void sensitivity_num_dimensions_8(void) { use_tpch_setting(8, micro_tpch_size); - md_trie<8> mdtrie(max_depth, trie_depth, max_tree_node); + md_trie<8> mdtrie(8, max_depth, trie_depth, max_tree_node); MdTrieBench<8> bench(&mdtrie); p_key_to_treeblock_compact = new bitmap::CompactPtrVector(total_points_count); @@ -125,7 +149,7 @@ void sensitivity_num_dimensions_7(void) { use_tpch_setting(7, micro_tpch_size); - md_trie<7> mdtrie(max_depth, trie_depth, max_tree_node); + md_trie<7> mdtrie(7, max_depth, trie_depth, max_tree_node); MdTrieBench<7> bench(&mdtrie); p_key_to_treeblock_compact = new bitmap::CompactPtrVector(total_points_count); @@ -147,7 +171,7 @@ void sensitivity_num_dimensions_6(void) { use_tpch_setting(6, micro_tpch_size); - md_trie<6> mdtrie(max_depth, trie_depth, max_tree_node); + md_trie<6> mdtrie(6, max_depth, trie_depth, max_tree_node); MdTrieBench<6> bench(&mdtrie); p_key_to_treeblock_compact = new bitmap::CompactPtrVector(total_points_count); bench.insert(TPCH_DATA_ADDR, @@ -168,7 +192,7 @@ void sensitivity_num_dimensions_5(void) { use_tpch_setting(5, micro_tpch_size); - md_trie<5> mdtrie(max_depth, trie_depth, max_tree_node); + md_trie<5> mdtrie(5, max_depth, trie_depth, max_tree_node); MdTrieBench<5> bench(&mdtrie); p_key_to_treeblock_compact = new bitmap::CompactPtrVector(total_points_count); @@ -190,7 +214,7 @@ void sensitivity_num_dimensions_4(void) { use_tpch_setting(4, micro_tpch_size); - md_trie<4> mdtrie(max_depth, trie_depth, max_tree_node); + md_trie<4> mdtrie(4, max_depth, trie_depth, max_tree_node); MdTrieBench<4> bench(&mdtrie); p_key_to_treeblock_compact = new bitmap::CompactPtrVector(total_points_count); @@ -211,7 +235,7 @@ void sensitivity_num_dimensions_4(void) void sensitivity_num_dimensions_20(void) { use_tpch_setting(20, micro_tpch_size); - md_trie<20> mdtrie(max_depth, trie_depth, max_tree_node); + md_trie<20> mdtrie(20, max_depth, trie_depth, max_tree_node); MdTrieBench<20> bench(&mdtrie); p_key_to_treeblock_compact = new bitmap::CompactPtrVector(total_points_count); // Use fewer points. @@ -235,7 +259,7 @@ void sensitivity_selectivity(void) { use_tpch_setting(TPCH_DIMENSION, micro_tpch_size); - md_trie mdtrie(max_depth, trie_depth, max_tree_node); + md_trie mdtrie((dimension_t) TPCH_DIMENSION, max_depth, trie_depth, max_tree_node); MdTrieBench bench(&mdtrie); p_key_to_treeblock_compact = new bitmap::CompactPtrVector(total_points_count); @@ -253,7 +277,7 @@ void sensitivity_selectivity(void) void sensitivity_treeblock_sizes(int treeblock_size) { use_tpch_setting(TPCH_DIMENSION, micro_tpch_size); - md_trie mdtrie(max_depth, trie_depth, treeblock_size); + md_trie mdtrie((dimension_t) TPCH_DIMENSION, max_depth, trie_depth, treeblock_size); MdTrieBench bench(&mdtrie); p_key_to_treeblock_compact = new bitmap::CompactPtrVector(total_points_count); bench.insert(TPCH_DATA_ADDR, @@ -278,7 +302,7 @@ int main(int argc, char *argv[]) int treeblock_size = -1; is_microbenchmark = true; - while ((arg = getopt(argc, argv, "b:o:d:t:")) != -1) + while ((arg = getopt(argc, argv, "b:o:d:t:w:m:")) != -1) switch (arg) { case 'b': @@ -301,13 +325,21 @@ int main(int argc, char *argv[]) case 'd': sensitivity_dimensions = atoi(optarg); break; + case 'w': + trie_width = (dimension_t) atoi(optarg); + break; + case 'm': + max_tree_node = (preorder_t) atoi(optarg); + break; default: abort(); } std::cout << "benchmark: " << argvalue << ", optimization: " << optimization << ", dimensions: " << sensitivity_dimensions - << ", treeblock_size: " << treeblock_size << std::endl; + << ", treeblock_size: " << treeblock_size + << ", trie_width: " << (int) trie_width + << ", max_tree_node: " << (int) max_tree_node << std::endl; if (argvalue == "tpch") tpch_bench(); else if (argvalue == "github") diff --git a/libmdtrie/bench/search_test.cpp b/libmdtrie/bench/search_test.cpp new file mode 100644 index 00000000..d2c6c525 --- /dev/null +++ b/libmdtrie/bench/search_test.cpp @@ -0,0 +1,171 @@ +#include "benchmark.hpp" +#include "common.hpp" +#include "parser.hpp" +#include "trie.h" +#include +#include +#include +#include +#include +#include + +bool check_size = false; + +// Template function that accepts a reference to an array of any type and size. +template +void printArray(const T* arr, std::size_t N) { + std::cout << "["; + for (std::size_t i = 0; i < N; ++i) { + std::cout << arr[i]; + if (i != N - 1) { + std::cout << ", "; + } + } + std::cout << "]" << std::endl; +} + +// Function to generate a random integer in the range [min, max] +int random_int(int min, int max) +{ + static std::random_device rd; + static std::mt19937 gen(rd()); + std::uniform_int_distribution<> distrib(min, max); + return distrib(gen); +} + +void run_example(std::vector bit_widths, std::vector start_bits, int total_count, dimension_t width) { + + max_depth = (24 * 10) / width; + if ((24 * 10) % width != 0) { + max_depth++; + } + + create_level_to_num_children(bit_widths, start_bits, max_depth, width); + + // std::cout << "Level to num children (width = " << std::to_string(width) << "): "; + // printArray(level_to_num_children, max_depth); + + md_trie<10> mdtrie(width, max_depth, trie_depth, max_tree_node); + // md_trie<10> mdtrie(max_depth, trie_depth, max_tree_node); + bitmap::CompactPtrVector primary_key_to_treeblock_mapping(total_count); + + // Reserve space in a vector for total_count data_point<10> objects + std::vector> points; + points.reserve(total_count); + + for (int primary_key = 0; primary_key < total_count; primary_key++) { + // data_point<10> point(width); + data_point<10> point; + // Use primary_key as the first coordinate (for lookup correctness checking) + point.set_coordinate(0, primary_key); + // For the remaining dimensions, assign random values + for (dimension_t i = 1; i < 10; ++i) { + point.set_coordinate(i, random_int(1, (int)1 << 16)); + } + // Push the generated point into the vector + points.push_back(point); + } + + /* ----------- INSERT ----------- */ + TimeStamp start = 0, cumulative = 0; + for (int primary_key = 0; primary_key < total_count; primary_key++) { + // Insert each point from the vector into the trie. + start = GetTimestamp(); + mdtrie.insert_trie(&points[primary_key], primary_key, &primary_key_to_treeblock_mapping); + cumulative += GetTimestamp() - start; + } + std::cout << "Insertion Latency: " << (float)cumulative / total_count << " us" << std::endl; + if (check_size) + std::cout << "Size after insertion: " << mdtrie.size(&primary_key_to_treeblock_mapping) << std::endl; + + /* ---------- LOOKUP ------------ */ + for (int primary_key = 0; primary_key < total_count; primary_key++) + { + data_point<10> *pt = mdtrie.lookup_trie(primary_key, &primary_key_to_treeblock_mapping); + for (int i = 0; i < 10; i++) { + if ((int) pt->get_coordinate(i) != (int) points[primary_key].get_coordinate(i)) { + std::cerr << "Wrong point retrieved!" << std::endl; + break; + } + } + } + + /* ---------- RANGE QUERY ------------ */ + cumulative = 0; + int num_queries = 10; + for (int c = 0; c < num_queries; c++) + { + // data_point<10> start_range(width); + // data_point<10> end_range(width); + data_point<10> start_range; + data_point<10> end_range; + std::vector found_points; + for (dimension_t i = 0; i < 10; i++) + { + start_range.set_coordinate(i, 0); + end_range.set_coordinate(i, (int)1 << 16); + } + + start = GetTimestamp(); + mdtrie.range_search_trie(&start_range, &end_range, mdtrie.root(), 0, found_points); + // Coordinates are flattened into one vector. + if ((int)(found_points.size() / 10) != total_count) + { + std::cerr << "Wrong number of points found! (" + << std::to_string(found_points.size() / 10) << ")" << std::endl; + } + cumulative += GetTimestamp() - start; + } + std::cout << "Query Latency: " << (float)cumulative / num_queries << std::endl << std::endl; +} + +int main(int argc, char *argv[]) +{ + int total_count = 100; + trie_depth = 6; + no_dynamic_sizing = true; + + // defaults + max_tree_node = 512; + optimization_code = OPTIMIZATION_SM; + + int arg; + + while ((arg = getopt(argc, argv, "o:t:s:")) != -1) + switch (arg) + { + case 't': + max_tree_node = atoi(optarg); + break; + case 'o': + optimization = std::string(optarg); + if (optimization == "SM") + optimization_code = OPTIMIZATION_SM; + if (optimization == "B") + optimization_code = OPTIMIZATION_B; + if (optimization == "CN") + optimization_code = OPTIMIZATION_CN; + if (optimization == "GM") + optimization_code = OPTIMIZATION_GM; + break; + case 's': + check_size = true; + break; + default: + abort(); + } + + /* ---------- Initialization ------------ */ + std::vector bit_widths = { + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24}; + std::vector start_bits = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + run_example(bit_widths, start_bits, total_count, 4); + run_example(bit_widths, start_bits, total_count, 6); + run_example(bit_widths, start_bits, total_count, 8); + run_example(bit_widths, start_bits, total_count, 10); + run_example(bit_widths, start_bits, total_count, 16); + + return 0; +} \ No newline at end of file diff --git a/libmdtrie/src/compact_ptr.h b/libmdtrie/src/compact_ptr.h index e2cac451..9f209149 100644 --- a/libmdtrie/src/compact_ptr.h +++ b/libmdtrie/src/compact_ptr.h @@ -73,6 +73,8 @@ namespace bits uint64_t size_overhead() { + // if (!is_valid((void *) this)) + // return 0; if (flag_ == 0) { diff --git a/libmdtrie/src/compressed_bitmap.h b/libmdtrie/src/compressed_bitmap.h index 285f1623..94ddf178 100644 --- a/libmdtrie/src/compressed_bitmap.h +++ b/libmdtrie/src/compressed_bitmap.h @@ -20,7 +20,7 @@ namespace compressed_bitmap #define CLRBIT(n, i) n = (n & ~(1UL << i)) #define BITS2BLOCKS(bits) \ - (((bits) % 64 == 0) ? ((bits) / 64) : (((bits) / 64) + 1)) + (((bits) % 64 == 0) ? ((bits) / 64) : (((bits) / 64) + 1)) #define GETBITVAL(data, i) GETBIT((data)[(i) / 64], (i) % 64) #define SETBITVAL(data, i) SETBIT((data)[(i) / 64], (i) % 64) @@ -144,6 +144,8 @@ namespace compressed_bitmap inline uint64_t size() const { + // if (!is_valid((void *) this)) + // return 0; uint64_t total_size = 0; total_size += sizeof(data_size_) + sizeof(flag_size_); diff --git a/libmdtrie/src/data_point.h b/libmdtrie/src/data_point.h index 80a0489f..7c880b85 100644 --- a/libmdtrie/src/data_point.h +++ b/libmdtrie/src/data_point.h @@ -40,19 +40,18 @@ class data_point { morton_t result = 0; - dimension_t dimension = DIMENSION; + auto &tbl = _dim_off_table[level]; - for (size_t i = 0; i < dimension; i++) - { - if (dimension_to_num_bits[i] <= level || level < start_dimension_bits[i]) - continue; + for (uint16_t i = 0; i < tbl.size(); i++) { + + auto [dim, off] = tbl[i]; - level_t offset = dimension_to_num_bits[i] - level - 1; - point_t coordinate = coordinates_[i]; + point_t coordinate = coordinates_[dim]; - bool bit = GETBIT(coordinate, offset); + bool bit = GETBIT (coordinate, off); result = (result << 1U) + bit; } + return result; } @@ -60,19 +59,18 @@ class data_point { morton_t result = 0; - dimension_t dimension = DIMENSION; - - for (size_t i = 0; i < dimension; i++) - { - if (dimension_to_num_bits[i] <= level || level < start_dimension_bits[i]) - continue; + auto &tbl = _dim_off_table[level]; + for (uint16_t i = 0; i < tbl.size(); i++) { bool bit = 1; result = (result << 1U) + bit; } + return result; } + // NOT USED ANYWHERE, but + // might need to change 32 to max_depth of trie uint64_t coordinate_to_raw_morton() { @@ -97,42 +95,33 @@ class data_point level_t level) { - dimension_t dimension = DIMENSION; + // dimension_t dimension = DIMENSION; size_t visited_ct = 0; - for (size_t j = 0; j < dimension; j++) - { + auto &tbl = _dim_off_table[level]; + dimension_t bits_in_lvl = (dimension_t) tbl.size(); - if (dimension_to_num_bits[j] <= level || level < start_dimension_bits[j]) - continue; + for (uint16_t i = 0; i < bits_in_lvl; i++) { + auto [dim, off] = tbl[i]; visited_ct++; - level_t offset = dimension_to_num_bits[j] - level - 1U; - - point_t start_coordinate = coordinates_[j]; - point_t end_coordinate = end_range->coordinates_[j]; - dimension_t symbol_offset = level_to_num_children[level] - visited_ct; + dimension_t sym_off = bits_in_lvl - visited_ct; - bool start_bit = GETBIT(start_coordinate, offset); - bool end_bit = GETBIT(end_coordinate, offset); - bool symbol_bit = GETBIT(current_symbol, symbol_offset); + bool start_bit = GETBIT(coordinates_[dim], off); + bool end_bit = GETBIT(end_range->coordinates_[dim], off); + bool sym_bit = GETBIT(current_symbol, sym_off); - // Bring the start of the search range to second half - if (symbol_bit && !start_bit) - { - start_coordinate = - start_coordinate & compressed_bitmap::low_bits_unset[offset]; - SETBIT(start_coordinate, offset); + // adjust the range endpoints: + if (sym_bit && !start_bit) { + auto v = coordinates_[dim] & low_bits_unset[off]; + SETBIT(v, off); + coordinates_[dim] = v; } - // Bring the end of the search range to first half - if (!symbol_bit && end_bit) - { - end_coordinate = - end_coordinate | compressed_bitmap::low_bits_set[offset]; - CLRBIT(end_coordinate, offset); + if (!sym_bit && end_bit) { + auto v = end_range->coordinates_[dim] | low_bits_set[off]; + CLRBIT(v, off); + end_range->coordinates_[dim] = v; } - coordinates_[j] = start_coordinate; - end_range->coordinates_[j] = end_coordinate; } } @@ -154,6 +143,7 @@ class data_point * "struct" for range search Range search can either return a vector of * coordinates or a vector of primary keys */ + // dimension_t width_; point_t coordinates_[DIMENSION] = {0}; n_leaves_t primary_key_ = 0; }; diff --git a/libmdtrie/src/debug_logger.h b/libmdtrie/src/debug_logger.h new file mode 100644 index 00000000..aaf8bcdb --- /dev/null +++ b/libmdtrie/src/debug_logger.h @@ -0,0 +1,70 @@ +#ifndef DEBUG_LOGGER_H +#define DEBUG_LOGGER_H + +#include +#include +#include +#include + +class DebugLogger { +public: + // Returns the singleton instance. + static DebugLogger& getInstance() { + static DebugLogger instance; + return instance; + } + + // Initialize the output file. Call this before logging. + void init(const std::string &filename) { + std::lock_guard lock(m_mutex); + if(m_out.is_open()){ + m_out.close(); + } + m_out.open(filename, std::ios::out | std::ios::app); + if(!m_out.is_open()){ + std::cerr << "Failed to open debug file: " << filename << std::endl; + } + } + + // Log a message in a thread-safe manner. + void log(const std::string &msg) { + std::lock_guard lock(m_mutex); + if (m_out.is_open()) { + m_out << msg << std::endl; + } else { + // Optionally, write to stderr if no file is open. + std::cerr << msg << std::endl; + } + } + + // Template member function to log an array with its name. + template + void logArray(const std::string &arrayName, const T (&arr)[N]) { + std::ostringstream oss; + oss << arrayName << " = ["; + for (std::size_t i = 0; i < N; i++) { + oss << arr[i]; + if (i < N - 1) { + oss << ", "; + } + } + oss << "]"; + log(oss.str()); + } + + // Delete copy and assignment. + DebugLogger(const DebugLogger&) = delete; + DebugLogger& operator=(const DebugLogger&) = delete; + +private: + DebugLogger() {} // no default file open; must call init() + ~DebugLogger() { if(m_out.is_open()) m_out.close(); } + + std::ofstream m_out; + std::mutex m_mutex; +}; + +// Define the DEBUG_LOG macro here. +#define DEBUG_LOG(msg) DebugLogger::getInstance().log(msg) + +#endif // DEBUG_LOGGER_H diff --git a/libmdtrie/src/defs.h b/libmdtrie/src/defs.h index 4919bceb..a8a9bc04 100644 --- a/libmdtrie/src/defs.h +++ b/libmdtrie/src/defs.h @@ -82,7 +82,10 @@ GetTimestamp() n_leaves_t total_points_count = 0; int discount_factor = 1; level_t trie_depth_; -morton_t level_to_num_children[32] = {0}; +dimension_t trie_width_; +morton_t level_to_num_children[80] = {0}; +// for faster indexing with flexible widths +std::vector>> _dim_off_table; preorder_t max_tree_nodes_ = 512; level_t max_depth_; @@ -118,27 +121,92 @@ uint64_t checked_points_count = 0; int query_optimization = 2; bool is_collapsed_node_exp = false; +// build a ragged 2D “dim_off” table: _dim_off_table[level][i] = {dim,offset} +void create_dim_off_table(const std::vector& bit_widths, + const std::vector& start_bits, + dimension_t W) { + + _dim_off_table.clear(); + + dimension_t D = (dimension_t) bit_widths.size(); + assert(D == dimension_t(start_bits.size())); + assert(W > 0); + + // compute how many bits each dim really contributes, and total + std::vector rem(D); + level_t total = 0, max_rem = 0; + for (uint16_t d = 0; d < D; ++d) { + assert(bit_widths[d] >= start_bits[d]); + rem[d] = bit_widths[d] - start_bits[d]; + total += rem[d]; + max_rem = std::max(max_rem, rem[d]); + } + + // prepare the ragged 2D result + _dim_off_table.emplace_back(); + uint16_t in_this_level = 0; + + // emit in “global bit‐rounds” order, grouping every W bits into one level + for (level_t g = 0; g < max_rem; ++g) { + for (dimension_t d = 0; d < D; ++d) { + if (g >= start_bits[d] && g < start_bits[d] + rem[d]) { + // compute offset of bit g in dimension d + level_t offset = bit_widths[d] - 1 - g; + + // if current level is full, start a new one + if (in_this_level == W) { + _dim_off_table.emplace_back(); + in_this_level = 0; + } + + _dim_off_table.back().emplace_back(d, offset); + ++in_this_level; + } + } + } + + // sanity check: we should have emitted exactly 'total' bits + int check = 0; + for (auto &lvl : _dim_off_table) check += int(lvl.size()); + assert(check == total); +} + void create_level_to_num_children(std::vector bit_widths, std::vector start_bits, - level_t max_level) + level_t max_level, + dimension_t width) { + for (int i = 0; i < 80; i++) { + level_to_num_children[i] = 0; + } dimension_to_num_bits = bit_widths; start_dimension_bits = start_bits; + + create_dim_off_table(dimension_to_num_bits, start_dimension_bits, width); + + max_depth_ = (level_t) _dim_off_table.size(); + + assert(max_depth_ == max_level); + + for (level_t lvl = 0; lvl < max_depth_; lvl++) { + level_to_num_children[lvl] = _dim_off_table[lvl].size(); + } + + // sanity check dimension_t num_dimensions = bit_widths.size(); - for (level_t level = 0; level < max_level; level++) - { + uint16_t total_bits = 0; - dimension_t dimension_left = num_dimensions; - for (dimension_t j = 0; j < num_dimensions; j++) - { + for (dimension_t i = 0; i < num_dimensions; i++) { + total_bits += (dimension_to_num_bits[i] - start_dimension_bits[i]); + } - if (level + 1 > bit_widths[j] || level < start_dimension_bits[j]) - dimension_left--; - } - level_to_num_children[level] = dimension_left; + for (level_t lvl = 0; lvl < max_depth_; lvl++) { + total_bits -= level_to_num_children[lvl]; } + + assert(total_bits == 0); } // #define USE_LINEAR_SCAN // Possibly disable at microbenchmark diff --git a/libmdtrie/src/tree_block.h b/libmdtrie/src/tree_block.h index 92dc0445..fc287edd 100644 --- a/libmdtrie/src/tree_block.h +++ b/libmdtrie/src/tree_block.h @@ -12,7 +12,8 @@ template class tree_block { public: - explicit tree_block(level_t root_depth, + explicit tree_block(/* dimension_t width, */ + level_t root_depth, preorder_t node_capacity, node_pos_t bit_capacity, preorder_t num_nodes, @@ -21,7 +22,7 @@ class tree_block trie_node *parent_trie_node, compressed_bitmap::compressed_bitmap *dfuds = NULL) { - + // width_ = width; root_depth_ = root_depth; node_capacity_ = node_capacity; max_depth_ = max_depth; @@ -917,7 +918,8 @@ class tree_block n_nodes_copied += 1; } new_dfuds->keep_bits(dest_node_pos, true); - auto new_block = new tree_block(selected_node_depth, + auto new_block = new tree_block(/* width_ ,*/ + selected_node_depth, subtree_size, dest_node_pos, subtree_size, @@ -1574,30 +1576,33 @@ class tree_block { // Will be free-ed in the benchmark code + // auto coordinates = new data_point(width_); auto coordinates = new data_point(); - for (level_t i = 0; i < max_depth_; i++) - { - morton_t current_symbol = node_path[i]; - morton_t current_symbol_pos = level_to_num_children[i] - 1; + for (level_t lvl = 0; lvl < max_depth_; lvl++) { - for (dimension_t j = 0; j < dimension; j++) - { + auto &tbl = _dim_off_table[lvl]; + morton_t current_symbol = node_path[lvl]; + + int tbl_size = tbl.size(); + morton_t current_symbol_pos = (morton_t) tbl_size - 1; + + for (uint16_t i = 0; i < tbl_size; i++) { - if (dimension_to_num_bits[j] <= i || i < start_dimension_bits[j]) - continue; + auto dim = tbl[i].first; level_t current_bit = GETBIT(current_symbol, current_symbol_pos); current_symbol_pos--; - point_t coordinate = coordinates->get_coordinate(j); + point_t coordinate = coordinates->get_coordinate(dim); coordinate = (coordinate << 1) + current_bit; - coordinates->set_coordinate(j, coordinate); + coordinates->set_coordinate(dim, coordinate); } } + if (!coordinates) { - std::cerr << "TPCH: range search failed!" << std::endl; + std::cerr << "Range search failed!" << std::endl; exit(-1); } return coordinates; @@ -1610,25 +1615,27 @@ class tree_block // Will be free-ed in the benchmark code std::vector ret_vect(dimension, 0); - for (level_t i = 0; i < max_depth_; i++) - { - morton_t current_symbol = node_path[i]; - morton_t current_symbol_pos = level_to_num_children[i] - 1; + for (level_t lvl = 0; lvl < max_depth_; lvl++) { - for (dimension_t j = 0; j < dimension; j++) - { + auto &tbl = _dim_off_table[lvl]; + morton_t current_symbol = node_path[lvl]; + + int tbl_size = tbl.size(); + morton_t current_symbol_pos = (morton_t) tbl_size - 1; - if (dimension_to_num_bits[j] <= i || i < start_dimension_bits[j]) - continue; + for (uint16_t i = 0; i < tbl_size; i++) { + + auto dim = tbl[i].first; level_t current_bit = GETBIT(current_symbol, current_symbol_pos); current_symbol_pos--; - point_t coordinate = ret_vect[j]; + point_t coordinate = ret_vect[dim]; coordinate = (coordinate << 1) + current_bit; - ret_vect[j] = coordinate; + ret_vect[dim] = coordinate; } } + return ret_vect; } @@ -1834,8 +1841,11 @@ class tree_block uint64_t size() { + // if (!is_valid((void *) this)) + // return 0; uint64_t total_size = 0; + // total_size += sizeof(width_); total_size += sizeof(root_depth_); total_size += sizeof(num_nodes_); total_size += sizeof(total_nodes_bits_); @@ -1844,12 +1854,18 @@ class tree_block total_size += sizeof(dfuds_); total_size += dfuds_->size(); + // uint16_t num_frontiers = std::min(num_frontiers_, sizeof(frontiers_) / sizeof(frontier_node *)); + total_size += num_frontiers_ * sizeof(frontier_node) + sizeof(frontiers_); - for (uint16_t i = 0; i < num_frontiers_; i++) - { - total_size += ((frontier_node *)frontiers_)[i].pointer_->size(); - } + + // if (is_valid((void *) frontiers_)) { + for (uint16_t i = 0; i < num_frontiers_; i++) + { + // if (is_valid((void *) frontiers_[i].pointer_)) + total_size += ((frontier_node *)frontiers_)[i].pointer_->size(); + } + // } total_size += sizeof(num_frontiers_); total_size += sizeof(parent_combined_ptr_); @@ -1858,12 +1874,14 @@ class tree_block primary_key_list.size() * sizeof(bits::compact_ptr); for (preorder_t i = 0; i < primary_key_list.size(); i++) { - total_size += primary_key_list[i].size_overhead(); + // if (is_valid((void *) &primary_key_list[i])) + total_size += primary_key_list[i].size_overhead(); } return total_size; } private: + // dimension_t width_; level_t root_depth_; preorder_t num_nodes_; preorder_t total_nodes_bits_; diff --git a/libmdtrie/src/trie.h b/libmdtrie/src/trie.h index 978c636c..d73c507d 100644 --- a/libmdtrie/src/trie.h +++ b/libmdtrie/src/trie.h @@ -24,17 +24,21 @@ template class md_trie { public: - explicit md_trie(level_t max_depth, + explicit md_trie(dimension_t width, + level_t max_depth, level_t trie_depth, preorder_t max_tree_nodes) { max_depth_ = max_depth; trie_depth_ = trie_depth; + trie_width_ = width; max_tree_nodes_ = max_tree_nodes; root_ = new trie_node(false, level_to_num_children[0]); } + // inline dimension_t get_width() { return width_; } + inline trie_node *root() { return root_; } tree_block *walk_trie(trie_node *current_trie_node, @@ -80,7 +84,8 @@ class md_trie if (current_trie_node->get_block() == nullptr) { current_treeblock = - new tree_block(trie_depth_, + new tree_block(/* width_, */ + trie_depth_, 1 /* initial_tree_capacity_ */, 1 << level_to_num_children[trie_depth_], 1, @@ -117,7 +122,9 @@ class md_trie morton_t parent_symbol_from_primary = t_ptr->get_node_path_primary_key(primary_key, node_path_from_primary); node_path_from_primary[max_depth_ - 1] = parent_symbol_from_primary; - return t_ptr->node_path_to_coordinates(node_path_from_primary, 9); + // return t_ptr->node_path_to_coordinates(node_path_from_primary, 9); + dimension_t dimension = DIMENSION; + return t_ptr->node_path_to_coordinates(node_path_from_primary, dimension); } bool check(data_point *leaf_point) const @@ -136,6 +143,7 @@ class md_trie uint64_t total_size = sizeof(root_) + sizeof(max_depth_); total_size += sizeof(max_tree_nodes_); + // total_size += sizeof(width_); std::queue *> trie_node_queue; trie_node_queue.push(root_); @@ -161,13 +169,15 @@ class md_trie for (int i = 0; i < (1 << level_to_num_children[current_level]); i++) { - if (current_node->get_child(i)) + // quick fix, not sure why some data is corrupted + // ex. current_node->get_child(i) might return 0x21 or 0x1818181818181818 + if (current_node->get_child(i) /* && is_valid((void *) current_node->get_child(i)) */) { trie_node_queue.push(current_node->get_child(i)); } } } - else + else /* if (is_valid((void *) current_node->get_block())) */ { total_size += current_node->get_block()->size(); } @@ -181,6 +191,7 @@ class md_trie total_size += sizeof(max_tree_nodes_); total_size += sizeof(max_depth_); total_size += sizeof(trie_depth_); + total_size += sizeof(trie_width_); total_size += sizeof(p_key_to_treeblock_compact); total_size += p_key_to_treeblock_compact->size_overhead(); @@ -257,6 +268,7 @@ class md_trie trie_node *root_ = nullptr; level_t max_depth_; preorder_t max_tree_nodes_; + // dimension_t width_; }; #endif // MD_TRIE_MD_TRIE_H diff --git a/libmdtrie/src/trie_node.h b/libmdtrie/src/trie_node.h index 84f5c6cb..89a1adc8 100644 --- a/libmdtrie/src/trie_node.h +++ b/libmdtrie/src/trie_node.h @@ -66,6 +66,8 @@ class trie_node uint64_t size(level_t num_children, bool is_leaf) { + // if (is_valid((void *) this)) + // return 0; uint64_t total_size = sizeof(trie_or_treeblock_ptr_); total_size += sizeof(parent_trie_node_); // parent_trie_node_ diff --git a/libmdtrie/src/utils.h b/libmdtrie/src/utils.h index 306edc74..4a063a7f 100644 --- a/libmdtrie/src/utils.h +++ b/libmdtrie/src/utils.h @@ -6,7 +6,7 @@ #define CLRBIT(n, i) n = (n & ~(1UL << i)) #define BITS2BLOCKS(bits) \ - (((bits) % 64 == 0) ? ((bits) / 64) : (((bits) / 64) + 1)) + (((bits) % 64 == 0) ? ((bits) / 64) : (((bits) / 64) + 1)) #define GETBITVAL(data, i) GETBIT((data)[(i) / 64], (i) % 64) #define SETBITVAL(data, i) SETBIT((data)[(i) / 64], (i) % 64) diff --git a/librpc/src/MDTrieShard.cpp b/librpc/src/MDTrieShard.cpp index d5a5407f..a8036298 100644 --- a/librpc/src/MDTrieShard.cpp +++ b/librpc/src/MDTrieShard.cpp @@ -1,5 +1,5 @@ /** - * Autogenerated by Thrift Compiler (0.21.0) + * Autogenerated by Thrift Compiler (0.20.0) * * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING * @generated diff --git a/librpc/src/MDTrieShard.h b/librpc/src/MDTrieShard.h index 86b04ecc..c0d1ff89 100644 --- a/librpc/src/MDTrieShard.h +++ b/librpc/src/MDTrieShard.h @@ -1,5 +1,5 @@ /** - * Autogenerated by Thrift Compiler (0.21.0) + * Autogenerated by Thrift Compiler (0.20.0) * * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING * @generated diff --git a/librpc/src/MDTrieShard.tcc b/librpc/src/MDTrieShard.tcc index 76be80bc..baeb31e4 100644 --- a/librpc/src/MDTrieShard.tcc +++ b/librpc/src/MDTrieShard.tcc @@ -1,5 +1,5 @@ /** - * Autogenerated by Thrift Compiler (0.21.0) + * Autogenerated by Thrift Compiler (0.20.0) * * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING * @generated diff --git a/librpc/src/rpc_types.h b/librpc/src/rpc_types.h index f615cd3b..8fff0194 100644 --- a/librpc/src/rpc_types.h +++ b/librpc/src/rpc_types.h @@ -1,5 +1,5 @@ /** - * Autogenerated by Thrift Compiler (0.21.0) + * Autogenerated by Thrift Compiler (0.20.0) * * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING * @generated diff --git a/librpc/src/rpc_types.tcc b/librpc/src/rpc_types.tcc index 58eeed39..9a20694e 100644 --- a/librpc/src/rpc_types.tcc +++ b/librpc/src/rpc_types.tcc @@ -1,5 +1,5 @@ /** - * Autogenerated by Thrift Compiler (0.21.0) + * Autogenerated by Thrift Compiler (0.20.0) * * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING * @generated