Adds a limit for number of results returned in Nearest service, resolves #2872

This commit is contained in:
Daniel J. Hofmann 2016-09-12 11:47:22 +02:00 committed by Moritz Kobitzsch
parent e6fe9d0d67
commit e3c1b133bf
8 changed files with 68 additions and 11 deletions

View File

@ -21,6 +21,8 @@
- Fixed an issue that would detect turning circles as sliproads
- Fixed a bug where post-processing instructions (e.g. left + left -> uturn) could result in false pronunciations
- Fixes a bug where a bearing range of zero would cause exhaustive graph traversals
- Infrastructure:
- Adds a feature to limit results in nearest service with a default of 100 in `osrm-routed`
# 5.3.0
Changes from 5.3.0-rc.3

View File

@ -51,6 +51,7 @@ namespace engine
* - Route
* - Table
* - Match
* - Nearest
*
* In addition, shared memory can be used for datasets loaded with osrm-datastore.
*
@ -65,6 +66,7 @@ struct EngineConfig final
int max_locations_viaroute = -1;
int max_locations_distance_table = -1;
int max_locations_map_matching = -1;
int max_results_nearest = -1;
bool use_shared_memory = true;
};
}

View File

@ -15,9 +15,12 @@ namespace plugins
class NearestPlugin final : public BasePlugin
{
public:
explicit NearestPlugin(datafacade::BaseDataFacade &facade);
explicit NearestPlugin(datafacade::BaseDataFacade &facade, const int max_results);
Status HandleRequest(const api::NearestParameters &params, util::json::Object &result);
private:
const int max_results;
};
}
}

View File

@ -146,7 +146,7 @@ Engine::Engine(EngineConfig &config)
route_plugin = create<ViaRoutePlugin>(*query_data_facade, config.max_locations_viaroute);
table_plugin = create<TablePlugin>(*query_data_facade, config.max_locations_distance_table);
nearest_plugin = create<NearestPlugin>(*query_data_facade);
nearest_plugin = create<NearestPlugin>(*query_data_facade, config.max_results_nearest);
trip_plugin = create<TripPlugin>(*query_data_facade, config.max_locations_trip);
match_plugin = create<MatchPlugin>(*query_data_facade, config.max_locations_map_matching);
tile_plugin = create<TilePlugin>(*query_data_facade);

View File

@ -15,11 +15,15 @@ bool EngineConfig::IsValid() const
storage_config.datasource_names_path.empty() &&
storage_config.datasource_indexes_path.empty() && storage_config.names_data_path.empty();
const bool limits_valid =
(max_locations_distance_table == -1 || max_locations_distance_table > 2) &&
(max_locations_map_matching == -1 || max_locations_map_matching > 2) &&
(max_locations_trip == -1 || max_locations_trip > 2) &&
(max_locations_viaroute == -1 || max_locations_viaroute > 2);
const auto unlimited_or_more_than = [](const int v, const int limit) {
return v == -1 || v > limit;
};
const bool limits_valid = unlimited_or_more_than(max_locations_distance_table, 2) &&
unlimited_or_more_than(max_locations_map_matching, 2) &&
unlimited_or_more_than(max_locations_trip, 2) &&
unlimited_or_more_than(max_locations_viaroute, 2) &&
unlimited_or_more_than(max_results_nearest, 0);
return ((use_shared_memory && all_path_are_empty) || storage_config.IsValid()) && limits_valid;
}

View File

@ -16,13 +16,24 @@ namespace engine
namespace plugins
{
NearestPlugin::NearestPlugin(datafacade::BaseDataFacade &facade) : BasePlugin{facade} {}
NearestPlugin::NearestPlugin(datafacade::BaseDataFacade &facade, const int max_results_)
: BasePlugin{facade}, max_results{max_results_}
{
}
Status NearestPlugin::HandleRequest(const api::NearestParameters &params,
util::json::Object &json_result)
{
BOOST_ASSERT(params.IsValid());
if (params.number_of_results > max_results)
{
return Error("TooBig",
"Number of results " + std::to_string(params.number_of_results) +
" is higher than current maximum (" + std::to_string(max_results) + ")",
json_result);
}
if (!CheckAllCoordinates(params.coordinates))
return Error("InvalidOptions", "Coordinates are invalid", json_result);

View File

@ -63,7 +63,8 @@ inline unsigned generateServerProgramOptions(const int argc,
int &max_locations_trip,
int &max_locations_viaroute,
int &max_locations_distance_table,
int &max_locations_map_matching)
int &max_locations_map_matching,
int &max_results_nearest)
{
using boost::program_options::value;
using boost::filesystem::path;
@ -100,7 +101,10 @@ inline unsigned generateServerProgramOptions(const int argc,
"Max. locations supported in distance table query") //
("max-matching-size",
value<int>(&max_locations_map_matching)->default_value(100),
"Max. locations supported in map matching query");
"Max. locations supported in map matching query") //
("max-nearest-size",
value<int>(&max_results_nearest)->default_value(100),
"Max. results supported in nearest query");
// hidden options, will be allowed on command line, but will not be shown to the user
boost::program_options::options_description hidden_options("Hidden options");
@ -189,7 +193,8 @@ int main(int argc, const char *argv[]) try
config.max_locations_trip,
config.max_locations_viaroute,
config.max_locations_distance_table,
config.max_locations_map_matching);
config.max_locations_map_matching,
config.max_results_nearest);
if (init_result == INIT_OK_DO_NOT_START_ENGINE)
{
return EXIT_SUCCESS;

View File

@ -4,6 +4,7 @@
#include "args.hpp"
#include "osrm/match_parameters.hpp"
#include "osrm/nearest_parameters.hpp"
#include "osrm/route_parameters.hpp"
#include "osrm/table_parameters.hpp"
#include "osrm/trip_parameters.hpp"
@ -136,4 +137,33 @@ BOOST_AUTO_TEST_CASE(test_match_limits)
BOOST_CHECK(code == "TooBig"); // per the New-Server API spec
}
BOOST_AUTO_TEST_CASE(test_nearest_limits)
{
const auto args = get_args();
BOOST_REQUIRE_EQUAL(args.size(), 1);
using namespace osrm;
EngineConfig config;
config.storage_config = {args[0]};
config.use_shared_memory = false;
config.max_results_nearest = 2;
OSRM osrm{config};
NearestParameters params;
params.coordinates.emplace_back(util::FloatLongitude{}, util::FloatLatitude{});
params.number_of_results = 10000;
json::Object result;
const auto rc = osrm.Nearest(params, result);
BOOST_CHECK(rc == Status::Error);
// Make sure we're not accidentally hitting a guard code path before
const auto code = result.values["code"].get<json::String>().value;
BOOST_CHECK(code == "TooBig"); // per the New-Server API spec
}
BOOST_AUTO_TEST_SUITE_END()