diff --git a/include/opendht/dht_proxy_client.h b/include/opendht/dht_proxy_client.h index e3f82875..df3fe363 100644 --- a/include/opendht/dht_proxy_client.h +++ b/include/opendht/dht_proxy_client.h @@ -227,13 +227,8 @@ public: return types.getType(type_id); } - std::vector> getLocal(const InfoHash&, Value::Filter) const { - return {}; - } - - Sp getLocalById(const InfoHash&, Value::Id) const { - return {}; - } + std::vector> getLocal(const InfoHash& k, Value::Filter filter) const; + Sp getLocalById(const InfoHash& k, Value::Id id) const; /** * NOTE: The following methods will not be implemented because the diff --git a/src/dht_proxy_client.cpp b/src/dht_proxy_client.cpp index 8562bb39..9a5b2d05 100644 --- a/src/dht_proxy_client.cpp +++ b/src/dht_proxy_client.cpp @@ -84,6 +84,22 @@ DhtProxyClient::~DhtProxyClient() cancelAllListeners(); } +std::vector> +DhtProxyClient::getLocal(const InfoHash& k, Value::Filter filter) const { + auto s = listeners_.find(k); + if (s == listeners_.end()) + return {}; + return s->second.ops.get(filter); +} + +Sp +DhtProxyClient::getLocalById(const InfoHash& k, Value::Id id) const { + auto s = listeners_.find(k); + if (s == listeners_.end()) + return {}; + return s->second.ops.get(id); +} + void DhtProxyClient::cancelAllOperations() { diff --git a/src/op_cache.h b/src/op_cache.h index e20f8845..e2f26008 100644 --- a/src/op_cache.h +++ b/src/op_cache.h @@ -139,6 +139,23 @@ public: return listeners.empty(); } + std::vector> get(Value::Filter& filter) const { + std::vector> ret; + if (not filter) + ret.reserve(values.size()); + for (const auto& v : values) + if (not filter or filter(*v.second.data)) + ret.emplace_back(v.second.data); + return ret; + } + + Sp get(Value::Id id) const { + auto v = values.find(id); + if (v == values.end()) + return {}; + return v->second.data; + } + size_t searchToken; private: std::map listeners; @@ -188,6 +205,28 @@ public: return false; } + std::vector> get(Value::Filter& filter) const { + if (ops.size() == 1) + return ops.begin()->second.get(filter); + std::map> c; + for (const auto& op : ops) { + for (const auto& v : op.second.get(filter)) + c.emplace(v->id, v); + } + std::vector> ret; + ret.reserve(c.size()); + for (auto& v : c) + ret.emplace_back(std::move(v.second)); + return ret; + } + + Sp get(Value::Id id) const { + for (const auto& op : ops) + if (auto v = op.second.get(id)) + return v; + return {}; + } + private: std::map, OpCache> ops; size_t nextToken_ {1};