예제 #1
0
파일: heap.cpp 프로젝트: chris-ream/factor
/* Called after reading the code heap from the image file, and after code GC.

In the former case, we must add a large free block from compiling.base + size to
compiling.limit. */
void heap::build_free_list(cell size)
{
	heap_block *prev = NULL;

	clear_free_list();

	size = (size + block_size_increment - 1) & ~(block_size_increment - 1);

	heap_block *scan = first_block();
	free_heap_block *end = (free_heap_block *)(seg->start + size);

	/* Add all free blocks to the free list */
	while(scan && scan < (heap_block *)end)
	{
		switch(scan->status)
		{
		case B_FREE:
			add_to_free_list((free_heap_block *)scan);
			break;
		case B_ALLOCATED:
			break;
		default:
			myvm->critical_error("Invalid scan->status",(cell)scan);
			break;
		}

		prev = scan;
		scan = next_block(scan);
	}

	/* If there is room at the end of the heap, add a free block. This
	branch is only taken after loading a new image, not after code GC */
	if((cell)(end + 1) <= seg->end)
	{
		end->status = B_FREE;
		end->size = seg->end - (cell)end;

		/* add final free block */
		add_to_free_list(end);
	}
	/* This branch is taken if the newly loaded image fits exactly, or
	after code GC */
	else
	{
		/* even if there's no room at the end of the heap for a new
		free block, we might have to jigger it up by a few bytes in
		case prev + prev->size */
		if(prev) prev->size = seg->end - (cell)prev;
	}

}
예제 #2
0
/**********************************************************
 * coalesce
 * Covers the 4 cases discussed in the text:
 * - both neighbours are allocated
 * - the next block is available for coalescing
 * - the previous block is available for coalescing
 * - both neighbours are available for coalescing
 **********************************************************/
void *coalesce(void *bp)
{
	//printf("IN COALESCE\n");
	//printf("coalescing block ptr %p\n",bp);
	size_t prev_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp)));
	size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp)));
	size_t size = GET_SIZE(HDRP(bp));
	//printf("sizeof size_t %08p\n",sizeof(size_t));

	if (prev_alloc && next_alloc) {       /* Case 1 */
		//printf("case 1\n");
		add_to_free_list(bp);	//add to the free list
		//print_ptr(bp);
		return bp;
	}
	else if (prev_alloc && !next_alloc) { /* Case 2 */

		//printf("case 2\n");
		size += GET_SIZE(HDRP(NEXT_BLKP(bp)));

		remove_free_block(NEXT_BLKP(bp)); //remove the free block from the free list
		PUT(HDRP(bp), PACK(size, 0));
		PUT(FTRP(bp), PACK(size, 0));
		add_to_free_list(bp);
		return (bp);
	}
	else if (!prev_alloc && next_alloc) { /* Case 3 */
		//printf("case 3\n");
		size += GET_SIZE(HDRP(PREV_BLKP(bp)));

		remove_free_block(PREV_BLKP(bp));
		PUT(FTRP(bp), PACK(size, 0));
		PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
		add_to_free_list(PREV_BLKP(bp));
		//print_ptr(PREV_BLKP(bp));
		//print_ptr(bp);
		return (PREV_BLKP(bp));
	}
	else {            /* Case 4 */
		//printf("case 4\n");
		size += GET_SIZE(HDRP(PREV_BLKP(bp)))+GET_SIZE(FTRP(NEXT_BLKP(bp)));
		remove_free_block(PREV_BLKP(bp));
		remove_free_block(NEXT_BLKP(bp));
		PUT(HDRP(PREV_BLKP(bp)), PACK(size,0));
		PUT(FTRP(NEXT_BLKP(bp)), PACK(size,0));
		add_to_free_list(PREV_BLKP(bp));
		//print_ptr(bp);

		return (PREV_BLKP(bp));
	}
}
예제 #3
0
/**********************************************************
 * place
 * Mark the block as allocated
 **********************************************************/
