void node_load_from_disk( node* n, u32 id ) { printf("Loading node %d from disk\n", id); node_debug( n ); c.loads++; }
void node_store_on_disk( node* n ) { printf("Storing node %d on disk\n", n->id); node_debug( n ); c.stores++; }
void node_debug(node_t* node) { unsigned int i = 0; node_t* current = NULL; node_iterator_t* iter = NULL; for(i = 0; i < node->depth; i++) { printf("\t"); } if(node->isRoot) { printf("ROOT\n"); } if(node->isLeaf && !node->isRoot) { printf("LEAF\n"); } else { if(!node->isRoot) { printf("NODE\n"); } iter = node_iterator_create(node->children); for(current = iter->begin; current != NULL; current = iter->next(iter)) { node_debug(current); } } }
internal void dl_list_debug( entry* head ) { printf("Debug list %p\n", (void*) head ); if( head != NULL ) { entry* start = head; entry* current = head; do { entry_debug( current ); node_debug( current->node ); current = current->next; } while( current != start ); } }
// Remove a node from the cache in order: clean data, clean index, dirty data, dirty index // Make sure we don't evict ones with refcount > 0 as they are in use node* node_cache_evict_node( node_cache* nc ) { node* result = NULL; u32 evict_order[4] = { NC_LIST_DATA_CLEAN, NC_LIST_INDEX_CLEAN, NC_LIST_DATA_DIRTY, NC_LIST_INDEX_DIRTY }; for( u32 i=0; i<4; i++ ) { entry* list = nc->list[ evict_order[i] ]; printf("Trying to evict from list %d\n", i); if( list != NULL ) { dl_list_debug( list ); entry* current = list; do { if( current->refcount == 0 ) { node* to_be_evicted = current->node; printf("\tEviction candidate found: \n"); entry_debug( current ); node_debug( to_be_evicted ); node_store_on_disk( to_be_evicted ); to_be_evicted->flags = 0; // reset all, though only would need ~NODE_FLAG_USED result = to_be_evicted; // we can immediately reuse this one if needed u32 bucket_entry_index = index_from_node_pointer( nc, to_be_evicted ); entry* bucket_entry = &nc->bucket_entries[bucket_entry_index]; u32 bucket_index = bucket_index_from_node( to_be_evicted ); nc->bucket[bucket_index] = dl_list_remove( nc->bucket[bucket_index], bucket_entry ); nc->list[ evict_order[i] ] = dl_list_remove( list, current ); dl_list_debug( nc->list[ evict_order[i] ] ); c.evicts[ evict_order[i] ]++; goto DONE; } current = current->next; } while( current != list ); } } assert( result != NULL ); if( result == NULL ) { printf("[FAIL]: Could not evict any nodes. Maybe all are in use? (refcount > 0)\n"); } DONE: return result; }