summaryrefslogtreecommitdiffstats
path: root/test/rtree/test_bulkload_main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/rtree/test_bulkload_main.cpp')
-rw-r--r--test/rtree/test_bulkload_main.cpp281
1 files changed, 281 insertions, 0 deletions
diff --git a/test/rtree/test_bulkload_main.cpp b/test/rtree/test_bulkload_main.cpp
new file mode 100644
index 0000000..8295c29
--- /dev/null
+++ b/test/rtree/test_bulkload_main.cpp
@@ -0,0 +1,281 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * Copyright (c) 2018 Kohei Yoshida
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ ************************************************************************/
+
+#include "test_global.hpp" // This must be the first header to be included.
+#include "test_global_rtree.hpp"
+
+#include <vector>
+#include <fstream>
+#include <unordered_map>
+
+using namespace mdds;
+using namespace std;
+
+void rtree_test_bl_empty()
+{
+ stack_printer __stack_printer__("::rtree_test_bl_empty");
+ using rt_type = rtree<int16_t, std::string>;
+ rt_type::integrity_check_properties check_props;
+ check_props.throw_on_first_error = false;
+
+ // Load nothing.
+ rt_type::bulk_loader loader;
+ rt_type tree = loader.pack();
+ assert(tree.empty());
+ tree.check_integrity(check_props);
+}
+
+void rtree_test_bl_insert_points_move()
+{
+ stack_printer __stack_printer__("::rtree_test_bl_insert_points_move");
+ using rt_type = rtree<int16_t, std::string, tiny_trait_2d_forced_reinsertion>;
+ using key_type = rt_type::key_type;
+ rt_type::integrity_check_properties check_props;
+ check_props.throw_on_first_error = true;
+
+ rt_type::bulk_loader loader;
+ for (key_type x = 0; x < 20; ++x)
+ {
+ key_type yn = (x == 0) ? 19 : 20;
+ for (key_type y = 0; y < yn; ++y)
+ {
+ std::ostringstream os;
+ os << '(' << x << ',' << y << ')';
+ loader.insert({x, y}, os.str());
+ }
+ }
+
+ auto tree = loader.pack();
+ assert(tree.size() == 399);
+ tree.check_integrity(check_props);
+ export_tree(tree, "rtree-test-bl-insert-points-move");
+}
+
+void rtree_test_bl_insert_points_copy()
+{
+ stack_printer __stack_printer__("::rtree_test_bl_insert_points_copy");
+ using rt_type = rtree<int16_t, std::string, tiny_trait_2d_forced_reinsertion>;
+ using point_type = rt_type::point_type;
+ using search_type = rt_type::search_type;
+ rt_type::integrity_check_properties check_props;
+ check_props.throw_on_first_error = true;
+
+ struct kv
+ {
+ point_type point;
+ std::string value;
+ };
+
+ std::vector<kv> values = {
+ {{0, 0}, "origin"}, {{125, 125}, "middle"}, {{22, 987}, "somewhere"},
+ {{-34, -200}, "negative"}, {{2, 3}, "near origin"},
+ };
+
+ // Insert less than max node size in order to test the packing
+ // implementation that doesn't involve per-level packing.
+ tiny_trait_2d_forced_reinsertion t;
+ assert(values.size() <= t.max_node_size);
+
+ for (size_t n_values = 1; n_values <= values.size(); ++n_values)
+ {
+ auto loader = rt_type::bulk_loader();
+
+ // Insert specified number of value(s).
+ for (size_t i = 0; i < n_values; ++i)
+ loader.insert(values[i].point, values[i].value);
+
+ // Populate and pack the tree.
+ auto tree = loader.pack();
+ tree.check_integrity(check_props);
+ assert(tree.size() == n_values);
+
+ // Make sure the inserted values are all there.
+ for (size_t i = 0; i < n_values; ++i)
+ {
+ auto res = tree.search(values[i].point, search_type::match);
+ assert(std::distance(res.begin(), res.end()) == 1);
+ auto it = res.begin();
+ assert(*it == values[i].value);
+
+ // The values should all be the immediate children of the root
+ // directory node.
+ assert(it.depth() == 1);
+ }
+ }
+}
+
+void rtree_test_bl_insert_extents_move()
+{
+ stack_printer __stack_printer__("::rtree_test_bl_insert_extents_move");
+ using rt_type = rtree<int16_t, only_movable, tiny_trait_2d_forced_reinsertion>;
+ using extent_type = rt_type::extent_type;
+ using search_type = rt_type::search_type;
+ rt_type::integrity_check_properties check_props;
+ check_props.throw_on_first_error = true;
+
+ struct kv
+ {
+ int16_t x;
+ int16_t y;
+ int16_t w;
+ int16_t h;
+ double value;
+ };
+
+ std::vector<kv> values = {
+ {2142, 2777, 1781, 1273, 1.0}, {5063, 2396, 765, 1019, 1.1}, {1887, 4935, 1400, 892, 1.2},
+ {4428, 4046, 1527, 1146, 1.3}, {2268, 6713, 1146, 2162, 1.4}, {7729, 7094, 2924, 1908, 1.5},
+ {10396, 2014, 6480, 892, 1.6}, {3158, 12302, 2035, 2289, 1.7}, {10777, 11032, 3432, 2289, 1.8},
+ {14334, 5063, 1781, 2797, 1.9}, {8365, 4301, 3051, 1019, 2.0}, {16619, 11794, 638, 511, 2.1},
+ {15222, 9254, 892, 511, 2.2}, {8111, 10142, 765, 638, 2.3}, {6587, 10397, 765, 511, 2.4},
+ {7475, 11793, 638, 1146, 2.5}, {8746, 11285, 765, 892, 2.6}, {16620, 3665, 511, 2162, 2.7},
+ {6332, 14714, 2162, 1908, 2.8}, {1634, 12048, 765, 5083, 2.9}, {15349, 16238, 1400, 1400, 3.0},
+ {11666, 14587, 1400, 1146, 3.1},
+ };
+
+ for (size_t n_values = 5; n_values <= values.size(); ++n_values)
+ {
+ rt_type::bulk_loader loader = rt_type::bulk_loader();
+
+ for (size_t i = 0; i < n_values; ++i)
+ {
+ const auto& v = values[i];
+ extent_type extent{{v.x, v.y}, {int16_t(v.x + v.w), int16_t(v.y + v.h)}};
+ only_movable vv(v.value);
+
+ loader.insert(extent, std::move(vv));
+ }
+
+ auto tree = loader.pack();
+ assert(tree.size() == n_values);
+ tree.check_integrity(check_props);
+
+ // Make sure the values are all there.
+ for (size_t i = 0; i < n_values; ++i)
+ {
+ const auto& v = values[i];
+ extent_type extent{{v.x, v.y}, {int16_t(v.x + v.w), int16_t(v.y + v.h)}};
+ auto res = tree.search(extent, search_type::match);
+ assert(std::distance(res.begin(), res.end()) == 1);
+ assert(res.begin()->get() == v.value);
+ }
+
+ if (n_values == values.size())
+ export_tree(tree, "rtree-test-bl-insert-extents-move");
+ }
+}
+
+void rtree_test_bl_insert_extents_copy()
+{
+ stack_printer __stack_printer__("::rtree_test_bl_insert_extents_copy");
+ using rt_type = rtree<int16_t, only_copyable, tiny_trait_2d_forced_reinsertion>;
+ using extent_type = rt_type::extent_type;
+ using search_type = rt_type::search_type;
+ rt_type::integrity_check_properties check_props;
+ check_props.throw_on_first_error = true;
+
+ struct kv
+ {
+ int16_t x;
+ int16_t y;
+ int16_t w;
+ int16_t h;
+ double value;
+ };
+
+ std::vector<kv> values = {
+ {2142, 2777, 1781, 1273, 1.0}, {5063, 2396, 765, 1019, 1.1}, {1887, 4935, 1400, 892, 1.2},
+ {4428, 4046, 1527, 1146, 1.3}, {2268, 6713, 1146, 2162, 1.4}, {7729, 7094, 2924, 1908, 1.5},
+ {10396, 2014, 6480, 892, 1.6}, {2904, 11286, 2035, 2289, 1.7}, {11412, 10524, 3432, 2289, 1.8},
+ {14334, 5063, 1781, 2797, 1.9}, {8365, 4301, 3051, 1019, 2.0}, {16619, 11794, 638, 511, 2.1},
+ {15222, 9254, 892, 511, 2.2}, {8111, 10142, 765, 638, 2.3}, {6587, 10397, 765, 511, 2.4},
+ {7475, 11793, 638, 1146, 2.5}, {8746, 11285, 765, 892, 2.6}, {16620, 3665, 511, 2162, 2.7},
+ {1760, 17762, 2162, 1908, 2.8}, {1634, 12048, 765, 5083, 2.9}, {15349, 16238, 1400, 1400, 3.0},
+ {11793, 13190, 1400, 1146, 3.1}, {4174, 6078, 1019, 638, 3.2}, {13191, 3412, 1781, 257, 3.3},
+ {6714, 11413, 511, 765, 3.4}, {2903, 14969, 892, 511, 3.5}, {3919, 16366, 638, 511, 3.6},
+ {4554, 15222, 892, 638, 3.7}, {2904, 16238, 511, 892, 3.8}, {1507, 20557, 6099, 257, 3.9},
+ {4047, 7221, 1273, 384, 4.0}, {12301, 3538, 638, 1908, 4.1}, {12174, 6460, 1146, 511, 4.2},
+ {13318, 4046, 1273, 384, 4.3}, {16620, 6459, 1019, 638, 4.4}, {14080, 8238, 511, 765, 4.5},
+ {8365, 12555, 765, 384, 4.6}, {16493, 7349, 511, 511, 4.7}, {7603, 11031, 511, 384, 4.8},
+ {13571, 13191, 638, 1527, 4.9}, {15858, 13826, 2035, 2035, 5.0}, {7094, 1380, 892, 3305, 5.1},
+ {7094, 6332, 1400, 1400, 5.2}, {10142, 8237, 2162, 384, 5.3}, {13444, 9761, 4, 130, 5.4},
+ };
+
+ for (size_t n_values = 22; n_values <= values.size(); ++n_values)
+ {
+ rt_type::bulk_loader loader = rt_type::bulk_loader();
+
+ for (size_t i = 0; i < n_values; ++i)
+ {
+ const auto& v = values[i];
+ extent_type extent{{v.x, v.y}, {int16_t(v.x + v.w), int16_t(v.y + v.h)}};
+ only_copyable vv(v.value);
+
+ loader.insert(extent, vv);
+ }
+
+ auto tree = loader.pack();
+ assert(tree.size() == n_values);
+ tree.check_integrity(check_props);
+
+ // Make sure the values are all there.
+ for (size_t i = 0; i < n_values; ++i)
+ {
+ const auto& v = values[i];
+ extent_type extent{{v.x, v.y}, {int16_t(v.x + v.w), int16_t(v.y + v.h)}};
+ auto res = tree.search(extent, search_type::match);
+ assert(std::distance(res.begin(), res.end()) == 1);
+ assert(res.begin()->get() == v.value);
+ }
+
+ if (n_values == values.size())
+ export_tree(tree, "rtree-test-bl-insert-extents-copy");
+ }
+}
+
+int main()
+{
+ try
+ {
+ rtree_test_bl_empty();
+ rtree_test_bl_insert_points_move();
+ rtree_test_bl_insert_points_copy();
+ rtree_test_bl_insert_extents_move();
+ rtree_test_bl_insert_extents_copy();
+ }
+ catch (const std::exception& e)
+ {
+ cout << "Test failed: " << e.what() << endl;
+ return EXIT_FAILURE;
+ }
+
+ cout << "Test finished successfully!" << endl;
+ return EXIT_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */