+resource::StandardLinkImpl* NetZoneImpl::get_link_by_name_or_null(const std::string& name) const
+{
+ auto link_it = links_.find(name);
+ if (link_it != links_.end())
+ return link_it->second;
+
+ for (const auto* child : children_) {
+ auto* link = child->get_link_by_name_or_null(name);
+ if (link)
+ return link;
+ }
+
+ return nullptr;
+}
+
+resource::SplitDuplexLinkImpl* NetZoneImpl::get_split_duplex_link_by_name_or_null(const std::string& name) const
+{
+ auto link_it = split_duplex_links_.find(name);
+ if (link_it != split_duplex_links_.end())
+ return link_it->second.get();
+
+ for (const auto* child : children_) {
+ auto* link = child->get_split_duplex_link_by_name_or_null(name);
+ if (link)
+ return link;
+ }
+
+ return nullptr;
+}
+
+resource::HostImpl* NetZoneImpl::get_host_by_name_or_null(const std::string& name) const
+{
+ for (auto const& [_, host] : hosts_) {
+ if (host->get_name() == name)
+ return host;
+ /* keep old behavior where host and VMs were saved together on EngineImpl::hosts_
+ * get hosts returns VMs too */
+ auto* vm = host->get_vm_by_name_or_null(name);
+ if (vm)
+ return vm;
+ }
+
+ for (const auto* child : children_) {
+ auto* host = child->get_host_by_name_or_null(name);
+ if (host)
+ return host;
+ }
+
+ return nullptr;
+}
+
+std::vector<s4u::Host*> NetZoneImpl::get_filtered_hosts(const std::function<bool(s4u::Host*)>& filter) const
+{
+ std::vector<s4u::Host*> filtered_list;
+ for (auto const& [_, host] : hosts_) {
+ s4u::Host* h = host->get_iface();
+ if (filter(h))
+ filtered_list.push_back(h);
+ /* Engine::get_hosts returns the VMs too */
+ for (auto* vm : h->get_impl()->get_vms()) {
+ if (filter(vm))
+ filtered_list.push_back(vm);
+ }
+ }
+
+ for (const auto* child : children_) {
+ auto child_links = child->get_filtered_hosts(filter);
+ filtered_list.insert(filtered_list.end(), std::make_move_iterator(child_links.begin()),
+ std::make_move_iterator(child_links.end()));
+ }
+ return filtered_list;
+}
+