You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by tr...@apache.org on 2016/11/23 13:56:46 UTC

[3/3] qpid-dispatch git commit: DISPATCH-568 - Cleanup of the iterator module - Renamed type and methods to qd_iterator_* (removed field/address hierarchy) - Organized the header/API around lifecycle, usage, annotation, and hashing - Added namespac

DISPATCH-568 - Cleanup of the iterator module
  - Renamed type and methods to qd_iterator_* (removed field/address hierarchy)
  - Organized the header/API around lifecycle, usage, annotation, and hashing
  - Added namespace support
  - Added tests
  - Moved the parse tests into the buffer-size-specific unit test set


Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/6a783b07
Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/6a783b07
Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/6a783b07

Branch: refs/heads/master
Commit: 6a783b07fab75e92f0b0e2db86f6a9cec388d44b
Parents: 456f618
Author: Ted Ross <tr...@redhat.com>
Authored: Wed Nov 23 08:50:47 2016 -0500
Committer: Ted Ross <tr...@redhat.com>
Committed: Wed Nov 23 08:50:47 2016 -0500

----------------------------------------------------------------------
 include/qpid/dispatch/compose.h           |   4 +-
 include/qpid/dispatch/hash.h              |  14 +-
 include/qpid/dispatch/iterator.h          | 300 ++++++++-----
 include/qpid/dispatch/message.h           |   4 +-
 include/qpid/dispatch/parse.h             |   8 +-
 include/qpid/dispatch/router.h            |   8 +-
 include/qpid/dispatch/router_core.h       |  18 +-
 src/compose.c                             |  20 +-
 src/container.c                           |  65 +--
 src/hash.c                                |  40 +-
 src/iterator.c                            | 588 +++++++++++++------------
 src/message.c                             |  28 +-
 src/parse.c                               | 122 ++---
 src/python_embedded.c                     |  22 +-
 src/router_config.c                       |  40 +-
 src/router_core/agent.c                   |  44 +-
 src/router_core/agent_address.c           |  10 +-
 src/router_core/agent_address.h           |   6 +-
 src/router_core/agent_config_address.c    |  52 +--
 src/router_core/agent_config_address.h    |  16 +-
 src/router_core/agent_config_auto_link.c  |  42 +-
 src/router_core/agent_config_auto_link.h  |  16 +-
 src/router_core/agent_config_link_route.c |  46 +-
 src/router_core/agent_config_link_route.h |  16 +-
 src/router_core/agent_link.c              |  22 +-
 src/router_core/agent_link.h              |   4 +-
 src/router_core/connections.c             |  38 +-
 src/router_core/error.c                   |   8 +-
 src/router_core/forwarder.c               |   8 +-
 src/router_core/management_agent.c        |  72 +--
 src/router_core/route_control.c           |  32 +-
 src/router_core/route_control.h           |   4 +-
 src/router_core/route_tables.c            |  24 +-
 src/router_core/router_core.c             |  30 +-
 src/router_core/router_core_private.h     |  16 +-
 src/router_core/terminus.c                |  10 +-
 src/router_core/transfer.c                |  10 +-
 src/router_node.c                         |  48 +-
 src/trace_mask.c                          |   8 +-
 tests/CMakeLists.txt                      |   2 +-
 tests/field_test.c                        | 456 ++++++++++++-------
 tests/message_test.c                      |  26 +-
 tests/parse_test.c                        |  99 ++++-
 tests/run_unit_tests.c                    |   2 -
 tests/run_unit_tests_size.c               |   2 +
 45 files changed, 1376 insertions(+), 1074 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/include/qpid/dispatch/compose.h
----------------------------------------------------------------------
diff --git a/include/qpid/dispatch/compose.h b/include/qpid/dispatch/compose.h
index 956900c..00d505e 100644
--- a/include/qpid/dispatch/compose.h
+++ b/include/qpid/dispatch/compose.h
@@ -190,7 +190,7 @@ void qd_compose_insert_string(qd_composed_field_t *field, const char *value);
  * @param iter An iterator for a string value.  The caller is responsible for freeing
  *        this iterator after the call is complete.
  */
-void qd_compose_insert_string_iterator(qd_composed_field_t *field, qd_field_iterator_t *iter);
+void qd_compose_insert_string_iterator(qd_composed_field_t *field, qd_iterator_t *iter);
 
 /**
  * Insert a symbol into the field.
@@ -207,7 +207,7 @@ void qd_compose_insert_symbol(qd_composed_field_t *field, const char *value);
  * @param iter An iterator for a typed value.  The caller is responsible for freeing
  *        this iterator after the call is complete.
  */
-void qd_compose_insert_typed_iterator(qd_composed_field_t *field, qd_field_iterator_t *iter);
+void qd_compose_insert_typed_iterator(qd_composed_field_t *field, qd_iterator_t *iter);
 
 /**
  * Begin composing a new sub field that can be appended to a composed field.

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/include/qpid/dispatch/hash.h
----------------------------------------------------------------------
diff --git a/include/qpid/dispatch/hash.h b/include/qpid/dispatch/hash.h
index aaedc0b..7b9b3ec 100644
--- a/include/qpid/dispatch/hash.h
+++ b/include/qpid/dispatch/hash.h
@@ -34,11 +34,11 @@ qd_hash_t *qd_hash(int bucket_exponent, int batch_size, int value_is_const);
 void qd_hash_free(qd_hash_t *h);
 
 size_t qd_hash_size(qd_hash_t *h);
-qd_error_t qd_hash_insert(qd_hash_t *h, qd_field_iterator_t *key, void *val, qd_hash_handle_t **handle);
-qd_error_t qd_hash_insert_const(qd_hash_t *h, qd_field_iterator_t *key, const void *val, qd_hash_handle_t **handle);
-qd_error_t qd_hash_retrieve(qd_hash_t *h, qd_field_iterator_t *key, void **val);
-qd_error_t qd_hash_retrieve_const(qd_hash_t *h, qd_field_iterator_t *key, const void **val);
-qd_error_t qd_hash_remove(qd_hash_t *h, qd_field_iterator_t *key);
+qd_error_t qd_hash_insert(qd_hash_t *h, qd_iterator_t *key, void *val, qd_hash_handle_t **handle);
+qd_error_t qd_hash_insert_const(qd_hash_t *h, qd_iterator_t *key, const void *val, qd_hash_handle_t **handle);
+qd_error_t qd_hash_retrieve(qd_hash_t *h, qd_iterator_t *key, void **val);
+qd_error_t qd_hash_retrieve_const(qd_hash_t *h, qd_iterator_t *key, const void **val);
+qd_error_t qd_hash_remove(qd_hash_t *h, qd_iterator_t *key);
 
 void qd_hash_handle_free(qd_hash_handle_t *handle);
 const unsigned char *qd_hash_key_by_handle(const qd_hash_handle_t *handle);
@@ -57,12 +57,12 @@ qd_error_t qd_hash_remove_by_handle2(qd_hash_t *h, qd_hash_handle_t *handle, uns
  * @param iter An iterator containing the address string to search on.
  * @param **val The qd_address_t value if there is a full or prefix match.
  */
-void qd_hash_retrieve_prefix(qd_hash_t *h, qd_field_iterator_t *iter, void **val);
+void qd_hash_retrieve_prefix(qd_hash_t *h, qd_iterator_t *iter, void **val);
 
 /**
  * Same as qd_hash_retrieve_prefix but returns the value as a constant which cannot be modified.
  * @see qd_hash_retrieve_prefix
  */
-void qd_hash_retrieve_prefix_const(qd_hash_t *h, qd_field_iterator_t *iter, const void **val);
+void qd_hash_retrieve_prefix_const(qd_hash_t *h, qd_iterator_t *iter, const void **val);
 
 #endif

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/include/qpid/dispatch/iterator.h
----------------------------------------------------------------------
diff --git a/include/qpid/dispatch/iterator.h b/include/qpid/dispatch/iterator.h
index b2669ef..ad7b7f9 100644
--- a/include/qpid/dispatch/iterator.h
+++ b/include/qpid/dispatch/iterator.h
@@ -24,9 +24,9 @@
 #include <qpid/dispatch/buffer.h>
 #include <qpid/dispatch/iovec.h>
 
+
 /**@file
- * Iterate over message buffer chains and addresse fields.
- *
+ * Iterate over message buffer chains and address fields.
  *
  * @defgroup iterator iterator
  *
@@ -38,34 +38,30 @@
  *
  * @{
  */
-typedef struct qd_field_iterator_t qd_field_iterator_t;
+
+/** \name typedef
+ * Type Definitions
+ * @{
+ */
+typedef struct qd_iterator_t qd_iterator_t;
+
 
 /**
+ * qd_iterator_view_t
+ *
  * Type of iterator view. Iterator views allow the code traversing an address
  * field to see a transformed view of the raw field.
  *
  * ITER_VIEW_ALL - No transformation of the raw field data
  *
- * ITER_VIEW_NO_HOST - Remove the scheme and host fields from the view
- *
- *     amqp://host.domain.com:port/node-id/node/specific
- *                                 ^^^^^^^^^^^^^^^^^^^^^
- *     node-id/node/specific
- *     ^^^^^^^^^^^^^^^^^^^^^
- *
- * ITER_VIEW_NODE_ID - Isolate the node identifier from an address
- *
- *     amqp://host.domain.com:port/node-id/node/specific
- *                                ^^^^^^^
- *     node-id/node/specific
- *     ^^^^^^^
- *
- * ITER_VIEW_NODE_SPECIFIC - Isolate node-specific text from an address
+ * ITER_VIEW_ADDRESS_NO_HOST - Remove the scheme and host fields from the view
  *
- *     amqp://host.domain.com:port/node-id/node/specific
- *                                         ^^^^^^^^^^^^^
- *     node-id/node/specific
- *             ^^^^^^^^^^^^^
+ *     amqp://host.domain.com:port/other/address/text
+ *                                 ^^^^^^^^^^^^^^^^^^
+ *     amqp:/other/address/text
+ *           ^^^^^^^^^^^^^^^^^^
+ *     other/address/text
+ *     ^^^^^^^^^^^^^^^^^^
  *
  * ITER_VIEW_ADDRESS_HASH - Isolate the hashable part of the address depending on address syntax
  *
@@ -97,118 +93,150 @@ typedef struct qd_field_iterator_t qd_field_iterator_t;
  */
 typedef enum {
     ITER_VIEW_ALL,
-    ITER_VIEW_NO_HOST,
-    ITER_VIEW_NODE_ID,
-    ITER_VIEW_NODE_SPECIFIC,
+    ITER_VIEW_ADDRESS_NO_HOST,
     ITER_VIEW_ADDRESS_HASH,
     ITER_VIEW_NODE_HASH
 } qd_iterator_view_t;
 
+/** @} */
+/** \name global
+ * Global Methods
+ * @{
+ */
 
 /**
- * Create an iterator from a null-terminated string.
+ * Set the area and router names for the local router.  These are used to match
+ * my-area and my-router in address fields.  These settings are global and used
+ * for all iterators in the process.
  *
- * The "text" string must stay intact for the whole life of the iterator.  The iterator
- * does not copy the string, it references it.
+ * @param area The name of the router's area
+ * @param router The identifier of the router in the area
  */
-qd_field_iterator_t* qd_address_iterator_string(const char         *text,
-                                                qd_iterator_view_t  view);
+void qd_iterator_set_address(const char *area, const char *router);
 
-static inline qd_field_iterator_t* qd_field_iterator_string(const char *text)
-{
-    return qd_address_iterator_string(text, ITER_VIEW_ALL);
-}
+/** @} */
+/** \name lifecycle
+ * Methods to control iterator lifecycle
+ * @{
+ */
 
