diff --git a/repos/gems/src/app/fs_query/for_each_subdir_name.h b/repos/gems/src/app/fs_query/for_each_subdir_name.h index 3a300f33bd..be20df8676 100644 --- a/repos/gems/src/app/fs_query/for_each_subdir_name.h +++ b/repos/gems/src/app/fs_query/for_each_subdir_name.h @@ -16,9 +16,7 @@ /* Genode includes */ #include - -/* local includes */ -#include +#include namespace Genode { @@ -31,43 +29,35 @@ template static void Genode::for_each_subdir_name(Allocator &alloc, Directory const &dir, FN const &fn) { - using Dirname = Directory::Entry::Name; + using Name = Directory::Entry::Name; - struct Name : Interface, private Dirname + struct Dirname : Dictionary::Element { - using Dirname::string; - - Name(Dirname const &name) : Dirname(name) { } - - bool higher(Name const &other) const - { - return (strcmp(other.string(), string()) > 0); - } + Dirname(Dictionary & dict, Name const & name) + : Dictionary::Element(dict, name) + { } }; - /* obtain list of sub directory names */ - Registry> names { }; + /* obtain dictionary of sub directory names */ + Dictionary names { }; dir.for_each_entry([&] (Directory::Entry const &entry) { if (entry.dir()) - new (alloc) Registered(names, entry.name()); }); + new (alloc) Dirname(names, entry.name()); }); - auto destroy_names = [&] () - { - names.for_each([&] (Registered &name) { - destroy(alloc, &name); }); - }; + auto destroy_element = [&] (Dirname &element) { + destroy(alloc, &element); }; - /* iterate over sorted list */ + /* iterate over dictionary */ try { - sorted_for_each(alloc, names, [&] (Name const &name) { - fn(name.string()); }); + names.for_each([&] (Dirname const &element) { + fn(element.name.string()); }); } catch (...) { - destroy_names(); + while (names.with_any_element(destroy_element)) { } throw; } - destroy_names(); + while (names.with_any_element(destroy_element)) { } } #endif /* _FOR_EACH_SUBDIR_NAME_H_ */ diff --git a/repos/gems/src/app/fs_query/main.cc b/repos/gems/src/app/fs_query/main.cc index 0d23332a93..2438c2484c 100644 --- a/repos/gems/src/app/fs_query/main.cc +++ b/repos/gems/src/app/fs_query/main.cc @@ -21,6 +21,7 @@ #include /* local includes */ +#include #include namespace Fs_query { @@ -39,10 +40,9 @@ struct Fs_query::Watched_file /** * Support for 'sorted_for_each' */ - bool higher(Watched_file const &other) const - { - return (strcmp(other._name.string(), _name.string()) > 0); - } + using Name = File_content::Path; + + Name const &name() const { return _name; } Node_rwx const _rwx; diff --git a/repos/gems/src/app/fs_query/sorted_for_each.h b/repos/gems/src/app/fs_query/sorted_for_each.h index a4f4c5dd05..ce27eae757 100644 --- a/repos/gems/src/app/fs_query/sorted_for_each.h +++ b/repos/gems/src/app/fs_query/sorted_for_each.h @@ -16,6 +16,7 @@ #include #include +#include namespace Genode { template @@ -26,55 +27,52 @@ namespace Genode { /** * Execute 'fn' for each registry element * - * The type T must be equipped with a method that defines the sort criterion: + * The type T must be equipped with a method name() and a type Name: * - * bool higher(T const &other) const + * const & Name name() const * - * It must implement a strict order over all registry elements. E.g., if the - * registry contains a set of names, no name must occur twice. The allocator - * passed as 'alloc' is used to for temporary allocations. + * The allocator passed as 'alloc' is used to for temporary allocations. */ template static inline void Genode::sorted_for_each(Allocator &alloc, Registry const ®istry, FN const &fn) { - struct Sorted_item : Avl_node + using Name = T::Name; + struct SortedItem : Dictionary::Element { T const &element; - Sorted_item(T const &element) : element(element) { } - - bool higher(Sorted_item const *item) const - { - return item ? element.higher(item->element) : false; - } + SortedItem(Dictionary & dict, Name const & name, T const & element) + : Dictionary::Element(dict, name), + element(element) + { } }; - /* build temporary AVL tree of sorted elements */ - Avl_tree sorted { }; + /* build temporary Dictionary of sorted and unique elements */ + using Dict = Dictionary; + Dict sorted { }; registry.for_each([&] (T const &element) { - sorted.insert(new (alloc) Sorted_item(element)); }); + /* skip duplicates */ + if (sorted.exists(element.name())) return; - auto destroy_sorted = [&] () - { - while (Sorted_item *item = sorted.first()) { - sorted.remove(item); - destroy(alloc, item); - } - }; + new (alloc) SortedItem(sorted, element.name(), element); + }); + + auto destroy_element = [&] (SortedItem &item) { + destroy(alloc, &item); }; /* iterate over sorted elements, 'fn' may throw */ try { - sorted.for_each([&] (Sorted_item const &item) { + sorted.for_each([&] (SortedItem const &item) { fn(item.element); }); } catch (...) { - destroy_sorted(); + while (sorted.with_any_element(destroy_element)) { } throw; } - destroy_sorted(); + while (sorted.with_any_element(destroy_element)) { } } #endif /* _SORTED_FOR_EACH_H_ */