void place(void* bp, size_t asize)
{
	/* Get the current block size */
	size_t bsize = GET_SIZE(HDRP(bp));
	/* size 32 is the minimum possible chunk to hold some data*/
	if((bsize-asize) >= 32)	//check if splitting is possible
	{
		/* first block - which will be allocated*/
		//header
		PUT(HDRP(bp),PACK(asize,1));
		//footer
		PUT(FTRP(bp),PACK(asize,1));
		/* second block - which will be freed*/
		//header
		PUT((bp+asize-WSIZE),PACK(bsize-asize,0));
		//footer
		PUT(FTRP(bp+asize),PACK(bsize-asize,0));
		//add the second block to the free list
		add_to_free_list(bp+asize);
	}
	else	//if splitting is not possible
	{
		PUT(HDRP(bp), PACK(bsize, 1));
		PUT(FTRP(bp), PACK(bsize, 1));
	}
}
예제 #4
0
/**********************************************************
 * extend_heap
 * Extend the heap by "words" words, maintaining alignment
 * requirements of course. Free the former epilogue block
 * and reallocate its new header
 **********************************************************/
void *extend_heap(size_t words)
{
    char *bp;
    size_t size;

    /* Allocate an even number of words to maintain alignments */
    size = (words % 2) ? (words+1) * WSIZE : words * WSIZE;
    if ( (bp = mem_sbrk(size)) == (void *)-1 )
        return NULL;

    /* Initialize free block header/footer and the epilogue header */
    PUT(HDRP(bp), PACK(size, 0));                // free block header
    PUT(FTRP(bp), PACK(size, 0));                // free block footer
    PUT(HDRP(NEXT_BLKP(bp)), PACK(0, 1));        // new epilogue header

    /* Place at top of free list  */

    add_to_free_list(bp);

    printf("add_to_free being called in extend()\n");
    printf("extend - bp: %p\n", bp);
    printf("extend - addr of prev: %p\n", PREV_FR_BP(bp));
    printf("extend - addr of next: %p\n", NEXT_FR_BP(bp));
    /* Coalesce if the previous block was free */
    return coalesce(bp);
}
예제 #5
0
/**********************************************************
 * split_and_place
 * Split the block into new_size and GET_SIZE(bp) minus new_size
 * then allocate and free the new areas
 **********************************************************/
