diff options
-rw-r--r-- | control/zone.cpp | 87 | ||||
-rw-r--r-- | control/zone.hpp | 35 |
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; |