Author: rhs
Date: Wed May 29 13:34:19 2013
New Revision: 1487479

URL: http://svn.apache.org/r1487479
Log:
added iteration API to map and hash

Modified:
    qpid/proton/trunk/proton-c/include/proton/object.h
    qpid/proton/trunk/proton-c/src/object/object.c
    qpid/proton/trunk/proton-c/src/tests/object.c

Modified: qpid/proton/trunk/proton-c/include/proton/object.h
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/include/proton/object.h?rev=1487479&r1=1487478&r2=1487479&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/include/proton/object.h (original)
+++ qpid/proton/trunk/proton-c/include/proton/object.h Wed May 29 13:34:19 2013
@@ -62,6 +62,7 @@ PN_EXTERN ssize_t pn_list_index(pn_list_
 PN_EXTERN bool pn_list_remove(pn_list_t *list, void *value);
 PN_EXTERN void pn_list_del(pn_list_t *list, int index, int n);
 
+typedef uintptr_t pn_handle_t;
 
 typedef struct pn_map_t pn_map_t;
 
@@ -73,6 +74,10 @@ PN_EXTERN size_t pn_map_size(pn_map_t *m
 PN_EXTERN int pn_map_put(pn_map_t *map, void *key, void *value);
 PN_EXTERN void *pn_map_get(pn_map_t *map, void *key);
 PN_EXTERN void pn_map_del(pn_map_t *map, void *key);
+PN_EXTERN pn_handle_t pn_map_head(pn_map_t *map);
+PN_EXTERN pn_handle_t pn_map_next(pn_map_t *map, pn_handle_t entry);
+PN_EXTERN void *pn_map_key(pn_map_t *map, pn_handle_t entry);
+PN_EXTERN void *pn_map_value(pn_map_t *map, pn_handle_t entry);
 
 typedef struct pn_hash_t pn_hash_t;
 
@@ -81,6 +86,10 @@ PN_EXTERN size_t pn_hash_size(pn_hash_t 
 PN_EXTERN int pn_hash_put(pn_hash_t *hash, uintptr_t key, void *value);
 PN_EXTERN void *pn_hash_get(pn_hash_t *hash, uintptr_t key);
 PN_EXTERN void pn_hash_del(pn_hash_t *hash, uintptr_t key);
+PN_EXTERN pn_handle_t pn_hash_head(pn_hash_t *hash);
+PN_EXTERN pn_handle_t pn_hash_next(pn_hash_t *hash, pn_handle_t entry);
+PN_EXTERN uintptr_t pn_hash_key(pn_hash_t *hash, pn_handle_t entry);
+PN_EXTERN void *pn_hash_value(pn_hash_t *hash, pn_handle_t entry);
 
 typedef struct pn_string_t pn_string_t;
 

Modified: qpid/proton/trunk/proton-c/src/object/object.c
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/object/object.c?rev=1487479&r1=1487478&r2=1487479&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/object/object.c (original)
+++ qpid/proton/trunk/proton-c/src/object/object.c Wed May 29 13:34:19 2013
@@ -479,6 +479,44 @@ void pn_map_del(pn_map_t *map, void *key
   }
 }
 
+pn_handle_t pn_map_head(pn_map_t *map)
+{
+  assert(map);
+  for (size_t i = 0; i < map->capacity; i++)
+  {
+    if (map->entries[i].state != PNI_ENTRY_FREE) {
+      return i + 1;
+    }
+  }
+
+  return 0;
+}
+
+pn_handle_t pn_map_next(pn_map_t *map, pn_handle_t entry)
+{
+  for (size_t i = entry; i < map->capacity; i++) {
+    if (map->entries[i].state != PNI_ENTRY_FREE) {
+      return i + 1;
+    }
+  }
+
+  return 0;
+}
+
+void *pn_map_key(pn_map_t *map, pn_handle_t entry)
+{
+  assert(map);
+  assert(entry);
+  return map->entries[entry - 1].key;
+}
+
+void *pn_map_value(pn_map_t *map, pn_handle_t entry)
+{
+  assert(map);
+  assert(entry);
+  return map->entries[entry - 1].value;
+}
+
 struct pn_hash_t {
   pn_map_t map;
 };
@@ -523,6 +561,27 @@ void pn_hash_del(pn_hash_t *hash, uintpt
   pn_map_del(&hash->map, (void *) key);
 }
 
+pn_handle_t pn_hash_head(pn_hash_t *hash)
+{
+  return pn_map_head(&hash->map);
+}
+
+pn_handle_t pn_hash_next(pn_hash_t *hash, pn_handle_t entry)
+{
+  return pn_map_next(&hash->map, entry);
+}
+
+uintptr_t pn_hash_key(pn_hash_t *hash, pn_handle_t entry)
+{
+  return (uintptr_t) pn_map_key(&hash->map, entry);
+}
+
+void *pn_hash_value(pn_hash_t *hash, pn_handle_t entry)
+{
+  return pn_map_value(&hash->map, entry);
+}
+
+
 #define PNI_NULL_SIZE (-1)
 
 struct pn_string_t {

Modified: qpid/proton/trunk/proton-c/src/tests/object.c
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/tests/object.c?rev=1487479&r1=1487478&r2=1487479&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/tests/object.c (original)
+++ qpid/proton/trunk/proton-c/src/tests/object.c Wed May 29 13:34:19 2013
@@ -19,6 +19,7 @@
  *
  */
 
+#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -26,6 +27,68 @@
 
 #define assert(E) ((E) ? 0 : (abort(), 0))
 
+static char mem;
+static void *END = &mem;
+
+static pn_list_t *build_list(size_t capacity, int options, ...)
+{
+  pn_list_t *result = pn_list(capacity, options);
+  va_list ap;
+
+  va_start(ap, options);
+  while (true) {
+    void *arg = va_arg(ap, void *);
+    if (arg == END) {
+      break;
+    }
+
+    pn_list_add(result, arg);
+    if (PN_REFCOUNT & options) {
+      pn_decref(arg);
+    }
+  }
+  va_end(ap);
+
+  return result;
+}
+
+static pn_map_t *build_map(size_t capacity, float load_factor, int options, 
...)
+{
+  pn_map_t *result = pn_map(capacity, load_factor, options);
+  va_list ap;
+
+  void *prev = NULL;
+
+  va_start(ap, options);
+  int count = 0;
+  while (true) {
+    void *arg = va_arg(ap, void *);
+    bool last = arg == END;
+    if (arg == END) {
+      arg = NULL;
+    }
+
+    if (count % 2) {
+      pn_map_put(result, prev, arg);
+      if (PN_REFCOUNT & options) {
+        pn_decref(prev);
+        pn_decref(arg);
+      }
+    } else {
+      prev = arg;
+    }
+
+    if (last) {
+      break;
+    }
+
+    count++;
+  }
+  va_end(ap);
+
+  return result;
+}
+
 static void noop(void *o) {}
 static uintptr_t zero(void *o) { return 0; }
 static intptr_t delta(void *a, void *b) { return (uintptr_t) b - (uintptr_t) 
a; }
@@ -254,6 +317,82 @@ static void test_list_index()
   pn_free(nonexistent);
 }
 
+static bool pn_strequals(const char *a, const char *b)
+{
+  return !strcmp(a, b);
+}
+
+static void test_build_list()
+{
+  pn_list_t *l = build_list(0, PN_REFCOUNT,
+                            pn_string("one"),
+                            pn_string("two"),
+                            pn_string("three"),
+                            END);
+
+  assert(pn_list_size(l) == 3);
+
+  assert(pn_strequals(pn_string_get((pn_string_t *) pn_list_get(l, 0)),
+                      "one"));
+  assert(pn_strequals(pn_string_get((pn_string_t *) pn_list_get(l, 1)),
+                      "two"));
+  assert(pn_strequals(pn_string_get((pn_string_t *) pn_list_get(l, 2)),
+                      "three"));
+
+  pn_free(l);
+}
+
+static void test_build_map()
+{
+  pn_map_t *m = build_map(0, 0.75, PN_REFCOUNT,
+                          pn_string("key"),
+                          pn_string("value"),
+                          pn_string("key2"),
+                          pn_string("value2"),
+                          END);
+
+  assert(pn_map_size(m) == 2);
+
+  pn_string_t *key = pn_string(NULL);
+
+  pn_string_set(key, "key");
+  assert(pn_strequals(pn_string_get((pn_string_t *) pn_map_get(m, key)),
+                      "value"));
+  pn_string_set(key, "key2");
+  assert(pn_strequals(pn_string_get((pn_string_t *) pn_map_get(m, key)),
+                      "value2"));
+
+  pn_free(m);
+  pn_free(key);
+}
+
+static void test_build_map_odd()
+{
+  pn_map_t *m = build_map(0, 0.75, PN_REFCOUNT,
+                          pn_string("key"),
+                          pn_string("value"),
+                          pn_string("key2"),
+                          pn_string("value2"),
+                          pn_string("key3"),
+                          END);
+
+  assert(pn_map_size(m) == 3);
+
+  pn_string_t *key = pn_string(NULL);
+
+  pn_string_set(key, "key");
+  assert(pn_strequals(pn_string_get((pn_string_t *) pn_map_get(m, key)),
+                      "value"));
+  pn_string_set(key, "key2");
+  assert(pn_strequals(pn_string_get((pn_string_t *) pn_map_get(m, key)),
+                      "value2"));
+  pn_string_set(key, "key3");
+  assert(pn_map_get(m, key) == NULL);
+
+  pn_free(m);
+  pn_free(key);
+}
+
 static void test_map()
 {
   void *one = pn_new(0, NULL);
@@ -440,6 +579,45 @@ static void test_string_format()
   pn_free(str);
 }
 
+static void test_map_iteration(int n)
+{
+  pn_list_t *pairs = pn_list(2*n, PN_REFCOUNT);
+  for (int i = 0; i < n; i++) {
+    void *key = pn_new(0, NULL);
+    void *value = pn_new(0, NULL);
+    pn_list_add(pairs, key);
+    pn_list_add(pairs, value);
+    pn_decref(key);
+    pn_decref(value);
+  }
+
+  pn_map_t *map = pn_map(0, 0.75, PN_REFCOUNT);
+
+  assert(pn_map_head(map) == 0);
+
+  for (int i = 0; i < n; i++) {
+    pn_map_put(map, pn_list_get(pairs, 2*i), pn_list_get(pairs, 2*i + 1));
+  }
+
+  for (pn_handle_t entry = pn_map_head(map); entry; entry = pn_map_next(map, 
entry))
+  {
+    void *key = pn_map_key(map, entry);
+    void *value = pn_map_value(map, entry);
+    ssize_t idx = pn_list_index(pairs, key);
+    assert(idx >= 0);
+
+    assert(pn_list_get(pairs, idx) == key);
+    assert(pn_list_get(pairs, idx + 1) == value);
+
+    pn_list_del(pairs, idx, 2);
+  }
+
+  assert(pn_list_size(pairs) == 0);
+
+  pn_decref(map);
+  pn_decref(pairs);
+}
+
 int main(int argc, char **argv)
 {
   for (size_t i = 0; i < 128; i++) {
@@ -481,5 +659,14 @@ int main(int argc, char **argv)
 
   test_string_format();
 
+  test_build_list();
+  test_build_map();
+  test_build_map_odd();
+
+  for (int i = 0; i < 64; i++)
+  {
+    test_map_iteration(i);
+  }
+
   return 0;
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to