void CHashMap::init_pool_data(int node_total, int bucket_size, int key_size) { hash_map_->node_total_ = node_total; hash_map_->bucket_size_ = bucket_size; hash_map_->key_size_ = key_size; hash_map_->used_node_num_ = 0; hash_map_->used_bucket_num_ = 0; hash_map_->add_head_ = INVALID_BC_MEM_HANDLER; hash_map_->add_tail_ = INVALID_BC_MEM_HANDLER; hash_map_->free_list_ = INVALID_BC_MEM_HANDLER; int i; for(i = 0; i < bucket_size; i++) { hash_map_->bucket[i] = INVALID_BC_MEM_HANDLER; } //将所有节点插入到空闲链表中 THashNode* hash_node; int offset; for(i = 0; i < node_total; i++) { offset = i * (sizeof(THashNode) + key_size); hash_node = (THashNode*)((char*)hash_node_ + offset); init_node(hash_node); free_list_insert(hash_node); } return; }
int CHashMap::delete_node(THashNode* node, char* data, int* data_len) { //旧节点存在 if(data != NULL && data_len != NULL) { //返回旧数据 if(allocator_.merge(node->chunk_head_, node->chunk_len_, data, data_len) != 0) { return -1; } } else if(data_len != NULL) { *data_len = node->chunk_len_; } delete_from_add_list(node); free_node(node); free_list_insert(node); return 0; }
THashNode* CHashMap::insert_node(void * key, void* new_data, int new_len) { THashNode* node = free_list_remove(); if (node == NULL) { return NULL; } int new_chunk_num = allocator_.get_chunk_num(new_len); BC_MEM_HANDLER head_hdr = allocator_.malloc(new_chunk_num); if(head_hdr == INVALID_BC_MEM_HANDLER) { free_list_insert(node); return NULL; } allocator_.split(head_hdr, new_data, new_len); use_node(node, key, new_len, head_hdr); //将该节点插入到附加链表头部 node->add_info_1_ = time(NULL); ++node->add_info_2_; insert_add_list_head(node); return node; }
void freeGroup(bdescr *p) { StgWord ln; // Todo: not true in multithreaded GC // ASSERT_SM_LOCK(); ASSERT(p->free != (P_)-1); p->free = (void *)-1; /* indicates that this block is free */ p->gen = NULL; p->gen_no = 0; /* fill the block group with garbage if sanity checking is on */ IF_DEBUG(sanity,memset(p->start, 0xaa, (W_)p->blocks * BLOCK_SIZE)); if (p->blocks == 0) barf("freeGroup: block size is zero"); if (p->blocks >= BLOCKS_PER_MBLOCK) { StgWord mblocks; mblocks = BLOCKS_TO_MBLOCKS(p->blocks); // If this is an mgroup, make sure it has the right number of blocks ASSERT(p->blocks == MBLOCK_GROUP_BLOCKS(mblocks)); n_alloc_blocks -= mblocks * BLOCKS_PER_MBLOCK; free_mega_group(p); return; } ASSERT(n_alloc_blocks >= p->blocks); n_alloc_blocks -= p->blocks; // coalesce forwards { bdescr *next; next = p + p->blocks; if (next <= LAST_BDESCR(MBLOCK_ROUND_DOWN(p)) && next->free == (P_)-1) { p->blocks += next->blocks; ln = log_2(next->blocks); dbl_link_remove(next, &free_list[ln]); if (p->blocks == BLOCKS_PER_MBLOCK) { free_mega_group(p); return; } setup_tail(p); } } // coalesce backwards if (p != FIRST_BDESCR(MBLOCK_ROUND_DOWN(p))) { bdescr *prev; prev = p - 1; if (prev->blocks == 0) prev = prev->link; // find the head if (prev->free == (P_)-1) { ln = log_2(prev->blocks); dbl_link_remove(prev, &free_list[ln]); prev->blocks += p->blocks; if (prev->blocks >= BLOCKS_PER_MBLOCK) { free_mega_group(prev); return; } p = prev; } } setup_tail(p); free_list_insert(p); IF_DEBUG(sanity, checkFreeListSanity()); }