Add SourceNodeIndex to compute the source node per channel

We keep doing this type of thing.  Time to go write a function.  Doing a
bunch of string compares is slow, so we should really cache it up front.

It feels like it might be getting close to time to try to write a class
which will let us compute and cache all these things reasonably
efficiently and move logger and others over to it.  Let's start with a
function to compute the things we care about.

Change-Id: I4b788b1395656e8e6e6c3c7eb28f4d410080c636
Signed-off-by: Austin Schuh <austin.schuh@bluerivertech.com>
diff --git a/aos/configuration.cc b/aos/configuration.cc
index c2e42c9..d794a37 100644
--- a/aos/configuration.cc
+++ b/aos/configuration.cc
@@ -1261,5 +1261,18 @@
   return nullptr;
 }
 
+std::vector<size_t> SourceNodeIndex(const Configuration *config) {
+  CHECK(config->has_channels());
+  std::vector<size_t> result;
+  result.resize(config->channels()->size(), 0u);
+  if (MultiNode(config)) {
+    for (size_t i = 0; i < config->channels()->size(); ++i) {
+      result[i] = GetNodeIndex(
+          config, config->channels()->Get(i)->source_node()->string_view());
+    }
+  }
+  return result;
+}
+
 }  // namespace configuration
 }  // namespace aos
diff --git a/aos/configuration.h b/aos/configuration.h
index c22a1cf..f9b772d 100644
--- a/aos/configuration.h
+++ b/aos/configuration.h
@@ -156,6 +156,9 @@
 std::vector<std::string_view> SourceNodeNames(const Configuration *config,
                                               const Node *my_node);
 
+// Returns the source node index for each channel in a config.
+std::vector<size_t> SourceNodeIndex(const Configuration *config);
+
 // Returns the all nodes that are logging timestamps on our node.
 std::vector<const Node *> TimestampNodes(const Configuration *config,
                                          const Node *my_node);
diff --git a/aos/configuration_test.cc b/aos/configuration_test.cc
index ff991a2..c650a5d 100644
--- a/aos/configuration_test.cc
+++ b/aos/configuration_test.cc
@@ -857,6 +857,15 @@
   EXPECT_EQ(nullptr, GetNodeFromHostname(&config.message(), "3"));
 }
 
+// Tests that SourceNodeIndex reasonably handles a multi-node log file.
+TEST_F(ConfigurationTest, SourceNodeIndex) {
+  FlatbufferDetachedBuffer<Configuration> config =
+      ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
+  std::vector<size_t> result = SourceNodeIndex(&config.message());
+
+  EXPECT_THAT(result, ::testing::ElementsAreArray({0, 1, 0, 0}));
+}
+
 }  // namespace testing
 }  // namespace configuration
 }  // namespace aos
diff --git a/aos/testdata/good_multinode.json b/aos/testdata/good_multinode.json
index 109ffb8..38d57b8 100644
--- a/aos/testdata/good_multinode.json
+++ b/aos/testdata/good_multinode.json
@@ -17,6 +17,12 @@
       "type": ".aos.baz",
       "max_size": 5,
       "source_node": "pi1"
+    },
+    {
+      "name": "/cat",
+      "type": ".aos.baz",
+      "max_size": 5,
+      "source_node": "pi2"
     }
   ],
   "maps": [