void split_and_place(void* bp, size_t a_new_size)
{
    size_t old_size = GET_SIZE(HDRP(bp));
    size_t f_new_size = old_size - a_new_size;

    // remove this block from the explicit free list
    remove_from_free_list(bp);

    // if old_size - a_new_size >= MINBLOCK SIZE, do split
    if (f_new_size < MINBLOCKSIZE) {
        size_t bsize = GET_SIZE(HDRP(bp));
        PUT(HDRP(bp), PACK(bsize, 1));
        PUT(FTRP(bp), PACK(bsize, 1));
        // free block completely removed, so no need to add to free list

    } else {
        char * alloc_head = HDRP(bp);
        char * free_foot = FTRP(bp);
        char * free_head = alloc_head + a_new_size;
        char * alloc_foot = free_head - WSIZE;

        PUT(alloc_head, PACK(a_new_size, 1));
        PUT(free_foot, PACK(f_new_size,0));
        PUT(free_head, PACK(f_new_size,0));
        PUT(alloc_foot, PACK(a_new_size, 1));
        add_to_free_list(free_head + WSIZE);

        printf("add_to_free being called in split_place()\n");
        printf("split_place - bp: %p\n", NEXT_BLKP(bp));
        printf("split_place - addr of prev: %p\n", PREV_FR_BP(NEXT_BLKP(bp)));
        printf("split_place - addr of next: %p\n", NEXT_FR_BP(NEXT_BLKP(bp)));
    }
}
예제 #6
0
파일: memory.c 프로젝트: enispes/titan.core
void Free(void *ptr)
#endif
{
    if (ptr != NULL) {
#ifdef MEMORY_DEBUG
	memory_block *block_ptr = NULL;
	block_ptr = (memory_block*)(void*)((unsigned char*)ptr - offset);
#ifdef MEMORY_DEBUG_ADDRESS
        check_memory_address(block_ptr, 2);
#endif
	check_magic_values(filename, line, block_ptr, 0);
	remove_from_list(block_ptr);
	allocated_size -= block_ptr->size;
	memset(ptr, 0xAA, block_ptr->size);
#ifdef MEMORY_DEBUG_FREE
	add_to_free_list(block_ptr);
#else
	free(block_ptr);
#endif
#else
	free(ptr);
#endif
	free_count++;
    }
}
예제 #7
0
파일: stringindex.c 프로젝트: jkeiren/muCRL
int SIdelete(string_index_t si,const char*str) {
    ub4 hash;
    ub4 len;
    int bucket;
    int idx,next,deleted;

    len=strlen(str);
    hash=hash_4_1((unsigned char*) str,len,0);
    bucket=hash&si->mask;
    idx=si->table[bucket];
    si->table[bucket]=END_OF_LIST;
    while(idx!=END_OF_LIST) {
        if (0==strcmp(str,si->data[idx])) {
            deleted=idx;
            free(si->data[idx]);
            si->count--;
            idx=si->next[idx];
            while(idx!=END_OF_LIST) {
                next=si->next[idx];
                si->next[idx]=si->table[bucket];
                si->table[bucket]=idx;
                idx=next;
            }
            add_to_free_list(si,deleted);
            return 0;
        } else {
            next=si->next[idx];
            si->next[idx]=si->table[bucket];
            si->table[bucket]=idx;
            idx=next;
        }
    }
    return 0;
}
예제 #8
0
void SIdeleteC(string_index_t si,const char*str,int len){
	uint32_t hash;
	int bucket;
	int idx,next,deleted;

	hash=SuperFastHash(str,len,0);
	bucket=hash&si->mask;
	idx=si->table[bucket];
	si->table[bucket]=END_OF_LIST;
	while(idx!=END_OF_LIST){
		if (0==strcmp(str,si->data[idx])) {
			deleted=idx;
			RTfree(si->data[idx]);
			si->count--;
			idx=si->next[idx];
			while(idx!=END_OF_LIST){
				next=si->next[idx];
				si->next[idx]=si->table[bucket];
				si->table[bucket]=idx;
				idx=next;
			}
			add_to_free_list(si,deleted);
			return;
		} else {
			next=si->next[idx];
			si->next[idx]=si->table[bucket];
			si->table[bucket]=idx;
			idx=next;
		}
	}
}
예제 #9
0
파일: Allocator.hpp 프로젝트: kawuum/grappa
  void try_merge_buddy_recursive( ChunkMap::iterator cmit ) {
    // compute address of buddy
    intptr_t address = cmit->second.address;
    intptr_t buddy_address = (address ^ cmit->second.size);
    DVLOG(5) << cmit->second << " buddy address " << (void *) buddy_address;

    // does it exist?
    ChunkMap::iterator buddy_iterator = chunks_.find( buddy_address );
    if( buddy_iterator != chunks_.end() && 
        buddy_iterator->second.size == cmit->second.size &&
        buddy_iterator->second.in_use == false ) {
      DVLOG(5) << "buddy found! address " << (void *) address << " buddy address " << (void *) buddy_address;

      // remove the higher-addressed chunk
      ChunkMap::iterator higher_iterator = address < buddy_address ? buddy_iterator : cmit;
      remove_from_free_list( higher_iterator );
      chunks_.erase( higher_iterator );

      // keep the the lower-addressed chunk in the map:
      // update its size and move it to the right free list
      ChunkMap::iterator lower_iterator = address < buddy_address ? cmit : buddy_iterator;
      remove_from_free_list( lower_iterator ); // should these be swapped? I think so.
      lower_iterator->second.size *= 2;
      add_to_free_list( lower_iterator );

      // see if we have more to merge
      try_merge_buddy_recursive( lower_iterator );
    }
  }
