Skip to content

Commit 2285e0e

Browse files
committed
Optionally give node_locations_t store a max number of bytes to use
1 parent 8ce9bbe commit 2285e0e

File tree

4 files changed

+52
-4
lines changed

4 files changed

+52
-4
lines changed

src/node-locations.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,12 @@
2121
#include <cassert>
2222
#include <limits>
2323

24-
void node_locations_t::set(osmid_t id, osmium::Location location)
24+
bool node_locations_t::set(osmid_t id, osmium::Location location)
2525
{
26+
if (used_memory() >= m_max_size && will_resize()) {
27+
return false;
28+
}
29+
2630
if (first_entry_in_block()) {
2731
m_did.clear();
2832
m_dx.clear();
@@ -37,6 +41,8 @@ void node_locations_t::set(osmid_t id, osmium::Location location)
3741
&m_data, protozero::encode_zigzag64(m_dy.update(location.y())));
3842

3943
++m_count;
44+
45+
return true;
4046
}
4147

4248
osmium::Location node_locations_t::get(osmid_t id) const

src/node-locations.hpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include <array>
1919
#include <cstddef>
20+
#include <limits>
2021
#include <string>
2122
#include <utility>
2223

@@ -35,12 +36,25 @@
3536
class node_locations_t
3637
{
3738
public:
39+
/**
40+
* Construct a node locations store. Takes a single optional argument
41+
* which gives the maximum number of bytes this store should be allowed
42+
* to use. If this is not specified, the size is only limited by available
43+
* memory. The store will try to keep the memory used under what's
44+
* specified here.
45+
*/
46+
explicit node_locations_t(
47+
std::size_t max_size = std::numeric_limits<std::size_t>::max())
48+
: m_max_size(max_size)
49+
{}
50+
3851
/**
3952
* Store a node location.
4053
*
4154
* \pre id must be strictly larger than all ids stored before.
55+
* \return True if the entry was added, false if the index is full.
4256
*/
43-
void set(osmid_t id, osmium::Location location);
57+
bool set(osmid_t id, osmium::Location location);
4458

4559
/**
4660
* Retrieve a node location. If the location wasn't stored before, an
@@ -69,6 +83,17 @@ class node_locations_t
6983
return m_count % block_size == 0;
7084
}
7185

86+
/// The maximum number of bytes an entry will need in storage.
87+
constexpr static std::size_t max_bytes_per_entry() noexcept {
88+
return 10U /*max varint length*/ * 3U /*id, x, y*/;
89+
}
90+
91+
bool will_resize() const noexcept
92+
{
93+
return m_index.will_resize() ||
94+
(m_data.size() + max_bytes_per_entry() >= m_data.capacity());
95+
}
96+
7297
/**
7398
* The block size used for internal blocks. The larger the block size
7499
* the less memory is consumed but the more expensive the access is.
@@ -78,6 +103,9 @@ class node_locations_t
78103
ordered_index_t m_index;
79104
std::string m_data;
80105

106+
/// Maximum size in bytes this object may allocate.
107+
std::size_t m_max_size;
108+
81109
/// The number of (id, location) pairs stored.
82110
std::size_t m_count = 0;
83111

src/ordered-index.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ class ordered_index_t
150150
m_size = 0;
151151
}
152152

153+
/// Return true if adding an entry to the index will make it resize.
154+
bool will_resize() const noexcept { return m_size + 1 >= m_capacity; }
155+
153156
private:
154157
struct second_level_index_entry
155158
{

tests/test-node-locations.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ TEST_CASE("node locations basics", "[NoDB]")
1616
node_locations_t nl;
1717
REQUIRE(nl.size() == 0);
1818

19-
nl.set(3, {1.2, 3.4});
20-
nl.set(5, {5.6, 7.8});
19+
REQUIRE(nl.set(3, {1.2, 3.4}));
20+
REQUIRE(nl.set(5, {5.6, 7.8}));
2121

2222
REQUIRE(nl.size() == 2);
2323

@@ -76,3 +76,14 @@ TEST_CASE("node locations in more than one block", "[NoDB]")
7676
}
7777
}
7878

79+
TEST_CASE("full node locations store", "[NoDB]")
80+
{
81+
node_locations_t nl{30};
82+
REQUIRE(nl.size() == 0);
83+
84+
REQUIRE(nl.set(3, {1.2, 3.4}));
85+
REQUIRE_FALSE(nl.set(5, {5.6, 7.8}));
86+
87+
REQUIRE(nl.size() == 1);
88+
}
89+

0 commit comments

Comments
 (0)