diff options
author | Michael Widenius <monty@askmonty.org> | 2012-03-23 18:11:29 +0200 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2012-03-23 18:11:29 +0200 |
commit | de1765fb64dda7c610217c27a6012955f01d88e4 (patch) | |
tree | 292516abaed11a44af3ddb838f7f7bfa70fe2478 /storage/heap | |
parent | da9aabbbb653274de997763b7f833ac6822f81bf (diff) | |
download | mariadb-git-de1765fb64dda7c610217c27a6012955f01d88e4.tar.gz |
Speedups:
- Optimize away calls to hp_rec_hashnr() by cashing hash
- Try to get more rows / block (to minimize overhead of HP_PTRS) in HEAP tables.
storage/heap/_check.c:
Optimize away calls to hp_rec_hashnr() by cashing hash.
Print cleanups
storage/heap/heapdef.h:
Added place to hold calculated hash value for row
storage/heap/hp_create.c:
Try to get more rows / block (to minimize overhead of HP_PTRS)
storage/heap/hp_delete.c:
Optimize away calls to hp_rec_hashnr() by cashing hash.
storage/heap/hp_hash.c:
Optimize away calls to hp_rec_hashnr() by cashing hash.
Remove some not needed DBUG_PRINT
storage/heap/hp_test2.c:
Increased max table size as now heap tables takes a bit more space (a few %)
storage/heap/hp_write.c:
Optimize away calls to hp_rec_hashnr() by cashing hash.
Remove duplicated code
More DBUG_PRINT
storage/maria/ma_create.c:
More DBUG_PRINT
Diffstat (limited to 'storage/heap')
-rw-r--r-- | storage/heap/_check.c | 23 | ||||
-rw-r--r-- | storage/heap/heapdef.h | 1 | ||||
-rw-r--r-- | storage/heap/hp_create.c | 14 | ||||
-rw-r--r-- | storage/heap/hp_delete.c | 9 | ||||
-rw-r--r-- | storage/heap/hp_hash.c | 12 | ||||
-rw-r--r-- | storage/heap/hp_test2.c | 4 | ||||
-rw-r--r-- | storage/heap/hp_write.c | 60 |
7 files changed, 78 insertions, 45 deletions
diff --git a/storage/heap/_check.c b/storage/heap/_check.c index 08b6da62ae1..6cd01012d84 100644 --- a/storage/heap/_check.c +++ b/storage/heap/_check.c @@ -110,8 +110,13 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records, for (i=found=max_links=seek=0 ; i < records ; i++) { hash_info=hp_find_hash(&keydef->block,i); - if (hp_mask(hp_rec_hashnr(keydef, hash_info->ptr_to_rec), - blength,records) == i) + if (hash_info->hash_of_key != hp_rec_hashnr(keydef, hash_info->ptr_to_rec)) + { + DBUG_PRINT("error", + ("Found row with wrong hash_of_key at position %lu", i)); + error= 1; + } + if (hp_mask(hash_info->hash_of_key, blength, records) == i) { found++; seek++; @@ -119,9 +124,7 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records, while ((hash_info=hash_info->next_key) && found < records + 1) { seek+= ++links; - if ((rec_link = hp_mask(hp_rec_hashnr(keydef, hash_info->ptr_to_rec), - blength, records)) - != i) + if ((rec_link= hp_mask(hash_info->hash_of_key, blength, records)) != i) { DBUG_PRINT("error", ("Record in wrong link: Link %lu Record: 0x%lx Record-link %lu", @@ -147,14 +150,14 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records, error=1; } DBUG_PRINT("info", - ("records: %ld seeks: %lu max links: %lu hitrate: %.2f " - "buckets: %lu", - records,seek,max_links, + ("key: %u records: %ld seeks: %lu max links: %lu " + "hitrate: %.2f buckets: %lu", + keynr, records,seek,max_links, (float) seek / (float) (records ? records : 1), hash_buckets_found)); if (print_status) - printf("Key: %d records: %ld seeks: %lu max links: %lu " - "hitrate: %.2f buckets: %lu\n", + printf("Key: %u records: %ld seeks: %lu max links: %lu " + "hitrate: %.2f buckets: %lu\n", keynr, records, seek, max_links, (float) seek / (float) (records ? records : 1), hash_buckets_found); diff --git a/storage/heap/heapdef.h b/storage/heap/heapdef.h index 3fc94062303..b9a3eab3432 100644 --- a/storage/heap/heapdef.h +++ b/storage/heap/heapdef.h @@ -50,6 +50,7 @@ typedef struct st_hp_hash_info { struct st_hp_hash_info *next_key; uchar *ptr_to_rec; + ulong hash_of_key; } HASH_INFO; typedef struct { diff --git a/storage/heap/hp_create.c b/storage/heap/hp_create.c index e87f09feb18..baa2f06cf4b 100644 --- a/storage/heap/hp_create.c +++ b/storage/heap/hp_create.c @@ -241,12 +241,20 @@ static void init_block(HP_BLOCK *block, uint reclength, ulong min_records, max_records= 1000; /* As good as quess as anything */ recbuffer= (uint) (reclength + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1); records_in_block= max_records / 10; - if (records_in_block < 10 && max_records) + + /* + We don't want too few records_in_block as otherwise the overhead of + of the HP_PTRS block will be too notable + */ + records_in_block= min(1000, max_records); + if (records_in_block < 10) records_in_block= 10; - if (!records_in_block || records_in_block*recbuffer > + + /* The + 1 is there to ensure that we get at least 1 row per level */ + if (records_in_block*recbuffer > (my_default_record_cache_size-sizeof(HP_PTRS)*HP_MAX_LEVELS)) records_in_block= (my_default_record_cache_size - sizeof(HP_PTRS) * - HP_MAX_LEVELS) / recbuffer + 1; + HP_MAX_LEVELS) / recbuffer + 1; block->records_in_block= records_in_block; block->recbuffer= recbuffer; block->last_allocated= 0L; diff --git a/storage/heap/hp_delete.c b/storage/heap/hp_delete.c index db2c0df6128..d00ac94a918 100644 --- a/storage/heap/hp_delete.c +++ b/storage/heap/hp_delete.c @@ -149,8 +149,9 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, else if (pos->next_key) { empty=pos->next_key; - pos->ptr_to_rec=empty->ptr_to_rec; - pos->next_key=empty->next_key; + pos->ptr_to_rec= empty->ptr_to_rec; + pos->next_key= empty->next_key; + pos->hash_of_key= empty->hash_of_key; } else keyinfo->hash_buckets--; @@ -159,7 +160,7 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, DBUG_RETURN (0); /* Move the last key (lastpos) */ - lastpos_hashnr = hp_rec_hashnr(keyinfo, lastpos->ptr_to_rec); + lastpos_hashnr= lastpos->hash_of_key; /* pos is where lastpos should be */ pos=hp_find_hash(&keyinfo->block, hp_mask(lastpos_hashnr, share->blength, share->records)); @@ -168,7 +169,7 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, empty[0]=lastpos[0]; DBUG_RETURN(0); } - pos_hashnr = hp_rec_hashnr(keyinfo, pos->ptr_to_rec); + pos_hashnr= pos->hash_of_key; /* pos3 is where the pos should be */ pos3= hp_find_hash(&keyinfo->block, hp_mask(pos_hashnr, share->blength, share->records)); diff --git a/storage/heap/hp_hash.c b/storage/heap/hp_hash.c index 208453309aa..5c96bb771e8 100644 --- a/storage/heap/hp_hash.c +++ b/storage/heap/hp_hash.c @@ -149,8 +149,8 @@ uchar *hp_search(HP_INFO *info, HP_KEYDEF *keyinfo, const uchar *key, { flag=0; /* Reset flag */ if (hp_find_hash(&keyinfo->block, - hp_mask(hp_rec_hashnr(keyinfo, pos->ptr_to_rec), - share->blength, share->records)) != pos) + hp_mask(pos->hash_of_key, + share->blength, share->records)) != pos) break; /* Wrong link */ } } @@ -300,7 +300,9 @@ ulong hp_hashnr(register HP_KEYDEF *keydef, register const uchar *key) } } } +#ifdef ONLY_FOR_HASH_DEBUGGING DBUG_PRINT("exit", ("hash: 0x%lx", nr)); +#endif return((ulong) nr); } @@ -367,7 +369,9 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const uchar *rec) } } } +#ifdef ONLY_FOR_HASH_DEBUGGING DBUG_PRINT("exit", ("hash: 0x%lx", nr)); +#endif return(nr); } @@ -438,7 +442,9 @@ ulong hp_hashnr(register HP_KEYDEF *keydef, register const uchar *key) } } } +#ifdef ONLY_FOR_HASH_DEBUGGING DBUG_PRINT("exit", ("hash: 0x%lx", nr)); +#endif return(nr); } @@ -491,7 +497,9 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const uchar *rec) } } } +#ifdef ONLY_FOR_HASH_DEBUGGING DBUG_PRINT("exit", ("hash: 0x%lx", nr)); +#endif return(nr); } diff --git a/storage/heap/hp_test2.c b/storage/heap/hp_test2.c index fe6ef254218..a534a5cf904 100644 --- a/storage/heap/hp_test2.c +++ b/storage/heap/hp_test2.c @@ -72,7 +72,7 @@ int main(int argc, char *argv[]) get_options(argc,argv); bzero(&hp_create_info, sizeof(hp_create_info)); - hp_create_info.max_table_size= 1024L*1024L; + hp_create_info.max_table_size= 2*1024L*1024L; write_count=update=opt_delete=0; key_check=0; @@ -642,7 +642,7 @@ static int get_options(int argc,char *argv[]) case 'V': case 'I': case '?': - printf("%s Ver 1.1 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE); + printf("%s Ver 1.2 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE); puts("TCX Datakonsult AB, by Monty, for your professional use\n"); printf("Usage: %s [-?ABIKLsWv] [-m#] [-t#]\n",progname); exit(0); diff --git a/storage/heap/hp_write.c b/storage/heap/hp_write.c index 300813218ae..42d924d8f2d 100644 --- a/storage/heap/hp_write.c +++ b/storage/heap/hp_write.c @@ -154,6 +154,13 @@ static uchar *next_free_record_pos(HP_SHARE *info) if ((info->records > info->max_records && info->max_records) || (info->data_length + info->index_length >= info->max_table_size)) { + DBUG_PRINT("error", + ("record file full. records: %u max_records: %lu " + "data_length: %llu index_length: %llu " + "max_table_size: %llu", + info->records, info->max_records, + info->data_length, info->index_length, + info->max_table_size)); my_errno=HA_ERR_RECORD_FILE_FULL; DBUG_RETURN(NULL); } @@ -200,6 +207,7 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, HP_SHARE *share = info->s; int flag; ulong halfbuff,hashnr,first_index; + ulong UNINIT_VAR(hash_of_key), UNINIT_VAR(hash_of_key2); uchar *UNINIT_VAR(ptr_to_rec),*UNINIT_VAR(ptr_to_rec2); HASH_INFO *empty,*UNINIT_VAR(gpos),*UNINIT_VAR(gpos2),*pos; DBUG_ENTER("hp_write_key"); @@ -230,7 +238,7 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, { do { - hashnr = hp_rec_hashnr(keyinfo, pos->ptr_to_rec); + hashnr = pos->hash_of_key; if (flag == 0) { /* @@ -262,7 +270,6 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, flag=LOWFIND | HIGHFIND; /* key shall be moved to the current empty position */ gpos=empty; - ptr_to_rec=pos->ptr_to_rec; empty=pos; /* This place is now free */ } else @@ -273,7 +280,6 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, */ flag=LOWFIND | LOWUSED; gpos=pos; - ptr_to_rec=pos->ptr_to_rec; } } else @@ -282,13 +288,15 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, if (!(flag & LOWUSED)) { /* Change link of previous lower-list key */ - gpos->ptr_to_rec=ptr_to_rec; - gpos->next_key=pos; + gpos->ptr_to_rec= ptr_to_rec; + gpos->next_key= pos; + gpos->hash_of_key= hash_of_key; flag= (flag & HIGHFIND) | (LOWFIND | LOWUSED); } gpos=pos; - ptr_to_rec=pos->ptr_to_rec; } + ptr_to_rec= pos->ptr_to_rec; + hash_of_key= pos->hash_of_key; } else { @@ -299,20 +307,21 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, /* key shall be moved to the last (empty) position */ gpos2= empty; empty= pos; - ptr_to_rec2=pos->ptr_to_rec; } else { if (!(flag & HIGHUSED)) { /* Change link of previous upper-list key and save */ - gpos2->ptr_to_rec=ptr_to_rec2; - gpos2->next_key=pos; + gpos2->ptr_to_rec= ptr_to_rec2; + gpos2->next_key= pos; + gpos2->hash_of_key= hash_of_key2; flag= (flag & LOWFIND) | (HIGHFIND | HIGHUSED); } gpos2=pos; - ptr_to_rec2=pos->ptr_to_rec; } + ptr_to_rec2= pos->ptr_to_rec; + hash_of_key2= pos->hash_of_key; } } while ((pos=pos->next_key)); @@ -328,23 +337,27 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, if ((flag & (LOWFIND | LOWUSED)) == LOWFIND) { - gpos->ptr_to_rec=ptr_to_rec; - gpos->next_key=0; + gpos->ptr_to_rec= ptr_to_rec; + gpos->hash_of_key= hash_of_key; + gpos->next_key= 0; } if ((flag & (HIGHFIND | HIGHUSED)) == HIGHFIND) { - gpos2->ptr_to_rec=ptr_to_rec2; - gpos2->next_key=0; + gpos2->ptr_to_rec= ptr_to_rec2; + gpos2->hash_of_key= hash_of_key2; + gpos2->next_key= 0; } } /* Check if we are at the empty position */ - pos=hp_find_hash(&keyinfo->block, hp_mask(hp_rec_hashnr(keyinfo, record), - share->blength, share->records + 1)); + hash_of_key= hp_rec_hashnr(keyinfo, record); + pos=hp_find_hash(&keyinfo->block, + hp_mask(hash_of_key, share->blength, share->records + 1)); if (pos == empty) { - pos->ptr_to_rec=recpos; - pos->next_key=0; + pos->ptr_to_rec= recpos; + pos->hash_of_key= hash_of_key; + pos->next_key= 0; keyinfo->hash_buckets++; } else @@ -352,18 +365,17 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, /* Check if more records in same hash-nr family */ empty[0]=pos[0]; gpos=hp_find_hash(&keyinfo->block, - hp_mask(hp_rec_hashnr(keyinfo, pos->ptr_to_rec), + hp_mask(pos->hash_of_key, share->blength, share->records + 1)); + + pos->ptr_to_rec= recpos; + pos->hash_of_key= hash_of_key; if (pos == gpos) - { - pos->ptr_to_rec=recpos; pos->next_key=empty; - } else { keyinfo->hash_buckets++; - pos->ptr_to_rec=recpos; - pos->next_key=0; + pos->next_key= 0; hp_movelink(pos, gpos, empty); } |