Skip to content

Commit

Permalink
Uri|Refactor: Integrated PathMap functionality
Browse files Browse the repository at this point in the history
The PathMap class implemented a string subsection map, allowing said
subsections (named "fragments") to be more easily referenced without
dynamically allocating a bunch of additional strings or passing around
pairs of indices. These "fragments" of also incorporated a name hash
cache which was used to accelerate file system performance.

Uri now incorporates all previous functionality of PathMap.

The redundant PathMap has now been dumped (there is no longer a need
for this as an independent class given there are better alternatives
available in Qt).

Todo: Revise the implementation (Qt's QStringRef should be useful).
Todo: Cleanup.
  • Loading branch information
danij-deng committed Nov 11, 2012
1 parent 0a727d9 commit 22a28ab
Show file tree
Hide file tree
Showing 17 changed files with 506 additions and 626 deletions.
72 changes: 67 additions & 5 deletions doomsday/engine/api/uri.h
Expand Up @@ -63,6 +63,9 @@
#define DEFAULT_PRINTURIFLAGS (UPF_OUTPUT_RESOLVED|UPF_TRANSFORM_PATH_MAKEPRETTY)
///@}

// Range of the fragment hash.
#define URI_PATHNODE_NAMEHASH_SIZE 512

#ifdef __cplusplus
#ifndef DENG2_C_API_ONLY

Expand All @@ -83,7 +86,12 @@ namespace de
*/
class Uri : public LogEntry::Arg::Base
{
struct Instance; // needs to be friended by PathNode

public:
/// A nonexistent path node was referenced. @ingroup errors
DENG2_ERROR(NotPathNodeError);

/// Base class for resolve-related errors. @ingroup errors
DENG2_ERROR(ResolveError);

Expand All @@ -93,6 +101,40 @@ namespace de
/// An unresolveable symbol was encountered in the embedded expression. @ingroup errors
DENG2_SUB_ERROR(ResolveError, ResolveSymbolError);

/**
* This is a hash function. It generates from @a name a somewhat-random
* number between @c 0 and @c URI_PATHNODE_NAMEHASH_SIZE
*
* @return The generated hash key.
*/
static ushort hashPathNodeName(char const* name, int len);

/**
* Path Node represents a name in the URI path hierarchy.
*/
struct PathNode
{
/// @return Hash for this node's name.
ushort hash();

/// @return Length of this node's name in characters.
int length() const;

/// @return Parent of this node else @c NULL.
PathNode* parent() const;

String toString() const;

friend class Uri;
friend struct Uri::Instance;

private:
bool haveHash;
ushort hash_;
char const* from, *to;
struct PathNode* parent_;
};

public:
/**
* Construct a default (empty) Uri instance.
Expand All @@ -108,7 +150,7 @@ namespace de
* is not @c RC_NULL, ask the resource locator whether it knows of an
* appropriate default scheme for this class of resource.
*/
Uri(String path, resourceclass_t defaultResourceClass = RC_UNKNOWN);
Uri(String path, resourceclass_t defaultResourceClass = RC_UNKNOWN, QChar delimiter = '/');

/**
* Construct a Uri instance by duplicating @a other.
Expand Down Expand Up @@ -170,7 +212,7 @@ namespace de
/**
* Change the path to @a newPath.
*/
Uri& setPath(String newPath);
Uri& setPath(String newPath, QChar delimiter = '/');

/**
* Update this uri by parsing new values from the specified arguments.
Expand All @@ -181,7 +223,8 @@ namespace de
* is not @c RC_NULL, ask the resource locator whether it knows of an
* appropriate default scheme for this class of resource.
*/
Uri& setUri(String newUri, resourceclass_t defaultResourceClass = RC_UNKNOWN);
Uri& setUri(String newUri, resourceclass_t defaultResourceClass = RC_UNKNOWN,
QChar delimiter = '/');

/**
* Compose from this uri a plain-text representation. Any internal encoding
Expand All @@ -190,7 +233,27 @@ namespace de
*
* @return Plain-text String representation.
*/
String compose() const;
String compose(QChar delimiter = '/') const;

/// @return Number of nodes in the path.
int pathNodeCount() const;

/**
* Retrieve the path node with index @a idx. Note that path nodes are indexed
* in reverse order (right to left) and NOT the autological left to right order.
*
* For example, if the path is "c:/mystuff/myaddon.addon" the corresponding
* path node map is arranged as follows:
* <pre>
* [0:{myaddon.addon}, 1:{mystuff}, 2:{c:}].
* </pre>
*
* @param index Reverse-index of the path node to be retrieved. Note that
* index @c 0 is always valid.
*
* @return Referenced path node.
*/
PathNode& pathNode(int index) const;

/**
* Transform the uri into a human-friendly representation. Percent decoding done.
Expand Down Expand Up @@ -231,7 +294,6 @@ namespace de
String unresolvedText = "") const;

private:
struct Instance;
Instance* d;
};

Expand Down
2 changes: 0 additions & 2 deletions doomsday/engine/engine.pro
Expand Up @@ -268,7 +268,6 @@ DENG_HEADERS += \
portable/include/p_polyobjs.h \
portable/include/p_sight.h \
portable/include/p_ticker.h \
portable/include/pathmap.h \
portable/include/pathtree.h \
portable/include/plane.h \
portable/include/polyobj.h \
Expand Down Expand Up @@ -555,7 +554,6 @@ SOURCES += \
portable/src/p_sight.c \
portable/src/p_think.c \
portable/src/p_ticker.c \
portable/src/pathmap.cpp \
portable/src/pathtree.cpp \
portable/src/pathtreenode.cpp \
portable/src/plane.c \
Expand Down
157 changes: 0 additions & 157 deletions doomsday/engine/portable/include/pathmap.h

This file was deleted.

40 changes: 15 additions & 25 deletions doomsday/engine/portable/include/pathtree.h
Expand Up @@ -35,7 +35,6 @@
#include <de/Error>
#include <de/String>
#include <de/str.h>
#include "pathmap.h"
#include "uri.h"

/**
Expand All @@ -51,20 +50,17 @@
(i.e., relative) matches. */
///@}

// Number of buckets in the hash table.
#define PATHTREE_PATHHASH_SIZE 512

/// Identifier used with the search and iteration algorithms in place of a
/// hash when the caller does not wish to narrow the set of considered nodes.
#define PATHTREE_NOHASH PATHTREE_PATHHASH_SIZE

/**
* @defgroup pathTreeFlags Path Tree Flags
*/
///@{
#define PATHTREE_MULTI_LEAF 0x1 ///< There can be more than one leaf with a given name.
///@}

/// Identifier used with the search and iteration algorithms in place of a
/// hash when the caller does not wish to narrow the set of considered nodes.
#define PATHTREE_NOHASH URI_PATHNODE_NAMEHASH_SIZE

namespace de
{
/**
Expand Down Expand Up @@ -108,14 +104,6 @@ namespace de
/// @return Print-ready name for node @a type.
static String const& nodeTypeName(NodeType type);

/**
* This is a hash function. It uses the path fragment string to generate a
* somewhat-random number between @c 0 and @c PATHTREE_PATHHASH_SIZE
*
* @return The generated hash key.
*/
static ushort hashPathFragment(char const* fragment, size_t len, char delimiter = '/');

#if _DEBUG
static void debugPrint(PathTree& pathtree, QChar delimiter = '/');
static void debugPrintHashDistribution(PathTree& pathtree);
Expand Down Expand Up @@ -164,7 +152,7 @@ namespace de
* allow for further optimizations elsewhere (in the file system
* for example) -ds
*/
int comparePath(PathMap& candidatePath, int flags) const;
int comparePath(de::Uri& candidatePath, int flags) const;

/**
* Composes the URI for this node. 'Composing' the path of a node is to
Expand Down Expand Up @@ -289,21 +277,23 @@ namespace de
int findAllPaths(FoundPaths& found, int flags = 0, QChar delimiter = '/');

/**
* Iterate over nodes in the hierarchy making a callback for each. Iteration ends
* when all nodes have been visited or a callback returns non-zero.
* Traverse the node hierarchy making a callback for visited node. Traversal
* ends when all selected nodes have been visited or a callback returns a
* non-zero value.
*
* @param flags @ref pathComparisonFlags
* @param parent Parent node reference, used when restricting processing
* to the child nodes of this node. Only used when the flag
* PCF_MATCH_PARENT is set in @a flags.
* @param hash If not @c PATHTREE_NOHASH only consider nodes whose hashed
* name matches this.
* @param parent Used in combination with @a flags= PCF_MATCH_PARENT
* to limit the traversal to only the child nodes of
* this node.
* @param hash If not @c PATHTREE_NOHASH only consider nodes whose
* hashed name matches this.
* @param callback Callback function ptr.
* @param parameters Passed to the callback.
*
* @return @c 0 iff iteration completed wholly.
*/
int iterate(int flags, Node* parent, ushort hash, int (*callback) (Node& node, void* parameters), void* parameters = 0);
int traverse(int flags, Node* parent, ushort hash, int (*callback) (Node& node, void* parameters),
void* parameters = 0);

/**
* Provides access to the nodes for efficent traversals.
Expand Down

0 comments on commit 22a28ab

Please sign in to comment.