/* 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; } }
/********************************************************** * 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)); } }
/********************************************************** * 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)); } }
/********************************************************** * 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); }
/********************************************************** * 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))); } }
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++; } }
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; }
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; } } }
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 ); } }
/* 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); } }
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; }
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; }
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); }
/********************************************************** * 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); }
/* * ======== 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; }
/* * 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"); }
/* 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); }
// 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)); }
/* Deallocates a block manually */ void heap::heap_free(heap_block *block) { block->status = B_FREE; add_to_free_list((free_heap_block *)block); }
/* * ======== 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; }
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); }
/* 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); }