+/**
+ * Create an iterator for a null-terminated string.
+ *
+ * The "text" string must stay intact for the whole life of the iterator.  The iterator
+ * does not copy the string, it references it.
+ *
+ * @param text A null-terminated character string
+ * @param view The view for the iterator
+ * @return A newly allocated iterator that references the text string.
+ */
+qd_iterator_t* qd_iterator_string(const char         *text,
+                                  qd_iterator_view_t  view);
 
 /**
  * Create an iterator from binary data.
  *
  * The "text" string must stay intact for the whole life of the iterator.  The iterator
  * does not copy the data, it references it.
+ *
+ * @param text Pointer to the first octet in an octet string
+ * @param length Number of octets in the contiguous octet string
+ * @param view The view for the iterator
+ * @return A newly allocated iterator that references the octet string.
  */
-qd_field_iterator_t* qd_address_iterator_binary(const char         *text,
-                                                int                 length,
-                                                qd_iterator_view_t  view);
-static inline qd_field_iterator_t *qd_field_iterator_binary(const char *text,
-                                                            int         length)
-{
-    return qd_address_iterator_binary(text, length, ITER_VIEW_ALL);
-}
-
+qd_iterator_t* qd_iterator_binary(const char         *text,
+                                  int                 length,
+                                  qd_iterator_view_t  view);
 
 /**
  * Create an iterator from a field in a buffer chain
-
+ *
  * The buffer chain must stay intact for the whole life of the iterator.  The iterator
  * does not copy the buffer, it references it.
+ *
+ * @param buffer Pointer to the first buffer in the buffer chain
+ * @param offset The offset in the first buffer where the first octet of the field is
+ * @param length Number of octets in the field
+ * @param view The view for the iterator
+ * @return A newly allocated iterator that references the field.
  */
-qd_field_iterator_t *qd_address_iterator_buffer(qd_buffer_t        *buffer,
-                                                int                 offset,
-                                                int                 length,
-                                                qd_iterator_view_t  view);
-static inline qd_field_iterator_t *qd_field_iterator_buffer(qd_buffer_t *buffer,
-                                                            int          offset,
-                                                            int          length)
-{
-    return qd_address_iterator_buffer(buffer, offset, length, ITER_VIEW_ALL);
-}
+qd_iterator_t *qd_iterator_buffer(qd_buffer_t        *buffer,
+                                  int                 offset,
+                                  int                 length,
+                                  qd_iterator_view_t  view);
 
 /**
- * Free an iterator
+ * Free an allocated iterator
+ *
+ * @param iter An allocated iterator that is no longer to be used
  */
-void qd_field_iterator_free(qd_field_iterator_t *iter);
+void qd_iterator_free(qd_iterator_t *iter);
 
-/**
- * Set the area and router names for the local router.  These are used to match
- * my-area and my-router in address fields.
+
+/** @} */
+/** \name normal
+ * Methods to manipulate and traverse an iterator
+ * @{
  */
-void qd_field_iterator_set_address(const char *area, const char *router);
 
 /**
- * Reset the iterator to the first octet and set a new view
+ * Reset the iterator to the first octet.
+ *
+ * @param iter Pointer to an iterator to be reset
  */
-void qd_field_iterator_reset(qd_field_iterator_t *iter);
-
-void qd_address_iterator_reset_view(qd_field_iterator_t *iter,
-                                  qd_iterator_view_t   view);
-qd_iterator_view_t qd_address_iterator_get_view(const qd_field_iterator_t *iter);
+void qd_iterator_reset(qd_iterator_t *iter);
 
-void qd_address_iterator_set_phase(qd_field_iterator_t *iter, char phase);
+/**
+ * Reset the iterator and set the view.  If the iterator was trimmed, clear the trim state.
+ *
+ * @param iter Pointer to an iterator to be reset
+ * @param view The new view for the iterator
+ */
+void qd_iterator_reset_view(qd_iterator_t      *iter,
+                            qd_iterator_view_t  view);
 
 /**
- * Override the hash-prefix with a custom character.
+ * Return the view for the iterator
+ *
+ * @param iter Pointer to an iterator
+ * @return The view for the iterator
  */
-void qd_address_iterator_override_prefix(qd_field_iterator_t *iter, char prefix);
+qd_iterator_view_t qd_iterator_get_view(const qd_iterator_t *iter);
 
 /**
- * Trims octets from the end of the iterator's field by reducing the length of the iterator.
+ * Trims octets from both ends of the iterator's view by reducing the length of the view and by
+ * resetting the base of the view to the current location.
+ *
+ * Note that an iterator may be repeatedly trimmed, but the trimming must always reduce
+ * the size of the view.  Trimming will never increase the size of the view.  To re-trim
+ * with a bigger size, qd_iterator_reset_view must be called to clear the trimmed state.
  *
- * @param iter - the iterator whose length should be trimmed
- * @param length - the length of the trimmed field.  If greater than or equal to the current length,
- *                 then there shall be no effect.
+ * @param iter The iterator whose length should be trimmed
+ * @param length The length of the trimmed field.  If greater than or equal to the current length,
+ *               then there shall be no effect.
  */
-void qd_field_iterator_trim(qd_field_iterator_t *iter, int length);
+void qd_iterator_trim_view(qd_iterator_t *iter, int length);
 
 /**
  * Return the current octet in the iterator's view and step to the next.
  */
-unsigned char qd_field_iterator_octet(qd_field_iterator_t *iter);
+unsigned char qd_iterator_octet(qd_iterator_t *iter);
 
 /**
  * Return true iff the iterator has no more octets in the view.
  */
-int qd_field_iterator_end(const qd_field_iterator_t *iter);
+bool qd_iterator_end(const qd_iterator_t *iter);
 
 /**
  * Return a sub-iterator that equals the supplied iterator except that it
  * starts at the supplied iterator's current position.
  */
-qd_field_iterator_t *qd_field_iterator_sub(const qd_field_iterator_t *iter, uint32_t length);
+qd_iterator_t *qd_iterator_sub(const qd_iterator_t *iter, uint32_t length);
 
 /**
  * Move the iterator's cursor forward up to length bytes
  */
-void qd_field_iterator_advance(qd_field_iterator_t *iter, uint32_t length);
+void qd_iterator_advance(qd_iterator_t *iter, uint32_t length);
 
 /**
  * Return the remaining length (in octets) for the iterator.
@@ -220,12 +248,17 @@ void qd_field_iterator_advance(qd_field_iterator_t *iter, uint32_t length);
  * @param iter A field iterator
  * @return The number of octets remaining in the view (or more)
  */
-uint32_t qd_field_iterator_remaining(const qd_field_iterator_t *iter);
+uint32_t qd_iterator_remaining(const qd_iterator_t *iter);
+
+/**
+ * Return the exact length of the iterator's view.
+ */
+int qd_iterator_length(const qd_iterator_t *iter);
 
 /**
  * Compare an input string to the iterator's view.  Return true iff they are equal.
  */
-int qd_field_iterator_equal(qd_field_iterator_t *iter, const unsigned char *string);
+bool qd_iterator_equal(qd_iterator_t *iter, const unsigned char *string);
 
 /**
  * Return true iff the string matches the characters at the current location in the view.
@@ -233,26 +266,21 @@ int qd_field_iterator_equal(qd_field_iterator_t *iter, const unsigned char *stri
  * This function does not alter the position of the iterator if the prefix does not match,
  * if it matches, the prefix is consumed.
  */
-int qd_field_iterator_prefix(qd_field_iterator_t *iter, const char *prefix);
-
-/**
- * Return the exact length of the iterator's view.
- */
-int qd_field_iterator_length(const qd_field_iterator_t *iter);
+bool qd_iterator_prefix(qd_iterator_t *iter, const char *prefix);
 
 /**
  * Copy the iterator's view into buffer up to a maximum of n bytes.  Cursor is
  * advanced by the number of bytes copied. There is no trailing '\0' added.
  * @return number of bytes copied.
  */
-int qd_field_iterator_ncopy(qd_field_iterator_t *iter, unsigned char* buffer, int n);
+int qd_iterator_ncopy(qd_iterator_t *iter, unsigned char* buffer, int n);
 
 /**
  * Return a new copy of the iterator's view, with a trailing '\0' added.  The
  * cursor is advanced to the end of the view.
  * @return Copy of the view, free with free()
  */
-unsigned char *qd_field_iterator_copy(qd_field_iterator_t *iter);
+unsigned char *qd_iterator_copy(qd_iterator_t *iter);
 
 /**
  * Return a new iterator that is a duplicate of the original iterator, referring
@@ -261,7 +289,7 @@ unsigned char *qd_field_iterator_copy(qd_field_iterator_t *iter);
  * @param iter Input iterator
  * @return Pointer to a new, identical iterator referring to the same data.
  */
-qd_field_iterator_t *qd_field_iterator_dup(const qd_field_iterator_t *iter);
+qd_iterator_t *qd_iterator_dup(const qd_iterator_t *iter);
 
 /**
  * Copy the iterator's view into buffer as a null terminated string,
@@ -269,7 +297,7 @@ qd_field_iterator_t *qd_field_iterator_dup(const qd_field_iterator_t *iter);
  * copied.  Useful for log messages.
  * @return buffer.
  */
-char* qd_field_iterator_strncpy(qd_field_iterator_t *iter, char* buffer, int n);
+char* qd_iterator_strncpy(qd_iterator_t *iter, char* buffer, int n);
 
 /**
  * Return the contents of this iter into an iovec structure.  This is used in a
@@ -279,48 +307,92 @@ char* qd_field_iterator_strncpy(qd_field_iterator_t *iter, char* buffer, int n);
  * @param iter A field iterator
  * @return An iovec structure that references the data in the iterator's buffers.
  */
-qd_iovec_t *qd_field_iterator_iovec(const qd_field_iterator_t *iter);
+qd_iovec_t *qd_iterator_iovec(const qd_iterator_t *iter);
+
+
+/** @} */
+/** \name annotation
+ * Methods to modify the view annotations of an iterator
+ * @{
+ */
+
+/**
+ * Set the phase character to annotate a mobile address view.
+ *
+ * @param iter Pointer to an iterator
+ * @param phase A character used to annotate a mobile address view
+ */
+void qd_iterator_annotate_phase(qd_iterator_t *iter, char phase);
 
 /**
- * Steps through the iterator hashing each octet and also trying to find a separator. The separator is hardcoded to be a '/'.
- * It stores the hash of each segment as a node (qd_hash_segment_t) in the linked list qd_hash_segment_list_t of the iterator.
- * The linked list contains as many nodes as there are segments.
+ * Override the prefix character for a mobile address view.
  *
- *     +------------------------+
- *     |                        |
- *     | qd_hash_segment_list_t |----------->+
- *     |                        |            |
- *     +------------------------+            |       "policy"              "policy/org"            "policy/org/apache"
- *                                           |    +-------------------+   +-------------------+   +-------------------+
- *                                           +--->| qd_hash_segment_t |-->| qd_hash_segment_t |-->| qd_hash_segment_t |--/
- *                                                +-------------------+   +-------------------+   +-------------------+
+ * @param iter Pointer to an iterator
+ * @param prefix A character to use as the prefix of a mobile address view
+ */
+void qd_iterator_annotate_prefix(qd_iterator_t *iter, char prefix);
+
+/**
+ * Annotate a mobile address view with a tenant namespace.
  *
- * In the above example the first qd_hash_segment_t stores the hash of the string "policy" and the next qd_hash_segment_t contains \
- * the hash to "policy/org" and so on. The purpose of doing this is to pre-generate the hash and hash length and store
- * it so matches can be quickly made.
+ * Note that the space string is not copied into the iterator.  It must remain in-place
+ * and unchanged for the lifetime of the iterator.
  *
+ * @param iter Pointer to an iterator
+ * @param space Pointer to the first character of a character string representing a namespace
+ * @param space_len The number of characters in the space string
+ */
+void qd_iterator_annotate_space(qd_iterator_t *iter, const char* space, int space_len);
+
+
+/** @} */
+/** \name hash
+ * Methods to calculate hash values for iterator views
  *
- * @param iter An address iterator
+ * All hashing functions use the djb2 algorithm (http://www.cse.yorku.ca/~oz/hash.html).
+ * @{
  */
