1010#include " node-locations.hpp"
1111
1212#include < osmium/osm/location.hpp>
13- #include < osmium/util/delta.hpp>
1413
1514// Workaround: This must be included before buffer_string.hpp due to a missing
1615// include in the upstream code. https://github.com/mapbox/protozero/pull/104
2221#include < cassert>
2322#include < limits>
2423
25- void node_locations_t::set (osmid_t id, osmium::Location location)
24+ bool node_locations_t::set (osmid_t id, osmium::Location location)
2625{
27- assert (block_index () == 0 || m_block[block_index () - 1 ].first < id);
26+ if (used_memory () >= m_max_size && will_resize ()) {
27+ return false ;
28+ }
2829
29- m_block[block_index ()] = {id, location};
30- ++m_count;
31- if (block_index () == 0 ) {
32- freeze ();
30+ if (first_entry_in_block ()) {
31+ m_did.clear ();
32+ m_dx.clear ();
33+ m_dy.clear ();
34+ m_index.add (id, m_data.size ());
3335 }
36+
37+ protozero::add_varint_to_buffer (&m_data, m_did.update (id));
38+ protozero::add_varint_to_buffer (
39+ &m_data, protozero::encode_zigzag64 (m_dx.update (location.x ())));
40+ protozero::add_varint_to_buffer (
41+ &m_data, protozero::encode_zigzag64 (m_dy.update (location.y ())));
42+
43+ ++m_count;
44+
45+ return true ;
3446}
3547
3648osmium::Location node_locations_t::get (osmid_t id) const
@@ -46,72 +58,29 @@ osmium::Location node_locations_t::get(osmid_t id) const
4658 char const *const end = m_data.data () + m_data.size ();
4759
4860 osmium::DeltaDecode<osmid_t > did;
49- std::size_t num = block_size;
50- for (std::size_t n = 0 ; n < block_size; ++n) {
51- auto bid = did.update (protozero::decode_varint (&begin, end));
52- if (bid == id) {
53- num = n;
54- }
55- if (bid > id && num == block_size) {
56- return osmium::Location{};
57- }
58- }
59- if (num == block_size) {
60- return osmium::Location{};
61- }
62-
6361 osmium::DeltaDecode<int64_t > dx;
6462 osmium::DeltaDecode<int64_t > dy;
65- int32_t x = 0 ;
66- int32_t y = 0 ;
67- for (std:: size_t n = 0 ; n <= num; ++n) {
68- x = dx.update (
63+
64+ for (std:: size_t n = 0 ; n < block_size && begin != end; ++n) {
65+ auto const bid = did. update ( protozero::decode_varint (&begin, end));
66+ int32_t const x = dx.update (
6967 protozero::decode_zigzag64 (protozero::decode_varint (&begin, end)));
70- y = dy.update (
68+ int32_t const y = dy.update (
7169 protozero::decode_zigzag64 (protozero::decode_varint (&begin, end)));
70+ if (bid == id) {
71+ return osmium::Location{x, y};
72+ }
73+ if (bid > id) {
74+ break ;
75+ }
7276 }
73-
74- return osmium::Location{x, y};
75- }
76-
77- void node_locations_t::freeze ()
78- {
79- encode_block ();
80- clear_block ();
77+ return osmium::Location{};
8178}
8279
8380void node_locations_t::clear ()
8481{
8582 m_data.clear ();
8683 m_data.shrink_to_fit ();
8784 m_index.clear ();
88- clear_block ();
8985 m_count = 0 ;
9086}
91-
92- void node_locations_t::encode_block ()
93- {
94- auto const offset = m_data.size ();
95- osmium::DeltaEncode<osmid_t > did;
96- osmium::DeltaEncode<int64_t > dx;
97- osmium::DeltaEncode<int64_t > dy;
98- for (auto const &nl : m_block) {
99- protozero::add_varint_to_buffer (&m_data, did.update (nl.first ));
100- }
101- for (auto const &nl : m_block) {
102- protozero::add_varint_to_buffer (
103- &m_data, protozero::encode_zigzag64 (dx.update (nl.second .x ())));
104- protozero::add_varint_to_buffer (
105- &m_data, protozero::encode_zigzag64 (dy.update (nl.second .y ())));
106- }
107- m_index.add (m_block[0 ].first , offset);
108- }
109-
110- void node_locations_t::clear_block ()
111- {
112- for (auto &nl : m_block) {
113- nl.first = std::numeric_limits<osmid_t >::max ();
114- nl.second = osmium::Location{};
115- }
116- }
117-
0 commit comments