Add reverse name lookup for channels
This makes it so that if you know the fully-resolved channel name you
can figure out all the possible ways that it can be referred to. This is
potentially useful for a variety of things, including:
* Config validation (e.g. identifying all the channels that exist
on the /aos/remote_timestamp/* namespace, to determine if there are
any extraneous channels).
* Improving auto-complete for command-line utilities.
* Adding more options for how channel names are presented in
log-analysis tools (e.g., currently foxglove doesn't support the
concept of channel maps/aliases/whatever, so making node-agnostic
plots is irritating).
Change-Id: I334881199ad6b300a97f96d4a427ae25e55fa15f
Signed-off-by: James Kuszmaul <jabukuszmaul+collab@gmail.com>
diff --git a/aos/configuration.cc b/aos/configuration.cc
index ed99e2a..d05cba8 100644
--- a/aos/configuration.cc
+++ b/aos/configuration.cc
@@ -458,6 +458,58 @@
}
}
+void HandleReverseMaps(
+ const flatbuffers::Vector<flatbuffers::Offset<aos::Map>> *maps,
+ std::string_view type, const Node *node, std::set<std::string> *names) {
+ for (const Map *map : *maps) {
+ CHECK_NOTNULL(map);
+ const Channel *const match = CHECK_NOTNULL(map->match());
+ const Channel *const rename = CHECK_NOTNULL(map->rename());
+
+ // Handle type specific maps.
+ const flatbuffers::String *const match_type_string = match->type();
+ if (match_type_string != nullptr &&
+ match_type_string->string_view() != type) {
+ continue;
+ }
+
+ // Now handle node specific maps.
+ const flatbuffers::String *const match_source_node_string =
+ match->source_node();
+ if (node != nullptr && match_source_node_string != nullptr &&
+ match_source_node_string->string_view() !=
+ node->name()->string_view()) {
+ continue;
+ }
+
+ const flatbuffers::String *const match_name_string = match->name();
+ const flatbuffers::String *const rename_name_string = rename->name();
+ if (match_name_string == nullptr || rename_name_string == nullptr) {
+ continue;
+ }
+
+ const std::string rename_name = rename_name_string->str();
+ const std::string_view match_name = match_name_string->string_view();
+
+ std::set<std::string> possible_renames;
+
+ // Check if the current name(s) could have been reached using the provided
+ // rename.
+ if (match_name.back() == '*') {
+ for (const std::string &option : *names) {
+ if (option.substr(0, rename_name.size()) == rename_name) {
+ possible_renames.insert(
+ absl::StrCat(match_name.substr(0, match_name.size() - 1),
+ option.substr(rename_name.size())));
+ }
+ }
+ names->insert(possible_renames.begin(), possible_renames.end());
+ } else if (names->count(rename_name) != 0) {
+ names->insert(std::string(match_name));
+ }
+ }
+}
+
} // namespace
// Maps name for the provided maps. Modifies name.
@@ -466,6 +518,9 @@
// pointers. These combine to make it a performance hotspot during many tests
// under msan, so there is some optimizing around caching intermediates instead
// of dereferencing the pointer multiple times.
+//
+// Deliberately not in an anonymous namespace so that the log-reading code can
+// reference it.
void HandleMaps(const flatbuffers::Vector<flatbuffers::Offset<aos::Map>> *maps,
std::string *name, std::string_view type, const Node *node) {
// For the same reason we merge configs in reverse order, we want to process
@@ -527,6 +582,25 @@
}
}
+std::set<std::string> GetChannelAliases(const Configuration *config,
+ std::string_view name,
+ std::string_view type,
+ const std::string_view application_name,
+ const Node *node) {
+ std::set<std::string> names{std::string(name)};
+ if (config->has_maps()) {
+ HandleReverseMaps(config->maps(), type, node, &names);
+ }
+ {
+ const Application *application =
+ GetApplication(config, node, application_name);
+ if (application != nullptr && application->has_maps()) {
+ HandleReverseMaps(application->maps(), type, node, &names);
+ }
+ }
+ return names;
+}
+
FlatbufferDetachedBuffer<Configuration> MergeConfiguration(
const Flatbuffer<Configuration> &config) {
// auto_merge_config will contain all the fields of the Configuration that are