예제 #10
0
파일: heap.cpp 프로젝트: harold/factor
/* Called after reading the code heap from the image file, and after code GC.

In the former case, we must add a large free block from compiling.base + size to
compiling.limit. */
void heap::build_free_list(cell size)
{
	heap_block *prev = NULL;

	clear_free_list();

	size = (size + block_size_increment - 1) & ~(block_size_increment - 1);

	heap_block *scan = first_block();
	free_heap_block *end = (free_heap_block *)(seg->start + size);

	/* Add all free blocks to the free list */
	while(scan && scan < (heap_block *)end)
	{
		if(scan->type() == FREE_BLOCK_TYPE)
			add_to_free_list((free_heap_block *)scan);

		prev = scan;
		scan = next_block(scan);
	}

	/* If there is room at the end of the heap, add a free block. This
	branch is only taken after loading a new image, not after code GC */
	if((cell)(end + 1) <= seg->end)
	{
		end->set_marked_p(false);
		end->set_type(FREE_BLOCK_TYPE);
		end->set_size(seg->end - (cell)end);

		/* add final free block */
		add_to_free_list(end);
	}
	/* This branch is taken if the newly loaded image fits exactly, or
	after code GC */
	else
	{
		/* even if there's no room at the end of the heap for a new
		free block, we might have to jigger it up by a few bytes in
		case prev + prev->size */
		if(prev) prev->set_size(seg->end - (cell)prev);
	}

}
예제 #11
0
파일: heap.cpp 프로젝트: chris-ream/factor
free_heap_block *heap::split_free_block(free_heap_block *block, cell size)
{
	if(block->size != size )
	{
		/* split the block in two */
		free_heap_block *split = (free_heap_block *)((cell)block + size);
		split->status = B_FREE;
		split->size = block->size - size;
		split->next_free = block->next_free;
		block->size = size;
		add_to_free_list(split);
	}

	return block;
}
예제 #12
0
파일: heap.cpp 프로젝트: harold/factor
free_heap_block *heap::split_free_block(free_heap_block *block, cell size)
{
	if(block->size() != size )
	{
		/* split the block in two */
		free_heap_block *split = (free_heap_block *)((cell)block + size);
		split->set_type(FREE_BLOCK_TYPE);
		split->set_size(block->size() - size);
		split->next_free = block->next_free;
		block->set_size(size);
		add_to_free_list(split);
	}

	return block;
}
예제 #13
0
void		free(void *ptr, int is_kernel)
{
  t_kchunk	*free;

  free = ptr - sizeof(*free);
  if (free->magic == KFREE_MAGIC)
    kprintf("Warning: Pointer (0x%x) is already free.\n", ptr);
  else if (free->magic == KMALLOC_MAGIC)
    {
      free->magic = KFREE_MAGIC;
      free->next = NULL;
      add_to_free_list(free, is_kernel);
    }
  else
    kprintf("Warning: Pointer (0x%x) is not a valid block.\n", ptr);
}
예제 #14
0
/**********************************************************
 * mm_free
 * Free the block and coalesce with neighbouring blocks
 **********************************************************/
void mm_free(void *bp)
{
    printf("\n FREE CALLED \n\n");
    if(bp == NULL){
      return;
    }
    size_t size = GET_SIZE(HDRP(bp));
    PUT(HDRP(bp), PACK(size,0));
    PUT(FTRP(bp), PACK(size,0));

    add_to_free_list(bp);
    printf("add_to_free being called in free()\n");
    printf("free - bp: %p\n", bp);
    printf("free - addr of prev: %p\n", PREV_FR_BP(bp));
    printf("free - addr of next: %p\n", NEXT_FR_BP(bp));
    coalesce(bp);
}
예제 #15
0
파일: cmm.c 프로젝트: AdiPat/i9003_Kernel
/*
 *  ======== cmm_free_buf ========
 *  Purpose:
 *      Free the given buffer.
 */
