From 3c3feab0d385a927e77e75485a6f9c0320c954d3 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 26 Mar 2017 19:10:45 +0200 Subject: Make Store keyed by URI instead of Path --- ingen/Store.hpp | 33 +++++++++++++++++++++------- src/ClashAvoider.cpp | 2 +- src/Serialiser.cpp | 16 ++++++++------ src/Store.cpp | 51 ++++++++++++-------------------------------- src/client/ClientStore.cpp | 4 ++-- src/gui/GraphCanvas.cpp | 16 ++++++++------ src/server/events/Delete.cpp | 2 +- 7 files changed, 62 insertions(+), 62 deletions(-) diff --git a/ingen/Store.hpp b/ingen/Store.hpp index d9a52102..1f0ca1c8 100644 --- a/ingen/Store.hpp +++ b/ingen/Store.hpp @@ -33,23 +33,38 @@ namespace Ingen { */ class INGEN_API Store : public Raul::Noncopyable , public Raul::Deletable - , public std::map< const Raul::Path, SPtr > { + , public std::map< const Raul::URI, SPtr > { public: void add(Node* o); - Node* get(const Raul::Path& path) { - const iterator i = find(path); + Node* get(const Raul::URI& uri) { + const iterator i = find(uri); return (i == end()) ? NULL : i->second.get(); } - typedef std::pair const_range; + Node* get(const Raul::Path& path) { return get(path_to_uri(path)); } + + const_iterator find(const Raul::Path& path) const { + return find(path_to_uri(path)); + } - typedef std::map< Raul::Path, SPtr > Objects; + iterator find(const Raul::Path& path) { + return find(path_to_uri(path)); + } - iterator find_descendants_end(Store::iterator parent); - const_iterator find_descendants_end(Store::const_iterator parent) const; + const_iterator find(const Raul::URI& uri) const { + return std::map< const Raul::URI, SPtr >::find(uri); + } - const_range children_range(SPtr o) const; + iterator find(const Raul::URI& uri) { + return std::map< const Raul::URI, SPtr >::find(uri); + } + + const_iterator find_first_child(SPtr o) const; + + typedef std::pair const_range; + + typedef std::map< Raul::URI, SPtr > Objects; /** Remove the object at `top` and all its children from the store. * @@ -75,6 +90,8 @@ public: Mutex& mutex() { return _mutex; } private: + iterator find_descendants_end(iterator parent); + Mutex _mutex; }; diff --git a/src/ClashAvoider.cpp b/src/ClashAvoider.cpp index 3c7ea827..6e9700fc 100644 --- a/src/ClashAvoider.cpp +++ b/src/ClashAvoider.cpp @@ -127,7 +127,7 @@ ClashAvoider::map_path(const Raul::Path& in) bool ClashAvoider::exists(const Raul::Path& path) const { - return _store.find(path) != _store.end(); + return _store.find(path_to_uri(path)) != _store.end(); } } // namespace Ingen diff --git a/src/Serialiser.cpp b/src/Serialiser.cpp index 70a1d286..c6d1bb59 100644 --- a/src/Serialiser.cpp +++ b/src/Serialiser.cpp @@ -356,10 +356,12 @@ Serialiser::Impl::serialise_graph(SPtr graph, std::set plugins; - const Store::const_range kids = _world.store()->children_range(graph); - for (Store::const_iterator n = kids.first; n != kids.second; ++n) { - if (n->first.parent() != graph->path()) + for (Store::const_iterator n = _world.store()->find_first_child(graph); + n != _world.store()->end() && n->first.is_child_of(graph->uri()); + ++n) { + if (uri_to_path(n->first).parent() != graph->path()) { continue; + } if (n->second->has_property(uris.rdf_type, uris.ingen_Graph)) { const SPtr subgraph = n->second; @@ -465,10 +467,12 @@ Serialiser::Impl::serialise_block(SPtr block, } } - const Store::const_range kids = _world.store()->children_range(block); - for (Store::const_iterator n = kids.first; n != kids.second; ++n) { - if (n->first.parent() != block->path()) + for (Store::const_iterator n = _world.store()->find_first_child(block); + n != _world.store()->end() && n->first.is_child_of(block->uri()); + ++n) { + if (uri_to_path(n->first).parent() != block->path()) { continue; + } if (n->second->has_property(uris.rdf_type, uris.lv2_InputPort) || n->second->has_property(uris.rdf_type, uris.lv2_InputPort)) { diff --git a/src/Store.cpp b/src/Store.cpp index e2f0f368..ba41bffc 100644 --- a/src/Store.cpp +++ b/src/Store.cpp @@ -25,24 +25,15 @@ namespace Ingen { void Store::add(Node* o) { - if (find(o->path()) != end()) { + if (find(o->uri()) != end()) { return; } - insert(make_pair(o->path(), SPtr(o))); + insert(make_pair(o->uri(), SPtr(o))); } -/* - TODO: These methods are currently O(n_children) but should logarithmic. The - std::map methods do not allow passing a comparator, but std::upper_bound - does. This should be achievable by making a rooted comparator that is a - normal ordering except compares a special sentinel value as the greatest - element that is a child of the parent. Searching for this sentinel should - then find the end of the descendants in logarithmic time. -*/ - Store::iterator -Store::find_descendants_end(const iterator parent) +Store::find_descendants_end(iterator parent) { iterator descendants_end = parent; ++descendants_end; @@ -55,28 +46,13 @@ Store::find_descendants_end(const iterator parent) } Store::const_iterator -Store::find_descendants_end(const const_iterator parent) const -{ - const_iterator descendants_end = parent; - ++descendants_end; - while (descendants_end != end() && - descendants_end->first.is_child_of(parent->first)) { - ++descendants_end; - } - - return descendants_end; -} - -Store::const_range -Store::children_range(SPtr o) const +Store::find_first_child(SPtr o) const { - const const_iterator parent = find(o->path()); - if (parent != end()) { - const_iterator first_child = parent; - ++first_child; - return std::make_pair(first_child, find_descendants_end(parent)); + const_iterator i = find(o->uri()); + if (i == end()) { + return i; } - return make_pair(end(), end()); + return ++i; } void @@ -92,7 +68,7 @@ Store::remove(const iterator top, Objects& removed) void Store::rename(const iterator top, const Raul::Path& new_path) { - const Raul::Path old_path = top->first; + const Raul::Path old_path = uri_to_path(top->first); // Remove the object and all its descendants Objects removed; @@ -100,14 +76,15 @@ Store::rename(const iterator top, const Raul::Path& new_path) // Rename all the removed objects for (Objects::const_iterator i = removed.begin(); i != removed.end(); ++i) { - const Raul::Path path = (i->first == old_path) + const Raul::Path old = uri_to_path(i->first); + const Raul::Path path = (old == old_path) ? new_path : new_path.child( - Raul::Path(i->first.substr(old_path.base().length() - 1))); + Raul::Path(old.substr(old_path.base().length() - 1))); i->second->set_uri(path_to_uri(path)); assert(find(path) == end()); // Shouldn't be dropping objects! - insert(make_pair(path, i->second)); + insert(make_pair(path_to_uri(path), i->second)); } } @@ -124,7 +101,7 @@ Store::child_name_offset(const Raul::Path& parent, if (offset > 0) { ss << "_" << offset; } - if (find(parent.child(Raul::Symbol(ss.str()))) == end() && + if (find(path_to_uri(parent.child(Raul::Symbol(ss.str())))) == end() && (allow_zero || offset > 0)) { break; } else if (offset == 0) { diff --git a/src/client/ClientStore.cpp b/src/client/ClientStore.cpp index a622068c..9f84f660 100644 --- a/src/client/ClientStore.cpp +++ b/src/client/ClientStore.cpp @@ -78,13 +78,13 @@ ClientStore::add_object(SPtr object) parent->add_child(object); assert(parent && (object->parent() == parent)); - (*this)[object->path()] = object; + (*this)[object->uri()] = object; _signal_new_object.emit(object); } else { _log.error(fmt("Object %1% with no parent\n") % object->path()); } } else { - (*this)[object->path()] = object; + (*this)[object->uri()] = object; _signal_new_object.emit(object); } } diff --git a/src/gui/GraphCanvas.cpp b/src/gui/GraphCanvas.cpp index e9224cfc..fa5ed149 100644 --- a/src/gui/GraphCanvas.cpp +++ b/src/gui/GraphCanvas.cpp @@ -235,13 +235,14 @@ GraphCanvas::build_menus() void GraphCanvas::build() { - const Store::const_range kids = _app.store()->children_range(_graph); - // Create modules for blocks - for (Store::const_iterator i = kids.first; i != kids.second; ++i) { - SPtr block = dynamic_ptr_cast(i->second); - if (block && block->parent() == _graph) + for (Store::const_iterator n = _app.store()->find_first_child(_graph); + n != _app.store()->end() && n->first.is_child_of(_graph->uri()); + ++n) { + SPtr block = dynamic_ptr_cast(n->second); + if (block && block->parent() == _graph) { add_block(block); + } } // Create pseudo modules for ports (ports on this canvas, not on our module) @@ -699,7 +700,7 @@ GraphCanvas::paste() float min_x = std::numeric_limits::max(); float min_y = std::numeric_limits::max(); for (const auto& c : clipboard) { - if (c.first.parent() == Raul::Path("/")) { + if (uri_to_path(c.first).parent() == Raul::Path("/")) { const Atom& x = c.second->get_property(uris.ingen_canvasX); const Atom& y = c.second->get_property(uris.ingen_canvasY); if (x.type() == uris.atom_Float) { @@ -723,7 +724,8 @@ GraphCanvas::paste() // Put each top level object in the clipboard store ClashAvoider avoider(*_app.store().get()); for (const auto& c : clipboard) { - if (c.first.is_root() || c.first.parent() != Raul::Path("/")) { + const Raul::Path path(uri_to_path(c.first)); + if (path.is_root() || path.parent() != Raul::Path("/")) { continue; } diff --git a/src/server/events/Delete.cpp b/src/server/events/Delete.cpp index b19ffd18..5683f3a4 100644 --- a/src/server/events/Delete.cpp +++ b/src/server/events/Delete.cpp @@ -165,7 +165,7 @@ Delete::post_process() void Delete::undo(Interface& target) { - auto i = _removed_objects.find(_path); + auto i = _removed_objects.find(_uri); if (i != _removed_objects.end()) { target.put(_uri, i->second->properties()); if (_disconnect_event) { -- cgit v1.2.1