From 63c4eeb9c9ccc3321599fef7374665643586bd3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20D=C3=A9saulniers?= <rostydela@gmail.com> Date: Wed, 13 Jan 2016 11:08:47 -0500 Subject: [PATCH] cover empty leaf case in inexact match lookup In case this is inexact match lookup and we end up on an empty leaf (diffrent than the root), the search goes on in the leaf's sibling subtree. --- include/opendht/indexation/pht.h | 2 ++ src/indexation/pht.cpp | 6 ++++++ tools/dhtnode.cpp | 22 ++++++++++++---------- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/include/opendht/indexation/pht.h b/include/opendht/indexation/pht.h index 815fb1c1..aed1921c 100644 --- a/include/opendht/indexation/pht.h +++ b/include/opendht/indexation/pht.h @@ -42,6 +42,8 @@ struct Prefix { return Prefix(*this, len); } + Prefix getFullSize() { return Prefix(*this, content_.size()*8); } + /** * This methods gets the prefix of its sibling in the PHT structure. * diff --git a/src/indexation/pht.cpp b/src/indexation/pht.cpp index 1b2e2636..4ac390a5 100644 --- a/src/indexation/pht.cpp +++ b/src/indexation/pht.cpp @@ -24,6 +24,12 @@ void Pht::lookupStep(Prefix p, std::shared_ptr<int> lo, std::shared_ptr<int> hi, if (is_leaf or *lo > *hi) { // leaf node if (cb) + if (vals->size() == 0 and max_common_prefix_len and mid > 0) { + auto p_ = (p.getPrefix(mid)).getSibling().getFullSize(); + *lo = mid; + *hi = p_.size_; + lookupStep(p_, lo, hi, vals, cb, done_cb, max_common_prefix_len); + } cb(*vals, p.getPrefix(mid)); if (done_cb) done_cb(true); diff --git a/tools/dhtnode.cpp b/tools/dhtnode.cpp index 1480b25f..ee3199be 100644 --- a/tools/dhtnode.cpp +++ b/tools/dhtnode.cpp @@ -60,16 +60,16 @@ void print_help() { << " lr Print the full current routing table of this node" << std::endl; std::cout << std::endl << "Operations on the DHT:" << std::endl - << " b ip:port Ping potential node at given IP address/port." << std::endl - << " g [key] [where] Get values at [key]. [where] is the 'where' part of an SQL-ish string." << std::endl - << " q [key] [query] Query field values at [key]. [query] is an SQL-ish string." << std::endl - << " l [key] [where] Listen for value changes at [key]. [where] is the 'where' part of an SQL-ish string." << std::endl - << " p [key] [str] Put string value at [key]." << std::endl - << " s [key] [str] Put string value at [key], signed with our generated private key." << std::endl - << " e [key] [dest] [str] Put string value at [key], encrypted for [dest] with its public key (if found)." << std::endl; + << " b <ip:port> Ping potential node at given IP address/port." << std::endl + << " g <key> Get values at <key>." << std::endl + << " l <key> Listen for value changes at <key>." << std::endl + << " p <key> <str> Put string value at <key>." << std::endl + << " s <key> <str> Put string value at <key>, signed with our generated private key." << std::endl + << " e <key> <dest> <str> Put string value at <key>, encrypted for <dest> with its public key (if found)." << std::endl; std::cout << std::endl << "Indexation operations on the DHT:" << std::endl - << " il [name] [key] Lookup the index named [name] with the key [key]." << std::endl - << " ii [name] [key] [value] Inserts the value [value] under the key [key] in the index named [name]." << std::endl + << " il <name> <key> [exact match] Lookup the index named <name> with the key <key>." << std::endl + << " Set [exact match] to 'false' for inexact match lookup." << std::endl + << " ii <name> <key> <value> Inserts the value <value> under the key <key> in the index named <name>." << std::endl << std::endl; } @@ -265,6 +265,8 @@ void cmd_loop(std::shared_ptr<DhtRunner>& dht, std::map<std::string, dht::indexa }); } else if (op == "il") { + std::string exact_match; + iss >> exact_match; indexes.at(index).lookup(createPhtKey(parseStringMap(keystr)), [=](std::vector<std::shared_ptr<indexation::Value>>& vals, indexation::Prefix p) { std::cout << "Pht::lookup: at prefix \"" << p.toString() << "\"" << ", hash is " << p.hash() << std::endl; @@ -278,7 +280,7 @@ void cmd_loop(std::shared_ptr<DhtRunner>& dht, std::map<std::string, dht::indexa if (not ok) { std::cout << "Pht::lookup: dht Get failed." << std::endl; } - } + }, exact_match.size() != 0 and exact_match == "false" ? false : true ); } else if (op == "ii") { -- GitLab