int cmm_free_buf(struct cmm_object *hcmm_mgr, void *buf_pa,
			u32 ul_seg_id)
{
	struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr;
	int status = -EFAULT;
	struct cmm_mnode *mnode_obj = NULL;
	struct cmm_allocator *allocator = NULL;
	struct cmm_attrs *pattrs;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(buf_pa != NULL);

	if (ul_seg_id == 0) {
		pattrs = &cmm_dfltalctattrs;
		ul_seg_id = pattrs->ul_seg_id;
	}
	if (!hcmm_mgr || !(ul_seg_id > 0)) {
		status = -EFAULT;
		return status;
	}
	/* get the allocator for this segment id */
	allocator = get_allocator(cmm_mgr_obj, ul_seg_id);
	if (allocator != NULL) {
		mutex_lock(&cmm_mgr_obj->cmm_lock);
		mnode_obj =
		    (struct cmm_mnode *)lst_first(allocator->in_use_list_head);
		while (mnode_obj) {
			if ((u32) buf_pa == mnode_obj->dw_pa) {
				/* Found it */
				lst_remove_elem(allocator->in_use_list_head,
						(struct list_head *)mnode_obj);
				/* back to freelist */
				add_to_free_list(allocator, mnode_obj);
				status = 0;	/* all right! */
				break;
			}
			/* next node. */
			mnode_obj = (struct cmm_mnode *)
			    lst_next(allocator->in_use_list_head,
				     (struct list_head *)mnode_obj);
		}
		mutex_unlock(&cmm_mgr_obj->cmm_lock);
	}
	return status;
}
예제 #16
0
파일: mm.c 프로젝트: divd/ece454
/*
 * Get array position which best fits free block
 * split_bp: Pointer to partition + WSIZE (i.e. the payload of the partition)
 * split_size_payload: Payload of the partition in bytes
 */
