From e3663c995a7704802aafbeb57f0bd48f17e4e7b4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <adrien.beraud@savoirfairelinux.com>
Date: Sun, 23 Oct 2016 16:47:44 -0400
Subject: [PATCH] log: add storage filter

---
 include/opendht/dht.h       |  3 +++
 include/opendht/dhtrunner.h |  1 +
 src/dht.cpp                 | 52 +++++++++++++++++++++++++------------
 src/dhtrunner.cpp           |  6 +++++
 tools/dhtnode.cpp           |  7 ++++-
 5 files changed, 52 insertions(+), 17 deletions(-)

diff --git a/include/opendht/dht.h b/include/opendht/dht.h
index c5ba9c0f..603b128d 100644
--- a/include/opendht/dht.h
+++ b/include/opendht/dht.h
@@ -271,6 +271,8 @@ public:
     unsigned getNodesStats(sa_family_t af, unsigned *good_return, unsigned *dubious_return, unsigned *cached_return,
             unsigned *incoming_return) const;
     std::string getStorageLog() const;
+    std::string getStorageLog(const InfoHash&) const;
+
     std::string getRoutingTablesLog(sa_family_t) const;
     std::string getSearchesLog(sa_family_t) const;
 
@@ -416,6 +418,7 @@ private:
     bool storageStore(const InfoHash& id, const std::shared_ptr<Value>& value, time_point created);
     void expireStorage();
     void storageChanged(const InfoHash& id, Storage& st, ValueStorage&);
+    std::string printStorageLog(const decltype(store)::value_type&) const;
 
     /**
      * For a given storage, if values don't belong there anymore because this
diff --git a/include/opendht/dhtrunner.h b/include/opendht/dhtrunner.h
index c0fea590..c05a3c0a 100644
--- a/include/opendht/dhtrunner.h
+++ b/include/opendht/dhtrunner.h
@@ -279,6 +279,7 @@ public:
 
     std::vector<unsigned> getNodeMessageStats(bool in = false) const;
     std::string getStorageLog() const;
+    std::string getStorageLog(const InfoHash&) const;
     std::string getRoutingTablesLog(sa_family_t af) const;
     std::string getSearchesLog(sa_family_t af = 0) const;
     std::vector<SockAddr> getPublicAddress(sa_family_t af = 0);
diff --git a/src/dht.cpp b/src/dht.cpp
index caf19312..c315ea8d 100644
--- a/src/dht.cpp
+++ b/src/dht.cpp
@@ -2603,27 +2603,47 @@ Dht::dumpTables() const
 std::string
 Dht::getStorageLog() const
 {
-    const auto& now = scheduler.time();
-    using namespace std::chrono;
     std::stringstream out;
-    for (const auto& st : store) {
-        out << "Storage " << st.first << " "
-                          << st.second.listeners.size() << " list., "
-                          << st.second.valueCount() << " values ("
-                          << st.second.totalSize() << " bytes)" << std::endl;
-        if (not st.second.local_listeners.empty())
-            out << "   " << st.second.local_listeners.size() << " local listeners" << std::endl;
-        for (const auto& l : st.second.listeners) {
-            out << "   " << "Listener " << l.first->toString();
-            auto since = duration_cast<seconds>(now - l.second.time);
-            auto expires = duration_cast<seconds>(l.second.time + Node::NODE_EXPIRE_TIME - now);
-            out << " (since " << since.count() << "s, exp in " << expires.count() << "s)" << std::endl;
-        }
-    }
+    for (const auto& s : store)
+        out << printStorageLog(s);
     out << "Total " << store.size() << " storages, " << total_values << " values (" << (total_store_size/1024) << " KB)" << std::endl;
     return out.str();
 }
 
+std::string
+Dht::getStorageLog(const InfoHash& h) const
+{
+    auto s = store.find(h);
+    if (s == store.end()) {
+        std::stringstream out;
+        out << "Storage " << h << " empty" << std::endl;
+        return out.str();
+    }
+    return printStorageLog(*s);
+}
+
+std::string
+Dht::printStorageLog(const decltype(store)::value_type& s) const
+{
+    std::stringstream out;
+    using namespace std::chrono;
+    const auto& st = s.second;
+    out << "Storage " << s.first << " "
+                      << st.listeners.size() << " list., "
+                      << st.valueCount() << " values ("
+                      << st.totalSize() << " bytes)" << std::endl;
+    if (not st.local_listeners.empty())
+        out << "   " << st.local_listeners.size() << " local listeners" << std::endl;
+    const auto& now = scheduler.time();
+    for (const auto& l : st.listeners) {
+        out << "   " << "Listener " << l.first->toString();
+        auto since = duration_cast<seconds>(now - l.second.time);
+        auto expires = duration_cast<seconds>(l.second.time + Node::NODE_EXPIRE_TIME - now);
+        out << " (since " << since.count() << "s, exp in " << expires.count() << "s)" << std::endl;
+    }
+    return out.str();
+}
+
 std::string
 Dht::getRoutingTablesLog(sa_family_t af) const
 {
diff --git a/src/dhtrunner.cpp b/src/dhtrunner.cpp
index 5bb478f5..2d99e687 100644
--- a/src/dhtrunner.cpp
+++ b/src/dhtrunner.cpp
@@ -253,6 +253,12 @@ DhtRunner::getStorageLog() const
     return dht_->getStorageLog();
 }
 std::string
+DhtRunner::getStorageLog(const InfoHash& f) const
+{
+    std::lock_guard<std::mutex> lck(dht_mtx);
+    return dht_->getStorageLog(f);
+}
+std::string
 DhtRunner::getRoutingTablesLog(sa_family_t af) const
 {
     std::lock_guard<std::mutex> lck(dht_mtx);
diff --git a/tools/dhtnode.cpp b/tools/dhtnode.cpp
index 8d266e6d..698382ec 100644
--- a/tools/dhtnode.cpp
+++ b/tools/dhtnode.cpp
@@ -113,7 +113,12 @@ void cmd_loop(std::shared_ptr<DhtRunner>& dht, dht_params& params)
             std::cout << dht->getRoutingTablesLog(AF_INET6) << std::endl;
             continue;
         } else if (op == "ld") {
-            std::cout << dht->getStorageLog() << std::endl;
+            iss >> idstr;
+            InfoHash filter(idstr);
+            if (filter == InfoHash{})
+                std::cout << dht->getStorageLog() << std::endl;
+            else
+                std::cout << dht->getStorageLog(filter) << std::endl;
             continue;
         } else if (op == "ls") {
             std::cout << "Searches:" << std::endl;
-- 
GitLab