debugging
[rrq/rrqmisc.git] / vector / vector.c
index 8dadf00a440873ad7ee4e4962ee50c822b75db29..129ba02990e8e01d03ec6364b1092ac418e654d9 100644 (file)
@@ -7,6 +7,31 @@
  * void*, and an index is "unsigned long" (64 bits).
  */
 
+#if VECTOR_LEVEL_BITS == 4
+typedef union {
+    vector_index as_whole;
+    struct {
+       unsigned int msb:4; unsigned int lsb:4;
+    } __attribute__ ((__packed__)) as_byte[8];
+} vector_indexing;
+
+#define VECTOR_PART_BYTE(i,p) ((vector_indexing*)(i))->as_byte[ (p)/2 ]
+
+static int VECTOR_INDEX_PART(vector_index *index,int part) {
+    if ( part & 1 ) {
+       return VECTOR_PART_BYTE(index,part).lsb;
+    }
+    return VECTOR_PART_BYTE(index,part).msb;
+}
+
+static int VECTOR_INDEX_PART_INC(vector_index *index,int part) {
+    if ( part & 1 ) {
+       return ++VECTOR_PART_BYTE(index,part).lsb;
+    }
+    return ++VECTOR_PART_BYTE(index,part).msb;
+}
+#endif
+
 /**
  * Advances a vector index to the next used slot at or below the
  * given level, starting from the indexed entry (inclusive) and up.
@@ -35,7 +60,7 @@ static void **vector_level_next_used(
                *p = 0;
            }
        }
-       if ( ++VECTOR_INDEX_PART( index, level ) == 0 ) {
+       if ( VECTOR_INDEX_PART_INC( index, level ) == 0 ) {
            break; // cycling this level => nothing found
        }
     }
@@ -149,15 +174,21 @@ int vector_resize(
        vector_page *entries;
        vector_page **pp = &pv->entries;
        while ( level.old-- > level.new ) {
-           pp = (vector_page **)(*pp)[0];
+           if ( pp ) {
+               pp = (vector_page **)(*pp)[0];
+           }
        }
        if ( pp != &pv->entries ) {
            entries = pv->entries;
-           pv->entries = *pp;
-           *pp = 0;
+           if ( pp ) {
+               pv->entries = *pp;
+               *pp = 0; // Detach subtree
+           } else {
+               pv->entries = 0;
+           }
            vector_reclaim( entries, level.old );
        }
-       if ( new_size == 0 ) {
+       if ( new_size == 0 && pv->entries ) {
            free( pv->entries );
            pv->entries = 0;
        }