Make it easy to find the paired filter when solving for time

We are doing an linear search to find the matched filter going the
other way.  This is kinda expensive today, but will get a lot more
expensive as we start to handle having only one (recent) direction when
solving.

Change-Id: I9f2a11db39d02104e34c20053216ef33e9d5bc39
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
diff --git a/aos/network/multinode_timestamp_filter.cc b/aos/network/multinode_timestamp_filter.cc
index 262cb5c..06cb526 100644
--- a/aos/network/multinode_timestamp_filter.cc
+++ b/aos/network/multinode_timestamp_filter.cc
@@ -82,22 +82,11 @@
     // another boot.  We wouldn't bother to build a problem to solve for
     // this node otherwise.  Confirm that is true so we at least get
     // notified if that assumption falls apart.
-    bool valid = false;
-    for (const struct FilterPair &other_filter :
-         clock_offset_filter_for_node_[filter.b_index]) {
-      if (other_filter.b_index == node_a) {
-        // Found our match.  Confirm it has timestamps.
-        if (other_filter.filter->timestamps_size(
-                base_clock_[filter.b_index].boot, base_clock_[node_a].boot) !=
-            0u) {
-          valid = true;
-        }
-        break;
-      }
-    }
-    if (!valid) {
+    if (filter.b_filter == nullptr) {
       return false;
     }
+    return (filter.b_filter->timestamps_size(base_clock_[filter.b_index].boot,
+                                             base_clock_[node_a].boot) != 0u);
   }
   return true;
 }
@@ -114,20 +103,9 @@
         // another boot.  We wouldn't bother to build a problem to solve for
         // this node otherwise.  Confirm that is true so we at least get
         // notified if that assumption falls apart.
