]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fix the skiplist brokenness Nick found:
authorJeremy Fitzhardinge <jeremy@valgrind.org>
Tue, 27 Jul 2004 21:49:23 +0000 (21:49 +0000)
committerJeremy Fitzhardinge <jeremy@valgrind.org>
Tue, 27 Jul 2004 21:49:23 +0000 (21:49 +0000)
 - use a simple memset to initialize the next pointer vector
 - fix some previously unexercised code as a result of the above
Still haven't verified we're actually getting skipping, but it doesn't
crash with a make regtest.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2532

coregrind/vg_skiplist.c

index 350f53c1756133c5a920a617cce75335aaec8ff5..fac7b7c0afad6e21d03fe1d305269e686355d39c 100644 (file)
@@ -210,11 +210,14 @@ static inline void validate_skiplist(const SkipList *l, const Char *where)
 
 void *VG_(SkipNode_Alloc)(const SkipList *l)
 {
-   UInt size = l->size;
-   Int h = get_height();
+   UInt size;
+   Int h;
    SkipNode *n;
    Char *ret;
 
+   h = get_height();
+
+   size = l->size;
    size += sizeof(SkipNode) + (h+1)*sizeof(SkipNode *);
 
    if (l->arena == -1)
@@ -229,8 +232,7 @@ void *VG_(SkipNode_Alloc)(const SkipList *l)
    n->level = h;
    n->magic = SKIPLIST_MAGIC;
 
-   while(h-- >= 0)
-      n->next[h] = NULL;
+   VG_(memset)(n->next, 0, sizeof(n->next[0]) * (h+1));
 
    return ret;
 }
@@ -349,7 +351,7 @@ void *VG_(SkipList_Find)(const SkipList *l, void *k)
 void VG_(SkipList_Insert)(SkipList *l, void *data)
 {
    SkipNode *update[SK_MAXHEIGHT];
-   SkipNode *n;
+   SkipNode *n, *nn;
    void *k = key_of_data(l, data);
    Int i;
 
@@ -372,19 +374,25 @@ void VG_(SkipList_Insert)(SkipList *l, void *data)
       l->head->level = 0;
    }
 
-   n = SkipList__Find(l, k, update);
-   
-   vg_assert(n == NULL || (l->cmp)(key_of_node(l, n), k) != 0);
-
    n = node_of_data(l, data);
 
+   /* update size of head's next vector to fit this new node */
    vg_assert(l->head != NULL);
    if (l->head->level < n->level) {
       for(i = l->head->level+1; i <= n->level; i++)
-        l->head->next[i] = n;
+        l->head->next[i] = NULL;
       l->head->level = n->level;
    }
 
+   /* Look for the node, but we're mostly interested in setting
+      "update", which is the set of previous nodes with next pointers
+      we need to fix up. */
+   nn = SkipList__Find(l, k, update);
+   
+   /* check the new entry is unique */
+   vg_assert(nn == NULL || (l->cmp)(key_of_node(l, nn), k) != 0);
+
+   /* update the previous node's next pointers */
    for(i = 0; i <= n->level; i++) {
       n->next[i] = update[i]->next[i];
       update[i]->next[i] = n;