Example #1
0
double_struct *merge_partitions(cog *c, long low, long high) {
  list *list = create_list();
  int has_merge_work;
  gather_partitions(list, c);
  struct cog *right_replacement = NULL;
  struct cog *left_replacement = NULL;
  struct list *list_iter;
  struct iter_list *tail; 
  struct stack_triple *stack = create_stack();
  struct iter_list *head_list = malloc(sizeof(struct iter_list));
  tail = head_list;
  list_iter = list;
  iterator merge_iter;
  cog *c1 = malloc(sizeof(struct cog));
  while(list_has_next(list_iter)) {
    list_iter = get_cog_from_list(list_iter, c1);
    struct extracted_components *components = extract_partitions(c1, low, high);
    if(components->iter != NULL) {
      has_merge_work = 1;
      tail = iter_list_add(tail, components->iter);
    }

    if(components->rhs != NULL) {
      if(right_replacement == NULL) {
        right_replacement = components->rhs;
      } else {
        right_replacement = make_concat(right_replacement, components->rhs); 
      }
    }

    if(components->lhs != NULL) {
      if(left_replacement == NULL) {
        left_replacement = components->lhs;
      } else {
        left_replacement = make_concat(left_replacement, components->lhs);
      }
    }
    free(components);
  }
  cleanup_list(list);
  free(c1);
  if(has_merge_work != 0) {
    double_struct *ret = create_double_struct();
    merge_iter = iter_merge(head_list);
    record r = malloc(sizeof(struct record));
    while(1) {
      int i;
      buffer out = buffer_alloc(MERGE_BLOCK_SIZE);
      record buf = out->data;
      for(i = 0; i < MERGE_BLOCK_SIZE && iter_has_next(merge_iter); i++) {
        iter_next(merge_iter, r);
        record_set(&buf[i], r->key, r->value);
      }
      if(i == 0) {
        break;
      }
      struct cog *buffer = make_sortedarray(0, i, out);
      fold_append(&stack, buffer, cog_min(buffer));
      if(i < MERGE_BLOCK_SIZE) {
        break;
      }
    }
    cog *root = fold(&stack);
    if(root == NULL) {
      root = make_btree(left_replacement, right_replacement, high);
    } else {
      ret->iter = scan(root, low, high);
      if(left_replacement != NULL && cog_length(left_replacement) != 0) {
        root = make_btree(left_replacement, root, cog_min(root));
      }
      if(right_replacement != NULL && cog_length(right_replacement) != 0) {
        root = make_btree(root, right_replacement, cog_min(right_replacement));
      }
    }
    free(r);
    cleanup_stack(stack);
    iter_list_cleanup(head_list);
    iter_cleanup(merge_iter);
    ret->cog = root;
    return ret;
  } else {
    double_struct *ret;
    ret = amerge(list->cog, low, high);
    if(left_replacement != NULL) {
      ret->cog = make_concat(ret->cog, left_replacement);
    }
    if(right_replacement != NULL) {
      ret->cog = make_concat(ret->cog, right_replacement);
    }
    return ret;
  }
}
Example #2
0
int main(int argc, char *argv[])
{
	if(argc < 3)
	{
		printf("Insufficient number of arguments supplied\n");
		exit(-1);
	}

	if(argc > 3)
	{
		printf("Too many arguments supplied\n");
		exit(-1);
	}

	char index_file[DEF];
	memset(index_file,0,sizeof(char)*DEF);
	if(argv[1]==NULL)
	{
		printf("Received a NULL index filename");
		exit(-1);
	}
	//Index file
	strcpy(index_file,argv[1]);

	if(argv[2]==NULL)
	{
		printf("Received a NULL B Tree order");
		exit(-1);
	}
	//B tree order
	btree_order=atoi(argv[2]);

	if(btree_order < 3)
	{
		printf("The order of the tree should be greater than or equal to 3\n");
		exit(-1);
	}


	btree_node_ptr node_in_mem=NULL;
	btree_node_ptr aux_node_in_mem=NULL;
	//Get a new node which you can reuse
	node_in_mem = new_node_init();
	//Get a new aux node which can we reused
	aux_node_in_mem = new_aux_node();


	//debug bool
	//bool debug=true;
	if(debug)	printf("Index filename received : %s\n",index_file);
	if(debug)	printf("B Tree order : %d\n",btree_order);
	bool cmdIsValid=false;
	//File needs to be opened here
	//FILE *fin;
	fin = fopen (index_file, "r+b");
	if(fin == NULL)
	{
		root_offset = -1;
		//Write -1 to the file
		fin = fopen (index_file, "w+b");
		if(fin == NULL)
		{
			perror("Index file open error: ");
			exit(-1);
		}
		//else
		//	fwrite(&root_offset, sizeof(long), 1, fin);
	}
	else
		fread(&root_offset, sizeof(long), 1, fin);

	//Open two aux FDs
	//file_open(index_file);

	char *cmd=(char *)malloc(sizeof(char)*CMD_LEN);
	char *temp_cmd=(char *)malloc(sizeof(char)*CMD_LEN);
	char *temp2_cmd=(char *)malloc(sizeof(char)*CMD_LEN);
	memset(cmd,0,sizeof(char)*CMD_LEN);
	memset(temp_cmd,0,sizeof(char)*CMD_LEN);
	memset(temp2_cmd,0,sizeof(char)*CMD_LEN);

	while(1)
	{
		cmdIsValid=false;
		int ret;
		size_t len = sizeof(char)*CMD_LEN;
		memset(cmd,0,sizeof(char)*CMD_LEN);
		memset(temp_cmd,0,sizeof(char)*CMD_LEN);
		memset(temp2_cmd,0,sizeof(char)*CMD_LEN);
		ret=getline(&cmd,&len,stdin);
		if(ret==-1)
		{
			perror("Command Read Error :");
			exit(-1);
		}
		
		//Strip \n
		cmd[strlen(cmd)-1]='\0';
		if(strlen(cmd)==0)	continue;
	
		if(debug)	printf("getline returns : %s\n",cmd);
		strcpy(temp_cmd,cmd);
		strcpy(temp2_cmd,cmd);
		char *tok=strtok(temp_cmd," ");
		if(strcmp(tok,"add")==0 || strcmp(tok,"find")==0 || strcmp(tok,"print")==0 || strcmp(tok,"end")==0)
			cmdIsValid=true;
		if(cmdIsValid)
		{
		if(strcmp(tok,"add")==0)
		{
			tok=strtok(NULL," ");
			if(tok==NULL)
			{
				printf("Key value not supplied to 'add' utility\n");
				continue;
			}
			int key=atoi(tok);
			int found=0;
			found=find_key_in_btree(index_file, key);
			if(found)
				printf("Entry with key=%d already exists\n",key);
			else
			{
				//Add logic begins here
				size_of_tree++;
				if(root_offset==-1)
				{
					//The tree is empty. Construct the root;
					//Cleanup the node
					btree_node_ptr root = node_clean_up(node_in_mem);
					//btree_node_ptr root = new_node_init();
					(root)->keys[0] = key;
					(root)->no_of_keys++;
					if(debug)	printf("Root data : %d\t%d\n",(root)->keys[0],(root)->no_of_keys);
					//Write this node to the file
					//btree_node_ptr node= *root;
					//memcpy(node, *root, sizeof(btree_node));
					write_node(root);
					root_offset = sizeof(long);
				}
				
				//Tree is not empty
				else
				{
					//Check if the root is not full
					//fseek(fin, sizeof(long), SEEK_SET);
					fseek(fin, root_offset, SEEK_SET);
					int keys_in_root=0;
					fread(&keys_in_root, sizeof(int), 1, fin);
					if(debug)	printf("keys_in_root : %d\n",keys_in_root);
					{
						//printf("Root is Full \n");
						//The recursive procedure goes here to split upto the root
						//Step 1 : Populate the parent pointers upto the leaf responsible for this insert
						//long parent_pointers[size_of_tree];
						int i=0;
						/*for(i=0;i<size_of_tree;i++)
						{
							parent_pointers[i] = -1;
							if(debug)	printf("parent pointer : %d\t%ld",i,parent_pointers[i]);
						}*/
						
						//Essentially a find operation that pushes in the parent offsets in a stack
						cleanup_stack();
						populate_parents( index_file, key);
						//print_stack();

						//Step 2 : Get the leaf offset
						if(debug)	printf("Leaf offset : %ld\n",leaf_offset);
						//Get the number of nodes in the leaf
						fseek(fin, 0, SEEK_SET);
						fseek(fin, leaf_offset, SEEK_CUR);
						int node_keys = 0;
						fread(&node_keys, sizeof(int), 1, fin);
						if(debug)	printf("Keys in node : %d\n",node_keys);
						if(node_keys == btree_order - 1)
							add_key_to_tree(aux_node_in_mem, node_keys, leaf_offset, key);
						else
							insert_in_node(leaf_offset, node_keys, key);
						
					}
				}
			}
			
		}

		else if(strcmp(tok,"find")==0)
		{
			
			tok=strtok(NULL," ");
			if(tok==NULL)
			{
				printf("Key value not supplied to 'find' utility\n");
				continue;
			}
			int key=atoi(tok);
			bool found=find_key_in_btree(index_file, key);
			if(found)
				printf("Entry with key=%d exists\n",key);
			else
				printf("Entry with key=%d does not exist\n",key);
		}

		else if(strcmp(tok,"print")==0)
		{
			print_tree(index_file);
		}

		else if(strcmp(tok,"end")==0)
		{
			//Write the updates root offset
			fseek(fin, 0, SEEK_SET);
			fwrite(&root_offset, sizeof(long), 1, fin);
			fclose(fin);
			break;
		}
	
		else
			printf("Invalid command received\n");
		
		}
		else
			printf("Invalid command received\n");
	}
	return 0;
}