Fix geo_db may seek an error key when they have the same quadkey

Summary: Closes https://github.com/facebook/rocksdb/pull/3832

Differential Revision: D7994326

Pulled By: miasantreble

fbshipit-source-id: 84a81b35b97750360423a9d4eca5b5a14d002134
main
acelyc111 7 years ago committed by Facebook Github Bot
parent 12ad711247
commit 42cb4775c1
  1. 5
      utilities/geodb/geodb_impl.cc
  2. 60
      utilities/geodb/geodb_test.cc

@ -247,7 +247,7 @@ GeoIterator* GeoDBImpl::SearchRadial(const GeoPosition& pos,
auto res = std::mismatch(qid.begin(), qid.end(), quadkey->begin()); auto res = std::mismatch(qid.begin(), qid.end(), quadkey->begin());
if (res.first == qid.end()) { if (res.first == qid.end()) {
GeoPosition obj_pos(atof(parts[3].c_str()), atof(parts[4].c_str())); GeoPosition obj_pos(atof(parts[3].c_str()), atof(parts[4].c_str()));
GeoObject obj(obj_pos, parts[4], iter->value().ToString()); GeoObject obj(obj_pos, parts[2], iter->value().ToString());
values.push_back(obj); values.push_back(obj);
number_of_values--; number_of_values--;
} else { } else {
@ -284,10 +284,11 @@ std::string GeoDBImpl::MakeKey2(Slice id) {
std::string GeoDBImpl::MakeKey1Prefix(std::string quadkey, std::string GeoDBImpl::MakeKey1Prefix(std::string quadkey,
Slice id) { Slice id) {
std::string key = "p:"; std::string key = "p:";
key.reserve(3 + quadkey.size() + id.size()); key.reserve(4 + quadkey.size() + id.size());
key.append(quadkey); key.append(quadkey);
key.append(":"); key.append(":");
key.append(id.ToString()); key.append(id.ToString());
key.append(":");
return key; return key;
} }

@ -108,8 +108,17 @@ TEST_F(GeoDBTest, Search) {
ASSERT_EQ(iter1->geo_object().value, "midvalue1"); ASSERT_EQ(iter1->geo_object().value, "midvalue1");
uint32_t size = 0; uint32_t size = 0;
while (iter1->Valid()) { while (iter1->Valid()) {
GeoObject obj;
status = getdb()->GetById(Slice(id1), &obj);
ASSERT_TRUE(status.ok());
ASSERT_EQ(iter1->geo_object().position.latitude, pos1.latitude);
ASSERT_EQ(iter1->geo_object().position.longitude, pos1.longitude);
ASSERT_EQ(iter1->geo_object().id.compare(id1), 0);
ASSERT_EQ(iter1->geo_object().value, value1);
size++; size++;
iter1->Next(); iter1->Next();
ASSERT_TRUE(!iter1->Valid());
} }
ASSERT_EQ(size, 1U); ASSERT_EQ(size, 1U);
delete iter1; delete iter1;
@ -122,6 +131,57 @@ TEST_F(GeoDBTest, Search) {
delete iter2; delete iter2;
} }
TEST_F(GeoDBTest, DifferentPosInSameQuadkey) {
// insert obj1 into database
GeoPosition pos1(40.00001, 116.00001);
std::string id1("12");
std::string value1("value1");
GeoObject obj1(pos1, id1, value1);
Status status = getdb()->Insert(obj1);
ASSERT_TRUE(status.ok());
// insert obj2 into database
GeoPosition pos2(40.00002, 116.00002);
std::string id2("123");
std::string value2 = "value2";
GeoObject obj2(pos2, id2, value2);
status = getdb()->Insert(obj2);
ASSERT_TRUE(status.ok());
// get obj1's quadkey
ReadOptions opt;
PinnableSlice quadkey1;
status = getdb()->Get(opt, getdb()->DefaultColumnFamily(), "k:" + id1, &quadkey1);
ASSERT_TRUE(status.ok());
// get obj2's quadkey
PinnableSlice quadkey2;
status = getdb()->Get(opt, getdb()->DefaultColumnFamily(), "k:" + id2, &quadkey2);
ASSERT_TRUE(status.ok());
// obj1 and obj2 have the same quadkey
ASSERT_EQ(quadkey1, quadkey2);
// get obj1 by id, and check value
GeoObject obj;
status = getdb()->GetById(Slice(id1), &obj);
ASSERT_TRUE(status.ok());
ASSERT_EQ(obj.position.latitude, pos1.latitude);
ASSERT_EQ(obj.position.longitude, pos1.longitude);
ASSERT_EQ(obj.id.compare(id1), 0);
ASSERT_EQ(obj.value, value1);
// get obj2 by id, and check value
status = getdb()->GetById(Slice(id2), &obj);
ASSERT_TRUE(status.ok());
ASSERT_EQ(obj.position.latitude, pos2.latitude);
ASSERT_EQ(obj.position.longitude, pos2.longitude);
ASSERT_EQ(obj.id.compare(id2), 0);
ASSERT_EQ(obj.value, value2);
}
} // namespace rocksdb } // namespace rocksdb
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {

Loading…
Cancel
Save