You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by cl...@apache.org on 2014/07/02 21:52:45 UTC
svn commit: r1607465 - in /qpid/proton/trunk/proton-c/src: object/object.c
tests/object.c
Author: cliffjansen
Date: Wed Jul 2 19:52:45 2014
New Revision: 1607465
URL: http://svn.apache.org/r1607465
Log:
PROTON-617: pn_map_del fix to restore lost linking information between map entries
Modified:
qpid/proton/trunk/proton-c/src/object/object.c
qpid/proton/trunk/proton-c/src/tests/object.c
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=1607465&r1=1607464&r2=1607465&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/object/object.c (original)
+++ qpid/proton/trunk/proton-c/src/object/object.c Wed Jul 2 19:52:45 2014
@@ -631,17 +631,24 @@ void pn_map_del(pn_map_t *map, void *key
pni_entry_t *prev = NULL;
pni_entry_t *entry = pni_map_entry(map, key, &prev, false);
if (entry) {
+ void *dref_key = (map->count_keys) ? entry->key : NULL;
+ void *dref_value = (map->count_values) ? entry->value : NULL;
if (prev) {
prev->next = entry->next;
prev->state = entry->state;
+ } else if (entry->next) {
+ assert(entry->state == PNI_ENTRY_LINK);
+ pni_entry_t *next = &map->entries[entry->next];
+ *entry = *next;
+ entry = next;
}
entry->state = PNI_ENTRY_FREE;
entry->next = 0;
- if (map->count_keys) pn_decref2(entry->key, map);
entry->key = NULL;
- if (map->count_values) pn_decref2(entry->value, map);
entry->value = NULL;
map->size--;
+ if (dref_key) pn_decref2(dref_key, map);
+ if (dref_value) pn_decref2(dref_value, map);
}
}
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=1607465&r1=1607464&r2=1607465&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/tests/object.c (original)
+++ qpid/proton/trunk/proton-c/src/tests/object.c Wed Jul 2 19:52:45 2014
@@ -499,6 +499,50 @@ static void test_hash(void)
pn_decref(three);
}
+
+// collider class: all objects have same hash, no two objects compare equal
+static intptr_t collider_compare(void *a, void *b)
+{
+ if (a == b) return 0;
+ return (a > b) ? 1 : -1;
+}
+
+static uintptr_t collider_hashcode(void *obj)
+{
+ return 23;
+}
+
+#define collider_initialize NULL
+#define collider_finalize NULL
+#define collider_inspect NULL
+
+static void test_map_links(void)
+{
+ const pn_class_t collider_clazz = PN_CLASS(collider);
+ void *keys[3];
+ for (int i = 0; i < 3; i++)
+ keys[i] = pn_new(0, &collider_clazz);
+
+ // test deleting a head, middle link, tail
+
+ for (int delete_idx=0; delete_idx < 3; delete_idx++) {
+ pn_map_t *map = pn_map(0, 0.75, 0);
+ // create a chain of entries that have same head (from identical key hashcode)
+ for (int i = 0; i < 3; i++) {
+ pn_map_put(map, keys[i], keys[i]);
+ }
+ pn_map_del(map, keys[delete_idx]);
+ for (int i = 0; i < 3; i++) {
+ void *value = (i == delete_idx) ? NULL : keys[i];
+ assert (pn_map_get(map, keys[i]) == value);
+ }
+ pn_free(map);
+ }
+ for (int i = 0; i < 3; i++)
+ pn_free(keys[i]);
+}
+
+
static bool equals(const char *a, const char *b)
{
if (a == NULL && b == NULL) {
@@ -792,6 +836,7 @@ int main(int argc, char **argv)
test_list_index();
test_map();
+ test_map_links();
test_hash();
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org