-void qd_iterator_hash_segments(qd_field_iterator_t *iter);
 
 /**
- * Populates the passed in hash with the hash from the tail hash segment and deletes and frees it.
- * This hash can be further used arrive at the hash bucket.
- * Returns false if it cannot find anymore tail hash_segments, true otherwise.
+ * Generate the hash of the view of the iterator.
  *
  * @param iter A field iterator
+ * @return The hash value of the iterator's view
+ */
+uint32_t qd_iterator_hash_view(qd_iterator_t *iter);
+
+/**
+ * Generate a series of hash values for a segmented view.  For example, consider the following view:
+ *
+ *    "M0policy/org.apache.qpid"
+ *
+ * The hash values computed will be for the following strings:
+ *
+ *    "M0policy/org.apache.qpid"
+ *    "M0policy/org.apache"
+ *    "M0policy/org"
+ *    "M0policy"
+ *
+ * These hash values and the sub-views associated with them shall be stored in the iterator.
+ *
+ * @param iter An address iterator
  */
-bool qd_iterator_hash_and_reset(qd_field_iterator_t *iter, uint32_t *hash);
+void qd_iterator_hash_view_segments(qd_iterator_t *iter);
 
 /**
- * Generates and returns a hash of the contents of the iterator by stepping through the iterator octet by octet.
- * Uses the djb2 algorithm for hashing - can be found at http://www.cse.yorku.ca/~oz/hash.html
+ * Iterate over the segment hash values pre-computed using qd_iterator_hash_view_segments.
+ *
+ * This function returns the longest remaining segment hash, removes the hash from the set of
+ * stored segment values, and adjusts the view so that it includes only the subset of the view
+ * associated with the hash value.
  *
  * @param iter A field iterator
+ * @param hash (output) Hash value for the next segment
+ * @return True iff there is another segment hash to be compared
  */
-uint32_t qd_iterator_hash_function(qd_field_iterator_t *iter);
+bool qd_iterator_next_segment(qd_iterator_t *iter, uint32_t *hash);
 
 /** @} */
+/** @} */
 
 #endif

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/include/qpid/dispatch/message.h
----------------------------------------------------------------------
diff --git a/include/qpid/dispatch/message.h b/include/qpid/dispatch/message.h
index 66601ba..b60f118 100644
--- a/include/qpid/dispatch/message.h
+++ b/include/qpid/dispatch/message.h
@@ -233,8 +233,8 @@ int qd_message_check(qd_message_t *msg, qd_message_depth_t depth);
  * @param field The field to be returned via iterator.
  * @return A field iterator that spans the requested field.
  */
-qd_field_iterator_t *qd_message_field_iterator_typed(qd_message_t *msg, qd_message_field_t field);
-qd_field_iterator_t *qd_message_field_iterator(qd_message_t *msg, qd_message_field_t field);
+qd_iterator_t *qd_message_field_iterator_typed(qd_message_t *msg, qd_message_field_t field);
+qd_iterator_t *qd_message_field_iterator(qd_message_t *msg, qd_message_field_t field);
 
 ssize_t qd_message_field_length(qd_message_t *msg, qd_message_field_t field);
 ssize_t qd_message_field_copy(qd_message_t *msg, qd_message_field_t field, void *buffer, size_t *hdr_length);

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/include/qpid/dispatch/parse.h
----------------------------------------------------------------------
diff --git a/include/qpid/dispatch/parse.h b/include/qpid/dispatch/parse.h
index d4fdf42..454e99f 100644
--- a/include/qpid/dispatch/parse.h
+++ b/include/qpid/dispatch/parse.h
@@ -27,7 +27,7 @@
  *
  * @defgroup parse parse
  *
