Exemplo n.º 1
0
static int      tree_delete_block(tree_t *tree, unsigned int block_vid){ // {{{
	ssize_t           ret;
	
	hash_t    req_move[] = {
		{ HK(action),   DATA_UINT32T( ACTION_MOVE                     ) },
		{ HK(offset_from), DATA_OFFT ( (block_vid + 1) * sizeof(block_info) ) },
		{ HK(offset_to),   DATA_OFFT ( (block_vid    ) * sizeof(block_info) ) },
		hash_end
	};
	if( (ret = chain_next_query(tree->chain, req_move)) != 0)
		return ret;
	
	hash_t    req_delete[] = {
		{ HK(action), DATA_UINT32T( ACTION_DELETE                            ) },
		{ HK(offset),    DATA_OFFT ( (tree->blocks_count - 1) * sizeof(block_info) ) },
		{ HK(size),   DATA_SIZET( sizeof(block_info)                            ) },
		hash_end
	};
	if( (ret = chain_next_query(tree->chain, req_delete)) != 0)
		return ret;
	
	if(tree_reinit(tree) != 0)
		return -1;
	
	// TODO replace recalc with faster procedure which recalc only changed items instead of all
	if(tree_recalc(tree) != 0)
		return -1;
	
	return 0;
} // }}}
Exemplo n.º 2
0
static int      tree_resize_block(tree_t *tree, unsigned int block_vid, unsigned int new_size){ // {{{
	unsigned int      delta;
	ssize_t           ret;
	block_info        block;
	int               j;
	buffer_t          req_buffer;
	
	buffer_init_from_bare(&req_buffer, &block, sizeof(block));
	
	/* read block_info */
	hash_t    req_read[] = {
		{ HK(action), DATA_UINT32T( ACTION_READ               ) },
		{ HK(offset),    DATA_OFFT ( block_vid * sizeof(block_info) ) },
		{ HK(size),   DATA_SIZET( sizeof(block_info)             ) },
		{ HK(buffer), DATA_BUFFERT(&req_buffer)                    },
		hash_end
	};
	if( (ret = chain_next_query(tree->chain, req_read)) <= 0){
		buffer_destroy(&req_buffer);
		return -1;
	}
	
	/* fix block_info */
	delta      = new_size - block.size;
	block.size = new_size; 
	
	/* write block info */
	hash_t    req_write[] = {
		{ HK(action), DATA_UINT32T( ACTION_WRITE              ) },
		{ HK(offset),    DATA_OFFT ( block_vid * sizeof(block_info) ) },
		{ HK(size),   DATA_SIZET( sizeof(block_info)             ) },
		{ HK(buffer), DATA_BUFFERT(&req_buffer)                    },
		hash_end
	};
	chain_next_query(tree->chain, req_write);
	
	// TODO lock
		for(j=0; j < tree->nlevels; j++){
			tree->table[ tree->tof[j] + (block_vid / tree->lss[j]) ] += delta;
		}
	// TODO unlock
	
	buffer_destroy(&req_buffer);
	return 0;
} // }}}
Exemplo n.º 3
0
static int      tree_get_block(tree_t *tree, unsigned int block_vid, block_info *block){ // {{{
	buffer_t         req_buffer;
	
	buffer_init_from_bare(&req_buffer, block, sizeof(block_info));
	
	hash_t    req_read[] = {
		{ HK(action), DATA_UINT32T( ACTION_READ               ) },
		{ HK(offset),    DATA_OFFT ( block_vid * sizeof(block_info) ) },
		{ HK(size),   DATA_SIZET( sizeof(block_info)             ) },
		{ HK(buffer), DATA_BUFFERT(&req_buffer)                    },
		hash_end
	};
	if(chain_next_query(tree->chain, req_read) <= 0)
		return -1;
	
	buffer_destroy(&req_buffer);
	return 0;
} // }}}
Exemplo n.º 4
0
static int      tree_insert(tree_t *tree, unsigned int block_vid, unsigned int block_off, unsigned int size){ // {{{
	block_info       block;
	ssize_t          ret;
	buffer_t         req_buffer;
	
	buffer_init_from_bare(&req_buffer, &block, sizeof(block));
	
	block.real_block_off   = block_off;
	block.size             = size;
	
	hash_t    req_move[] = {
		{ HK(action),   DATA_UINT32T(ACTION_MOVE)                     },
		{ HK(offset_from), DATA_OFFT ((block_vid    ) * sizeof(block_info)) },
		{ HK(offset_to),   DATA_OFFT ((block_vid + 1) * sizeof(block_info)) },
		hash_end
	};
	ret = chain_next_query(tree->chain, req_move);
	
	hash_t    req_write[] = {
		{ HK(action), DATA_UINT32T( ACTION_WRITE              ) },
		{ HK(offset),    DATA_OFFT ( block_vid * sizeof(block_info) ) },
		{ HK(size),   DATA_SIZET( sizeof(block_info)             ) },
		{ HK(buffer), DATA_BUFFERT(&req_buffer)                    },
		hash_end
	};
	if( (ret = chain_next_query(tree->chain, req_write)) <= 0)
		goto cleanup;
	
	ret = -1;
	if(tree_reinit(tree) != 0)
		goto cleanup;
	
	// TODO replace recalc with faster procedure which recalc only changed items instead of all
	if(tree_recalc(tree) != 0)
		goto cleanup;
	
	ret = 0;
cleanup:
	buffer_destroy(&req_buffer);
	return ret;
} // }}}
Exemplo n.º 5
0
static ssize_t struct_machine_pack(machine_t *machine, request_t *request){
	ssize_t          ret;
	size_t           struct_size;
	data_t          *buffer;
	request_t       *values;
	struct_userdata *userdata = (struct_userdata *)machine->userdata;
		
	switch(userdata->values){
		case STRUCT_VALUES_WHOLE: values = request; break;
		case STRUCT_VALUES_ONE:
			hash_data_get(ret, TYPE_HASHT, values, request, userdata->key_values);
			if(ret != 0)
				return error("hash with keys not supplied");
			break;
	};
	
	if(userdata->lazy == 1){
		request_t r_next[] = {
			{ userdata->buffer, DATA_STRUCTT(userdata->structure, values) },
			hash_next(request)
		};
		
		return machine_pass(machine, r_next);
	}else{
		buffer = hash_data_find(request, userdata->buffer);
		if(buffer != NULL){
			if( (struct_size = struct_pack(userdata->structure, values, buffer)) == 0)
				return error("struct_pack failed");
			
			request_t new_request[] = {
				{ userdata->size, DATA_SIZET(struct_size) },
				hash_next(request)
			};
			
			return machine_pass(machine, new_request);
		}
		return machine_pass(machine, request);
	}
}
Exemplo n.º 6
0
static int      tree_get(tree_t *tree, off_t offset, unsigned int *block_vid, off_t *real_offset){ // {{{
	unsigned int   i,j,ret;
	off_t          level_off;
	unsigned int   ptr;
	size_t         chunk_size;
	block_info     block;
	
	if(offset >= tree->table[0]) // out of range
		return -1;
	
	ret       = -1;
	level_off = 0;
	ptr       = 0;
	// TODO lock
		for(i=1; i < tree->nlevels; i++){
			for(j=0; j < tree->elements_per_level; j++, ptr++){
				chunk_size = tree->table[ tree->tof[i] + ptr];
				
				/*printf("lev: %x el: %x ptr: %x (%x < %x + %x)\n",
					i, j, (unsigned int)ptr,
					(unsigned int)offset, (unsigned int)level_off, (unsigned int)chunk_size
				);*/
				
				if(offset < level_off + chunk_size)
					break;
				
				level_off += chunk_size;
			}
			
			ptr *= tree->elements_per_level;
		}
		// last level
		
		buffer_t  req_buffer;
		buffer_init_from_bare(&req_buffer, &block, sizeof(block));
		
		/* read block_info */
		for(j=0; j < tree->elements_per_level; j++, ptr++){
			hash_t    req_read[] = {
				{ HK(action), DATA_UINT32T( ACTION_READ               ) },
				{ HK(offset),    DATA_OFFT ( ptr * sizeof(block_info)       ) },
				{ HK(size),   DATA_SIZET( sizeof(block_info)             ) },
				{ HK(buffer), DATA_BUFFERT(&req_buffer)                    },
				hash_end
			};
			if(chain_next_query(tree->chain, req_read) <= 0)
				break;
			
			/*printf("el: %x ptr: %x (%x < %x + %x)\n",
				j, (unsigned int)ptr,
				(unsigned int)offset, (unsigned int)level_off, (unsigned int)block.size
			);*/
			
			if(offset < level_off + block.size){
				*block_vid   = ptr;
				*real_offset = block.real_block_off + (offset - level_off);
				ret = 0;
				break;
			}
			level_off += block.size;
		}
		buffer_destroy(&req_buffer);
		
	// TODO unlock
	return ret;
} // }}}
Exemplo n.º 7
0
static int      tree_recalc(tree_t *tree){ // {{{
	int           i,j;
	ssize_t       ret_size;
	unsigned int  block_size;
	unsigned int  read_size;
	buffer_t     *buffer;
	size_t       *calcs;
	size_t        blocks_left;
	unsigned int  ptr                = 0;
	unsigned int  nlevels            = tree->nlevels;
	
	if( (blocks_left = tree->blocks_count) == 0)
		return 0;
	
	calcs  = calloc(sizeof(size_t), tree->nlevels);
	buffer = buffer_alloc();
	
	while(blocks_left > 0){
		read_size = ( (blocks_left > tree->read_per_calc) ? tree->read_per_calc : blocks_left );
		
		hash_t    req_read[] = {
			{ HK(action), DATA_UINT32T(ACTION_READ)               },
			{ HK(offset),    DATA_OFFT (ptr * sizeof(block_info))       },
			{ HK(size),   DATA_SIZET(read_size * sizeof(block_info)) },
			{ HK(buffer), DATA_BUFFERT(buffer)                       },
			hash_end
		};
		if( (ret_size = chain_next_query(tree->chain, req_read)) <= 0)
			break;
		
		buffer_process(buffer, ret_size, 0,
			do {
				for(i=0; i < size; i += sizeof(block_info), ptr += 1){
					block_size = ((block_info *)(chunk + i))->size;
					
					//printf("block: %x size: %x\n", (unsigned int)ptr, (unsigned int)block_size);
					
					for(j=0; j < nlevels; j++){
						calcs[j] += block_size;
						
						//printf("block: [%x/%x] calcs[%x] = %x  (ptr: %x)\n",
						//	(unsigned int)ptr, (unsigned int)tree->blocks_count,
						//	(unsigned int)j, (unsigned int)calcs[j],
						//	(unsigned int)( ptr / tree->lss[j] )
						//);
						
						if( (ptr % tree->lss[j]) == tree->lss[j] - 1){
							tree->table[ tree->tof[j] + (ptr / tree->lss[j]) ]  = calcs[j];
							calcs[j]                                            = 0;
						}
					}
				}
			}while(0)
		);
		blocks_left -= ret_size / sizeof(block_info);
	}
	
	// flush
	for(j=0; j < nlevels; j++){
		/*
		printf("dumping j %x ptr: %x lss: %x [%x]=%x\n",
			j,
			(unsigned int)ptr,
			(unsigned int)tree->lss[j],
			(unsigned int)(tree->tof[j] + (ptr / tree->lss[j])),
			(unsigned int)calcs[j]
		);*/
		
		tree->table[ tree->tof[j] + (ptr / tree->lss[j]) ] = calcs[j];
	}
	
	buffer_free(buffer);
	free(calcs);
	return (blocks_left == 0) ? 0 : -1;
} // }}}