summaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorArne Juul <arnej@verizonmedia.com>2020-07-10 13:19:09 +0000
committerArne Juul <arnej@verizonmedia.com>2020-07-15 15:39:22 +0000
commit42a328d165fb48f800b9cba556b8d24d4759d609 (patch)
tree848073f152879e85ff6649dcd04871082dfeb611 /searchlib
parent2ff70ed24feb03080489b63bd84c30e26108066b (diff)
refactor geo location parsing
Diffstat (limited to 'searchlib')
-rw-r--r--searchlib/src/tests/common/location/geo_location_test.cpp4
-rw-r--r--searchlib/src/vespa/searchlib/common/geo_location_spec.cpp2
-rw-r--r--searchlib/src/vespa/searchlib/common/geo_location_spec.h2
-rw-r--r--searchlib/src/vespa/searchlib/common/location.cpp203
-rw-r--r--searchlib/src/vespa/searchlib/common/location.h39
5 files changed, 23 insertions, 227 deletions
diff --git a/searchlib/src/tests/common/location/geo_location_test.cpp b/searchlib/src/tests/common/location/geo_location_test.cpp
index 34567b430b7..452adea2579 100644
--- a/searchlib/src/tests/common/location/geo_location_test.cpp
+++ b/searchlib/src/tests/common/location/geo_location_test.cpp
@@ -8,12 +8,12 @@ using search::common::GeoLocationSpec;
bool is_parseable(const char *str) {
GeoLocationSpec loc;
- return loc.parse(str);
+ return loc.parseOldFormat(str);
}
GeoLocationSpec parse(const char *str) {
GeoLocationSpec loc;
- EXPECT_TRUE(loc.parse(str));
+ EXPECT_TRUE(loc.parseOldFormat(str));
return loc;
}
diff --git a/searchlib/src/vespa/searchlib/common/geo_location_spec.cpp b/searchlib/src/vespa/searchlib/common/geo_location_spec.cpp
index 76dffb5188e..3fbe72b310c 100644
--- a/searchlib/src/vespa/searchlib/common/geo_location_spec.cpp
+++ b/searchlib/src/vespa/searchlib/common/geo_location_spec.cpp
@@ -87,7 +87,7 @@ GeoLocationSpec::getLocationString() const
}
bool
-GeoLocationSpec::parse(const std::string &locStr)
+GeoLocationSpec::parseOldFormat(const std::string &locStr)
{
bool foundBoundingBox = false;
bool foundLoc = false;
diff --git a/searchlib/src/vespa/searchlib/common/geo_location_spec.h b/searchlib/src/vespa/searchlib/common/geo_location_spec.h
index f8f4b0f5cca..fadb2d5546f 100644
--- a/searchlib/src/vespa/searchlib/common/geo_location_spec.h
+++ b/searchlib/src/vespa/searchlib/common/geo_location_spec.h
@@ -27,7 +27,7 @@ public:
int32_t getMaxX() const { return _max_x; }
int32_t getMaxY() const { return _max_y; }
- bool parse(const std::string &locStr);
+ bool parseOldFormat(const std::string &locStr);
std::string getLocationString() const;
diff --git a/searchlib/src/vespa/searchlib/common/location.cpp b/searchlib/src/vespa/searchlib/common/location.cpp
index 6927d9ab6cb..bb8df6dcf26 100644
--- a/searchlib/src/vespa/searchlib/common/location.cpp
+++ b/searchlib/src/vespa/searchlib/common/location.cpp
@@ -5,198 +5,17 @@
namespace search::common {
-Location::Location() :
- _zBoundingBox(0,0,0,0),
- _x(0),
- _y(0),
- _xAspect(0u),
- _radius(std::numeric_limits<uint32_t>::max()),
- _minx(std::numeric_limits<int32_t>::min()),
- _maxx(std::numeric_limits<int32_t>::max()),
- _miny(std::numeric_limits<int32_t>::min()),
- _maxy(std::numeric_limits<int32_t>::max()),
- _rankOnDistance(false),
- _pruneOnDistance(false),
- _parseError(NULL)
-{
-}
-
-
-bool
-Location::getDimensionality(const char **pp)
-{
- if (**pp == '2') {
- (*pp)++;
- if (**pp != ',') {
- _parseError = "Missing comma after 2D dimensionality";
- return false;
- }
- (*pp)++;
- return true;
- }
- _parseError = "Bad dimensionality spec, not 2D";
- return false;
-}
-
-
-int
-Location::getInt(const char **pp)
-{
- const char *p = *pp;
- int val;
- bool isminus;
-
- val = 0;
- isminus = false;
- if (*p == '-') {
- isminus = true;
- p++;
+Location::Location() : _zBoundingBox(0,0,0,0) {}
+
+bool Location::parse(const std::string &locStr) {
+ bool valid = GeoLocationSpec::parseOldFormat(locStr);
+ if (valid) {
+ _zBoundingBox = vespalib::geo::ZCurve::BoundingBox(getMinX(),
+ getMaxX(),
+ getMinY(),
+ getMaxY());
}
- while (*p >= '0' && *p <= '9')
- val = val * 10 + *p++ - '0';
- *pp = p;
- return isminus ? - val : val;
+ return valid;
}
-bool Location::parse(const vespalib::string &locStr)
-{
- bool hadCutoff = false;
- bool hadLoc = false;
- const char *p = locStr.c_str();
- while (*p != '\0') {
- if (*p == '[') {
- p++;
- if (hadCutoff) {
- _parseError = "Duplicate square cutoff";
- return false;
- }
- hadCutoff = true;
- if (!getDimensionality(&p))
- return false;
- _minx = getInt(&p);
- if (*p != ',') {
- _parseError = "Missing ',' after minx";
- return false;
- }
- p++;
- _miny = getInt(&p);
- if (*p != ',') {
- _parseError = "Missing ',' after miny";
- return false;
- }
- p++;
- _maxx = getInt(&p);
- if (*p != ',') {
- _parseError = "Missing ',' after maxx";
- return false;
- }
- p++;
- _maxy = getInt(&p);
- if (*p != ']') {
- _parseError = "Missing ']' after maxy";
- return false;
- }
- p++;
- } else if (*p == '(') {
- p++;
- if (hadLoc) {
- _parseError = "Duplicate location";
- return false;
- }
- hadLoc = true;
- if (!getDimensionality(&p))
- return false;
- _x = getInt(&p);
- if (*p != ',') {
- _parseError = "Missing ',' after x position";
- return false;
- }
- p++;
- _y = getInt(&p);
- if (*p != ',') {
- _parseError = "Missing ',' after y position";
- return false;
- }
- p++;
- _radius = getInt(&p);
- if (*p != ',') {
- _parseError = "Missing ',' after radius";
- return false;
- }
- p++;
- /* _tableID = */ (void) getInt(&p);
- if (*p != ',') {
- _parseError = "Missing ',' after tableID";
- return false;
- }
- p++;
- /* _rankMultiplier = */ (void) getInt(&p);
- if (*p != ',') {
- _parseError = "Missing ',' after rank multiplier";
- return false;
- }
- p++;
- /* _rankOnlyOnDistance = */ (void) (getInt(&p) != 0);
- if (*p == ',') {
- p++;
- _xAspect = getInt(&p);
- if (*p != ')') {
- _parseError = "Missing ')' after xAspect";
- return false;
- }
- } else {
- if (*p != ')') {
- _parseError = "Missing ')' after rankOnlyOnDistance flag";
- return false;
- }
- }
- p++;
- } else if (*p == ' ')
- p++;
- else {
- _parseError = "Unexpected char in location spec";
- return false;
- }
- }
-
- if (hadLoc) {
- _rankOnDistance = true;
- uint32_t maxdx = _radius;
- if (_xAspect != 0) {
- uint64_t maxdx2 = ((static_cast<uint64_t>(_radius) << 32) + 0xffffffffu) /
- _xAspect;
- if (maxdx2 >= 0xffffffffu)
- maxdx = 0xffffffffu;
- else
- maxdx = static_cast<uint32_t>(maxdx2);
- }
- if (static_cast<int32_t>(_x - maxdx) > _minx &&
- static_cast<int64_t>(_x) - static_cast<int64_t>(maxdx) >
- static_cast<int64_t>(_minx))
- _minx = _x - maxdx;
- if (static_cast<int32_t>(_x + maxdx) < _maxx &&
- static_cast<int64_t>(_x) + static_cast<int64_t>(maxdx) <
- static_cast<int64_t>(_maxx))
- _maxx = _x + maxdx;
- if (static_cast<int32_t>(_y - _radius) > _miny &&
- static_cast<int64_t>(_y) - static_cast<int64_t>(_radius) >
- static_cast<int64_t>(_miny))
- _miny = _y - _radius;
- if (static_cast<int32_t>(_y + _radius) < _maxy &&
- static_cast<int64_t>(_y) + static_cast<int64_t>(_radius) <
- static_cast<int64_t>(_maxy))
- _maxy = _y + _radius;
- }
- if (_minx != std::numeric_limits<int32_t>::min() ||
- _maxx != std::numeric_limits<int32_t>::max() ||
- _miny != std::numeric_limits<int32_t>::min() ||
- _maxy != std::numeric_limits<int32_t>::max())
- {
- _pruneOnDistance = true;
- }
- _zBoundingBox = vespalib::geo::ZCurve::BoundingBox(_minx, _maxx, _miny, _maxy);
-
- return true;
-}
-
-}
+} // namespace
diff --git a/searchlib/src/vespa/searchlib/common/location.h b/searchlib/src/vespa/searchlib/common/location.h
index a00bb83648a..a2efa9a70dd 100644
--- a/searchlib/src/vespa/searchlib/common/location.h
+++ b/searchlib/src/vespa/searchlib/common/location.h
@@ -3,51 +3,28 @@
#pragma once
#include "documentlocations.h"
+#include "geo_location_spec.h"
+#include <string>
#include <vespa/vespalib/geo/zcurve.h>
#include <vespa/vespalib/stllike/string.h>
namespace search::common {
-class Location : public DocumentLocations
+class Location : public DocumentLocations,
+ public GeoLocationSpec
{
-private:
- static int getInt(const char **pp);
- bool getDimensionality(const char **pp);
-
public:
Location();
- bool getRankOnDistance() const { return _rankOnDistance; }
- bool getPruneOnDistance() const { return _pruneOnDistance; }
- uint32_t getXAspect() const { return _xAspect; }
- 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 _minx; }
- int32_t getMinY() const { return _miny; }
- int32_t getMaxX() const { return _maxx; }
- int32_t getMaxY() const { return _maxy; }
+ bool getRankOnDistance() const { return hasPoint(); }
+ bool getPruneOnDistance() const { return hasBoundingBox(); }
bool getzFailBoundingBoxTest(int64_t docxy) const {
return _zBoundingBox.getzFailBoundingBoxTest(docxy);
}
-
- bool parse(const vespalib::string &locStr);
-
+ bool parse(const std::string &locStr);
private:
+ GeoLocationSpec _spec;
vespalib::geo::ZCurve::BoundingBox _zBoundingBox;
- int32_t _x; /* Query X position */
- int32_t _y; /* Query Y position */
- uint32_t _xAspect; /* X distance multiplier fraction */
- uint32_t _radius; /* Radius for euclidean distance */
- int32_t _minx; /* Min X coordinate */
- int32_t _maxx; /* Max X coordinate */
- int32_t _miny; /* Min Y coordinate */
- int32_t _maxy; /* Max Y coordinate */
-
- bool _rankOnDistance;
- bool _pruneOnDistance;
- const char *_parseError;
};
}