- * Parse data from qd_field_iterator_t into a tree structure represeniting
+ * Parse data from qd_iterator_t into a tree structure represeniting
  * an AMQP data type tree.
  *@{
  */
@@ -40,7 +40,7 @@ typedef struct qd_parsed_field_t qd_parsed_field_t;
  * @param iter Field iterator for the field being parsed
  * @return A pointer to the newly created field.
  */
-qd_parsed_field_t *qd_parse(qd_field_iterator_t *iter);
+qd_parsed_field_t *qd_parse(qd_iterator_t *iter);
 
 /**
  * Free the resources associated with a parsed field.
@@ -97,7 +97,7 @@ uint8_t qd_parse_tag(qd_parsed_field_t *field);
  * @param field The field pointer returned by qd_parse.
  * @return A field iterator that describes the field's raw content.
  */
-qd_field_iterator_t *qd_parse_raw(qd_parsed_field_t *field);
+qd_iterator_t *qd_parse_raw(qd_parsed_field_t *field);
 
 
 /**
@@ -109,7 +109,7 @@ qd_field_iterator_t *qd_parse_raw(qd_parsed_field_t *field);
  * @param field The field pointer returned by qd_parse.
  * @return A field iterator that describes the field's typed content.
  */
-qd_field_iterator_t *qd_parse_typed(qd_parsed_field_t *field);
+qd_iterator_t *qd_parse_typed(qd_parsed_field_t *field);
 
 /**
  * Return the raw content as an unsigned integer up to 32-bits.  This is

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/include/qpid/dispatch/router.h
----------------------------------------------------------------------
diff --git a/include/qpid/dispatch/router.h b/include/qpid/dispatch/router.h
index f050775..86e6e6d 100644
--- a/include/qpid/dispatch/router.h
+++ b/include/qpid/dispatch/router.h
@@ -73,7 +73,7 @@ struct qd_router_forwarder_t {
                     qd_message_t *msg,
                     qd_router_delivery_t *delivery,
                     qd_address_t *addr,
-                    qd_field_iterator_t *ingress_iterator,
+                    qd_iterator_t *ingress_iterator,
                     bool is_direct);
 
     /** release the descriptor
@@ -119,9 +119,9 @@ void qd_address_set_static_cc(qd_address_t *address, qd_address_t *cc);
 void qd_address_set_dynamic_cc(qd_address_t *address, qd_address_t *cc);
 
 /** Send msg to local links and next-hops for address */
-void qd_router_send(qd_dispatch_t       *qd,
-                    qd_field_iterator_t *address,
-                    qd_message_t        *msg);
+void qd_router_send(qd_dispatch_t *qd,
+                    qd_iterator_t *address,
+                    qd_message_t  *msg);
 
 /** Send msg to local links and next-hops for address */
 void qd_router_send2(qd_dispatch_t *qd,

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/include/qpid/dispatch/router_core.h
----------------------------------------------------------------------
diff --git a/include/qpid/dispatch/router_core.h b/include/qpid/dispatch/router_core.h
index 9421481..b3f293b 100644
--- a/include/qpid/dispatch/router_core.h
+++ b/include/qpid/dispatch/router_core.h
@@ -115,7 +115,7 @@ void qdr_core_unsubscribe(qdr_subscription_t *sub);
  * @param exclude_inprocess If true, the message will not be sent to in-process subscribers.
  * @param control If true, this message is to be treated as control traffic and flow on a control link.
  */
-void qdr_send_to1(qdr_core_t *core, qd_message_t *msg, qd_field_iterator_t *addr,
+void qdr_send_to1(qdr_core_t *core, qd_message_t *msg, qd_iterator_t *addr,
                   bool exclude_inprocess, bool control);
 void qdr_send_to2(qdr_core_t *core, qd_message_t *msg, const char *addr,
                   bool exclude_inprocess, bool control);
@@ -323,7 +323,7 @@ void qdr_terminus_set_address(qdr_terminus_t *term, const char *addr);
  * @param term A qdr_terminus pointer returned by qdr_terminus()
  * @return A pointer to an iterator or 0 if the terminus is anonymous.
  */
-qd_field_iterator_t *qdr_terminus_get_address(qdr_terminus_t *term);
+qd_iterator_t *qdr_terminus_get_address(qdr_terminus_t *term);
 
 /**
  * qdr_terminus_dnp_address
@@ -334,7 +334,7 @@ qd_field_iterator_t *qdr_terminus_get_address(qdr_terminus_t *term);
  * @param term A qdr_terminus pointer returned by qdr_terminus()
  * @return A pointer to an iterator or 0 if there is no such field.
  */
-qd_field_iterator_t *qdr_terminus_dnp_address(qdr_terminus_t *term);
+qd_iterator_t *qdr_terminus_dnp_address(qdr_terminus_t *term);
 
 
 /**
@@ -508,10 +508,10 @@ void qdr_link_detach(qdr_link_t *link, qd_detach_type_t dt, qdr_error_t *error);
  *                       it built on the trace header from a received message.
  * @return Pointer to the qdr_delivery that will track the lifecycle of this delivery on this link.
  */
-qdr_delivery_t *qdr_link_deliver(qdr_link_t *link, qd_message_t *msg, qd_field_iterator_t *ingress,
+qdr_delivery_t *qdr_link_deliver(qdr_link_t *link, qd_message_t *msg, qd_iterator_t *ingress,
                                  bool settled, qd_bitmask_t *link_exclusion);
 qdr_delivery_t *qdr_link_deliver_to(qdr_link_t *link, qd_message_t *msg,
-                                    qd_field_iterator_t *ingress, qd_field_iterator_t *addr,
+                                    qd_iterator_t *ingress, qd_iterator_t *addr,
                                     bool settled, qd_bitmask_t *link_exclusion);
 qdr_delivery_t *qdr_link_deliver_to_routed_link(qdr_link_t *link, qd_message_t *msg, bool settled,
                                                 const uint8_t *tag, int tag_length);
@@ -594,7 +594,7 @@ typedef struct qdr_query_t qdr_query_t;
  * @param out_body A composed field for the body of the response message
  */
 void qdr_manage_create(qdr_core_t *core, void *context, qd_router_entity_type_t type,
-                       qd_field_iterator_t *name, qd_parsed_field_t *in_body, qd_composed_field_t *out_body);
+                       qd_iterator_t *name, qd_parsed_field_t *in_body, qd_composed_field_t *out_body);
 
 /**
  * qdr_manage_delete
@@ -608,7 +608,7 @@ void qdr_manage_create(qdr_core_t *core, void *context, qd_router_entity_type_t
  * @param identity The identity supplied with the request (or 0 if the name was supplied)
  */
 void qdr_manage_delete(qdr_core_t *core, void *context, qd_router_entity_type_t type,
-                       qd_field_iterator_t *name, qd_field_iterator_t *identity);
+                       qd_iterator_t *name, qd_iterator_t *identity);
 
 /**
  * qdr_manage_read
@@ -623,7 +623,7 @@ void qdr_manage_delete(qdr_core_t *core, void *context, qd_router_entity_type_t
  * @param body A composed field for the body of the response message
  */
 void qdr_manage_read(qdr_core_t *core, void *context, qd_router_entity_type_t type,
-                     qd_field_iterator_t *name, qd_field_iterator_t *identity, qd_composed_field_t *body);
+                     qd_iterator_t *name, qd_iterator_t *identity, qd_composed_field_t *body);
 
 
 /**
@@ -640,7 +640,7 @@ void qdr_manage_read(qdr_core_t *core, void *context, qd_router_entity_type_t ty
  * @param out_body A composed field for the body of the response message
  */
 void qdr_manage_update(qdr_core_t *core, void *context, qd_router_entity_type_t type,
-                       qd_field_iterator_t *name, qd_field_iterator_t *identity,
+                       qd_iterator_t *name, qd_iterator_t *identity,
                        qd_parsed_field_t *in_body, qd_composed_field_t *out_body);
 
 /**

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/src/compose.c
----------------------------------------------------------------------
diff --git a/src/compose.c b/src/compose.c
index df77f44..77b705d 100644
--- a/src/compose.c
+++ b/src/compose.c
@@ -432,17 +432,17 @@ void qd_compose_insert_string(qd_composed_field_t *field, const char *value)
 }
 
 
-void qd_compose_insert_string_iterator(qd_composed_field_t *field, qd_field_iterator_t *iter)
+void qd_compose_insert_string_iterator(qd_composed_field_t *field, qd_iterator_t *iter)
 {
     uint32_t len = 0;
 
-    qd_field_iterator_reset(iter);
-    while (!qd_field_iterator_end(iter)) {
-        qd_field_iterator_octet(iter);
+    qd_iterator_reset(iter);
+    while (!qd_iterator_end(iter)) {
+        qd_iterator_octet(iter);
         len++;
     }
 
-    qd_field_iterator_reset(iter);
+    qd_iterator_reset(iter);
     if (len < 256) {
         qd_insert_8(field, QD_AMQP_STR8_UTF8);
         qd_insert_8(field, (uint8_t) len);
@@ -451,8 +451,8 @@ void qd_compose_insert_string_iterator(qd_composed_field_t *field, qd_field_iter
         qd_insert_32(field, len);
     }
 
-    while (!qd_field_iterator_end(iter)) {
-        uint8_t octet = qd_field_iterator_octet(iter);
+    while (!qd_iterator_end(iter)) {
+        uint8_t octet = qd_iterator_octet(iter);
         qd_insert_8(field, octet);
     }
 
@@ -476,10 +476,10 @@ void qd_compose_insert_symbol(qd_composed_field_t *field, const char *value)
 }
 
 
-void qd_compose_insert_typed_iterator(qd_composed_field_t *field, qd_field_iterator_t *iter)
+void qd_compose_insert_typed_iterator(qd_composed_field_t *field, qd_iterator_t *iter)
 {
-    while (!qd_field_iterator_end(iter)) {
-        uint8_t octet = qd_field_iterator_octet(iter);
+    while (!qd_iterator_end(iter)) {
+        uint8_t octet = qd_iterator_octet(iter);
         qd_insert_8(field, octet);
     }
 

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/src/container.c
----------------------------------------------------------------------
diff --git a/src/container.c b/src/container.c
index 7abc3b2..9c0680b 100644
--- a/src/container.c
+++ b/src/container.c
@@ -85,29 +85,14 @@ struct qd_container_t {
 
 static void setup_outgoing_link(qd_container_t *container, pn_link_t *pn_link)
 {
-    sys_mutex_lock(container->lock);
-    qd_node_t  *node = 0;
-    const char *source = pn_terminus_get_address(pn_link_remote_source(pn_link));
-    qd_field_iterator_t *iter;
-    // TODO - Extract the name from the structured source
-
-    if (source) {
-        iter   = qd_address_iterator_string(source, ITER_VIEW_NODE_ID);
-        qd_hash_retrieve(container->node_map, iter, (void*) &node);
-        qd_field_iterator_free(iter);
-    }
-    sys_mutex_unlock(container->lock);
+    qd_node_t *node = container->default_node;
 
     if (node == 0) {
-        if (container->default_node)
-            node = container->default_node;
-        else {
-            pn_condition_t *cond = pn_link_condition(pn_link);
-            pn_condition_set_name(cond, "amqp:not-found");
-            pn_condition_set_description(cond, "Source node does not exist");
-            pn_link_close(pn_link);
-            return;
-        }
+        pn_condition_t *cond = pn_link_condition(pn_link);
+        pn_condition_set_name(cond, "amqp:not-found");
+        pn_condition_set_description(cond, "Source node does not exist");
+        pn_link_close(pn_link);
+        return;
     }
 
     qd_link_t *link = new_qd_link_t();
@@ -136,28 +121,14 @@ static void setup_outgoing_link(qd_container_t *container, pn_link_t *pn_link)
 
 static void setup_incoming_link(qd_container_t *container, pn_link_t *pn_link)
 {
-    sys_mutex_lock(container->lock);
-    qd_node_t   *node = 0;
-    const char  *target = pn_terminus_get_address(pn_link_remote_target(pn_link));
-    qd_field_iterator_t *iter;
-
-    if (target) {
-        iter   = qd_address_iterator_string(target, ITER_VIEW_NODE_ID);
-        qd_hash_retrieve(container->node_map, iter, (void*) &node);
-        qd_field_iterator_free(iter);
-    }
-    sys_mutex_unlock(container->lock);
+    qd_node_t *node = container->default_node;
 
     if (node == 0) {
-        if (container->default_node)
-            node = container->default_node;
-        else {
-            pn_condition_t *cond = pn_link_condition(pn_link);
-            pn_condition_set_name(cond, "amqp:not-found");
-            pn_condition_set_description(cond, "Target node does not exist");
-            pn_link_close(pn_link);
-            return;
-        }
+        pn_condition_t *cond = pn_link_condition(pn_link);
+        pn_condition_set_name(cond, "amqp:not-found");
+        pn_condition_set_description(cond, "Target node does not exist");
+        pn_link_close(pn_link);
+        return;
     }
 
     qd_link_t *link = new_qd_link_t();
@@ -615,7 +586,7 @@ int qd_container_register_node_type(qd_dispatch_t *qd, const qd_node_type_t *nt)
     qd_container_t *container = qd->container;
 
     int result;
-    qd_field_iterator_t *iter = qd_field_iterator_string(nt->type_name);
+    qd_iterator_t *iter = qd_iterator_string(nt->type_name, ITER_VIEW_ALL);
     qdc_node_type_t     *nt_item = NEW(qdc_node_type_t);
     DEQ_ITEM_INIT(nt_item);
     nt_item->ntype = nt;
@@ -625,7 +596,7 @@ int qd_container_register_node_type(qd_dispatch_t *qd, const qd_node_type_t *nt)
     DEQ_INSERT_TAIL(container->node_type_list, nt_item);
     sys_mutex_unlock(container->lock);
 
-    qd_field_iterator_free(iter);
+    qd_iterator_free(iter);
     if (result < 0)
         return result;
     qd_log(container->log_source, QD_LOG_TRACE, "Node Type Registered - %s", nt->type_name);
@@ -678,13 +649,13 @@ qd_node_t *qd_container_create_node(qd_dispatch_t        *qd,
     node->life_policy    = life_policy;
 
     if (name) {
-        qd_field_iterator_t *iter = qd_field_iterator_string(name);
+        qd_iterator_t *iter = qd_iterator_string(name, ITER_VIEW_ALL);
         sys_mutex_lock(container->lock);
         result = qd_hash_insert(container->node_map, iter, node, 0);
         if (result >= 0)
             DEQ_INSERT_HEAD(container->nodes, node);
         sys_mutex_unlock(container->lock);
-        qd_field_iterator_free(iter);
+        qd_iterator_free(iter);
         if (result < 0) {
             free_qd_node_t(node);
             return 0;
@@ -706,12 +677,12 @@ void qd_container_destroy_node(qd_node_t *node)
     qd_container_t *container = node->container;
 
     if (node->name) {
-        qd_field_iterator_t *iter = qd_field_iterator_string(node->name);
+        qd_iterator_t *iter = qd_iterator_string(node->name, ITER_VIEW_ALL);
         sys_mutex_lock(container->lock);
         qd_hash_remove(container->node_map, iter);
         DEQ_REMOVE(container->nodes, node);
         sys_mutex_unlock(container->lock);
-        qd_field_iterator_free(iter);
+        qd_iterator_free(iter);
         free(node->name);
     }
 

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/src/hash.c
----------------------------------------------------------------------
diff --git a/src/hash.c b/src/hash.c
index b5471f0..8e27a23 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -111,13 +111,13 @@ size_t qd_hash_size(qd_hash_t *h)
 }
 
 
-static qd_hash_item_t *qd_hash_internal_insert(qd_hash_t *h, qd_field_iterator_t *key, int *exists, qd_hash_handle_t **handle)
+static qd_hash_item_t *qd_hash_internal_insert(qd_hash_t *h, qd_iterator_t *key, int *exists, qd_hash_handle_t **handle)
 {
-    unsigned long   idx  = qd_iterator_hash_function(key) & h->bucket_mask;
+    unsigned long   idx  = qd_iterator_hash_view(key) & h->bucket_mask;
     qd_hash_item_t *item = DEQ_HEAD(h->buckets[idx].items);
 
     while (item) {
-        if (qd_field_iterator_equal(key, item->key))
+        if (qd_iterator_equal(key, item->key))
             break;
         item = item->next;
     }
@@ -134,7 +134,7 @@ static qd_hash_item_t *qd_hash_internal_insert(qd_hash_t *h, qd_field_iterator_t
         return 0;
 
     DEQ_ITEM_INIT(item);
-    item->key = qd_field_iterator_copy(key);
+    item->key = qd_iterator_copy(key);
 
     DEQ_INSERT_TAIL(h->buckets[idx].items, item);
     h->size++;
@@ -153,7 +153,7 @@ static qd_hash_item_t *qd_hash_internal_insert(qd_hash_t *h, qd_field_iterator_t
 }
 
 
-qd_error_t qd_hash_insert(qd_hash_t *h, qd_field_iterator_t *key, void *val, qd_hash_handle_t **handle)
+qd_error_t qd_hash_insert(qd_hash_t *h, qd_iterator_t *key, void *val, qd_hash_handle_t **handle)
 {
     int             exists = 0;
     qd_hash_item_t *item   = qd_hash_internal_insert(h, key, &exists, handle);
@@ -170,7 +170,7 @@ qd_error_t qd_hash_insert(qd_hash_t *h, qd_field_iterator_t *key, void *val, qd_
 }
 
 
-qd_error_t qd_hash_insert_const(qd_hash_t *h, qd_field_iterator_t *key, const void *val, qd_hash_handle_t **handle)
+qd_error_t qd_hash_insert_const(qd_hash_t *h, qd_iterator_t *key, const void *val, qd_hash_handle_t **handle)
 {
     assert(h->is_const);
 
@@ -183,14 +183,14 @@ qd_error_t qd_hash_insert_const(qd_hash_t *h, qd_field_iterator_t *key, const vo
 }
 
 
-static qd_hash_item_t *qd_hash_internal_retrieve_with_hash(qd_hash_t *h, uint32_t hash, qd_field_iterator_t *key)
+static qd_hash_item_t *qd_hash_internal_retrieve_with_hash(qd_hash_t *h, uint32_t hash, qd_iterator_t *key)
 {
     uint32_t   idx  = hash & h->bucket_mask;
 
 	qd_hash_item_t *item = DEQ_HEAD(h->buckets[idx].items);
 
 	while (item) {
-		if (qd_field_iterator_equal(key, item->key))
+		if (qd_iterator_equal(key, item->key))
 			break;
 		item = item->next;
 	}
@@ -199,22 +199,22 @@ static qd_hash_item_t *qd_hash_internal_retrieve_with_hash(qd_hash_t *h, uint32_
 }
 
 
-static qd_hash_item_t *qd_hash_internal_retrieve(qd_hash_t *h, qd_field_iterator_t *key)
+static qd_hash_item_t *qd_hash_internal_retrieve(qd_hash_t *h, qd_iterator_t *key)
 {
-    uint32_t hash = qd_iterator_hash_function(key);
+    uint32_t hash = qd_iterator_hash_view(key);
     return qd_hash_internal_retrieve_with_hash(h, hash, key);
 }
 
 
-void qd_hash_retrieve_prefix(qd_hash_t *h, qd_field_iterator_t *iter, void **val)
+void qd_hash_retrieve_prefix(qd_hash_t *h, qd_iterator_t *iter, void **val)
 {
 	//Hash individual segments by iterating thru the octets in the iterator.
-	qd_iterator_hash_segments(iter);
+	qd_iterator_hash_view_segments(iter);
 
 	uint32_t hash = 0;
 
 	qd_hash_item_t *item;
-	while (qd_iterator_hash_and_reset(iter, &hash)) {
+	while (qd_iterator_next_segment(iter, &hash)) {
 		item = qd_hash_internal_retrieve_with_hash(h, hash, iter);
 		if (item)
 			break;
@@ -227,7 +227,7 @@ void qd_hash_retrieve_prefix(qd_hash_t *h, qd_field_iterator_t *iter, void **val
 }
 
 
-void qd_hash_retrieve_prefix_const(qd_hash_t *h, qd_field_iterator_t *iter, const void **val)
+void qd_hash_retrieve_prefix_const(qd_hash_t *h, qd_iterator_t *iter, const void **val)
 {
     assert(h->is_const);
 
@@ -235,7 +235,7 @@ void qd_hash_retrieve_prefix_const(qd_hash_t *h, qd_field_iterator_t *iter, cons
 
     qd_hash_item_t *item;
 
-    while (qd_iterator_hash_and_reset(iter, &hash)) {
+    while (qd_iterator_next_segment(iter, &hash)) {
         item = qd_hash_internal_retrieve_with_hash(h, hash, iter);
         if (item)
             break;
@@ -248,7 +248,7 @@ void qd_hash_retrieve_prefix_const(qd_hash_t *h, qd_field_iterator_t *iter, cons
 }
 
 
-qd_error_t qd_hash_retrieve(qd_hash_t *h, qd_field_iterator_t *key, void **val)
+qd_error_t qd_hash_retrieve(qd_hash_t *h, qd_iterator_t *key, void **val)
 {
     qd_hash_item_t *item = qd_hash_internal_retrieve(h, key);
     if (item)
@@ -260,7 +260,7 @@ qd_error_t qd_hash_retrieve(qd_hash_t *h, qd_field_iterator_t *key, void **val)
 }
 
 
-qd_error_t qd_hash_retrieve_const(qd_hash_t *h, qd_field_iterator_t *key, const void **val)
+qd_error_t qd_hash_retrieve_const(qd_hash_t *h, qd_iterator_t *key, const void **val)
 {
     assert(h->is_const);
 
@@ -274,13 +274,13 @@ qd_error_t qd_hash_retrieve_const(qd_hash_t *h, qd_field_iterator_t *key, const
 }
 
 
-qd_error_t qd_hash_remove(qd_hash_t *h, qd_field_iterator_t *key)
+qd_error_t qd_hash_remove(qd_hash_t *h, qd_iterator_t *key)
 {
-    uint32_t   idx  = qd_iterator_hash_function(key) & h->bucket_mask;
+    uint32_t   idx  = qd_iterator_hash_view(key) & h->bucket_mask;
     qd_hash_item_t *item = DEQ_HEAD(h->buckets[idx].items);
 
     while (item) {
-        if (qd_field_iterator_equal(key, item->key))
+        if (qd_iterator_equal(key, item->key))
             break;
         item = item->next;
     }

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/src/iterator.c
----------------------------------------------------------------------
diff --git a/src/iterator.c b/src/iterator.c
index 8ae5abf..5f2f30a 100644
--- a/src/iterator.c
+++ b/src/iterator.c
@@ -25,7 +25,6 @@
 #include <stdio.h>
 #include <string.h>
 
-//static const char *log_module = "FIELD";
 
 typedef enum {
     MODE_TO_END,
@@ -35,43 +34,46 @@ typedef enum {
 typedef enum {
     STATE_AT_PREFIX,
     STATE_AT_PHASE,
-    STATE_IN_ADDRESS
-} addr_state_t;
+    STATE_IN_SPACE,
+    STATE_IN_BODY
+} view_state_t;
 
 typedef struct {
     qd_buffer_t   *buffer;
     unsigned char *cursor;
-    int            length;
+    int            remaining;
 } pointer_t;
 
-typedef struct qd_hash_segment_t qd_hash_segment_t;
-
-struct qd_hash_segment_t {
-    DEQ_LINKS(qd_hash_segment_t); //Adds the *prev and *next links
-    uint32_t   hash; //The hash of the segment
-    uint32_t segment_length; //The length of each hash segment
-};
+typedef struct qd_hash_segment_t {
+    DEQ_LINKS(struct qd_hash_segment_t);
+    uint32_t hash;           //The hash of the segment
+    uint32_t segment_length; //The length of the segment
+} qd_hash_segment_t;
 
 DEQ_DECLARE(qd_hash_segment_t, qd_hash_segment_list_t);
 ALLOC_DECLARE(qd_hash_segment_t);
 ALLOC_DEFINE(qd_hash_segment_t);
 
-struct qd_field_iterator_t {
-    pointer_t               start_pointer;
-    pointer_t               view_start_pointer;
-    pointer_t               pointer;
+struct qd_iterator_t {
+    pointer_t               start_pointer;      // Pointer to the raw data
+    pointer_t               view_start_pointer; // Pointer to the start of the view
+    pointer_t               view_pointer;       // Pointer to the remaining view
     qd_iterator_view_t      view;
+    int                     annotation_length;
+    int                     annotation_remaining;
     qd_hash_segment_list_t  hash_segments;
     parse_mode_t            mode;
-    addr_state_t            state;
-    bool                    view_prefix;
+    view_state_t            state;
     unsigned char           prefix;
     unsigned char           prefix_override;
     unsigned char           phase;
+    const char             *space;
+    int                     space_length;
+    int                     space_cursor;
 };
 
-ALLOC_DECLARE(qd_field_iterator_t);
-ALLOC_DEFINE(qd_field_iterator_t);
+ALLOC_DECLARE(qd_iterator_t);
+ALLOC_DEFINE(qd_iterator_t);
 
 typedef enum {
     STATE_START,
@@ -84,114 +86,112 @@ typedef enum {
 } state_t;
 
 
-static char *my_area    = "";
-static char *my_router  = "";
-
-const char *SEPARATORS  = "./";
+static char *my_area   = "";
+static char *my_router = "";
 
-const uint32_t HASH_INIT = 5381;
+static const char    *SEPARATORS = "./";
+static const uint32_t HASH_INIT  = 5381;
 
 
-static void parse_address_view(qd_field_iterator_t *iter)
+static void parse_address_view(qd_iterator_t *iter)
 {
     //
     // This function starts with an iterator view that is identical to
-    // ITER_VIEW_NO_HOST.  We will now further refine the view in order
-    // to aid the router in looking up addresses.
+    // ITER_VIEW_ADDRESS_NO_HOST.  We will now further refine the view
+    // in order to aid the router in looking up addresses.
     //
 
-    if (iter->prefix_override == '\0' && qd_field_iterator_prefix(iter, "_")) {
-        if (qd_field_iterator_prefix(iter, "local/")) {
-            iter->prefix      = 'L';
-            iter->state       = STATE_AT_PREFIX;
-            iter->view_prefix = true;
+    iter->annotation_length = 1;
+
+    if (iter->prefix_override == '\0' && qd_iterator_prefix(iter, "_")) {
+        if (qd_iterator_prefix(iter, "local/")) {
+            iter->prefix = 'L';
+            iter->state  = STATE_AT_PREFIX;
             return;
         }
 
-        if (qd_field_iterator_prefix(iter, "topo/")) {
-            if (qd_field_iterator_prefix(iter, "all/") || qd_field_iterator_prefix(iter, my_area)) {
-                if (qd_field_iterator_prefix(iter, "all/")) {
-                    iter->prefix      = 'T';
-                    iter->state       = STATE_AT_PREFIX;
-                    iter->view_prefix = true;
+        if (qd_iterator_prefix(iter, "topo/")) {
+            if (qd_iterator_prefix(iter, "all/") || qd_iterator_prefix(iter, my_area)) {
+                if (qd_iterator_prefix(iter, "all/")) {
+                    iter->prefix = 'T';
+                    iter->state  = STATE_AT_PREFIX;
                     return;
-                } else if (qd_field_iterator_prefix(iter, my_router)) {
-                    iter->prefix      = 'L';
-                    iter->state       = STATE_AT_PREFIX;
-                    iter->view_prefix = true;
+                } else if (qd_iterator_prefix(iter, my_router)) {
+                    iter->prefix = 'L';
+                    iter->state  = STATE_AT_PREFIX;
                     return;
                 }
 
-                iter->prefix      = 'R';
-                iter->state       = STATE_AT_PREFIX;
-                iter->view_prefix = true;
-                iter->mode        = MODE_TO_SLASH;
+                iter->prefix = 'R';
+                iter->state  = STATE_AT_PREFIX;
+                iter->mode   = MODE_TO_SLASH;
                 return;
             }
 
-            iter->prefix      = 'A';
-            iter->state       = STATE_AT_PREFIX;
-            iter->view_prefix = true;
-            iter->mode        = MODE_TO_SLASH;
+            iter->prefix = 'A';
+            iter->state  = STATE_AT_PREFIX;
+            iter->mode   = MODE_TO_SLASH;
             return;
         }
     }
 
-    iter->prefix      = iter->prefix_override ? iter->prefix_override : 'M';
-    iter->state       = STATE_AT_PREFIX;
-    iter->view_prefix = true;
+    iter->prefix            = iter->prefix_override ? iter->prefix_override : 'M';
+    iter->state             = STATE_AT_PREFIX;
+    iter->annotation_length = iter->space_length + (iter->prefix == 'M' ? 2 : 1);
 }
 
 
-static void parse_node_view(qd_field_iterator_t *iter)
+static void parse_node_view(qd_iterator_t *iter)
 {
     //
     // This function starts with an iterator view that is identical to
-    // ITER_VIEW_NO_HOST.  We will now further refine the view in order
+    // ITER_VIEW_ADDRESS_NO_HOST.  We will now further refine the view in order
     // to aid the router in looking up nodes.
     //
 
-    if (qd_field_iterator_prefix(iter, my_area)) {
-        iter->prefix      = 'R';
-        iter->state       = STATE_AT_PREFIX;
-        iter->view_prefix = true;
-        iter->mode        = MODE_TO_END;
+    iter->annotation_length = 1;
+
+    if (qd_iterator_prefix(iter, my_area)) {
+        iter->prefix = 'R';
+        iter->state  = STATE_AT_PREFIX;
+        iter->mode   = MODE_TO_END;
         return;
     }
 
-    iter->prefix      = 'A';
-    iter->state       = STATE_AT_PREFIX;
-    iter->view_prefix = true;
-    iter->mode        = MODE_TO_SLASH;
+    iter->prefix = 'A';
+    iter->state  = STATE_AT_PREFIX;
+    iter->mode   = MODE_TO_SLASH;
 }
 
 
-static void qd_address_iterator_remove_trailing_separator(qd_field_iterator_t *iter)
+void qd_iterator_remove_trailing_separator(qd_iterator_t *iter)
 {
     // Save the iterator's pointer so we can apply it back before returning from this function.
-    pointer_t save_pointer = iter->pointer;
+    pointer_t save_pointer = iter->view_pointer;
 
     char current_octet = 0;
-    while (!qd_field_iterator_end(iter)) {
-        current_octet = qd_field_iterator_octet(iter);
+    while (!qd_iterator_end(iter)) {
+        current_octet = qd_iterator_octet(iter);
     }
 
     // We have the last octet in current_octet
-    iter->pointer = save_pointer;
+    iter->view_pointer = save_pointer;
     if (current_octet && strrchr(SEPARATORS, (int) current_octet))
-        iter->pointer.length--;
+        iter->view_pointer.remaining--;
 }
 
 
-static void view_initialize(qd_field_iterator_t *iter)
+static void view_initialize(qd_iterator_t *iter)
 {
     //
     // The default behavior is for the view to *not* have a prefix.
     // We'll add one if it's needed later.
     //
-    iter->state       = STATE_IN_ADDRESS;
-    iter->view_prefix = false;
-    iter->mode        = MODE_TO_END;
+    iter->state                = STATE_IN_BODY;
+    iter->prefix               = '\0';
+    iter->mode                 = MODE_TO_END;
+    iter->annotation_length    = 0;
+    iter->annotation_remaining = 0;
 
     if (iter->view == ITER_VIEW_ALL)
         return;
@@ -199,18 +199,18 @@ static void view_initialize(qd_field_iterator_t *iter)
     //
     // Advance to the node-id.
     //
-    state_t        state = STATE_START;
-    unsigned int   octet;
-    pointer_t      save_pointer = {0,0,0};
+    state_t      state = STATE_START;
+    unsigned int octet;
+    pointer_t    save_pointer = {0,0,0};
 
-    while (!qd_field_iterator_end(iter) && state != STATE_AT_NODE_ID) {
-        octet = qd_field_iterator_octet(iter);
+    while (!qd_iterator_end(iter) && state != STATE_AT_NODE_ID) {
+        octet = qd_iterator_octet(iter);
 
         switch (state) {
         case STATE_START :
             if (octet == '/') {
                 state = STATE_SLASH_LEFT;
-                save_pointer = iter->pointer;
+                save_pointer = iter->view_pointer;
             } else
                 state = STATE_SCANNING;
             break;
@@ -220,7 +220,7 @@ static void view_initialize(qd_field_iterator_t *iter)
                 state = STATE_SKIPPING_TO_NEXT_SLASH;
             else {
                 state = STATE_AT_NODE_ID;
-                iter->pointer = save_pointer;
+                iter->view_pointer = save_pointer;
             }
             break;
 
@@ -237,7 +237,7 @@ static void view_initialize(qd_field_iterator_t *iter)
         case STATE_COLON :
             if (octet == '/') {
                 state = STATE_COLON_SLASH;
-                save_pointer = iter->pointer;
+                save_pointer = iter->view_pointer;
             } else
                 state = STATE_SCANNING;
             break;
@@ -247,7 +247,7 @@ static void view_initialize(qd_field_iterator_t *iter)
                 state = STATE_SKIPPING_TO_NEXT_SLASH;
             else {
                 state = STATE_AT_NODE_ID;
-                iter->pointer = save_pointer;
+                iter->view_pointer = save_pointer;
             }
             break;
 
@@ -256,87 +256,78 @@ static void view_initialize(qd_field_iterator_t *iter)
         }
     }
 
-    if (state != STATE_AT_NODE_ID) {
+    if (state != STATE_AT_NODE_ID){
         //
         // The address string was relative, not absolute.  The node-id
         // is at the beginning of the string.
         //
-        iter->pointer = iter->start_pointer;
+        iter->view_pointer = iter->start_pointer;
     }
 
     //
     // Cursor is now on the first octet of the node-id
     //
-    if (iter->view == ITER_VIEW_NODE_ID) {
-        iter->mode = MODE_TO_SLASH;
-        return;
-    }
-
-    if (iter->view == ITER_VIEW_NO_HOST) {
-        iter->mode = MODE_TO_END;
+    if (iter->view == ITER_VIEW_ADDRESS_NO_HOST)
         return;
-    }
 
     if (iter->view == ITER_VIEW_ADDRESS_HASH) {
-        iter->mode = MODE_TO_END;
-        qd_address_iterator_remove_trailing_separator(iter);
+        qd_iterator_remove_trailing_separator(iter); // FIXME - need this?
         parse_address_view(iter);
         return;
     }
 
     if (iter->view == ITER_VIEW_NODE_HASH) {
-        iter->mode = MODE_TO_END;
         parse_node_view(iter);
         return;
     }
-
-    if (iter->view == ITER_VIEW_NODE_SPECIFIC) {
-        iter->mode = MODE_TO_END;
-        while (!qd_field_iterator_end(iter)) {
-            octet = qd_field_iterator_octet(iter);
-            if (octet == '/')
-                break;
-        }
-        return;
-    }
 }
 
 
-static inline void field_iterator_move_cursor(qd_field_iterator_t *iter, uint32_t length)
+static inline void field_iterator_move_cursor(qd_iterator_t *iter, uint32_t length)
 {
     // Only safe to call this help method if the cursor is parsing the data,
     // i.e. if iter is an address iterator, the cursor must be 'past' the
     // prefix
-    assert(iter->state == STATE_IN_ADDRESS);
-    uint32_t count = ((length > iter->pointer.length)
-                      ? iter->pointer.length
-                      : length);
+    assert(iter->state == STATE_IN_BODY);
+    uint32_t count = (length > iter->view_pointer.remaining) ? iter->view_pointer.remaining : length;
 
-    if (iter->pointer.buffer) {
+    if (iter->view_pointer.buffer) {
         while (count) {
-            uint32_t remaining = qd_buffer_cursor(iter->pointer.buffer) - iter->pointer.cursor;
+            uint32_t remaining = qd_buffer_cursor(iter->view_pointer.buffer) - iter->view_pointer.cursor;
             remaining = (remaining > count) ? count : remaining;
-            iter->pointer.cursor += remaining;
-            iter->pointer.length -= remaining;
+            iter->view_pointer.cursor += remaining;
+            iter->view_pointer.remaining -= remaining;
             count -= remaining;
-            if (iter->pointer.cursor == qd_buffer_cursor(iter->pointer.buffer)) {
-                iter->pointer.buffer = iter->pointer.buffer->next;
-                if (iter->pointer.buffer == 0) {
-                    iter->pointer.length = 0;
-                    iter->pointer.cursor = 0;
+            if (iter->view_pointer.cursor == qd_buffer_cursor(iter->view_pointer.buffer)) {
+                iter->view_pointer.buffer = iter->view_pointer.buffer->next;
+                if (iter->view_pointer.buffer == 0) {
+                    iter->view_pointer.remaining = 0;
+                    iter->view_pointer.cursor = 0;
                     break;
                 } else {
-                    iter->pointer.cursor = qd_buffer_base(iter->pointer.buffer);
+                    iter->view_pointer.cursor = qd_buffer_base(iter->view_pointer.buffer);
                 }
             }
         }
     } else {    // string/binary data
-        iter->pointer.cursor += count;
-        iter->pointer.length -= count;
+        iter->view_pointer.cursor    += count;
+        iter->view_pointer.remaining -= count;
     }
 }
 
-void qd_field_iterator_set_address(const char *area, const char *router)
+
+static void qd_iterator_free_hash_segments(qd_iterator_t *iter)
+{
+    qd_hash_segment_t *seg = DEQ_HEAD(iter->hash_segments);
+    while (seg) {
+        DEQ_REMOVE_HEAD(iter->hash_segments);
+        free_qd_hash_segment_t(seg);
+        seg = DEQ_HEAD(iter->hash_segments);
+    }
+}
+
+
+void qd_iterator_set_address(const char *area, const char *router)
 {
     my_area = (char*) malloc(strlen(area) + 2);
     strcpy(my_area, area);
@@ -348,283 +339,333 @@ void qd_field_iterator_set_address(const char *area, const char *router)
 }
 
 
-qd_field_iterator_t* qd_address_iterator_string(const char *text, qd_iterator_view_t view)
+qd_iterator_t* qd_iterator_string(const char *text, qd_iterator_view_t view)
 {
-    qd_field_iterator_t *iter = new_qd_field_iterator_t();
+    qd_iterator_t *iter = new_qd_iterator_t();
     if (!iter)
         return 0;
 
-    iter->start_pointer.buffer     = 0;
-    iter->start_pointer.cursor     = (unsigned char*) text;
-    iter->start_pointer.length     = strlen(text);
-    iter->phase                    = '0';
-    iter->prefix_override          = '\0';
-
-    DEQ_INIT(iter->hash_segments);
+    ZERO(iter);
+    iter->start_pointer.cursor    = (unsigned char*) text;
+    iter->start_pointer.remaining = strlen(text);
+    iter->phase                   = '0';
 
-    qd_address_iterator_reset_view(iter, view);
+    qd_iterator_reset_view(iter, view);
 
     return iter;
 }
 
 
-qd_field_iterator_t* qd_address_iterator_binary(const char *text, int length, qd_iterator_view_t view)
+qd_iterator_t* qd_iterator_binary(const char *text, int length, qd_iterator_view_t view)
 {
-    qd_field_iterator_t *iter = new_qd_field_iterator_t();
+    qd_iterator_t *iter = new_qd_iterator_t();
     if (!iter)
         return 0;
 
-    iter->start_pointer.buffer = 0;
-    iter->start_pointer.cursor = (unsigned char*) text;
-    iter->start_pointer.length = length;
-    iter->phase                = '0';
-    iter->prefix_override      = '\0';
+    ZERO(iter);
+    iter->start_pointer.cursor    = (unsigned char*) text;
+    iter->start_pointer.remaining = length;
+    iter->phase                   = '0';
 
-    DEQ_INIT(iter->hash_segments);
-
-    qd_address_iterator_reset_view(iter, view);
+    qd_iterator_reset_view(iter, view);
 
     return iter;
 }
 
 
-qd_field_iterator_t *qd_address_iterator_buffer(qd_buffer_t *buffer, int offset, int length, qd_iterator_view_t view)
+qd_iterator_t *qd_iterator_buffer(qd_buffer_t *buffer, int offset, int length, qd_iterator_view_t view)
 {
-    qd_field_iterator_t *iter = new_qd_field_iterator_t();
+    qd_iterator_t *iter = new_qd_iterator_t();
     if (!iter)
         return 0;
 
-    iter->start_pointer.buffer = buffer;
-    iter->start_pointer.cursor = qd_buffer_base(buffer) + offset;
-    iter->start_pointer.length = length;
-    iter->phase                = '0';
-    iter->prefix_override      = '\0';
-
-    DEQ_INIT(iter->hash_segments);
+    ZERO(iter);
+    iter->start_pointer.buffer    = buffer;
+    iter->start_pointer.cursor    = qd_buffer_base(buffer) + offset;
+    iter->start_pointer.remaining = length;
+    iter->phase                   = '0';
 
-    qd_address_iterator_reset_view(iter, view);
+    qd_iterator_reset_view(iter, view);
 
     return iter;
 }
 
 
-void qd_field_iterator_free(qd_field_iterator_t *iter)
+void qd_iterator_free(qd_iterator_t *iter)
 {
-    if (!iter) return;
-    free_qd_field_iterator_t(iter);
+    if (!iter)
+        return;
+
+    qd_iterator_free_hash_segments(iter);
+    free_qd_iterator_t(iter);
 }
 
 
-void qd_field_iterator_reset(qd_field_iterator_t *iter)
+void qd_iterator_reset(qd_iterator_t *iter)
 {
-    iter->pointer = iter->view_start_pointer;
-    iter->state   = iter->view_prefix ? STATE_AT_PREFIX : STATE_IN_ADDRESS;
+    if (iter) {
+        iter->view_pointer         = iter->view_start_pointer;
+        iter->state                = iter->prefix ? STATE_AT_PREFIX : STATE_IN_BODY;
+        iter->annotation_remaining = iter->annotation_length;
+    }
 }
 
 
-void qd_address_iterator_reset_view(qd_field_iterator_t *iter, qd_iterator_view_t  view)
+void qd_iterator_reset_view(qd_iterator_t *iter, qd_iterator_view_t view)
 {
-    iter->pointer = iter->start_pointer;
-    iter->view    = view;
+    if (iter) {
+        iter->view_pointer = iter->start_pointer;
+        iter->view         = view;
+        view_initialize(iter);
+        iter->view_start_pointer   = iter->view_pointer;
+        iter->annotation_remaining = iter->annotation_length;
+    }
+}
 
-    view_initialize(iter);
 
-    iter->view_start_pointer = iter->pointer;
+qd_iterator_view_t qd_iterator_get_view(const qd_iterator_t *iter)
+{
+    return iter ? iter->view : ITER_VIEW_ALL;
 }
 
 
-qd_iterator_view_t qd_address_iterator_get_view(const qd_field_iterator_t *iter)
+void qd_iterator_annotate_phase(qd_iterator_t *iter, char phase)
 {
-    return iter->view;
+    if (iter)
+        iter->phase = phase;
 }
 
 
-void qd_address_iterator_set_phase(qd_field_iterator_t *iter, char phase)
+void qd_iterator_trim_view(qd_iterator_t *iter, int length)
 {
-    iter->phase = phase;
+    if (!iter)
+        return;
+
+    iter->view_start_pointer = iter->view_pointer;
+    int view_length = qd_iterator_length(iter);
+    if (view_length > length) {
+        if (iter->annotation_length > length) {
+            iter->annotation_length            = length;
+            iter->annotation_remaining         = length;
+            iter->view_start_pointer.remaining = 0;
+        } else
+            iter->view_start_pointer.remaining -= view_length - length;
+        iter->view_pointer = iter->view_start_pointer;
+    }
 }
 
-void qd_field_iterator_trim(qd_field_iterator_t *iter, int length)
+
+void qd_iterator_annotate_prefix(qd_iterator_t *iter, char prefix)
 {
-    if (qd_field_iterator_length(iter) > length) {
-        iter->start_pointer        = iter->pointer;
-        iter->start_pointer.length = length;
-        iter->view_start_pointer   = iter->start_pointer;
-        iter->pointer              = iter->start_pointer;
+    if (iter) {
+        iter->prefix_override = prefix;
+        qd_iterator_reset_view(iter, iter->view);
     }
 }
 
-void qd_address_iterator_override_prefix(qd_field_iterator_t *iter, char prefix)
+
+void qd_iterator_annotate_space(qd_iterator_t *iter, const char* space, int space_length)
 {
-    iter->prefix_override = prefix;
-    qd_address_iterator_reset_view(iter, iter->view);
+    if (iter) {
+        iter->space        = space;
+        iter->space_length = space_length;
+        if (iter->view == ITER_VIEW_ADDRESS_HASH)
+            iter->annotation_length = space_length + (iter->prefix == 'M' ? 2 : 1);
+    }
 }
 
 
-unsigned char qd_field_iterator_octet(qd_field_iterator_t *iter)
+unsigned char qd_iterator_octet(qd_iterator_t *iter)
 {
+    if (!iter)
+        return 0;
+
     if (iter->state == STATE_AT_PREFIX) {
-        iter->state =  iter->prefix == 'M' ? STATE_AT_PHASE : STATE_IN_ADDRESS;
+        iter->state = iter->prefix == 'M' ? STATE_AT_PHASE : (iter->space ? STATE_IN_SPACE : STATE_IN_BODY);
+        iter->space_cursor = 0;
+        iter->annotation_remaining--;
         return iter->prefix;
     }
 
     if (iter->state == STATE_AT_PHASE) {
-        iter->state = STATE_IN_ADDRESS;
+        iter->state = iter->space ? STATE_IN_SPACE : STATE_IN_BODY;
+        iter->space_cursor = 0;
+        iter->annotation_remaining--;
         return iter->phase;
     }
 
-    if (iter->pointer.length == 0)
+    if (iter->state == STATE_IN_SPACE) {
+        if (iter->space_cursor == iter->space_length - 1) {
+            iter->state = STATE_IN_BODY;
+            assert(iter->annotation_remaining == 1);
+        }
+        iter->annotation_remaining--;
+        return iter->space[iter->space_cursor++];
+    }
+
+    if (iter->view_pointer.remaining == 0)
         return (unsigned char) 0;
 
-    unsigned char result = *(iter->pointer.cursor);
+    unsigned char result = *(iter->view_pointer.cursor);
 
     field_iterator_move_cursor(iter, 1);
-    if (iter->pointer.length && iter->mode == MODE_TO_SLASH && *(iter->pointer.cursor) == '/')
-        iter->pointer.length = 0;
+    if (iter->view_pointer.remaining && iter->mode == MODE_TO_SLASH && *(iter->view_pointer.cursor) == '/')
+        iter->view_pointer.remaining = 0;
 
     return result;
 }
 
 
-int qd_field_iterator_end(const qd_field_iterator_t *iter)
+bool qd_iterator_end(const qd_iterator_t *iter)
 {
-    return iter->pointer.length == 0;
+    return iter ? qd_iterator_remaining(iter) == 0 : true;
 }
 
 
-qd_field_iterator_t *qd_field_iterator_sub(const qd_field_iterator_t *iter, uint32_t length)
+qd_iterator_t *qd_iterator_sub(const qd_iterator_t *iter, uint32_t length)
 {
-    qd_field_iterator_t *sub = new_qd_field_iterator_t();
-    if (!sub)
+    if (!iter)
         return 0;
 
-    sub->start_pointer        = iter->pointer;
-    sub->start_pointer.length = length;
-    sub->view_start_pointer   = sub->start_pointer;
-    sub->pointer              = sub->start_pointer;
-    sub->view                 = iter->view;
-    sub->mode                 = iter->mode;
-    sub->state                = STATE_IN_ADDRESS;
-    sub->view_prefix          = false;
-    sub->prefix_override      = '\0';
-    sub->phase                = '0';
+    qd_iterator_t *sub = new_qd_iterator_t();
+    if (!sub)
+        return 0;
 
-    DEQ_INIT(sub->hash_segments);
+    ZERO(sub);
+    sub->start_pointer           = iter->view_pointer;
+    sub->start_pointer.remaining = length;
+    sub->view_start_pointer      = sub->start_pointer;
+    sub->view_pointer            = sub->start_pointer;
+    sub->view                    = iter->view;
+    sub->mode                    = iter->mode;
+    sub->state                   = STATE_IN_BODY;
+    sub->phase                   = '0';
 
     return sub;
 }
 
 
-void qd_field_iterator_advance(qd_field_iterator_t *iter, uint32_t length)
+void qd_iterator_advance(qd_iterator_t *iter, uint32_t length)
 {
-    while (length > 0 && !qd_field_iterator_end(iter)) {
-        if (iter->state == STATE_IN_ADDRESS) {
+    if (!iter)
+        return;
+
+    while (length > 0 && !qd_iterator_end(iter)) {
+        if (iter->state == STATE_IN_BODY) {
             field_iterator_move_cursor(iter, length);
             break;
         } else {
-            qd_field_iterator_octet(iter);
+            qd_iterator_octet(iter);
             length--;
         }
     }
 }
 
 
-uint32_t qd_field_iterator_remaining(const qd_field_iterator_t *iter)
+uint32_t qd_iterator_remaining(const qd_iterator_t *iter)
 {
-    return iter->pointer.length;
+    return iter ? iter->annotation_remaining + iter->view_pointer.remaining : 0;
 }
 
 
-int qd_field_iterator_equal(qd_field_iterator_t *iter, const unsigned char *string)
+bool qd_iterator_equal(qd_iterator_t *iter, const unsigned char *string)
 {
-    qd_field_iterator_reset(iter);
+    if (!iter)
+        return false;
+
+    qd_iterator_reset(iter);
 
-    while (!qd_field_iterator_end(iter) && *string) {
-        if (*string != qd_field_iterator_octet(iter))
+    while (!qd_iterator_end(iter) && *string) {
+        if (*string != qd_iterator_octet(iter))
             break;
         string++;
     }
 
-    int match = (qd_field_iterator_end(iter) && (*string == 0));
-    qd_field_iterator_reset(iter);
+    bool match = (qd_iterator_end(iter) && (*string == 0));
+    qd_iterator_reset(iter);
     return match;
 }
 
 
-int qd_field_iterator_prefix(qd_field_iterator_t *iter, const char *prefix)
+bool qd_iterator_prefix(qd_iterator_t *iter, const char *prefix)
 {
-    pointer_t      save_pointer = iter->pointer;
+    if (!iter)
+        return false;
+
+    pointer_t      save_pointer = iter->view_pointer;
     unsigned char *c            = (unsigned char*) prefix;
 
     while(*c) {
-        if (*c != qd_field_iterator_octet(iter))
+        if (*c != qd_iterator_octet(iter))
             break;
         c++;
     }
 
     if (*c) {
-        iter->pointer = save_pointer;
-        return 0;
+        iter->view_pointer = save_pointer;
+        return false;
     }
 
-    return 1;
+    return true;
 }
 
 
-int qd_field_iterator_length(const qd_field_iterator_t *iter)
+int qd_iterator_length(const qd_iterator_t *iter)
 {
-    qd_field_iterator_t copy = *iter;
-    int length = 0;
-    qd_field_iterator_reset(&copy);
-    while (!qd_field_iterator_end(&copy)) {
-        qd_field_iterator_octet(&copy);
-        length++;
-    }
-    return length;
+    return iter ? iter->annotation_length + iter->view_start_pointer.remaining : 0;
 }
 
 
-int qd_field_iterator_ncopy(qd_field_iterator_t *iter, unsigned char* buffer, int n) {
-    qd_field_iterator_reset(iter);
+int qd_iterator_ncopy(qd_iterator_t *iter, unsigned char* buffer, int n)
+{
+    if (!iter)
+        return 0;
+
+    qd_iterator_reset(iter);
     int i = 0;
-    while (!qd_field_iterator_end(iter) && i < n)
-        buffer[i++] = qd_field_iterator_octet(iter);
+    while (!qd_iterator_end(iter) && i < n)
+        buffer[i++] = qd_iterator_octet(iter);
     return i;
 }
 
 
-char* qd_field_iterator_strncpy(qd_field_iterator_t *iter, char* buffer, int n) {
-    int i = qd_field_iterator_ncopy(iter, (unsigned char*)buffer, n-1);
+char* qd_iterator_strncpy(qd_iterator_t *iter, char* buffer, int n)
+{
+    int i = qd_iterator_ncopy(iter, (unsigned char*) buffer, n-1);
     buffer[i] = '\0';
     return buffer;
 }
 
 
-unsigned char *qd_field_iterator_copy(qd_field_iterator_t *iter)
+unsigned char *qd_iterator_copy(qd_iterator_t *iter)
 {
-    int length = qd_field_iterator_length(iter);
+    if (!iter)
+        return 0;
+
+    int length = qd_iterator_length(iter);
     unsigned char *copy = malloc(length+1);
-    int i = qd_field_iterator_ncopy(iter, copy, length+1);
+    int i = qd_iterator_ncopy(iter, copy, length+1);
     copy[i] = '\0';
     return copy;
 }
 
 
-qd_field_iterator_t *qd_field_iterator_dup(const qd_field_iterator_t *iter)
+qd_iterator_t *qd_iterator_dup(const qd_iterator_t *iter)
 {
-    if (iter == 0)
+    if (!iter)
         return 0;
 
-    qd_field_iterator_t *dup = new_qd_field_iterator_t();
+    qd_iterator_t *dup = new_qd_iterator_t();
     if (dup)
         *dup = *iter;
     return dup;
 }
 
 
-qd_iovec_t *qd_field_iterator_iovec(const qd_field_iterator_t *iter)
+qd_iovec_t *qd_iterator_iovec(const qd_iterator_t *iter)
 {
-    assert(!iter->view_prefix); // Not supported for views with a prefix
+    if (!iter)
+        return 0;
 
     //
     // Count the number of buffers this field straddles
@@ -633,7 +674,7 @@ qd_iovec_t *qd_field_iterator_iovec(const qd_field_iterator_t *iter)
     int          bufcnt    = 1;
     qd_buffer_t *buf       = pointer.buffer;
     size_t       bufsize   = qd_buffer_size(buf) - (pointer.cursor - qd_buffer_base(pointer.buffer));
-    ssize_t      remaining = pointer.length - bufsize;
+    ssize_t      remaining = pointer.remaining - bufsize;
 
     while (remaining > 0) {
         bufcnt++;
@@ -657,7 +698,7 @@ qd_iovec_t *qd_field_iterator_iovec(const qd_field_iterator_t *iter)
     buf        = pointer.buffer;
     bufsize    = qd_buffer_size(buf) - (pointer.cursor - qd_buffer_base(pointer.buffer));
     void *base = pointer.cursor;
-    remaining  = pointer.length;
+    remaining  = pointer.remaining;
 
     while (remaining > 0) {
         if (bufsize > remaining)
@@ -677,18 +718,6 @@ qd_iovec_t *qd_field_iterator_iovec(const qd_field_iterator_t *iter)
 }
 
 
-uint32_t qd_iterator_hash_function(qd_field_iterator_t *iter)
-{
-    uint32_t hash = HASH_INIT;
-
-    qd_field_iterator_reset(iter);
-    while (!qd_field_iterator_end(iter))
-        hash = ((hash << 5) + hash) + (int) qd_field_iterator_octet(iter); /* hash * 33 + c */
-
-    return hash;
-}
-
-
 /**
  * Creates and returns a new qd_hash_segment_t and initializes it.
  */
