summaryrefslogtreecommitdiffstats
path: root/control
diff options
context:
space:
mode:
Diffstat (limited to 'control')
-rw-r--r--control/zone.cpp87
-rw-r--r--control/zone.hpp35
2 files changed, 122 insertions, 0 deletions
diff --git a/control/zone.cpp b/control/zone.cpp
index 209d773..41ee0cc 100644
--- a/control/zone.cpp
+++ b/control/zone.cpp
@@ -479,6 +479,93 @@ void Zone::handleEvent(sdbusplus::message::message& msg,
});
}
+const std::string& Zone::getService(const std::string& path,
+ const std::string& intf)
+{
+ // Retrieve service from cache
+ auto srvIter = _servTree.find(path);
+ if (srvIter != _servTree.end())
+ {
+ for (auto& serv : srvIter->second)
+ {
+ auto it = std::find_if(
+ serv.second.begin(),
+ serv.second.end(),
+ [&intf](auto const& interface)
+ {
+ return intf == interface;
+ });
+ if (it != std::end(serv.second))
+ {
+ // Service found
+ return serv.first;
+ }
+ }
+ // Interface not found in cache, add and return
+ return addServices(path, intf, 0);
+ }
+ else
+ {
+ // Path not found in cache, add and return
+ return addServices(path, intf, 0);
+ }
+}
+
+const std::string& Zone::addServices(const std::string& path,
+ const std::string& intf,
+ int32_t depth)
+{
+ static const std::string empty = "";
+ auto it = _servTree.end();
+
+ // Get all subtree objects for the given interface
+ auto objects = util::SDBusPlus::getSubTree(_bus, "/", intf, depth);
+ // Add what's returned to the cache of path->services
+ for (auto& pIter : objects)
+ {
+ auto pathIter = _servTree.find(pIter.first);
+ if (pathIter != _servTree.end())
+ {
+ // Path found in cache
+ for (auto& sIter : pIter.second)
+ {
+ auto servIter = pathIter->second.find(sIter.first);
+ if (servIter != pathIter->second.end())
+ {
+ // Service found in cache
+ for (auto& iIter : sIter.second)
+ {
+ // Add interface to cache
+ servIter->second.emplace_back(iIter);
+ }
+ }
+ else
+ {
+ // Service not found in cache
+ pathIter->second.insert(sIter);
+ }
+ }
+ }
+ else
+ {
+ _servTree.insert(pIter);
+ }
+ // When the paths match, since a single interface constraint is given,
+ // that is the service to return
+ if (path == pIter.first)
+ {
+ it = _servTree.find(pIter.first);
+ }
+ }
+
+ if (it != _servTree.end())
+ {
+ return it->second.begin()->first;
+ }
+
+ return empty;
+}
+
}
}
}
diff --git a/control/zone.hpp b/control/zone.hpp
index 406af13..c047b62 100644
--- a/control/zone.hpp
+++ b/control/zone.hpp
@@ -382,6 +382,34 @@ class Zone
*/
void timerExpired(Group eventGroup, std::vector<Action> eventActions);
+ /**
+ * @brief Get the service for a given path and interface from cached
+ * dataset and add a service that's not found
+ *
+ * @param[in] path - Path to get service for
+ * @param[in] intf - Interface to get service for
+ *
+ * @return - The service name
+ */
+ const std::string& getService(const std::string& path,
+ const std::string& intf);
+
+ /**
+ * @brief Add a set of services for a path and interface
+ * by retrieving all the path subtrees to the given depth
+ * from root for the interface
+ *
+ * @param[in] path - Path to add services for
+ * @param[in] intf - Interface to add services for
+ * @param[in] depth - Depth of tree traversal from root path
+ *
+ * @return - The associated service to the given path and interface
+ * or empty string for no service found
+ */
+ const std::string& addServices(const std::string& path,
+ const std::string& intf,
+ int32_t depth);
+
private:
/**
@@ -508,6 +536,13 @@ class Zone
std::map<const Group, std::vector<Service>> _services;
/**
+ * @brief Map tree of paths to services of interfaces
+ */
+ std::map<std::string,
+ std::map<std::string,
+ std::vector<std::string>>> _servTree;
+
+ /**
* @brief List of signal event arguments and Dbus matches for callbacks
*/
std::vector<SignalEvent> _signalEvents;
OpenPOWER on IntegriCloud