static void *cl_rbtree_add_dup_allow(struct cl_rbtree *tree, void *value) { struct cl_rbnode *n = cl_pool_alloc(&tree->pool); if(n == NULL) return NULL; cl_rbnode_init(n, value); cl_rbtree_insert(tree, n); tree->n_items++; return value; }
/* Add into the rbtree thats on-disk */ static int cl_db_link_record(int handle,struct cl_db *ptr) { cldb_offset_t parent = -1; int go_left = -1; int err = -1; cldb_offset_t root = CL_DB_ROOT(handle) ; struct cl_db_header old_header; /*First take a copy of the header*/ memcpy(&old_header,&CL_DB_HEADER(handle),sizeof(old_header)); root = root ?:-1; while(root != -1) { struct cl_db record; int cmp; parent = root; if(cl_db_record_read_unfmt(handle,&record,parent,CLDB_DATA_ALL) < 0) { output("Error reading record"); goto out; } cmp = cl_db_compare(ptr,&record); if(!cmp) { output("Found a duplicate key for the record..."); err = CLDB_DUPLICATE; goto out; } if(cmp < 0) { go_left = 1; root = record.left; } else { go_left = 0; root = record.right; } free((void*)record.key); free((void*)record.data); } if(cl_db_commit_start(handle) < 0 ) { output("Error in starting commit.."); goto out; } /*First get the offsets first*/ if(cl_db_get_free_offset(handle,ptr) < 0 ) { output("Error in getting free offset..."); goto out_rollback; } if(cl_rbtree_insert(handle,ptr,parent,go_left) < 0 ) { output("Error in rbtree insert"); goto out_rollback; } if(cl_db_queue_record(handle,ptr,CL_DB_LAST_OFFSET(handle),-1) < 0 ) { output("Error in queueing record"); goto out_rollback; } if(cl_db_touch_node(handle,ptr) < 0 ) { output("Error touching node"); goto out_rollback; } ++CL_DB_HEADER(handle).records; if(cl_db_touch_header(handle) < 0 ) { output("Error updating header"); goto out_rollback; } if(cl_db_commit_end(handle) < 0 ) { output("Error committing the records to the disk..."); goto out; } err = 0; cl_db_display_root(handle); goto out; out_rollback: /*Restore the old header*/ output("Restoring the old db header..."); memcpy(&CL_DB_HEADER(handle),&old_header,sizeof(old_header)); if(cl_db_commit_rollback(handle) < 0 ) { output("Error in commit rollback..."); } out: return err; }