void trim_free_block(void *split_bp, int split_size) {
	// printf("Entering trim_free\n");
	assert(split_bp != NULL);
	void* partition_bp = split_bp;
	int partition_array_pos = -1;
	int partition_size = 0;
	// recursively split and place free blocks in appropriate free lists position
	while (split_size > DSIZE) {
		// get closest fit index
		int split_size_payload_dwords = (split_size >> 4) - 1;
		partition_array_pos = (__builtin_popcount(split_size_payload_dwords) > 1)? get_array_position_malloc(split_size_payload_dwords) - 1 : get_array_position_malloc(split_size_payload_dwords);

//		// printf("partition_array_pos : %d\n", partition_array_pos);

		int partition_size_payload = get_power_of_2(partition_array_pos) * DSIZE;
		partition_size = partition_size_payload + DSIZE;
		if(partition_size < 0)
			printf("ERROR: Size of partition is %d\n",partition_size);

//		// printf("(IN DW) partition_size: %d, split_size : %d\n", partition_size>>4, split_size>>4);
//		// printf("(IN DW) split_size - partition_size = %d\n", (split_size - partition_size)>>4);

		assert(partition_size >= 0);
//		if (partition_bp == (void *)0x7f11bbfc5020) {
//			printf("Array position: %d, partition_size: %d\n",partition_array_pos, partition_size);

//		}
		// set header and footer of free split block
		PUT(HDRP(partition_bp), PACK(partition_size, 0));
		PUT(FTRP(partition_bp), PACK(partition_size, 0));
		// insert into head of linked list at partition_array_pos
		add_to_free_list(partition_bp, partition_array_pos);

		partition_bp += partition_size;
		split_size -= partition_size;
	}
	// odd DW left, assign header and footer with size 1 DW
	if (split_size == DSIZE) {
		// set header and footer of free split block
		PUT(HDRP(partition_bp), PACK(split_size, 0));
		PUT(FTRP(partition_bp), PACK(split_size, 0));
	}
	// printf("Leaving trim_free\n");
}
예제 #17
0
/* effects: adds small blocks to the small blocks table, and
   large blocks to the correct location in the free list
*/
void add_to_free_blocks(struct block *new_block,
			struct block **free_list,
			struct block *small_blocks[])
{
  // "small" blocks are stored separately for fast allocation
  if (new_block->size <= SMALL_BLOCK_SIZE)
    {
      // calculate the array index
      int index = new_block->size/ALIGN_TO;

      // check that the array index is in-bounds
      assert(index >= 0 && index < NUM_SMALL_BLOCK_SIZES);
      
      new_block->markunion.next = small_blocks[index];
      small_blocks[index] = new_block;
    }
  else
    add_to_free_list(new_block, free_list);
}
예제 #18
0
// method for release allocated memory block
void freemem(void* p){
	if(p == NULL){
		return;
	}

	//case 1: check if p is adjacent to one of the free_list node
	memnode* cursor = free_list;
	while(cursor != NULL){
		if((memnode*)((uintptr_t)cursor + HEAD_SIZE + cursor->size + HEAD_SIZE) == (memnode*)p){
			cursor -> size = cursor -> size + ((memnode*)((uintptr_t)p - HEAD_SIZE))->size + HEAD_SIZE;
			//delete p from ALA;
			delete_from_allocate(((memnode*)((uintptr_t)p- HEAD_SIZE)));
			return; 
		}
		cursor = cursor->next;
	}
	//delete p from ALA;
	delete_from_allocate(((memnode*)((uintptr_t)p- HEAD_SIZE)));
	add_to_free_list((memnode*)((uintptr_t)p- HEAD_SIZE));
}
예제 #19
0
파일: heap.cpp 프로젝트: chris-ream/factor
/* Deallocates a block manually */
void heap::heap_free(heap_block *block)
{
	block->status = B_FREE;
	add_to_free_list((free_heap_block *)block);
}
예제 #20
0
파일: cmm.c 프로젝트: AdiPat/i9003_Kernel
/*
 *  ======== cmm_calloc_buf ========
 *  Purpose:
 *      Allocate a SM buffer, zero contents, and return the physical address
 *      and optional driver context virtual address(pp_buf_va).
 *
 *      The freelist is sorted in increasing size order. Get the first
 *      block that satifies the request and sort the remaining back on
 *      the freelist; if large enough. The kept block is placed on the
 *      inUseList.
 */
void *cmm_calloc_buf(struct cmm_object *hcmm_mgr, u32 usize,
		     struct cmm_attrs *pattrs, OUT void **pp_buf_va)
{
	struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr;
	void *buf_pa = NULL;
	struct cmm_mnode *pnode = NULL;
	struct cmm_mnode *new_node = NULL;
	struct cmm_allocator *allocator = NULL;
	u32 delta_size;
	u8 *pbyte = NULL;
	s32 cnt;

	if (pattrs == NULL)
		pattrs = &cmm_dfltalctattrs;

	if (pp_buf_va != NULL)
		*pp_buf_va = NULL;

