예제 #1
0
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;
}
예제 #2
0
파일: cldb.c 프로젝트: karthick18/cldb
/*
  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;
}