Use bpf_get_first_key in C++ API
authorTeng Qin <qinteng@fb.com>
Tue, 16 May 2017 20:00:48 +0000 (13:00 -0700)
committerTeng Qin <qinteng@fb.com>
Thu, 18 May 2017 18:07:48 +0000 (11:07 -0700)
src/cc/BPFTable.h
tests/cc/test_hash_table.cc

index f2d2e3e8526289925cac208ef58ad0c94c0fb435..655e9332056ad6415fe9879cbf5bf762f2efde2b 100644 (file)
@@ -70,6 +70,11 @@ class BPFTableBase {
                            static_cast<void*>(value)) >= 0;
   }
 
+  bool first(KeyType* key) {
+    return bpf_get_first_key(desc.fd, static_cast<void*>(key),
+                             desc.key_size) >= 0;
+  }
+
   bool next(KeyType* key, KeyType* next_key) {
     return bpf_get_next_key(desc.fd, static_cast<void*>(key),
                             static_cast<void*>(next_key)) >= 0;
@@ -174,17 +179,18 @@ class BPFHashTable : public BPFTableBase<KeyType, ValueType> {
 
   std::vector<std::pair<KeyType, ValueType>> get_table_offline() {
     std::vector<std::pair<KeyType, ValueType>> res;
-
-    KeyType cur, nxt;
+    KeyType cur;
     ValueType value;
 
+    if (!this->first(&cur))
+      return res;
+
     while (true) {
-      if (!this->next(&cur, &nxt))
+      if (!this->lookup(&cur, &value))
         break;
-      if (!this->lookup(&nxt, &value))
+      res.emplace_back(cur, value);
+      if (!this->next(&cur, &cur))
         break;
-      res.emplace_back(nxt, value);
-      std::swap(cur, nxt);
     }
 
     return res;
index 8d95fda986c6137b2b6f40c9e386f34e5792d622..caa078080f6e9897d7c59581cb9bf19184d50491 100644 (file)
@@ -71,4 +71,17 @@ TEST_CASE("test hash table", "[hash_table]") {
     res = t.get_value(k, v2);
     REQUIRE(res.code() != 0);
   }
+
+  SECTION("walk table") {
+    for (int i = 1; i <= 10; i++) {
+      res = t.update_value(i * 3, i);
+      REQUIRE(res.code() == 0);
+    }
+    auto offline = t.get_table_offline();
+    REQUIRE(offline.size() == 10);
+    for (const auto &pair : offline) {
+      REQUIRE(pair.first % 3 == 0);
+      REQUIRE(pair.first / 3 == pair.second);
+    }
+  }
 }