* 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.
*p = 0;
}
}
- if ( ++VECTOR_INDEX_PART( index, level ) == 0 ) {
+ if ( VECTOR_INDEX_PART_INC( index, level ) == 0 ) {
break; // cycling this level => nothing found
}
}
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;
}