@@ -696,7 +725,7 @@ static qd_hash_segment_t *qd_iterator_hash_segment(void)
 {
     qd_hash_segment_t *hash_segment = new_qd_hash_segment_t();
     DEQ_ITEM_INIT(hash_segment);
-    hash_segment->hash       = 0;
+    hash_segment->hash           = 0;
     hash_segment->segment_length = 0;
     return hash_segment;
 }
@@ -705,7 +734,7 @@ static qd_hash_segment_t *qd_iterator_hash_segment(void)
 /**
  * Create a new hash segment and insert it at the end of the linked list
  */
-static void qd_insert_hash_segment(qd_field_iterator_t *iter, uint32_t *hash, int segment_length)
+static void qd_insert_hash_segment(qd_iterator_t *iter, uint32_t *hash, int segment_length)
 {
     qd_hash_segment_t *hash_segment = qd_iterator_hash_segment();
 
@@ -717,17 +746,34 @@ static void qd_insert_hash_segment(qd_field_iterator_t *iter, uint32_t *hash, in
 }
 
 
-void qd_iterator_hash_segments(qd_field_iterator_t *iter)
+uint32_t qd_iterator_hash_view(qd_iterator_t *iter)
 {
+    uint32_t hash = HASH_INIT;
+
+    qd_iterator_reset(iter);
+    while (!qd_iterator_end(iter))
+        hash = ((hash << 5) + hash) + (uint32_t) qd_iterator_octet(iter); /* hash * 33 + c */
+
+    return hash;
+}
+
+
+void qd_iterator_hash_view_segments(qd_iterator_t *iter)
+{
+    if (!iter)
+        return;
+    
     // Reset the pointers in the iterator
-    qd_field_iterator_reset(iter);
+    qd_iterator_reset(iter);
     uint32_t hash = HASH_INIT;
     char octet;
     int segment_length=0;
 
-    while (!qd_field_iterator_end(iter)) {
+    qd_iterator_free_hash_segments(iter);
+
+    while (!qd_iterator_end(iter)) {
         // Get the octet at which the iterator is currently pointing to.
-        octet = qd_field_iterator_octet(iter);
+        octet = qd_iterator_octet(iter);
         segment_length += 1;
 
         if (strrchr(SEPARATORS, (int) octet)) {
@@ -738,34 +784,24 @@ void qd_iterator_hash_segments(qd_field_iterator_t *iter)
     }
 
     // Segments should never end with a separator. see view_initialize which in turn calls
-    // qd_address_iterator_remove_trailing_separator
+    // qd_iterator_remove_trailing_separator
     // Insert the last segment which was not inserted in the previous while loop
     qd_insert_hash_segment(iter, &hash, segment_length);
 
     // Return the pointers in the iterator back to the original state before returning from this function.
-    qd_field_iterator_reset(iter);
+    qd_iterator_reset(iter);
 }
 
 
-bool qd_iterator_hash_and_reset(qd_field_iterator_t *iter, uint32_t *hash)
+bool qd_iterator_next_segment(qd_iterator_t *iter, uint32_t *hash)
 {
     qd_hash_segment_t *hash_segment = DEQ_TAIL(iter->hash_segments);
     if (!hash_segment)
         return false;
 
     *hash = hash_segment->hash;
+    qd_iterator_trim_view(iter, hash_segment->segment_length);
 
-    // Get the length of the hashed segment and set it on the iterator so that the iterator can only advance till that length
-    // Check for a non empty iter->prefix and reduce the segment length by 1
-    if (iter->view_prefix) {
-        if (iter->prefix == 'M')
-            iter->view_start_pointer.length = hash_segment->segment_length - 2;
-        else
-            iter->view_start_pointer.length = hash_segment->segment_length - 1;
-    } else
-        iter->view_start_pointer.length = hash_segment->segment_length;
-
-    // Remove the tail from the hash segments since we have already compared it.
     DEQ_REMOVE_TAIL(iter->hash_segments);
 
     free_qd_hash_segment_t(hash_segment);

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/src/message.c
----------------------------------------------------------------------
diff --git a/src/message.c b/src/message.c
index 03586ee..5ae8f2e 100644
--- a/src/message.c
+++ b/src/message.c
@@ -86,16 +86,16 @@ static void quote(char* bytes, int n, char **begin, char *end) {
 static void copy_field(qd_message_t *msg,  int field, int max, char *pre, char *post,
                        char **begin, char *end)
 {
-    qd_field_iterator_t* iter = qd_message_field_iterator(msg, field);
+    qd_iterator_t* iter = qd_message_field_iterator(msg, field);
     if (iter) {
         aprintf(begin, end, "%s", pre);
-        qd_field_iterator_reset(iter);
-        for (int j = 0; !qd_field_iterator_end(iter) && j < max; ++j) {
-            char byte = qd_field_iterator_octet(iter);
+        qd_iterator_reset(iter);
+        for (int j = 0; !qd_iterator_end(iter) && j < max; ++j) {
+            char byte = qd_iterator_octet(iter);
             quote(&byte, 1, begin, end);
         }
         aprintf(begin, end, "%s", post);
-        qd_field_iterator_free(iter);
+        qd_iterator_free(iter);
     }
 }
 
@@ -633,7 +633,7 @@ qd_parsed_field_t *qd_message_message_annotations(qd_message_t *in_msg)
     if (content->parsed_message_annotations)
         return content->parsed_message_annotations;
 
-    qd_field_iterator_t *ma = qd_message_field_iterator(in_msg, QD_FIELD_MESSAGE_ANNOTATION);
+    qd_iterator_t *ma = qd_message_field_iterator(in_msg, QD_FIELD_MESSAGE_ANNOTATION);
     if (ma == 0)
         return 0;
 
@@ -641,13 +641,13 @@ qd_parsed_field_t *qd_message_message_annotations(qd_message_t *in_msg)
     if (content->parsed_message_annotations == 0 ||
         !qd_parse_ok(content->parsed_message_annotations) ||
         !qd_parse_is_map(content->parsed_message_annotations)) {
-        qd_field_iterator_free(ma);
+        qd_iterator_free(ma);
         qd_parse_free(content->parsed_message_annotations);
         content->parsed_message_annotations = 0;
         return 0;
     }
 
-    qd_field_iterator_free(ma);
+    qd_iterator_free(ma);
     return content->parsed_message_annotations;
 }
 
@@ -805,9 +805,9 @@ static void compose_message_annotations(qd_message_pvt_t *msg, qd_buffer_list_t
             if (!sub_key)
                 continue;
 
-            qd_field_iterator_t *iter = qd_parse_raw(sub_key);
+            qd_iterator_t *iter = qd_parse_raw(sub_key);
 
-            if (!qd_field_iterator_prefix(iter, QD_MA_PREFIX)) {
+            if (!qd_iterator_prefix(iter, QD_MA_PREFIX)) {
                 if (!map_started) {
                     qd_compose_start_map(out_ma);
                     map_started = true;
@@ -1099,17 +1099,17 @@ int qd_message_check(qd_message_t *in_msg, qd_message_depth_t depth)
 }
 
 
-qd_field_iterator_t *qd_message_field_iterator_typed(qd_message_t *msg, qd_message_field_t field)
+qd_iterator_t *qd_message_field_iterator_typed(qd_message_t *msg, qd_message_field_t field)
 {
     qd_field_location_t *loc = qd_message_field_location(msg, field);
     if (!loc)
         return 0;
 
-    return qd_field_iterator_buffer(loc->buffer, loc->offset, loc->length + loc->hdr_length);
+    return qd_iterator_buffer(loc->buffer, loc->offset, loc->length + loc->hdr_length, ITER_VIEW_ALL);
 }
 
 
-qd_field_iterator_t *qd_message_field_iterator(qd_message_t *msg, qd_message_field_t field)
+qd_iterator_t *qd_message_field_iterator(qd_message_t *msg, qd_message_field_t field)
 {
     qd_field_location_t *loc = qd_message_field_location(msg, field);
     if (!loc)
@@ -1122,7 +1122,7 @@ qd_field_iterator_t *qd_message_field_iterator(qd_message_t *msg, qd_message_fie
     unsigned char *cursor = qd_buffer_base(loc->buffer) + loc->offset;
     advance(&cursor, &buffer, loc->hdr_length, 0, 0);
 
-    return qd_field_iterator_buffer(buffer, cursor - qd_buffer_base(buffer), loc->length);
+    return qd_iterator_buffer(buffer, cursor - qd_buffer_base(buffer), loc->length, ITER_VIEW_ALL);
 }
 
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org