Loading heap/_check.c +18 −5 Original line number Diff line number Diff line Loading @@ -102,9 +102,11 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records, int error; uint i,found,max_links,seek,links; uint rec_link; /* Only used with debugging */ uint hash_buckets_found; HASH_INFO *hash_info; error=0; hash_buckets_found= 0; for (i=found=max_links=seek=0 ; i < records ; i++) { hash_info=hp_find_hash(&keydef->block,i); Loading @@ -128,21 +130,32 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records, found++; } if (links > max_links) max_links=links; hash_buckets_found++; } } if (found != records) { DBUG_PRINT("error",("Found %ld of %ld records")); DBUG_PRINT("error",("Found %ld of %ld records", found, records)); error=1; } if (keydef->hash_buckets != hash_buckets_found) { DBUG_PRINT("error",("Found %ld buckets, stats shows %ld buckets", hash_buckets_found, keydef->hash_buckets)); error=1; } DBUG_PRINT("info", ("records: %ld seeks: %d max links: %d hitrate: %.2f", ("records: %ld seeks: %d max links: %d hitrate: %.2f " "buckets: %d", records,seek,max_links, (float) seek / (float) (records ? records : 1))); (float) seek / (float) (records ? records : 1), hash_buckets_found)); if (print_status) printf("Key: %d records: %ld seeks: %d max links: %d hitrate: %.2f\n", printf("Key: %d records: %ld seeks: %d max links: %d " "hitrate: %.2f buckets: %d\n", keynr, records, seek, max_links, (float) seek / (float) (records ? records : 1)); (float) seek / (float) (records ? records : 1), hash_buckets_found); return error; } Loading heap/hp_block.c +46 −5 Original line number Diff line number Diff line Loading @@ -18,12 +18,19 @@ #include "heapdef.h" /* Find record according to record-position */ /* Find record according to record-position. The record is located by factoring position number pos into (p_0, p_1, ...) such that pos = SUM_i(block->level_info[i].records_under_level * p_i) {p_0, p_1, ...} serve as indexes to descend the blocks tree. */ byte *hp_find_block(HP_BLOCK *block, ulong pos) { reg1 int i; reg3 HP_PTRS *ptr; reg3 HP_PTRS *ptr; /* block base ptr */ for (i=block->levels-1, ptr=block->root ; i > 0 ; i--) { Loading @@ -34,8 +41,18 @@ byte *hp_find_block(HP_BLOCK *block, ulong pos) } /* get one new block-of-records. Alloc ptr to block if neaded */ /* Interrupts are stopped to allow ha_panic in interrupts */ /* Get one new block-of-records. Alloc ptr to block if needed SYNOPSIS hp_get_new_block() block HP_BLOCK tree-like block alloc_length OUT Amount of memory allocated from the heap Interrupts are stopped to allow ha_panic in interrupts RETURN 0 OK 1 Out of memory */ int hp_get_new_block(HP_BLOCK *block, ulong *alloc_length) { Loading @@ -46,6 +63,18 @@ int hp_get_new_block(HP_BLOCK *block, ulong *alloc_length) if (block->level_info[i].free_ptrs_in_block) break; /* Allocate space for leaf block plus space for upper level blocks up to first level that has a free slot to put the pointer. In some cases we actually allocate more then we need: Consider e.g. a situation where we have one level 1 block and one level 0 block, the level 0 block is full and this function is called. We only need a leaf block in this case. Nevertheless, we will get here with i=1 and will also allocate sizeof(HP_PTRS) for non-leaf block and will never use this space. This doesn't add much overhead - with current values of sizeof(HP_PTRS) and my_default_record_cache_size we get about 1/128 unused memory. */ *alloc_length=sizeof(HP_PTRS)*i+block->records_in_block* block->recbuffer; if (!(root=(HP_PTRS*) my_malloc(*alloc_length,MYF(0)))) return 1; Loading @@ -60,21 +89,33 @@ int hp_get_new_block(HP_BLOCK *block, ulong *alloc_length) dont_break(); /* Dont allow SIGHUP or SIGINT */ if ((uint) i == block->levels) { /* Adding a new level on top of the existing ones. */ block->levels=i+1; /* Use first allocated HP_PTRS as a top-level block. Put the current block tree into the first slot of a new top-level block. */ block->level_info[i].free_ptrs_in_block=HP_PTRS_IN_NOD-1; ((HP_PTRS**) root)[0]= block->root; block->root=block->level_info[i].last_blocks= root++; } /* Occupy the free slot we've found at level i */ block->level_info[i].last_blocks-> blocks[HP_PTRS_IN_NOD - block->level_info[i].free_ptrs_in_block--]= (byte*) root; /* Add a block subtree with each node having one left-most child */ for (j=i-1 ; j >0 ; j--) { block->level_info[j].last_blocks= root++; block->level_info[j].last_blocks->blocks[0]=(byte*) root; block->level_info[j].free_ptrs_in_block=HP_PTRS_IN_NOD-1; } /* root now points to last (block->records_in_block* block->recbuffer) allocated bytes. Use it as a leaf block. */ block->level_info[0].last_blocks= root; allow_break(); /* Allow SIGHUP & SIGINT */ } Loading heap/hp_clear.c +1 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ void hp_clear_keys(HP_SHARE *info) VOID(hp_free_level(block,block->levels,block->root,(byte*) 0)); block->levels=0; block->last_allocated=0; keyinfo->hash_buckets= 0; } } info->index_length=0; Loading heap/hp_create.c +1 −0 Original line number Diff line number Diff line Loading @@ -128,6 +128,7 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, max_records); keyinfo->delete_key= hp_delete_key; keyinfo->write_key= hp_write_key; keyinfo->hash_buckets= 0; } } share->min_records= min_records; Loading heap/hp_delete.c +9 −3 Original line number Diff line number Diff line Loading @@ -97,8 +97,8 @@ int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, flag Is set if we want's to correct info->current_ptr RETURN 0 ok # error number 0 Ok other Error code */ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, Loading Loading @@ -151,6 +151,8 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, pos->ptr_to_rec=empty->ptr_to_rec; pos->next_key=empty->next_key; } else keyinfo->hash_buckets--; if (empty == lastpos) /* deleted last hash key */ DBUG_RETURN (0); Loading Loading @@ -187,7 +189,11 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, } pos3= pos; /* Link pos->next after lastpos */ } else pos3= 0; /* Different positions merge */ else { pos3= 0; /* Different positions merge */ keyinfo->hash_buckets--; } empty[0]=lastpos[0]; hp_movelink(pos3, empty, pos->next_key); Loading Loading
heap/_check.c +18 −5 Original line number Diff line number Diff line Loading @@ -102,9 +102,11 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records, int error; uint i,found,max_links,seek,links; uint rec_link; /* Only used with debugging */ uint hash_buckets_found; HASH_INFO *hash_info; error=0; hash_buckets_found= 0; for (i=found=max_links=seek=0 ; i < records ; i++) { hash_info=hp_find_hash(&keydef->block,i); Loading @@ -128,21 +130,32 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records, found++; } if (links > max_links) max_links=links; hash_buckets_found++; } } if (found != records) { DBUG_PRINT("error",("Found %ld of %ld records")); DBUG_PRINT("error",("Found %ld of %ld records", found, records)); error=1; } if (keydef->hash_buckets != hash_buckets_found) { DBUG_PRINT("error",("Found %ld buckets, stats shows %ld buckets", hash_buckets_found, keydef->hash_buckets)); error=1; } DBUG_PRINT("info", ("records: %ld seeks: %d max links: %d hitrate: %.2f", ("records: %ld seeks: %d max links: %d hitrate: %.2f " "buckets: %d", records,seek,max_links, (float) seek / (float) (records ? records : 1))); (float) seek / (float) (records ? records : 1), hash_buckets_found)); if (print_status) printf("Key: %d records: %ld seeks: %d max links: %d hitrate: %.2f\n", printf("Key: %d records: %ld seeks: %d max links: %d " "hitrate: %.2f buckets: %d\n", keynr, records, seek, max_links, (float) seek / (float) (records ? records : 1)); (float) seek / (float) (records ? records : 1), hash_buckets_found); return error; } Loading
heap/hp_block.c +46 −5 Original line number Diff line number Diff line Loading @@ -18,12 +18,19 @@ #include "heapdef.h" /* Find record according to record-position */ /* Find record according to record-position. The record is located by factoring position number pos into (p_0, p_1, ...) such that pos = SUM_i(block->level_info[i].records_under_level * p_i) {p_0, p_1, ...} serve as indexes to descend the blocks tree. */ byte *hp_find_block(HP_BLOCK *block, ulong pos) { reg1 int i; reg3 HP_PTRS *ptr; reg3 HP_PTRS *ptr; /* block base ptr */ for (i=block->levels-1, ptr=block->root ; i > 0 ; i--) { Loading @@ -34,8 +41,18 @@ byte *hp_find_block(HP_BLOCK *block, ulong pos) } /* get one new block-of-records. Alloc ptr to block if neaded */ /* Interrupts are stopped to allow ha_panic in interrupts */ /* Get one new block-of-records. Alloc ptr to block if needed SYNOPSIS hp_get_new_block() block HP_BLOCK tree-like block alloc_length OUT Amount of memory allocated from the heap Interrupts are stopped to allow ha_panic in interrupts RETURN 0 OK 1 Out of memory */ int hp_get_new_block(HP_BLOCK *block, ulong *alloc_length) { Loading @@ -46,6 +63,18 @@ int hp_get_new_block(HP_BLOCK *block, ulong *alloc_length) if (block->level_info[i].free_ptrs_in_block) break; /* Allocate space for leaf block plus space for upper level blocks up to first level that has a free slot to put the pointer. In some cases we actually allocate more then we need: Consider e.g. a situation where we have one level 1 block and one level 0 block, the level 0 block is full and this function is called. We only need a leaf block in this case. Nevertheless, we will get here with i=1 and will also allocate sizeof(HP_PTRS) for non-leaf block and will never use this space. This doesn't add much overhead - with current values of sizeof(HP_PTRS) and my_default_record_cache_size we get about 1/128 unused memory. */ *alloc_length=sizeof(HP_PTRS)*i+block->records_in_block* block->recbuffer; if (!(root=(HP_PTRS*) my_malloc(*alloc_length,MYF(0)))) return 1; Loading @@ -60,21 +89,33 @@ int hp_get_new_block(HP_BLOCK *block, ulong *alloc_length) dont_break(); /* Dont allow SIGHUP or SIGINT */ if ((uint) i == block->levels) { /* Adding a new level on top of the existing ones. */ block->levels=i+1; /* Use first allocated HP_PTRS as a top-level block. Put the current block tree into the first slot of a new top-level block. */ block->level_info[i].free_ptrs_in_block=HP_PTRS_IN_NOD-1; ((HP_PTRS**) root)[0]= block->root; block->root=block->level_info[i].last_blocks= root++; } /* Occupy the free slot we've found at level i */ block->level_info[i].last_blocks-> blocks[HP_PTRS_IN_NOD - block->level_info[i].free_ptrs_in_block--]= (byte*) root; /* Add a block subtree with each node having one left-most child */ for (j=i-1 ; j >0 ; j--) { block->level_info[j].last_blocks= root++; block->level_info[j].last_blocks->blocks[0]=(byte*) root; block->level_info[j].free_ptrs_in_block=HP_PTRS_IN_NOD-1; } /* root now points to last (block->records_in_block* block->recbuffer) allocated bytes. Use it as a leaf block. */ block->level_info[0].last_blocks= root; allow_break(); /* Allow SIGHUP & SIGINT */ } Loading
heap/hp_clear.c +1 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ void hp_clear_keys(HP_SHARE *info) VOID(hp_free_level(block,block->levels,block->root,(byte*) 0)); block->levels=0; block->last_allocated=0; keyinfo->hash_buckets= 0; } } info->index_length=0; Loading
heap/hp_create.c +1 −0 Original line number Diff line number Diff line Loading @@ -128,6 +128,7 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, max_records); keyinfo->delete_key= hp_delete_key; keyinfo->write_key= hp_write_key; keyinfo->hash_buckets= 0; } } share->min_records= min_records; Loading
heap/hp_delete.c +9 −3 Original line number Diff line number Diff line Loading @@ -97,8 +97,8 @@ int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, flag Is set if we want's to correct info->current_ptr RETURN 0 ok # error number 0 Ok other Error code */ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, Loading Loading @@ -151,6 +151,8 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, pos->ptr_to_rec=empty->ptr_to_rec; pos->next_key=empty->next_key; } else keyinfo->hash_buckets--; if (empty == lastpos) /* deleted last hash key */ DBUG_RETURN (0); Loading Loading @@ -187,7 +189,11 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, } pos3= pos; /* Link pos->next after lastpos */ } else pos3= 0; /* Different positions merge */ else { pos3= 0; /* Different positions merge */ keyinfo->hash_buckets--; } empty[0]=lastpos[0]; hp_movelink(pos3, empty, pos->next_key); Loading