Ejemplo n.º 1
0
static void on_flow(const Level *level, FlowEvent *ev)
{
    int d;
    Type t = level_get_block(level, ev->x, ev->y, ev->z);

    if (!is_fluid(t)) return;

    for (d = 0; d < 6; ++d)
    {
        int nx, ny, nz;

        if (DY[d] > 0) continue;  /* don't flow upward */

        nx = ev->x + DX[d];
        ny = ev->y + DY[d];
        nz = ev->z + DZ[d];
        if (level_index_valid(level, nx, ny, nz))
        {
            Type u = level_get_block(level, nx, ny, nz);
            if ( u == BLOCK_EMPTY &&
                 !type_nearby(level, nx, ny, nz, BLOCK_SPONGE, 3))
            {
                /* Propagate fluid */
                update_block(nx, ny, nz, t);
            }
            else
            if ((is_water(t) && is_lava(u)) || (is_lava(t) && is_water(u)))
            {
                /* Water and lava make stone */
                update_block(nx, ny, nz, BLOCK_STONE_GREY);
            }
        }
    }
}
Ejemplo n.º 2
0
static void on_update(const Level *level, UpdateEvent *ev)
{
    if (level_get_block(level, ev->x, ev->y, ev->z) != ev->new_t) return;

    switch (ev->new_t)
    {
    case BLOCK_SPONGE:
        {
            int x1 = max(ev->x - 3 + 1, 0), x2 = min(ev->x + 3, level->size.x);
            int y1 = max(ev->y - 3 + 1, 0), y2 = min(ev->y + 3, level->size.y);
            int z1 = max(ev->z - 3 + 1, 0), z2 = min(ev->z + 3, level->size.z);
            int x, y, z;

            for (x = x1; x < x2; ++x)
            {
                for (y = y1; y < y2; ++y)
                {
                    for (z = z1; z < z2; ++z)
                    {
                        if (is_fluid(level_get_block(level, x, y, z)))
                            update_block(x, y, z, BLOCK_EMPTY);
                    }
                }
            }
        }
        break;

    case BLOCK_SUPERSPONGE:
        {
            /* Flood-filling super sponge */
            int d;
            for (d = 0; d < 6; ++d)
            {
                int nx = ev->x + DX[d];
                int ny = ev->y + DY[d];
                int nz = ev->z + DZ[d];
                Type t = level_get_block(level, nx, ny,nz);
                if (is_fluid(t))
                {
                    update_block_delayed(nx, ny, nz, BLOCK_SUPERSPONGE,
                                         &supersponge_delay);
                }
            }
            update_block(ev->x, ev->y, ev->z, BLOCK_EMPTY);
        }
        break;
    }

    if (ev->old_t == BLOCK_SPONGE)
    {
        activate_blocks_nearby(level, ev->x, ev->y, ev->z, 3);
    }
    else
    {
        activate_block(level, ev->x, ev->y, ev->z);
        activate_neighbours(level, ev->x, ev->y, ev->z);
    }
}
Ejemplo n.º 3
0
int blockfs_write(const char *path, const char *buf, size_t size,
                     off_t offset, struct fuse_file_info *fi)
{

  off_t num_blocks = NUMBLOCKS(size);
  off_t base_block_num  = OFFSET_2_BLOCKNO(offset);

  struct block_info *b;
  int count;
  ssize_t ret;
  
  if (strcmp(path, blockfs.path) != 0) {
    return -ENOENT;
  }

  ret = pwrite (blockfs.blkdev_fd, buf, size, offset);

  if (ret == -1 || ret < size) {
    perror("in blockfs_write(), error writing to block device ");
    exit(1);
  }

  count = 0;

  while( count != num_blocks) {
    b = blkdev_block + base_block_num + count;

    update_block (b);

    ++count;
  }
  

  return ret;
}
Ejemplo n.º 4
0
static void activate_block(const Level *level, int x, int y, int z)
{
    Type t = level_get_block(level, x, y, z); 
    switch (t)
    {
    case BLOCK_WATER1:
    case BLOCK_WATER2:
        post_flow_event(x, y, z, &water_flow_delay);
        break;

    case BLOCK_LAVA1:
    case BLOCK_LAVA2:
        post_flow_event(x, y, z, &lava_flow_delay);
        break;

    case BLOCK_DIRT:
        post_grow_event(x, y, z);
        break;

    case BLOCK_GRASS:
        if (is_light_blocker(level_get_block(level, x, y + 1, z)))
            update_block(x, y, z, BLOCK_DIRT);
        break;

    case BLOCK_STONE_YELLOW:
    case BLOCK_STONE_MIXED:
        {
            /* see if this block can fall down: */
            int ny = y;
            while (ny > 0 &&
                   !is_supporter(level_get_block(level, x, ny - 1, z))) --ny;
            if (y > ny)
            {
                /* fall down, removing everything in the way: */
                while (y > ny)
                    update_block(x, y--, z, BLOCK_EMPTY);
                update_block(x, y, z, t);
            }
        }
        break;

    default:
        if (is_plant(t) && !is_soil(level_get_block(level, x, y - 1, z)))
            update_block(x, y, z, BLOCK_EMPTY);
        break;
    }
}
Ejemplo n.º 5
0
int op_testpattern(const char *file, bool op_write)
{
    int fd = -1;
    mode_t mode = O_LARGEFILE;
    unsigned long long pos, len, i, op_blocks;
    double op_elapsed;
    struct timeval start_time;
    
    mode |= op_write ? O_RDWR : O_RDONLY;
    fd = open(file, mode);
    if (fd == -1) {
        fprintf(stderr, "Unable to open %s, errno %d\n", file, errno);
        return 1;
    }
    
    if (!check_file_size(fd)) {
        close(fd);
        return 1;
    }
    
    gettimeofday(&start_time, NULL);

    for(i = 0; i < max_blocks; i++) {
        pos = i * block_size;
        if (lseek(fd, pos, SEEK_SET) == (off_t)-1) {
            fprintf(stderr, "Unable to seek to offset %llx\n", pos);
            close(fd);
            return 1;
        }

        if (op_write) {
            update_block();
            len = atomicio(vwrite, fd, block_buf, block_size);
            if (len < block_size) {
                fprintf(stderr, "Write block %llx failed\n", i);
                close(fd);
                return 1;
            }
        } else {
            len = atomicio(read, fd, block_buf, block_size);
            if (len < block_size) {
                fprintf(stderr, "Read block %llx failed\n", i);
                close(fd);
                return 1;
            }
            verify_block();
        }

        op_blocks = i + 1;
        op_elapsed = get_op_elapsed(&start_time);
        if (max_time > 0 && op_elapsed >= max_time)
            break;
    }
    
    printf("%llu %llu %f %llu\n", max_blocks, op_blocks, op_elapsed, sect_errors);
    
    close(fd);
    return 0;
}
Ejemplo n.º 6
0
static void on_grow(const Level *level, GrowEvent *ev)
{
    if (level_get_block(level, ev->x, ev->y, ev->z) == BLOCK_DIRT &&
        !is_light_blocker(level_get_block(level, ev->x, ev->y + 1, ev->z)))
    {
        update_block(ev->x, ev->y, ev->z, BLOCK_GRASS);
    }
}
Ejemplo n.º 7
0
struct crypto777_block *generate_block(struct consensus_model *model,struct crypto777_node *nn,uint8_t *msg,int32_t len,uint32_t blocknum,uint32_t timestamp)
{
    struct crypto777_generator gen;
    struct crypto777_block *prev,*block = 0;
    if ( (prev= model->blocks[blocknum-1]) != 0 )
    {
        calc_generator(&gen,calc_stake(nn,model),nn->email,timestamp,prev->gen.metric,prev->gen.hash,model->POW_DIFF);
        //printf("node.%d GENERATE.%d %.8f (%.8f + prev %.8f)\n",nn->nodeid,blocknum,dstr(gen.metric),dstr(gen.hit),dstr(prev->gen.metric));
        block = sign_block(nn,&gen,msg,len,blocknum,timestamp);
        update_block(model,nn,model->blocks,blocknum,block,timestamp);
    }
    return(block);
}
Ejemplo n.º 8
0
void processrecv(struct consensus_model *model,struct crypto777_node *nn,struct crypto777_packet *recv,uint32_t timestamp,int32_t peeri)
{
    struct crypto777_block *block,*ptr;
    if ( recv != 0 )
    {
        nn->transport.numrecv++;
        //SETBIT(Recvmasks[nn->nodeid],recv->nodeid);
        if ( (block= parse_block777(model,nn,(struct crypto777_block *)&recv->recvbuf[sizeof(struct SaMhdr)],recv->recvlen - sizeof(struct SaMhdr),peeri)) != 0 )
        {
            if ( is_newhwm_block(model->blocks,block) != 0 )
            {
                ptr = calloc(1,block->blocksize);
                memcpy(ptr,block,block->blocksize);
                update_block(model,nn,model->blocks,block->blocknum,ptr,timestamp);
                Receiver++;
                if ( nn->peers[peeri] == 0 || recv->nodeid != nn->peers[peeri]->nodeid )
                    printf("recv newhwm for block.%u sig.%llu gennode.%d from peer.%d %d\n",block->blocknum,(long long)block->sig.txid,recv->nodeid,peeri,nn->peers[peeri]->nodeid);
            }
        } else printf("node.%d error parsing block\n",nn->nodeid);
    }
}
Ejemplo n.º 9
0
static int insert_ix(ENTRY *pe, IX_DESC *pix)
{
    ENTRY e, ee;
    pci = pix;
    ee = *pe;

    do
    {
        if(CO(pci->level) >= 0)
        {
            CO(pci->level) += ENT_SIZE(ENT_ADR(block_ptr, CO(pci->level)));
        }
        else
        {
            CO(pci->level) = 0;
        }

        update_block();
        if((block_ptr->bend + ENT_SIZE(&ee)) <= (uint32_t)split_size)
        {
            ins_level(pci->level, &ee);
            break;
        }
        else
        {
            split(pci->level,&ee, &e);
            ee = e;
            pci->level--;
            if (pci->level < 0)
            {
                ins_level(pci->level, &e);
                break;
            }
            retrieve_block(pci->level, CB(pci->level));
        }
    }
    while (1);

    return (IX_OK);
} 
Ejemplo n.º 10
0
void
update_status_line(struct status_line *status)
{
	int i;

	for (i = 0; i < status->num; ++i) {
		const struct block *config_block = status->blocks + i;
		struct block *updated_block = status->updated_blocks + i;

		/* Skip static block */
		if (!*config_block->command)
			continue;

		/* If a block needs an update, reset and execute it */
		if (need_update(updated_block)) {
			memcpy(updated_block, config_block, sizeof(struct block));
			if (update_block(updated_block))
				fprintf(stderr, "failed to update block %s\n", updated_block->name);
		}
	}

	if (caughtsig > 0)
		caughtsig = 0;
}
Ejemplo n.º 11
0
int sfs_fwrite(int fileID, const char *buf, int length){

	int inode_index = dir_table[fileID].inode_number;
	int num_bytes_to_be_written=0;
	
	//index of rw pointers which points to the current block of inode
	int rw_index = file_des_t[fileID].rw_pointer/BLOCKSIZE+1; 
	//rw pointer offset within its current block
	int rw_offset = file_des_t[fileID].rw_pointer%BLOCKSIZE; 
	//calculate number of blocks to be written
	int num_blocks;
	if(length<BLOCKSIZE-rw_offset){
		num_blocks=1;
	}
	else{
		num_blocks=(length-(BLOCKSIZE-rw_offset))/BLOCKSIZE+2; //+2 for the first & last partial blocks
	}

	//writing to an empty file.
	if(inodes[inode_index].pointers[0]==0){
	//If file is empty all inode pointers will be zero 
	int num_bytes_to_be_written = 0;
	int inode_index=dir_table[fileID].inode_number;
	int num_blocks=length/(BLOCKSIZE)+1;
	
		if(num_blocks<=(INODE_POINTERS-1)){ 
			//don't need the indirect pointer
			int j;
			char write_block_buffer[BLOCKSIZE];
			for(j=0;j<num_blocks-1;j++){
				//reset buffer
				memset(write_block_buffer,0,BLOCKSIZE); 
				memcpy(write_block_buffer,buf,BLOCKSIZE); 
				inodes[inode_index].pointers[j]=findfreeblock();
				
				int flag = write_blocks(inodes[inode_index].pointers[j],1,write_block_buffer);
				if(flag){ 
				//if write into disk successfully,count the number of bytes written
					num_bytes_to_be_written = num_bytes_to_be_written + BLOCKSIZE;
				}
				//upodate the bitmap
				markfreeblock(inodes[inode_index].pointers[j]);
			}
			
			//last block could be a partial block
			char direct_pointer_buf_last[BLOCKSIZE];
			memset(direct_pointer_buf_last,0,BLOCKSIZE);
			memcpy(direct_pointer_buf_last, buf+(num_blocks-1)*BLOCKSIZE, length % BLOCKSIZE);
			//find a free block for the last direct pointer
			int last_direct_pointer = findfreeblock();
			markfreeblock(last_direct_pointer);
			inodes[inode_index].pointers[num_blocks-1] = last_direct_pointer;
			//if write into disk successfully then count the number of bytes
			int flag = write_blocks(last_direct_pointer,1,direct_pointer_buf_last);
			if(flag){
				num_bytes_to_be_written = num_bytes_to_be_written + length%BLOCKSIZE;
			}
			//update the information in file descriptor table
			file_des_t[fileID].rw_pointer = file_des_t[fileID].rw_pointer + length;
			inodes[inode_index].size = inodes[inode_index].size + num_bytes_to_be_written;
			
			//update info on the disk
			int inode_number = inode_index;
			int block_of_inode=inode_number/8+1; 
			char inode_update_buf[BLOCKSIZE];
			memset(inode_update_buf,0, BLOCKSIZE);
			read_blocks(block_of_inode, 1, inode_update_buf);
			memcpy((void *)inode_update_buf+(inode_number%8)*sizeof(INODE),(const void *) &inodes[inode_number], sizeof(INODE));
			write_blocks(block_of_inode, 1, inode_update_buf);	
			write_blocks(TOTAL_NUM_BLOCKS-1,1,free_bitmap);
			return num_bytes_to_be_written;
		}
		else{	
				//else need the indirect pointer
				int m;
				char write_block_buffer[BLOCKSIZE];
				//handle all the direct pointer firstly,similar as the above 
				for(m=0;m<INODE_POINTERS-1;m++){
				memset(write_block_buffer,0,BLOCKSIZE); 
				memcpy(write_block_buffer,buf,BLOCKSIZE); 
				inodes[inode_index].pointers[m]=findfreeblock();
				int flag=write_blocks(inodes[inode_index].pointers[m],1,write_block_buffer);
				if(flag){num_bytes_to_be_written+=BLOCKSIZE;}
				markfreeblock(inodes[inode_index].pointers[m]);
			}
			//now let's handle the indirect pointer
			int num_indirect_pointers = num_blocks-(INODE_POINTERS-1);
			//get free blocks for indirect pointer
			int freeblock_indirect = findfreeblock(); 
			markfreeblock(freeblock_indirect);
			int arr_of_indirectptr[num_indirect_pointers];
			int k;
			//write the remaining data to the indirect blocks
			char indirect_pointer_buf[BLOCKSIZE];
			for(k=0;k<num_indirect_pointers-1;k++){
				arr_of_indirectptr[k] = findfreeblock();
				memset(indirect_pointer_buf,0,BLOCKSIZE);
				memcpy(indirect_pointer_buf, buf+(INODE_POINTERS-1)*BLOCKSIZE + k*BLOCKSIZE, BLOCKSIZE);
				int flag=write_blocks(arr_of_indirectptr[k],1,indirect_pointer_buf);
				if(flag){num_bytes_to_be_written+=BLOCKSIZE;}
				markfreeblock(arr_of_indirectptr[k]);
			}
			//handle partial indirect block
			int last_indirect_pointers = findfreeblock();
			arr_of_indirectptr[num_indirect_pointers-1] = last_indirect_pointers;
			markfreeblock(last_indirect_pointers);
			char last_indirect_pointer_buf[BLOCKSIZE];
			memset(last_indirect_pointer_buf,0,BLOCKSIZE);
			memcpy(last_indirect_pointer_buf,buf+(INODE_POINTERS-1)*BLOCKSIZE+(num_indirect_pointers-1)*BLOCKSIZE,length%BLOCKSIZE);
			int flag = write_blocks(arr_of_indirectptr[num_indirect_pointers-1],1,last_indirect_pointer_buf);
			if(flag){
				num_bytes_to_be_written = num_bytes_to_be_written + length%BLOCKSIZE;
			}
			
			//Write the indirect pointers to the indirect block
			char indirect_buffer[BLOCKSIZE];
			memset(indirect_buffer,0,BLOCKSIZE);
			memcpy(indirect_buffer,arr_of_indirectptr,num_indirect_pointers*sizeof(int));
			write_blocks(freeblock_indirect,1,indirect_buffer); 
			inodes[inode_index].pointers[INODE_POINTERS-1]=freeblock_indirect;
			file_des_t[fileID].rw_pointer = file_des_t[fileID].rw_pointer + length;
			inodes[inode_index].size = inodes[inode_index].size + num_bytes_to_be_written;
			
			//update all the info into the disk
			int inode_number = inode_index;
			int block_of_inode = inode_number/8+1; 
			char inode_update_buf[BLOCKSIZE];
			memset(inode_update_buf,0, BLOCKSIZE);
			read_blocks(block_of_inode, 1, inode_update_buf);
			memcpy((void *)inode_update_buf+(inode_number%8)*sizeof(INODE),(const void *) &inodes[inode_number], sizeof(INODE));
			write_blocks(block_of_inode, 1, inode_update_buf);	
			write_blocks(TOTAL_NUM_BLOCKS-1,1,free_bitmap);
			return num_bytes_to_be_written;
			}	
		}

	//file not empty
	int number_pointers;
	if(get_num_pointers_inode(inode_index)>INODE_POINTERS-1){
		//first ignore the indrect pointers if it is used
		number_pointers = get_num_pointers_inode(inode_index)-1; 
	}
	else{
		number_pointers = get_num_pointers_inode(inode_index);
	}
	
	int array_blockptr[number_pointers];
	get_pointers(inode_index,array_blockptr,number_pointers);

	int num_unchanged_blocks = rw_index;
	//Update all those blocks	
	int updated_array_blockptr[num_blocks + num_unchanged_blocks];
	memset(updated_array_blockptr,0,num_blocks*sizeof(int));
	//Copy the unchanged blocks
	int p;
	for(p = 0; p < rw_index-1; p++){		
		updated_array_blockptr[p] = array_blockptr[p];
	}

	int s;
	for(s=rw_index-1; s<((num_blocks+num_unchanged_blocks)-1); s++){
		//Allocate additional free blocks when s>total intial blocks
		if(s>number_pointers-1){
			//free block is not enough, find more
				if(s==(num_blocks+num_unchanged_blocks-2)){
				//last block need to do a partial write
				int free_block = findfreeblock();
				updated_array_blockptr[s] = free_block;
				markfreeblock(free_block);
				if(num_blocks==1){
					update_block(updated_array_blockptr[s],(char*)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index-1)),0,length);
					num_bytes_to_be_written=num_bytes_to_be_written+length;
				}
				else{
					if((BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index)<0){
						return -1;//write in last block
					}
					update_block(updated_array_blockptr[s],(char*)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index)),0,(length-(BLOCKSIZE-rw_offset))%BLOCKSIZE);	
					num_bytes_to_be_written = num_bytes_to_be_written + (length-(BLOCKSIZE-rw_offset)) % BLOCKSIZE;
				}			
			}
			else{				
				int free_block = findfreeblock();
				updated_array_blockptr[s] = free_block;
				markfreeblock(free_block);
				update_block(updated_array_blockptr[s],(char*)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index)),0,BLOCKSIZE);	
				num_bytes_to_be_written = num_bytes_to_be_written + BLOCKSIZE;
			}	
		}
		else{
			markfreeblock(array_blockptr[s]);
			updated_array_blockptr[s] = array_blockptr[s];	
			if(s==rw_index-1){
				//Overwriting the first block of write
				if(num_blocks==1){	
					//if only updating one block - will not be filling the first block of the write.
					update_block(array_blockptr[s],(char*)buf,rw_offset,length);
					num_bytes_to_be_written = num_bytes_to_be_written + length;
				}
				else{
					update_block(array_blockptr[s],(char*)buf,rw_offset,BLOCKSIZE-rw_offset);
					num_bytes_to_be_written = num_bytes_to_be_written + BLOCKSIZE-rw_offset;
				}
			}
			else if(s==(num_blocks + num_unchanged_blocks-2)){
				//last block may be partial
				if(num_blocks==1){
					//special case for one block write.
					update_block(updated_array_blockptr[s],(char*)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index-1)),0,length);
					num_bytes_to_be_written = num_bytes_to_be_written+length;
				}
				else{
					update_block(updated_array_blockptr[s],(char*)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index-1)),0,(length-(BLOCKSIZE-rw_offset))%BLOCKSIZE);
					num_bytes_to_be_written = num_bytes_to_be_written+(length-(BLOCKSIZE-rw_offset))%BLOCKSIZE;
				}
			}
			else{
				//overwriting a full block
				update_block(array_blockptr[s],(char *)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index-1)),0,BLOCKSIZE);
				num_bytes_to_be_written = num_bytes_to_be_written+BLOCKSIZE;
			}
		}
	}


	//storing the block pointers and put updated_array_blockptr into inode
	update_inode_pointers(inode_index,updated_array_blockptr,num_blocks+num_unchanged_blocks);
	int f_num_pointers = get_num_pointers_inode(inode_index);
	if(f_num_pointers > INODE_POINTERS-1){
		//exclude superblock if it is used
		f_num_pointers--;
	}
	int final_inode_pointers[f_num_pointers];
	get_pointers(inode_index,final_inode_pointers,f_num_pointers);
	file_des_t[fileID].rw_pointer+=length;
	inodes[inode_index].size = return_filesize(inode_index);
	
	//writing into disk
	int inode_number = inode_index;
	int block_of_inode=inode_number/8+1; 
	char inode_update_buf[BLOCKSIZE];
	memset(inode_update_buf,0, BLOCKSIZE);
	read_blocks(block_of_inode, 1, inode_update_buf);
	memcpy((void *)inode_update_buf+(inode_number%8)*sizeof(INODE),(const void *) &inodes[inode_number], sizeof(INODE));
	write_blocks(block_of_inode, 1, inode_update_buf);	
	write_blocks(TOTAL_NUM_BLOCKS-1,1,free_bitmap);
	return num_bytes_to_be_written;
}
Ejemplo n.º 12
0
int combineblk(RECPOS ads, int size)
{
    ENTRY  e;
    RECPOS address;
    int    esize, off, ret, saveoff, ibuff;
    ret = 0;
    saveoff = CO(--(pci->level));
    retrieve_block(pci->level, CB(pci->level));
    if ((off = next_entry( saveoff )) < block_ptr->bend)
        /* combine with page on right */
    {
        if ((ENT_SIZE(ENT_ADR(block_ptr, off)) + size) < (uint32_t)split_size)
        {
            copy_entry(&e, ENT_ADR(block_ptr, off));
            address = ENT_ADR(block_ptr, CO(pci->level))->idxptr;
            retrieve_block(++pci->level, address);
            ibuff = cache_ptr;
            spare_block = block_ptr;
            retrieve_block(pci->level, ads);
            esize = ENT_SIZE(&e);
            if(((block_ptr->bend + spare_block->bend + esize) >= split_size)&& (spare_block->bend <= block_ptr->bend + esize)) 
            {
                return  ret;
            }

            e.idxptr = spare_block->p0;
            ins_block(block_ptr, &e, block_ptr->bend);
            update_block();
            if ((block_ptr->bend + spare_block->bend) < split_size)
                /* combine the blocks */
            {
                memcpy(ENT_ADR(block_ptr, block_ptr->bend),ENT_ADR(spare_block, 0),spare_block->bend);
                block_ptr->bend += spare_block->bend;
                write_free(spare_block->brec, spare_block);
                BUFDIRTY(ibuff) = 0;
                BUFHANDLE(ibuff) = 0;
                --pci->level;
                ret = 1;
            }
            else
                /* move an entry up to replace the one moved */
            {
                copy_entry(&e, ENT_ADR(spare_block, 0));
                esize = ENT_SIZE(&e);
                movedown(spare_block, 0, esize);
                spare_block->bend -= esize;
                spare_block->p0 = e.idxptr;
                BUFDIRTY(ibuff) = 1;
                --(pci->level);
                replace_entry(&e);
            }
        }
    }
    else
        /* move from page on left */
    {
        if ( (ENT_SIZE(ENT_ADR(block_ptr, CO(pci->level))) + size) < (uint32_t)split_size)
        {
            copy_entry(&e, ENT_ADR(block_ptr, saveoff));
            off = prev_entry(saveoff);

            if (CO(pci->level) == -1) 
                address = block_ptr->p0;
            else 
                address = ENT_ADR(block_ptr, CO(pci->level))->idxptr;

            retrieve_block(++pci->level, address);
            off = last_entry();
            ibuff = cache_ptr;
            spare_block = block_ptr;
            retrieve_block(pci->level, ads);
            esize = ENT_SIZE(&e);

            if(((block_ptr->bend + spare_block->bend + esize) >= split_size)&& (spare_block->bend <= block_ptr->bend + esize))
            {
                return ret;
            }

            BUFDIRTY(ibuff) = 1;
            CO(pci->level) = 0;
            e.idxptr = block_ptr->p0;
            ins_block(block_ptr, &e, 0);
            if ((block_ptr->bend + spare_block->bend) < split_size)
                /* combine the blocks */
            {
                memcpy(ENT_ADR(spare_block, spare_block->bend),ENT_ADR(block_ptr, 0),block_ptr->bend);
                spare_block->bend += block_ptr->bend;
                write_free(block_ptr->brec, block_ptr);
                BUFDIRTY(cache_ptr) = 0;
                BUFHANDLE(cache_ptr) = 0;
                CO(--(pci->level)) = saveoff;
                ret = 1;
            }
            else
                /* move an entry up to replace the one moved */
            {
                block_ptr->p0 = ENT_ADR(spare_block,off)->idxptr;
                copy_entry(&e, ENT_ADR(spare_block, off));
                spare_block->bend = off;
                update_block();
                CO(--(pci->level)) = saveoff;
                replace_entry(&e);
            }
        }
    }
    root_dirty = 1;

    return ret;
} 
Ejemplo n.º 13
0
/* BPLUS delete key functions */
int delete_key(ENTRY *pe, IX_DESC *pix)
{
    ENTRY   e;
    RECPOS  ads;
    int     h, leveli, levelf;
    if (!find_exact(pe, pix))  
    {
        return (IX_NOTEXISTED);
    }
    h = 1;
    if ((ads = pe->idxptr) != NULLREC)
    {
        leveli = pci->level;
        do
        {
            retrieve_block(++(pci->level), ads);
            CO(pci->level) = -1;
        }

        while ((ads = block_ptr->p0) != NULLREC);
        CO(pci->level) = 0;
        copy_entry(&e, ENT_ADR(block_ptr, CO(pci->level)));
        levelf = pci->level;
        pci->level = leveli;
        replace_entry(&e);
        pci->level = levelf;
        /*update_root(&pci->root);*/
    }
    while ( h )
    {
        retrieve_block(pci->level, CB(pci->level));
        del_block(block_ptr, CO(pci->level));
        update_block();
        if ( (pci->level == 0) && (block_ptr->bend == 0))
            /* tree was reduced in height */
        {
            if (pci->root.p0 != NULLREC)
            {
                retrieve_block(++pci->level, pci->root.p0);
                memcpy(&(pci->root), block_ptr, sizeof(BLOCK));
                (pci->dx.nl)--;
                write_free(block_ptr->brec, block_ptr);
                BUFDIRTY(cache_ptr) = 0;
                BUFHANDLE(cache_ptr) = 0;
                update_root(&pci->root);
            }

            break;
        }
        h = (block_ptr->bend < comb_size) && (pci->level > 0);
        if ( h )
        {
            h = combineblk(CB(pci->level), block_ptr->bend);
        }
    }

    /*return flush_index(pix);*/
    if(root_dirty == 1)
    {
        flush_index(pix);
        root_dirty = 0;
    }

    return(IX_OK);
} 
static void
update_with_variant (GPid pid,
                     GVariant *info,
                     GError *error,
                     gpointer user_data)
{
    StoragedLinuxVolumeGroupObject *object = user_data;
    StoragedDaemon *daemon;
    GDBusObjectManagerServer *manager;
    GVariantIter *iter;
    GHashTableIter volume_iter;
    gpointer key, value;
    GHashTable *new_lvs;
    GHashTable *new_pvs;
    GList *objects, *l;
    gboolean needs_polling = FALSE;

    daemon = storaged_linux_volume_group_object_get_daemon (object);
    manager = storaged_daemon_get_object_manager (daemon);

    if (error)
    {
        storaged_warning ("Failed to update LVM volume group %s: %s",
                          storaged_linux_volume_group_object_get_name (object),
                          error->message);
        g_object_unref (object);
        return;
    }

    storaged_linux_volume_group_update (STORAGED_LINUX_VOLUME_GROUP (object->iface_volume_group), info, &needs_polling);

    if (!g_dbus_object_manager_server_is_exported (manager, G_DBUS_OBJECT_SKELETON (object)))
        g_dbus_object_manager_server_export_uniquely (manager, G_DBUS_OBJECT_SKELETON (object));

    new_lvs = g_hash_table_new (g_str_hash, g_str_equal);

    if (g_variant_lookup (info, "lvs", "aa{sv}", &iter))
    {
        GVariant *lv_info = NULL;
        while (g_variant_iter_loop (iter, "@a{sv}", &lv_info))
        {
            const gchar *name;
            StoragedLinuxLogicalVolumeObject *volume;

            g_variant_lookup (lv_info, "name", "&s", &name);

            update_operations (daemon, name, lv_info, &needs_polling);

            if (lv_is_pvmove_volume (name))
                needs_polling = TRUE;

            if (storaged_daemon_util_lvm2_name_is_reserved (name))
                continue;

            volume = g_hash_table_lookup (object->logical_volumes, name);
            if (volume == NULL)
            {
                volume = storaged_linux_logical_volume_object_new (daemon, object, name);
                storaged_linux_logical_volume_object_update (volume, lv_info, &needs_polling);
                storaged_linux_logical_volume_object_update_etctabs (volume);
                g_dbus_object_manager_server_export_uniquely (manager, G_DBUS_OBJECT_SKELETON (volume));
                g_hash_table_insert (object->logical_volumes, g_strdup (name), g_object_ref (volume));
            }
            else
                storaged_linux_logical_volume_object_update (volume, lv_info, &needs_polling);

            g_hash_table_insert (new_lvs, (gchar *)name, volume);
        }
        g_variant_iter_free (iter);
    }

    g_hash_table_iter_init (&volume_iter, object->logical_volumes);
    while (g_hash_table_iter_next (&volume_iter, &key, &value))
    {
        const gchar *name = key;
        StoragedLinuxLogicalVolumeObject *volume = value;

        if (!g_hash_table_contains (new_lvs, name))
        {
            g_dbus_object_manager_server_unexport (manager,
                                                   g_dbus_object_get_object_path (G_DBUS_OBJECT (volume)));
            g_hash_table_iter_remove (&volume_iter);

            g_object_unref (G_OBJECT (volume));
        }
    }

    storaged_volume_group_set_needs_polling (STORAGED_VOLUME_GROUP (object->iface_volume_group),
            needs_polling);

    /* Update block objects. */

    new_pvs = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)g_variant_unref);
    if (g_variant_lookup (info, "pvs", "aa{sv}", &iter))
    {
        const gchar *name;
        GVariant *pv_info;
        while (g_variant_iter_next (iter, "@a{sv}", &pv_info))
        {
            if (g_variant_lookup (pv_info, "device", "&s", &name))
                g_hash_table_insert (new_pvs, (gchar *)name, pv_info);
            else
                g_variant_unref (pv_info);
        }
    }

    objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (manager));
    for (l = objects; l != NULL; l = l->next)
    {
        if (STORAGED_IS_LINUX_BLOCK_OBJECT (l->data))
            update_block (STORAGED_LINUX_BLOCK_OBJECT (l->data), object, new_lvs, new_pvs);
    }
    g_list_free_full (objects, g_object_unref);

    g_hash_table_destroy (new_lvs);
    g_hash_table_destroy (new_pvs);

    g_object_unref (object);
}
Ejemplo n.º 15
0
int main(int argc, char *argv[]) {
  char query[100];
  const char *name, *sub;
  int i, id, ts, inputid, maxid = 0;
  double value;
  input_t *input;
  sqlite3_stmt *stmt;

  if (argc > 1) read_config(argv[1]);
  else read_config(NULL);

  if (!settings.sqlitefile) {
    fprintf(stderr, "No sqlite database defined in %s", argc>1?argv[1]:CONFIG_FILE);
    return EXIT_FAILURE;
  }
  if (sqlite3_open(settings.sqlitefile, &settings.sqlitehandle) != SQLITE_OK) {
    fprintf(stderr, "Failed to open sqlite database '%s': %s\n", settings.sqlitefile, sqlite3_errmsg(settings.sqlitehandle));
    return EXIT_FAILURE;
  }
  sqlite3_prepare_v2(settings.sqlitehandle, "SELECT `id`, `name`, `sub` FROM inputs", 40, &stmt, NULL);
  if (!stmt) {
    fprintf(stderr, "Failed to prepare query for inputs on SQLite db: %s\n", sqlite3_errmsg(settings.sqlitehandle));
    return EXIT_FAILURE;
  }
  while ((i = sqlite3_step(stmt)) == SQLITE_ROW) {
    if (sqlite3_column_count(stmt) != 3) break;
    id = sqlite3_column_int(stmt, 0);
    name = sqlite3_column_text(stmt, 1);
    sub = sqlite3_column_text(stmt, 2);
    for (input = inputs; input; input = input->next) {
      if (!strcmp(input->name, name)) {
        if (sub) input = add_input((char *)sub, input);
        input->sqlid = id;
      }
    }
  }
  if (i != SQLITE_DONE) {
    fprintf(stderr, "Error while reading inputs from SQLite db: %s\n", sqlite3_errmsg(settings.sqlitehandle));
    return EXIT_FAILURE;
  }

  snprintf(query, 100, "SELECT rowid, ts, value FROM data WHERE input = ? ORDER BY ts DESC LIMIT %d", block_width()-9);

  signal(SIGWINCH, do_winch);
  ioctl(0, TIOCGWINSZ, &settings.ws);
  go_ncurses();

  for (input = inputs; input; input = input->next) {
    if (!input->sqlid) continue;
    sqlite3_prepare_v2(settings.sqlitehandle, query, -1, &stmt, NULL);
    if (!stmt) {
      fprintf(stderr, "Failed to prepare query for latest data: %s\n", sqlite3_errmsg(settings.sqlitehandle));
      return EXIT_FAILURE;
    }
    if (sqlite3_bind_int(stmt, 1, input->sqlid) != SQLITE_OK) {
      fprintf(stderr, "Failed to bind param 1 on initial data query: %s\n", sqlite3_errmsg(settings.sqlitehandle));
      return EXIT_FAILURE;
    }
    while ((i = sqlite3_step(stmt)) == SQLITE_ROW) {
      if (sqlite3_column_count(stmt) != 3) break;
      id = sqlite3_column_int(stmt, 0);
      ts = sqlite3_column_int(stmt, 1);
      value = sqlite3_column_double(stmt, 2);
      if (id > maxid) maxid = id;
      if (input->vallast-input->valhist == VALUE_HIST_SIZE-1) input->vallast = input->valhist;
      else input->vallast++;
      input->valcnt++;
      if (input->update < ts) input->update = ts;
      *input->vallast = value;
    }
    sqlite3_finalize(stmt);
    if (i != SQLITE_DONE) fprintf(stderr, "Error while reading initial data from SQLite db: %s\n", sqlite3_errmsg(settings.sqlitehandle));
    update_block(input);
  }

  while (1) {
    if (settings.winch) {
      ioctl(0, TIOCGWINSZ, &settings.ws);
      refresh();
      resizeterm(settings.ws.ws_row, settings.ws.ws_col);
      arrange_blocks();
      settings.winch = 0;
    }

    sqlite3_prepare_v2(settings.sqlitehandle, "SELECT rowid, input, ts, value FROM data WHERE rowid > ? ORDER BY ts", 69, &stmt, NULL);
    if (!stmt) {
      fprintf(stderr, "Failed to prepare query for latest data on SQLite db: %s\n", sqlite3_errmsg(settings.sqlitehandle));
      return EXIT_FAILURE;
    }
    if (sqlite3_bind_int(stmt, 1, maxid) != SQLITE_OK) {
      fprintf(stderr, "Error binding param 1 for latest data query: %s\n", sqlite3_errmsg(settings.sqlitehandle));
      return EXIT_FAILURE;
    }
    while ((i = sqlite3_step(stmt)) == SQLITE_ROW) {
      if (sqlite3_column_count(stmt) != 4) break;
      id = sqlite3_column_int(stmt, 0);
      inputid = sqlite3_column_int(stmt, 1);
      ts = sqlite3_column_int(stmt, 2);
      value = sqlite3_column_double(stmt, 3);
      if (id > maxid) maxid = id;
      for (input = inputs; input; input = input->next) {
        if (inputid == input->sqlid) {
          if (input->vallast-input->valhist == VALUE_HIST_SIZE-1) input->vallast = input->valhist;
          else input->vallast++;
          input->valcnt++;
          input->update = ts;
          *input->vallast = value;
          update_block(input);
        }
      }
    }
    sqlite3_finalize(stmt);
    if (i != SQLITE_DONE) fprintf(stderr, "Error while reading data from SQLite db: %s\n", sqlite3_errmsg(settings.sqlitehandle));

    check_updates();

    sleep(60);
  }
}