summaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorArne Juul <arnej@verizonmedia.com>2020-07-10 17:36:59 +0000
committerArne Juul <arnej@verizonmedia.com>2020-07-15 15:39:22 +0000
commit2ef06d7de7cd52c9c41c6275413688e4359f979f (patch)
tree311aad2ed3470a737c42f37c8f1391abd4afd523 /searchlib
parent5fc7cc737144fc27ed7de2761a2f041750c949c7 (diff)
split out geo location parser into its own distinct class
Diffstat (limited to 'searchlib')
-rw-r--r--searchlib/src/tests/common/location/geo_location_test.cpp11
-rw-r--r--searchlib/src/tests/common/location/location_test.cpp39
-rw-r--r--searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp7
-rw-r--r--searchlib/src/vespa/searchlib/common/geo_location_spec.cpp75
-rw-r--r--searchlib/src/vespa/searchlib/common/geo_location_spec.h28
-rw-r--r--searchlib/src/vespa/searchlib/common/location.cpp27
-rw-r--r--searchlib/src/vespa/searchlib/common/location.h4
7 files changed, 106 insertions, 85 deletions
diff --git a/searchlib/src/tests/common/location/geo_location_test.cpp b/searchlib/src/tests/common/location/geo_location_test.cpp
index 452adea2579..b29133172df 100644
--- a/searchlib/src/tests/common/location/geo_location_test.cpp
+++ b/searchlib/src/tests/common/location/geo_location_test.cpp
@@ -4,17 +4,18 @@
#include <vespa/searchlib/common/geo_location_spec.h>
#include <vespa/vespalib/gtest/gtest.h>
+using search::common::GeoLocationParser;
using search::common::GeoLocationSpec;
bool is_parseable(const char *str) {
- GeoLocationSpec loc;
- return loc.parseOldFormat(str);
+ GeoLocationParser parser;
+ return parser.parseOldFormat(str);
}
GeoLocationSpec parse(const char *str) {
- GeoLocationSpec loc;
- EXPECT_TRUE(loc.parseOldFormat(str));
- return loc;
+ GeoLocationParser parser;
+ EXPECT_TRUE(parser.parseOldFormat(str));
+ return parser.spec();
}
TEST(GeoLocationSpec, malformed_bounding_boxes_are_not_parseable) {
diff --git a/searchlib/src/tests/common/location/location_test.cpp b/searchlib/src/tests/common/location/location_test.cpp
index d781e5b7275..79eec441d62 100644
--- a/searchlib/src/tests/common/location/location_test.cpp
+++ b/searchlib/src/tests/common/location/location_test.cpp
@@ -3,43 +3,16 @@
#include <vespa/searchlib/common/location.h>
#include <vespa/searchlib/attribute/attributeguard.h>
-
using search::common::Location;
-
-bool is_parseable(const char *str) {
- Location loc;
- return loc.parse(str);
-}
+using search::common::GeoLocationParser;
+using search::common::GeoLocationSpec;
Location parse(const char *str) {
- Location loc;
- if (!EXPECT_TRUE(loc.parse(str))) {
- fprintf(stderr, " parse error: %s\n", loc.getParseError());
+ GeoLocationParser parser;
+ if (!EXPECT_TRUE(parser.parseOldFormat(str))) {
+ fprintf(stderr, " parse error: %s\n", parser.getParseError());
}
- return loc;
-}
-
-TEST("require that malformed bounding boxes are not parseable") {
- EXPECT_TRUE(is_parseable("[2,10,20,30,40]"));
- EXPECT_FALSE(is_parseable("[2,10,20,30,40][2,10,20,30,40]"));
- EXPECT_FALSE(is_parseable("[1,10,20,30,40]"));
- EXPECT_FALSE(is_parseable("[3,10,20,30,40]"));
- EXPECT_FALSE(is_parseable("[2, 10, 20, 30, 40]"));
- EXPECT_FALSE(is_parseable("[2,10,20,30,40"));
- EXPECT_FALSE(is_parseable("[2,10,20,30]"));
- EXPECT_FALSE(is_parseable("[10,20,30,40]"));
-}
-
-TEST("require that malformed circles are not parseable") {
- EXPECT_TRUE(is_parseable("(2,10,20,5,0,0,0)"));
- EXPECT_FALSE(is_parseable("(2,10,20,5,0,0,0)(2,10,20,5,0,0,0)"));
- EXPECT_FALSE(is_parseable("(1,10,20,5,0,0,0)"));
- EXPECT_FALSE(is_parseable("(3,10,20,5,0,0,0)"));
- EXPECT_FALSE(is_parseable("(2, 10, 20, 5, 0, 0, 0)"));
- EXPECT_FALSE(is_parseable("(2,10,20,5)"));
- EXPECT_FALSE(is_parseable("(2,10,20,5,0,0,0"));
- EXPECT_FALSE(is_parseable("(2,10,20,5,0,0,0,1000"));
- EXPECT_FALSE(is_parseable("(10,20,5)"));
+ return Location(parser.spec());
}
TEST("require that bounding boxes can be parsed") {
diff --git a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp
index 62f4661b335..5148e6e02d2 100644
--- a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp
@@ -250,8 +250,11 @@ public:
_attribute(attribute),
_location()
{
- _location.setVec(attribute);
- _location.parse(loc.getLocationString());
+ search::common::GeoLocationParser parser;
+ if (parser.parseOldFormat(loc.getLocationString())) {
+ _location.setVec(attribute);
+ _location.setSpec(parser.spec());
+ }
uint32_t estHits = _attribute.getNumDocs();
LOG(debug, "location %s in attribute with numdocs %u", loc.getLocationString().c_str(), estHits);
HitEstimate estimate(estHits, estHits == 0);
diff --git a/searchlib/src/vespa/searchlib/common/geo_location_spec.cpp b/searchlib/src/vespa/searchlib/common/geo_location_spec.cpp
index 0535f70aabb..fc1cfc4e99c 100644
--- a/searchlib/src/vespa/searchlib/common/geo_location_spec.cpp
+++ b/searchlib/src/vespa/searchlib/common/geo_location_spec.cpp
@@ -28,9 +28,9 @@ namespace search::common {
GeoLocationSpec::GeoLocationSpec() :
_valid(false),
- _hasPoint(false),
- _hasRadius(false),
- _hasBoundingBox(false),
+ _has_point(false),
+ _has_radius(false),
+ _has_bounding_box(false),
_field_name(),
_x(0),
_y(0),
@@ -39,26 +39,9 @@ GeoLocationSpec::GeoLocationSpec() :
_min_x(std::numeric_limits<int32_t>::min()),
_max_x(std::numeric_limits<int32_t>::max()),
_min_y(std::numeric_limits<int32_t>::min()),
- _max_y(std::numeric_limits<int32_t>::max()),
- _parseError(NULL)
-{
-}
-
+ _max_y(std::numeric_limits<int32_t>::max())
+{}
-bool
-GeoLocationSpec::getDimensionality(const char * &p) {
- if (*p == '2') {
- p++;
- if (*p != ',') {
- _parseError = "Missing comma after 2D dimensionality";
- return false;
- }
- p++;
- return true;
- }
- _parseError = "Bad dimensionality spec, not 2D";
- return false;
-}
std::string
GeoLocationSpec::getLocationString() const
@@ -87,8 +70,38 @@ GeoLocationSpec::getLocationString() const
return loc.str();
}
+std::string
+GeoLocationSpec::getLocationStringWithField() const
+{
+ if (hasFieldName()) {
+ return getFieldName() + ":" + getLocationString();
+ } else {
+ return getLocationString();
+ }
+}
+
+
+GeoLocationParser::GeoLocationParser()
+ : GeoLocationSpec(), _parseError(NULL)
+{}
+
bool
-GeoLocationSpec::parseOldFormatWithField(const std::string &str)
+GeoLocationParser::getDimensionality(const char * &p) {
+ if (*p == '2') {
+ p++;
+ if (*p != ',') {
+ _parseError = "Missing comma after 2D dimensionality";
+ return false;
+ }
+ p++;
+ return true;
+ }
+ _parseError = "Bad dimensionality spec, not 2D";
+ return false;
+}
+
+bool
+GeoLocationParser::parseOldFormatWithField(const std::string &str)
{
auto sep = str.find(':');
if (sep == std::string::npos) {
@@ -101,7 +114,7 @@ GeoLocationSpec::parseOldFormatWithField(const std::string &str)
}
bool
-GeoLocationSpec::parseOldFormat(const std::string &locStr)
+GeoLocationParser::parseOldFormat(const std::string &locStr)
{
bool foundBoundingBox = false;
bool foundLoc = false;
@@ -201,9 +214,8 @@ GeoLocationSpec::parseOldFormat(const std::string &locStr)
return false;
}
}
-
if (foundLoc) {
- _hasRadius = (_radius != std::numeric_limits<uint32_t>::max());
+ _has_radius = (_radius != std::numeric_limits<uint32_t>::max());
uint32_t maxdx = _radius;
if (_x_aspect != 0) {
uint64_t maxdx2 = ((static_cast<uint64_t>(_radius) << 32) + 0xffffffffu) /
@@ -225,10 +237,13 @@ GeoLocationSpec::parseOldFormat(const std::string &locStr)
if (implied_max_y < _max_y) _max_y = implied_max_y;
if (implied_min_y > _min_y) _min_y = implied_min_y;
}
- _hasPoint = foundLoc;
- _hasBoundingBox = foundBoundingBox || _hasRadius;
- _valid = (_hasPoint || _hasBoundingBox);
+ _has_point = foundLoc;
+ _has_bounding_box = ((_min_x != std::numeric_limits<int32_t>::min()) ||
+ (_max_x != std::numeric_limits<int32_t>::max()) ||
+ (_min_y != std::numeric_limits<int32_t>::min()) ||
+ (_max_y != std::numeric_limits<int32_t>::max()));
+ _valid = (_has_point || _has_bounding_box);
return _valid;
}
-}
+} // namespace
diff --git a/searchlib/src/vespa/searchlib/common/geo_location_spec.h b/searchlib/src/vespa/searchlib/common/geo_location_spec.h
index 1a848e9d7ea..853ad43ff46 100644
--- a/searchlib/src/vespa/searchlib/common/geo_location_spec.h
+++ b/searchlib/src/vespa/searchlib/common/geo_location_spec.h
@@ -13,31 +13,29 @@ public:
GeoLocationSpec();
bool isValid() const { return _valid; }
- bool hasPoint() const { return _hasPoint; }
- bool hasBoundingBox() const { return _hasBoundingBox; }
+ bool hasPoint() const { return _has_point; }
+ bool hasBoundingBox() const { return _has_bounding_box; }
bool hasFieldName() const { return ! _field_name.empty(); }
uint32_t getXAspect() const { return _x_aspect; }
int32_t getX() const { return _x; }
int32_t getY() const { return _y; }
uint32_t getRadius() const { return _radius; }
- const char * getParseError() const { return _parseError; }
int32_t getMinX() const { return _min_x; }
int32_t getMinY() const { return _min_y; }
int32_t getMaxX() const { return _max_x; }
int32_t getMaxY() const { return _max_y; }
- bool parseOldFormat(const std::string &locStr);
- bool parseOldFormatWithField(const std::string &str);
-
std::string getLocationString() const;
+ std::string getLocationStringWithField() const;
+ std::string getFieldName() const { return _field_name; }
-private:
+protected:
bool _valid;
- bool _hasPoint;
- bool _hasRadius;
- bool _hasBoundingBox;
+ bool _has_point;
+ bool _has_radius;
+ bool _has_bounding_box;
std::string _field_name;
@@ -49,7 +47,17 @@ private:
int32_t _max_x; /* Max X coordinate */
int32_t _min_y; /* Min Y coordinate */
int32_t _max_y; /* Max Y coordinate */
+};
+class GeoLocationParser : private GeoLocationSpec
+{
+public:
+ GeoLocationParser();
+ bool parseOldFormat(const std::string &locStr);
+ bool parseOldFormatWithField(const std::string &str);
+ GeoLocationSpec spec() const { return *this; }
+ const char * getParseError() const { return _parseError; }
+private:
const char *_parseError;
bool getDimensionality(const char * &p);
};
diff --git a/searchlib/src/vespa/searchlib/common/location.cpp b/searchlib/src/vespa/searchlib/common/location.cpp
index bb8df6dcf26..ff87d5a260c 100644
--- a/searchlib/src/vespa/searchlib/common/location.cpp
+++ b/searchlib/src/vespa/searchlib/common/location.cpp
@@ -7,15 +7,34 @@ namespace search::common {
Location::Location() : _zBoundingBox(0,0,0,0) {}
+Location::Location(const GeoLocationSpec &other)
+ : _zBoundingBox(0,0,0,0)
+{
+ setSpec(other);
+}
+
+void
+Location::setSpec(const GeoLocationSpec &other)
+{
+ using vespalib::geo::ZCurve;
+
+ GeoLocationSpec::operator=(other);
+ if (isValid()) {
+ _zBoundingBox = ZCurve::BoundingBox(getMinX(), getMaxX(),
+ getMinY(), getMaxY());
+ }
+}
+
+
+#if 0
bool Location::parse(const std::string &locStr) {
bool valid = GeoLocationSpec::parseOldFormat(locStr);
if (valid) {
- _zBoundingBox = vespalib::geo::ZCurve::BoundingBox(getMinX(),
- getMaxX(),
- getMinY(),
- getMaxY());
+ _zBoundingBox = vespalib::geo::ZCurve::BoundingBox(getMinX(), getMaxX(),
+ getMinY(), getMaxY());
}
return valid;
}
+#endif
} // namespace
diff --git a/searchlib/src/vespa/searchlib/common/location.h b/searchlib/src/vespa/searchlib/common/location.h
index 72b7bbc7ca4..c73fe7b817c 100644
--- a/searchlib/src/vespa/searchlib/common/location.h
+++ b/searchlib/src/vespa/searchlib/common/location.h
@@ -16,6 +16,7 @@ class Location : public DocumentLocations,
{
public:
Location();
+ Location(const GeoLocationSpec& other);
~Location() {}
Location(Location &&) = default;
bool getRankOnDistance() const { return hasPoint(); }
@@ -23,7 +24,8 @@ public:
bool getzFailBoundingBoxTest(int64_t docxy) const {
return _zBoundingBox.getzFailBoundingBoxTest(docxy);
}
- bool parse(const std::string &locStr);
+ // bool parse(const std::string &locStr);
+ void setSpec(const GeoLocationSpec& other);
private:
GeoLocationSpec _spec;
vespalib::geo::ZCurve::BoundingBox _zBoundingBox;