1 #include "catch.hpp"
2
3 #include <osmium/index/detail/tmpfile.hpp>
4 #include <osmium/index/map/dense_file_array.hpp>
5 #include <osmium/index/map/sparse_mem_array.hpp>
6 #include <osmium/index/map/sparse_mmap_array.hpp>
7 #include <osmium/index/node_locations_map.hpp>
8 #include <osmium/osm/node_ref.hpp>
9 #include <osmium/osm/types.hpp>
10 #include <osmium/util/file.hpp>
11
12 #include <vector>
13
14 using dense_file_array = osmium::index::map::DenseFileArray<osmium::unsigned_object_id_type, osmium::Location>;
15
16 template <class TSparseIndex>
test_index()17 void test_index() {
18 const int fd = osmium::detail::create_tmp_file();
19 constexpr const size_t value_size = sizeof(typename TSparseIndex::element_type::second_type);
20 constexpr const size_t buffer_size = (10L * 1024L * 1024L) / value_size;
21
22 REQUIRE(osmium::file_size(fd) == 0);
23
24 std::vector<osmium::NodeRef> refs = {
25 osmium::NodeRef{1, osmium::Location{1.2, 4.5}},
26 osmium::NodeRef{6, osmium::Location{3.5, -7.2}},
27 osmium::NodeRef{2 * buffer_size, osmium::Location{10.2, 64.5}},
28 osmium::NodeRef{2 * buffer_size + 1, osmium::Location{39.5, -71.2}},
29 osmium::NodeRef{3 * buffer_size - 1, osmium::Location{-1.2, 54.6}},
30 osmium::NodeRef{3 * buffer_size, osmium::Location{-171.2, 9.3}},
31 osmium::NodeRef{3 * buffer_size + 1, osmium::Location{-171.21, 9.26}},
32 osmium::NodeRef{3 * buffer_size + 2, osmium::Location{-171.22, 9.25}},
33 osmium::NodeRef{3 * buffer_size + 3, osmium::Location{-171.24, 9.23}},
34 osmium::NodeRef{3 * buffer_size + 4, osmium::Location{-171.25, 9.22}},
35 osmium::NodeRef{3 * buffer_size + 5, osmium::Location{-171.26, 9.21}}
36 };
37
38 TSparseIndex sparse_index;
39 for (const auto& r : refs) {
40 sparse_index.set(r.ref(), r.location());
41 }
42 sparse_index.sort();
43 sparse_index.dump_as_array(fd);
44
45 dense_file_array dense_index{fd};
46 const auto max_id_in_refs = std::max_element(refs.begin(), refs.end())->ref();
47
48 // Array index should be as large as necessary.
49 REQUIRE(osmium::file_size(fd) >= max_id_in_refs * sizeof(osmium::Location));
50
51 // check beyond largest ID
52 REQUIRE_THROWS_AS(dense_index.get(max_id_in_refs + 1), osmium::not_found);
53
54 // check if written values can be retrieved
55 for (const auto& r : refs) {
56 REQUIRE(dense_index.get(r.ref()) == r.location());
57 }
58
59 // check if all other values are invalid locations
60 size_t invalid_count = 0;
61 for (osmium::object_id_type id = 0; id <= max_id_in_refs; ++id) {
62 if (!dense_index.get_noexcept(id).valid()) {
63 ++invalid_count;
64 }
65 }
66 REQUIRE(invalid_count == max_id_in_refs - refs.size() + 1);
67 }
68
69
70 #ifdef __linux__
71 using sparse_mmap_array = osmium::index::map::SparseMmapArray<osmium::unsigned_object_id_type, osmium::Location>;
72
73 TEST_CASE("Dump SparseMmapArray as array and load it as DenseFileArray") {
74 test_index<sparse_mmap_array>();
75 }
76 #else
77 # pragma message("not running 'SparseMmapArray' test case on this machine")
78 #endif
79
80 using sparse_mem_array = osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, osmium::Location>;
81
82 TEST_CASE("Dump SparseMemArray as array and load it as DenseFileArray") {
83 test_index<sparse_mem_array>();
84 }
85
86