summaryrefslogtreecommitdiffstats
path: root/raul/Path.hpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2010-02-02 20:37:50 +0000
committerDavid Robillard <d@drobilla.net>2010-02-02 20:37:50 +0000
commit36573e798c986e298c62daabed6036b12ea0314d (patch)
treec908c681c6f584831366283bf7c099b36f94ff52 /raul/Path.hpp
parent53648252376649bca9868aec48ad4a290e3ae073 (diff)
downloadraul-36573e798c986e298c62daabed6036b12ea0314d.tar.gz
raul-36573e798c986e298c62daabed6036b12ea0314d.tar.bz2
raul-36573e798c986e298c62daabed6036b12ea0314d.zip
Use Glib string interning (quarks) to make Path/URI operator== very fast.
This avoids a ton of string comparison overhead in Ingen when setting various properties (e.g. "ingen:value" was compared several times every time a port value was changed, now this is just a single pointer comparison and the full round trip of a value change does no string comparison at all, but is still property based and RDFey). git-svn-id: http://svn.drobilla.net/lad/trunk/raul@2408 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'raul/Path.hpp')
-rw-r--r--raul/Path.hpp69
1 files changed, 38 insertions, 31 deletions
diff --git a/raul/Path.hpp b/raul/Path.hpp
index ffa8aa0..55f3926 100644
--- a/raul/Path.hpp
+++ b/raul/Path.hpp
@@ -58,10 +58,10 @@ public:
static const std::string scheme;
static const std::string prefix;
static const size_t prefix_len;
- static const std::string root_uri;
+ static const Path root;
/** Construct an uninitialzed path, because the STL is annoying. */
- Path() : URI(root_uri) {}
+ Path() : URI(root) {}
/** Construct a Path from an std::string.
*
@@ -99,60 +99,66 @@ public:
static void replace_invalid_chars(std::string& str, size_t start, bool replace_slash = false);
- bool is_root() const { return str() == root_uri; }
+ bool is_root() const { return (*this) == root; }
bool is_child_of(const Path& parent) const;
bool is_parent_of(const Path& child) const;
Path child(const std::string& s) const {
if (is_valid(s))
- return std::string(base()) + Path(s).chop_scheme().substr(1);
+ return base() + Path(s).chop_scheme().substr(1);
else
- return std::string(base()) + s;
+ return base() + s;
}
- Path operator+(const Path& p) const { return child(p); }
-
- /** Return the name of this object (everything after the last '/').
- * This is the "method name" for OSC paths.
- * The empty string may be returned (if the path is "/").
- */
- inline std::string name() const {
- if (str() == root_uri)
- return "";
- else
- return substr(find_last_of("/")+1);
+ Path child(const Path& p) const {
+ return base() + p.chop_scheme().substr(1);
}
+ Path operator+(const Path& p) const { return child(p); }
- /** Return the name of this object (everything after the last '/').
- * This is the "method name" for OSC paths.
- * Note it is illegal to call this method on the path "/".
+ /** Return the symbol of this path (everything after the last '/').
+ * This is e.g. the "method name" for OSC paths, the filename
+ * for filesystem paths, etc.
+ * The empty string may be returned (if the path is the root path).
*/
- inline Symbol symbol() const {
- return substr(find_last_of("/")+1);
+ inline const char* symbol() const {
+ if ((*this) != root) {
+ const char* last_slash = strrchr(c_str(), '/');
+ if (last_slash) {
+ return last_slash + 1;
+ }
+ }
+ return "";
}
-
/** Return the parent's path.
*
* Calling this on the path "/" will return "/".
* This is the (deepest) "container path" for OSC paths.
*/
inline Path parent() const {
- if (str() == root_uri) {
- return str();
+ if ((*this) == root) {
+ return *this;
} else {
- size_t last_slash = find_last_of("/");
- return (last_slash == prefix_len) ? root_uri : substr(0, last_slash);
+ const std::string str(this->str());
+ const size_t last_slash = str.find_last_of('/');
+ return (last_slash == prefix_len) ? root : str.substr(0, last_slash);
}
}
+ /** Return the path's child with the given name (symbol)
+ */
+ inline Path child(const Raul::Symbol& symbol) const {
+ return base() + symbol.c_str();
+ }
+
+
/** Return path relative to some base path (chop prefix)
*/
inline Path relative_to_base(const Path& base) const {
- if (str() == base) {
+ if ((*this) == base) {
return "/";
} else {
assert(length() > base.length());
@@ -167,10 +173,11 @@ public:
* child path can be made using parent.base() + child_name.
*/
inline const std::string base() const {
- if (str() == root_uri)
- return str();
+ std::string ret = str();
+ if ((*this) == root && ret[ret.length() - 1] == '/')
+ return ret;
else
- return str() + "/";
+ return ret + '/';
}
/** Return path with a trailing "/".
@@ -187,7 +194,7 @@ public:
static bool descendant_comparator(const Path& parent, const Path& child) {
return ( child == parent || (child.length() > parent.length() &&
(!std::strncmp(parent.c_str(), child.c_str(), parent.length())
- && (parent.str() == root_uri || child[parent.length()] == '/'))) );
+ && (parent == root || child.str()[parent.length()] == '/'))) );
}
};