	if (cmm_mgr_obj && (usize != 0)) {
		if (pattrs->ul_seg_id > 0) {
			/* SegId > 0 is SM */
			/* get the allocator object for this segment id */
			allocator =
			    get_allocator(cmm_mgr_obj, pattrs->ul_seg_id);
			/* keep block size a multiple of ul_min_block_size */
			usize =
			    ((usize - 1) & ~(cmm_mgr_obj->ul_min_block_size -
					     1))
			    + cmm_mgr_obj->ul_min_block_size;
			mutex_lock(&cmm_mgr_obj->cmm_lock);
			pnode = get_free_block(allocator, usize);
		}
		if (pnode) {
			delta_size = (pnode->ul_size - usize);
			if (delta_size >= cmm_mgr_obj->ul_min_block_size) {
				/* create a new block with the leftovers and
				 * add to freelist */
				new_node =
				    get_node(cmm_mgr_obj, pnode->dw_pa + usize,
					     pnode->dw_va + usize,
					     (u32) delta_size);
				if (new_node) {
					/* leftovers go free */
					add_to_free_list(allocator, new_node);
				}
				/* adjust our node's size */
				pnode->ul_size = usize;
			}
			/* Tag node with client process requesting allocation
			 * We'll need to free up a process's alloc'd SM if the
			 * client process goes away.
			 */
			/* Return TGID instead of process handle */
			pnode->client_proc = current->tgid;

			/* put our node on InUse list */
			lst_put_tail(allocator->in_use_list_head,
				     (struct list_head *)pnode);
			buf_pa = (void *)pnode->dw_pa;	/* physical address */
			/* clear mem */
			pbyte = (u8 *) pnode->dw_va;
			for (cnt = 0; cnt < (s32) usize; cnt++, pbyte++)
				*pbyte = 0;

			if (pp_buf_va != NULL) {
				/* Virtual address */
				*pp_buf_va = (void *)pnode->dw_va;
			}
		}
		mutex_unlock(&cmm_mgr_obj->cmm_lock);
	}
	return buf_pa;
}
예제 #21
0
파일: lh.c 프로젝트: songchao43088/DBI
void rehash_keys(HFILE *hf, int i, INDEX_FILE *index_file){
	void *original_bucket;
	void *old_bucket;
	void *new_bucket;
	void *buf;
	int original_offset=12;
	int original_usage;
	int old_bucket_write_position = -1;
	int new_bucket_write_position = -1;
	int free_start_point;
	
	original_bucket = calloc(BSIZE,sizeof(char));
	if (original_bucket==NULL){
		printf("Malloc failed");
		exit(1);
	}
	old_bucket = calloc(BSIZE,sizeof(char));
	if (old_bucket==NULL){
		printf("Malloc failed");
		exit(1);
	}
	new_bucket = calloc(BSIZE,sizeof(char));
	if (new_bucket==NULL){
		printf("Malloc failed");
		exit(1);
	}
	buf = calloc(105,sizeof(char));
	if (buf==NULL){
		printf("Malloc failed");
		exit(1);
	}
	read_bucket(original_bucket, index_file->next, index_file->main_path);
	original_usage = ((int*)original_bucket)[0];
	read_bucket(old_bucket, index_file->next, index_file->main_path);
	((int*)old_bucket)[0]=12;

	read_bucket(new_bucket, index_file->n, index_file->main_path);
	for (original_offset = 12; original_offset < original_usage; original_offset += atoi((hf->schema[i])+1)+sizeof(long long)){
		RID rid = (*read_keypair[hf->schema_array[i]])(original_bucket, buf, original_offset, atoi((hf->schema[i])+1));
		long long new_index = (*calculate_index[hf->schema_array[i]])(buf,index_file->s,index_file->n+1, 0);
		if (new_index==index_file->next){//old
			if (((int*)old_bucket)[0] >= BSIZE-sizeof(long long)-atoi((index_file->type)+1)){//full, allocate new		
				if (old_bucket_write_position == -1){
					write_bucket(old_bucket, index_file->next, index_file->main_path);
				} else {
					write_bucket(old_bucket, old_bucket_write_position, index_file->overflow_path);
				}
				old_bucket_write_position = ((long long*)(old_bucket+4))[0];
				read_bucket(old_bucket, old_bucket_write_position, index_file->overflow_path);
				((int*)old_bucket)[0]=12;	
			}

			(*update_bucket[hf->schema_array[i]])(old_bucket,buf,rid,atoi((hf->schema[i])+1)+sizeof(long long),0);

		} else { //new
			if (((int*)new_bucket)[0] >= BSIZE-sizeof(long long)-atoi((index_file->type)+1)){//full, allocate new		
				if (new_bucket_write_position == -1){
					write_bucket(new_bucket, index_file->n, index_file->main_path);
					new_bucket_write_position = create_overflow_bucket(index_file);
					mylink(index_file->n, 0, new_bucket_write_position, index_file);
				} else {
					RID tmp = new_bucket_write_position;
					write_bucket(new_bucket, new_bucket_write_position, index_file->overflow_path);
					new_bucket_write_position = create_overflow_bucket(index_file);
					mylink(tmp, 1, new_bucket_write_position, index_file);
				}
				read_bucket(new_bucket, new_bucket_write_position, index_file->overflow_path);	
			}
			(*update_bucket[hf->schema_array[i]])(new_bucket,buf,rid,atoi((hf->schema[i])+1)+sizeof(long long),0);
		}
	}
	while (((long long*)(original_bucket+4))[0]!=-1){
		read_bucket(original_bucket, ((long long*)(original_bucket+4))[0], index_file->overflow_path);
		original_usage = ((int*)original_bucket)[0];
		for (original_offset = 12; original_offset < original_usage; original_offset += atoi((hf->schema[i])+1)+sizeof(long long)){
			RID rid = (*read_keypair[hf->schema_array[i]])(original_bucket, buf, original_offset, atoi((hf->schema[i])+1));
			long long new_index = (*calculate_index[hf->schema_array[i]])(buf,index_file->s,index_file->n+1, 0);
			if (new_index==index_file->next){//old
				if (((int*)old_bucket)[0] >= BSIZE-sizeof(long long)-atoi((index_file->type)+1)){//full, allocate new		
					if (old_bucket_write_position == -1){
						write_bucket(old_bucket, index_file->next, index_file->main_path);
					} else {
						write_bucket(old_bucket, old_bucket_write_position, index_file->overflow_path);
					}
					old_bucket_write_position = ((long long*)(old_bucket+4))[0];

					read_bucket(old_bucket, old_bucket_write_position, index_file->overflow_path);
					((int*)old_bucket)[0]=12;	
				}
				(*update_bucket[hf->schema_array[i]])(old_bucket,buf,rid,atoi((hf->schema[i])+1)+sizeof(long long),0);
			} else { //new
				if (((int*)new_bucket)[0] >= BSIZE-sizeof(long long)-atoi((index_file->type)+1)){//full, allocate new		
					if (new_bucket_write_position == -1){
						write_bucket(new_bucket, index_file->n, index_file->main_path);
						new_bucket_write_position = create_overflow_bucket(index_file);
						mylink(index_file->n, 0, new_bucket_write_position, index_file);
					} else {
						RID tmp = new_bucket_write_position;
						write_bucket(new_bucket, new_bucket_write_position, index_file->overflow_path);
						new_bucket_write_position = create_overflow_bucket(index_file);
						mylink(tmp, 1, new_bucket_write_position, index_file);
					}
					read_bucket(new_bucket, new_bucket_write_position, index_file->overflow_path);	
				}
				(*update_bucket[hf->schema_array[i]])(new_bucket,buf,rid,atoi((hf->schema[i])+1)+sizeof(long long),0);
			}
		}
	}
	free_start_point = ((long long*)(old_bucket+4))[0];
	if (free_start_point != -1){

		int original_free_tail = find_free_list_tail(index_file);
		if (original_free_tail != -1) {
			mylink(original_free_tail, 1, free_start_point, index_file);
		} else {
			add_to_free_list(free_start_point, index_file);
		}
	}
	((long long*)(old_bucket+4))[0] = -1;
	if (old_bucket_write_position == -1){
		write_bucket(old_bucket, index_file->next, index_file->main_path);
	} else {
		write_bucket(old_bucket, old_bucket_write_position, index_file->overflow_path);
	}
	if (new_bucket_write_position == -1){
		write_bucket(new_bucket, index_file->n, index_file->main_path);
	} else {
		write_bucket(new_bucket, new_bucket_write_position, index_file->overflow_path);
	}
	
	free(original_bucket);
	free(old_bucket);
	free(new_bucket);
	free(buf);
}
예제 #22
0
파일: heap.cpp 프로젝트: harold/factor
/* Deallocates a block manually */
void heap::heap_free(heap_block *block)
{
	block->set_type(FREE_BLOCK_TYPE);
	add_to_free_list((free_heap_block *)block);
}