- // Try reclaiming the slot,
- if ( reclaim && reclaim( pv, *index, *slot, data ) == 0 ) {
- *slot = 0;
+ return slot;
+ }
+ } while ( ++(*index) < pv->size );
+ if ( partial == 0 ) {
+ free( pv->entries );
+ pv->entries = 0;
+ }
+ *index = pv->size; // reached the end of the vector
+ return 0;
+}
+
+/**
+ * Advances a vector index to the prior used slot at or below the
+ * given level, starting from the indexed entry (inclusive) and down.
+ * The function will free any empty pages it discovers, and then
+ * update the index slots accordingly. The given index is advanced
+ * cyclically to match the found slot. The function returns a slot
+ * pointer to the used slot, if any, and 0 otherwise.
+ * The last parameter is a flag that gets set when the scanning is
+ * partial (i.e. not the whole index page).
+ */
+static void **vector_level_prev_used(
+ vector *pv,
+ vector_page *page,
+ vector_index *index,
+ int level,
+ int *partial )
+{
+ void **p = (void**)&(*page)[ VECTOR_INDEX_PART( pv, index, level ) ];
+ if ( VECTOR_INDEX_PART( pv, index, level ) != VECTOR_SLOTS( pv ) - 1 ) {
+ *partial = 1;
+ }
+ do {
+ if ( *p ) {
+ if ( level == 0 ) {
+ return p; // This is a used entry
+ }
+ // *p is an index that needs to be inspected recursively
+ int w = 0;
+ void **x = vector_level_prev_used( pv, *p, index, level - 1, &w );
+ if ( x ) {
+ return x; // Used slot was found; return it.
+ }
+ // If the page *p is all empty, it can/should be reclaimed.
+ if ( w == 0 ) {
+ free( *p );
+ *p = 0;