Skip to content

Commit 0b139ff

Browse files
authored
Merge pull request #5572 from Tomonobu3110/tomo_less_memory
Reduce memory usage for raster source handling.
2 parents f520379 + 9da6cf8 commit 0b139ff

File tree

4 files changed

+87
-55
lines changed

4 files changed

+87
-55
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
- CHANGED: allow routing past `barrier=arch` [#5352](https://github.com/Project-OSRM/osrm-backend/pull/5352)
1515
- CHANGED: default car weight was reduced to 2000 kg. [#5371](https://github.com/Project-OSRM/osrm-backend/pull/5371)
1616
- CHANGED: default car height was reduced to 2 meters. [#5389](https://github.com/Project-OSRM/osrm-backend/pull/5389)
17+
- Misc:
18+
- CHANGED: Reduce memory usage for raster source handling. [#5572](https://github.com/Project-OSRM/osrm-backend/pull/5572)
1719

1820
# 5.21.0
1921
- Changes from 5.20.0

include/extractor/raster_source.hpp

100644100755
Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,21 @@
44
#include "util/coordinate.hpp"
55
#include "util/exception.hpp"
66

7+
#include <boost/algorithm/string.hpp>
78
#include <boost/algorithm/string/trim.hpp>
89
#include <boost/assert.hpp>
910
#include <boost/filesystem.hpp>
1011
#include <boost/filesystem/fstream.hpp>
12+
#include <boost/foreach.hpp>
1113
#include <boost/spirit/include/qi.hpp>
1214
#include <boost/spirit/include/qi_int.hpp>
15+
1316
#include <storage/io.hpp>
1417

1518
#include <iterator>
19+
#include <string>
1620
#include <unordered_map>
21+
using namespace std;
1722

1823
namespace osrm
1924
{
@@ -43,37 +48,31 @@ class RasterGrid
4348
xdim = _xdim;
4449
ydim = _ydim;
4550
_data.reserve(ydim * xdim);
51+
BOOST_ASSERT(ydim * xdim <= _data.capacity());
4652

53+
// Construct FileReader
4754
storage::io::FileReader file_reader(filepath, storage::io::FileReader::HasNoFingerprint);
48-
4955
std::string buffer;
50-
buffer.resize(file_reader.GetSize());
51-
52-
BOOST_ASSERT(buffer.size() > 1);
53-
54-
file_reader.ReadInto(&buffer[0], buffer.size());
55-
56-
boost::algorithm::trim(buffer);
57-
58-
auto itr = buffer.begin();
59-
auto end = buffer.end();
60-
61-
bool r = false;
62-
try
63-
{
64-
r = boost::spirit::qi::parse(
65-
itr, end, +boost::spirit::qi::int_ % +boost::spirit::qi::space, _data);
66-
}
67-
catch (std::exception const &ex)
68-
{
69-
throw util::exception("Failed to read from raster source " + filepath.string() + ": " +
70-
ex.what() + SOURCE_REF);
71-
}
56+
buffer.resize(xdim * 11); // INT32_MAX = 2147483647 = 10 chars + 1 white space = 11
57+
BOOST_ASSERT(xdim * 11 <= buffer.size());
7258

73-
if (!r || itr != end)
59+
for (unsigned int y = 0; y < ydim; y++)
7460
{
75-
throw util::exception("Failed to parse raster source: " + filepath.string() +
76-
SOURCE_REF);
61+
// read one line from file.
62+
file_reader.ReadLine(&buffer[0], xdim * 11);
63+
boost::algorithm::trim(buffer);
64+
65+
std::vector<std::string> result;
66+
boost::split(
67+
result, buffer, boost::is_any_of(" \r\n\0"), boost::algorithm::token_compress_on);
68+
unsigned int x = 0;
69+
for (const auto &s : result)
70+
{
71+
if (x < xdim)
72+
_data[(y * xdim) + x] = atoi(s.c_str());
73+
++x;
74+
}
75+
BOOST_ASSERT(x == xdim);
7776
}
7877
}
7978

@@ -143,8 +142,36 @@ class RasterContainer
143142
RasterDatum GetRasterInterpolateFromSource(unsigned int source_id, double lon, double lat);
144143

145144
private:
145+
};
146+
147+
// << singletone >> RasterCache
148+
// The instance of RasterContainer is created for every threads osrm-extract uses.
149+
// To avoid multiple load of same file on each RasterContainer,
150+
// The LoadedSources and LoadedSourcePaths are separated to RasterCache class
151+
// and handled as the singletone pattern to avoid duplicate creation.
152+
class RasterCache
153+
{
154+
public:
155+
// class method to get the instance
156+
static RasterCache &getInstance()
157+
{
158+
if (NULL == g_instance)
159+
{
160+
g_instance = new RasterCache();
161+
}
162+
return *g_instance;
163+
}
164+
// get reference of cache
165+
std::vector<RasterSource> &getLoadedSources() { return LoadedSources; }
166+
std::unordered_map<std::string, int> &getLoadedSourcePaths() { return LoadedSourcePaths; }
167+
private:
168+
// constructor
169+
RasterCache() = default;
170+
// member
146171
std::vector<RasterSource> LoadedSources;
147172
std::unordered_map<std::string, int> LoadedSourcePaths;
173+
// the instance
174+
static RasterCache *g_instance;
148175
};
149176
}
150177
}

include/storage/io.hpp

100644100755
Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "util/log.hpp"
1111
#include "util/version.hpp"
1212

13+
#include <boost/filesystem.hpp>
1314
#include <boost/filesystem/fstream.hpp>
1415
#include <boost/iostreams/device/array.hpp>
1516
#include <boost/iostreams/seek.hpp>
@@ -60,29 +61,27 @@ class FileReader
6061

6162
std::size_t GetSize()
6263
{
63-
const boost::filesystem::ifstream::pos_type position = input_stream.tellg();
64-
input_stream.seekg(0, std::ios::end);
65-
const boost::filesystem::ifstream::pos_type file_size = input_stream.tellg();
66-
67-
if (file_size == boost::filesystem::ifstream::pos_type(-1))
64+
const boost::filesystem::path path(filepath);
65+
try
6866
{
69-
throw util::RuntimeError("Unable to determine file size for " +
70-
std::string(filepath.string()),
71-
ErrorCode::FileIOError,
72-
SOURCE_REF,
73-
std::strerror(errno));
67+
return std::size_t(boost::filesystem::file_size(path)) -
68+
((fingerprint == FingerprintFlag::VerifyFingerprint) ? sizeof(util::FingerPrint)
69+
: 0);
7470
}
75-
76-
// restore the current position
77-
input_stream.seekg(position, std::ios::beg);
78-
79-
if (fingerprint == FingerprintFlag::VerifyFingerprint)
71+
catch (const boost::filesystem::filesystem_error &ex)
8072
{
81-
return std::size_t(file_size) - sizeof(util::FingerPrint);
73+
std::cout << ex.what() << std::endl;
74+
throw;
8275
}
83-
else
76+
}
77+
78+
/* Read one line */
79+
template <typename T> void ReadLine(T *dest, const std::size_t count)
80+
{
81+
if (0 < count)
8482
{
85-
return file_size;
83+
memset(dest, 0, count * sizeof(T));
84+
input_stream.getline(reinterpret_cast<char *>(dest), count * sizeof(T));
8685
}
8786
}
8887

src/extractor/raster_source.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -92,15 +92,15 @@ int RasterContainer::LoadRasterSource(const std::string &path_string,
9292
const auto _ymin = static_cast<std::int32_t>(util::toFixed(util::FloatLatitude{ymin}));
9393
const auto _ymax = static_cast<std::int32_t>(util::toFixed(util::FloatLatitude{ymax}));
9494

95-
const auto itr = LoadedSourcePaths.find(path_string);
96-
if (itr != LoadedSourcePaths.end())
95+
const auto itr = RasterCache::getInstance().getLoadedSourcePaths().find(path_string);
96+
if (itr != RasterCache::getInstance().getLoadedSourcePaths().end())
9797
{
9898
util::Log() << "[source loader] Already loaded source '" << path_string << "' at source_id "
9999
<< itr->second;
100100
return itr->second;
101101
}
102102

103-
int source_id = static_cast<int>(LoadedSources.size());
103+
int source_id = static_cast<int>(RasterCache::getInstance().getLoadedSources().size());
104104

105105
util::Log() << "[source loader] Loading from " << path_string << " ... ";
106106
TIMER_START(loading_source);
@@ -116,8 +116,8 @@ int RasterContainer::LoadRasterSource(const std::string &path_string,
116116

117117
RasterSource source{std::move(rasterData), ncols, nrows, _xmin, _xmax, _ymin, _ymax};
118118
TIMER_STOP(loading_source);
119-
LoadedSourcePaths.emplace(path_string, source_id);
120-
LoadedSources.push_back(std::move(source));
119+
RasterCache::getInstance().getLoadedSourcePaths().emplace(path_string, source_id);
120+
RasterCache::getInstance().getLoadedSources().push_back(std::move(source));
121121

122122
util::Log() << "[source loader] ok, after " << TIMER_SEC(loading_source) << "s";
123123

@@ -127,10 +127,11 @@ int RasterContainer::LoadRasterSource(const std::string &path_string,
127127
// External function for looking up nearest data point from a specified source
128128
RasterDatum RasterContainer::GetRasterDataFromSource(unsigned int source_id, double lon, double lat)
129129
{
130-
if (LoadedSources.size() < source_id + 1)
130+
if (RasterCache::getInstance().getLoadedSources().size() < source_id + 1)
131131
{
132132
throw util::exception("Attempted to access source " + std::to_string(source_id) +
133-
", but there are only " + std::to_string(LoadedSources.size()) +
133+
", but there are only " +
134+
std::to_string(RasterCache::getInstance().getLoadedSources().size()) +
134135
" loaded" + SOURCE_REF);
135136
}
136137

@@ -139,7 +140,7 @@ RasterDatum RasterContainer::GetRasterDataFromSource(unsigned int source_id, dou
139140
BOOST_ASSERT(lon < 180);
140141
BOOST_ASSERT(lon > -180);
141142

142-
const auto &found = LoadedSources[source_id];
143+
const auto &found = RasterCache::getInstance().getLoadedSources()[source_id];
143144
return found.GetRasterData(static_cast<std::int32_t>(util::toFixed(util::FloatLongitude{lon})),
144145
static_cast<std::int32_t>(util::toFixed(util::FloatLatitude{lat})));
145146
}
@@ -148,10 +149,11 @@ RasterDatum RasterContainer::GetRasterDataFromSource(unsigned int source_id, dou
148149
RasterDatum
149150
RasterContainer::GetRasterInterpolateFromSource(unsigned int source_id, double lon, double lat)
150151
{
151-
if (LoadedSources.size() < source_id + 1)
152+
if (RasterCache::getInstance().getLoadedSources().size() < source_id + 1)
152153
{
153154
throw util::exception("Attempted to access source " + std::to_string(source_id) +
154-
", but there are only " + std::to_string(LoadedSources.size()) +
155+
", but there are only " +
156+
std::to_string(RasterCache::getInstance().getLoadedSources().size()) +
155157
" loaded" + SOURCE_REF);
156158
}
157159

@@ -160,10 +162,12 @@ RasterContainer::GetRasterInterpolateFromSource(unsigned int source_id, double l
160162
BOOST_ASSERT(lon < 180);
161163
BOOST_ASSERT(lon > -180);
162164

163-
const auto &found = LoadedSources[source_id];
165+
const auto &found = RasterCache::getInstance().getLoadedSources()[source_id];
164166
return found.GetRasterInterpolate(
165167
static_cast<std::int32_t>(util::toFixed(util::FloatLongitude{lon})),
166168
static_cast<std::int32_t>(util::toFixed(util::FloatLatitude{lat})));
167169
}
170+
171+
RasterCache *RasterCache::g_instance = NULL;
168172
}
169173
}

0 commit comments

Comments
 (0)