-        bool valid = false;
-        for (const struct FilterPair &other_filter :
-             clock_offset_filter_for_node_[filter.b_index]) {
-          if (other_filter.b_index == i) {
-            // Found our match.  Confirm it has timestamps.
-            if (other_filter.filter->timestamps_size(
-                    base_clock_[filter.b_index].boot, base_clock_[i].boot) !=
-                0u) {
-              valid = true;
-            }
-            break;
-          }
-        }
-        if (!valid) {
+        if (filter.b_filter == nullptr ||
+            filter.b_filter->timestamps_size(base_clock_[filter.b_index].boot,
+                                             base_clock_[i].boot) == 0u) {
           Debug();
           LOG(FATAL) << "Found no timestamps in either direction between nodes "
                      << i << " and " << filter.b_index;
@@ -947,10 +925,10 @@
         configuration::GetNodeIndex(logged_configuration_, node_b);
 
     // TODO(austin): Do a better job documenting which node is which here.
-    filters_per_node_[node_a_index].emplace_back(x.GetFilter(node_a),
-                                                 node_b_index);
-    filters_per_node_[node_b_index].emplace_back(x.GetFilter(node_b),
-                                                 node_a_index);
+    filters_per_node_[node_a_index].emplace_back(
+        x.GetFilter(node_a), node_b_index, x.GetFilter(node_b));
+    filters_per_node_[node_b_index].emplace_back(
+        x.GetFilter(node_b), node_a_index, x.GetFilter(node_a));
     return &x;
   } else {
     return &it->second;
@@ -1302,7 +1280,7 @@
           all_live_nodes.Set(node_a_index, true);
           all_live_nodes.Set(filter.b_index, true);
           problem.add_clock_offset_filter(node_a_index, filter.filter,
-                                          filter.b_index);
+                                          filter.b_index, filter.b_filter);
 
           if (timestamp_mappers_[node_a_index] != nullptr) {
             // Now, we have cases at startup where we have a couple of points
diff --git a/aos/network/multinode_timestamp_filter.h b/aos/network/multinode_timestamp_filter.h
index f959d7b..77d5226 100644
--- a/aos/network/multinode_timestamp_filter.h
+++ b/aos/network/multinode_timestamp_filter.h
@@ -47,8 +47,10 @@
   //   filter[a_index]->Offset(ta) + ta => t(b_index);
   void add_clock_offset_filter(size_t a_index,
                                const NoncausalTimestampFilter *filter,
-                               size_t b_index) {
-    clock_offset_filter_for_node_[a_index].emplace_back(filter, b_index);
+                               size_t b_index,
+                               const NoncausalTimestampFilter *b_filter) {
+    clock_offset_filter_for_node_[a_index].emplace_back(filter, b_index,
+                                                        b_filter);
   }
 
   // Solves the optimization problem phrased using the symmetric Netwon's method
@@ -138,10 +140,13 @@
   // Filter and the node index it is referencing.
   //   filter->Offset(ta) + ta => t_(b_node);
   struct FilterPair {
-    FilterPair(const NoncausalTimestampFilter *my_filter, size_t my_b_index)
-        : filter(my_filter), b_index(my_b_index) {}
+    FilterPair(const NoncausalTimestampFilter *my_filter, size_t my_b_index,
+               const NoncausalTimestampFilter *b_filter)
+        : filter(my_filter), b_index(my_b_index), b_filter(b_filter) {}
     const NoncausalTimestampFilter *const filter;
     const size_t b_index;
+
+    const NoncausalTimestampFilter *const b_filter;
   };
 
   // List of filters indexed by node.
@@ -394,10 +399,12 @@
   // Filter and the node index it is referencing.
   //   filter->Offset(ta) + ta => t_(b_node);
   struct FilterPair {
-    FilterPair(NoncausalTimestampFilter *my_filter, size_t my_b_index)
-        : filter(my_filter), b_index(my_b_index) {}
+    FilterPair(NoncausalTimestampFilter *my_filter, size_t my_b_index,
+               NoncausalTimestampFilter *b_filter)
+        : filter(my_filter), b_index(my_b_index), b_filter(b_filter) {}
     NoncausalTimestampFilter *const filter;
     const size_t b_index;
+    NoncausalTimestampFilter *const b_filter;
   };
   std::vector<std::vector<FilterPair>> filters_per_node_;
 
diff --git a/aos/network/multinode_timestamp_filter_test.cc b/aos/network/multinode_timestamp_filter_test.cc
index c2a3b71..e1a4cd6 100644
--- a/aos/network/multinode_timestamp_filter_test.cc
+++ b/aos/network/multinode_timestamp_filter_test.cc
@@ -1,12 +1,12 @@
-#include "aos/network/timestamp_filter.h"
+#include "aos/network/multinode_timestamp_filter.h"
 
 #include <chrono>
 
 #include "aos/configuration.h"
 #include "aos/json_to_flatbuffer.h"
 #include "aos/macros.h"
-#include "aos/network/multinode_timestamp_filter.h"
 #include "aos/network/testing_time_converter.h"
+#include "aos/network/timestamp_filter.h"
 #include "gtest/gtest.h"
 
 namespace aos {
@@ -189,7 +189,7 @@
   const BootTimestamp me = BootTimestamp::epoch();
   const BootTimestamp me2{.boot = 1u, .time = monotonic_clock::epoch()};
 
-  //LOG(FATAL) << "TODO(austin): Test ToDistributedClock too";
+  // LOG(FATAL) << "TODO(austin): Test ToDistributedClock too";
 
   TestingTimeConverter time_converter(3u);
   size_t reboot_counter = 0;
@@ -361,8 +361,8 @@
   TimestampProblem problem(2);
   problem.set_base_clock(0, ta);
   problem.set_base_clock(1, e);
-  problem.add_clock_offset_filter(0, &a, 1);
-  problem.add_clock_offset_filter(1, &b, 0);
+  problem.add_clock_offset_filter(0, &a, 1, &b);
+  problem.add_clock_offset_filter(1, &b, 0, &a);
 
   problem.Debug();