Commit de1765fb authored by Michael Widenius's avatar Michael Widenius

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
parent da9aabbb
...@@ -110,8 +110,13 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records, ...@@ -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++) for (i=found=max_links=seek=0 ; i < records ; i++)
{ {
hash_info=hp_find_hash(&keydef->block,i); hash_info=hp_find_hash(&keydef->block,i);
if (hp_mask(hp_rec_hashnr(keydef, hash_info->ptr_to_rec), if (hash_info->hash_of_key != hp_rec_hashnr(keydef, hash_info->ptr_to_rec))
blength,records) == i) {
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++; found++;
seek++; seek++;
...@@ -119,9 +124,7 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records, ...@@ -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) while ((hash_info=hash_info->next_key) && found < records + 1)
{ {
seek+= ++links; seek+= ++links;
if ((rec_link = hp_mask(hp_rec_hashnr(keydef, hash_info->ptr_to_rec), if ((rec_link= hp_mask(hash_info->hash_of_key, blength, records)) != i)
blength, records))
!= i)
{ {
DBUG_PRINT("error", DBUG_PRINT("error",
("Record in wrong link: Link %lu Record: 0x%lx Record-link %lu", ("Record in wrong link: Link %lu Record: 0x%lx Record-link %lu",
...@@ -147,13 +150,13 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records, ...@@ -147,13 +150,13 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records,
error=1; error=1;
} }
DBUG_PRINT("info", DBUG_PRINT("info",
("records: %ld seeks: %lu max links: %lu hitrate: %.2f " ("key: %u records: %ld seeks: %lu max links: %lu "
"buckets: %lu", "hitrate: %.2f buckets: %lu",
records,seek,max_links, keynr, records,seek,max_links,
(float) seek / (float) (records ? records : 1), (float) seek / (float) (records ? records : 1),
hash_buckets_found)); hash_buckets_found));
if (print_status) if (print_status)
printf("Key: %d records: %ld seeks: %lu max links: %lu " printf("Key: %u records: %ld seeks: %lu max links: %lu "
"hitrate: %.2f buckets: %lu\n", "hitrate: %.2f buckets: %lu\n",
keynr, records, seek, max_links, keynr, records, seek, max_links,
(float) seek / (float) (records ? records : 1), (float) seek / (float) (records ? records : 1),
......
...@@ -50,6 +50,7 @@ typedef struct st_hp_hash_info ...@@ -50,6 +50,7 @@ typedef struct st_hp_hash_info
{ {
struct st_hp_hash_info *next_key; struct st_hp_hash_info *next_key;
uchar *ptr_to_rec; uchar *ptr_to_rec;
ulong hash_of_key;
} HASH_INFO; } HASH_INFO;
typedef struct { typedef struct {
......
...@@ -241,9 +241,17 @@ static void init_block(HP_BLOCK *block, uint reclength, ulong min_records, ...@@ -241,9 +241,17 @@ static void init_block(HP_BLOCK *block, uint reclength, ulong min_records,
max_records= 1000; /* As good as quess as anything */ max_records= 1000; /* As good as quess as anything */
recbuffer= (uint) (reclength + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1); recbuffer= (uint) (reclength + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1);
records_in_block= max_records / 10; 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; 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)) (my_default_record_cache_size-sizeof(HP_PTRS)*HP_MAX_LEVELS))
records_in_block= (my_default_record_cache_size - sizeof(HP_PTRS) * records_in_block= (my_default_record_cache_size - sizeof(HP_PTRS) *
HP_MAX_LEVELS) / recbuffer + 1; HP_MAX_LEVELS) / recbuffer + 1;
......
...@@ -149,8 +149,9 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, ...@@ -149,8 +149,9 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
else if (pos->next_key) else if (pos->next_key)
{ {
empty=pos->next_key; empty=pos->next_key;
pos->ptr_to_rec=empty->ptr_to_rec; pos->ptr_to_rec= empty->ptr_to_rec;
pos->next_key=empty->next_key; pos->next_key= empty->next_key;
pos->hash_of_key= empty->hash_of_key;
} }
else else
keyinfo->hash_buckets--; keyinfo->hash_buckets--;
...@@ -159,7 +160,7 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, ...@@ -159,7 +160,7 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
DBUG_RETURN (0); DBUG_RETURN (0);
/* Move the last key (lastpos) */ /* 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 is where lastpos should be */
pos=hp_find_hash(&keyinfo->block, hp_mask(lastpos_hashnr, share->blength, pos=hp_find_hash(&keyinfo->block, hp_mask(lastpos_hashnr, share->blength,
share->records)); share->records));
...@@ -168,7 +169,7 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, ...@@ -168,7 +169,7 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
empty[0]=lastpos[0]; empty[0]=lastpos[0];
DBUG_RETURN(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 is where the pos should be */
pos3= hp_find_hash(&keyinfo->block, pos3= hp_find_hash(&keyinfo->block,
hp_mask(pos_hashnr, share->blength, share->records)); hp_mask(pos_hashnr, share->blength, share->records));
......
...@@ -149,7 +149,7 @@ uchar *hp_search(HP_INFO *info, HP_KEYDEF *keyinfo, const uchar *key, ...@@ -149,7 +149,7 @@ uchar *hp_search(HP_INFO *info, HP_KEYDEF *keyinfo, const uchar *key,
{ {
flag=0; /* Reset flag */ flag=0; /* Reset flag */
if (hp_find_hash(&keyinfo->block, if (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)) != pos) share->blength, share->records)) != pos)
break; /* Wrong link */ break; /* Wrong link */
} }
...@@ -300,7 +300,9 @@ ulong hp_hashnr(register HP_KEYDEF *keydef, register const uchar *key) ...@@ -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)); DBUG_PRINT("exit", ("hash: 0x%lx", nr));
#endif
return((ulong) nr); return((ulong) nr);
} }
...@@ -367,7 +369,9 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const uchar *rec) ...@@ -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)); DBUG_PRINT("exit", ("hash: 0x%lx", nr));
#endif
return(nr); return(nr);
} }
...@@ -438,7 +442,9 @@ ulong hp_hashnr(register HP_KEYDEF *keydef, register const uchar *key) ...@@ -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)); DBUG_PRINT("exit", ("hash: 0x%lx", nr));
#endif
return(nr); return(nr);
} }
...@@ -491,7 +497,9 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const uchar *rec) ...@@ -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)); DBUG_PRINT("exit", ("hash: 0x%lx", nr));
#endif
return(nr); return(nr);
} }
......
...@@ -72,7 +72,7 @@ int main(int argc, char *argv[]) ...@@ -72,7 +72,7 @@ int main(int argc, char *argv[])
get_options(argc,argv); get_options(argc,argv);
bzero(&hp_create_info, sizeof(hp_create_info)); 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; write_count=update=opt_delete=0;
key_check=0; key_check=0;
...@@ -642,7 +642,7 @@ static int get_options(int argc,char *argv[]) ...@@ -642,7 +642,7 @@ static int get_options(int argc,char *argv[])
case 'V': case 'V':
case 'I': case 'I':
case '?': 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"); puts("TCX Datakonsult AB, by Monty, for your professional use\n");
printf("Usage: %s [-?ABIKLsWv] [-m#] [-t#]\n",progname); printf("Usage: %s [-?ABIKLsWv] [-m#] [-t#]\n",progname);
exit(0); exit(0);
......
...@@ -154,6 +154,13 @@ static uchar *next_free_record_pos(HP_SHARE *info) ...@@ -154,6 +154,13 @@ static uchar *next_free_record_pos(HP_SHARE *info)
if ((info->records > info->max_records && info->max_records) || if ((info->records > info->max_records && info->max_records) ||
(info->data_length + info->index_length >= info->max_table_size)) (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; my_errno=HA_ERR_RECORD_FILE_FULL;
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
...@@ -200,6 +207,7 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, ...@@ -200,6 +207,7 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
HP_SHARE *share = info->s; HP_SHARE *share = info->s;
int flag; int flag;
ulong halfbuff,hashnr,first_index; 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); uchar *UNINIT_VAR(ptr_to_rec),*UNINIT_VAR(ptr_to_rec2);
HASH_INFO *empty,*UNINIT_VAR(gpos),*UNINIT_VAR(gpos2),*pos; HASH_INFO *empty,*UNINIT_VAR(gpos),*UNINIT_VAR(gpos2),*pos;
DBUG_ENTER("hp_write_key"); DBUG_ENTER("hp_write_key");
...@@ -230,7 +238,7 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, ...@@ -230,7 +238,7 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
{ {
do do
{ {
hashnr = hp_rec_hashnr(keyinfo, pos->ptr_to_rec); hashnr = pos->hash_of_key;
if (flag == 0) if (flag == 0)
{ {
/* /*
...@@ -262,7 +270,6 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, ...@@ -262,7 +270,6 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
flag=LOWFIND | HIGHFIND; flag=LOWFIND | HIGHFIND;
/* key shall be moved to the current empty position */ /* key shall be moved to the current empty position */
gpos=empty; gpos=empty;
ptr_to_rec=pos->ptr_to_rec;
empty=pos; /* This place is now free */ empty=pos; /* This place is now free */
} }
else else
...@@ -273,7 +280,6 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, ...@@ -273,7 +280,6 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
*/ */
flag=LOWFIND | LOWUSED; flag=LOWFIND | LOWUSED;
gpos=pos; gpos=pos;
ptr_to_rec=pos->ptr_to_rec;
} }
} }
else else
...@@ -282,13 +288,15 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, ...@@ -282,13 +288,15 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
if (!(flag & LOWUSED)) if (!(flag & LOWUSED))
{ {
/* Change link of previous lower-list key */ /* Change link of previous lower-list key */
gpos->ptr_to_rec=ptr_to_rec; gpos->ptr_to_rec= ptr_to_rec;
gpos->next_key=pos; gpos->next_key= pos;
gpos->hash_of_key= hash_of_key;
flag= (flag & HIGHFIND) | (LOWFIND | LOWUSED); flag= (flag & HIGHFIND) | (LOWFIND | LOWUSED);
} }
gpos=pos; gpos=pos;
ptr_to_rec=pos->ptr_to_rec;
} }
ptr_to_rec= pos->ptr_to_rec;
hash_of_key= pos->hash_of_key;
} }
else else
{ {
...@@ -299,20 +307,21 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, ...@@ -299,20 +307,21 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
/* key shall be moved to the last (empty) position */ /* key shall be moved to the last (empty) position */
gpos2= empty; gpos2= empty;
empty= pos; empty= pos;
ptr_to_rec2=pos->ptr_to_rec;
} }
else else
{ {
if (!(flag & HIGHUSED)) if (!(flag & HIGHUSED))
{ {
/* Change link of previous upper-list key and save */ /* Change link of previous upper-list key and save */
gpos2->ptr_to_rec=ptr_to_rec2; gpos2->ptr_to_rec= ptr_to_rec2;
gpos2->next_key=pos; gpos2->next_key= pos;
gpos2->hash_of_key= hash_of_key2;
flag= (flag & LOWFIND) | (HIGHFIND | HIGHUSED); flag= (flag & LOWFIND) | (HIGHFIND | HIGHUSED);
} }
gpos2=pos; 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)); while ((pos=pos->next_key));
...@@ -328,23 +337,27 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, ...@@ -328,23 +337,27 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
if ((flag & (LOWFIND | LOWUSED)) == LOWFIND) if ((flag & (LOWFIND | LOWUSED)) == LOWFIND)
{ {
gpos->ptr_to_rec=ptr_to_rec; gpos->ptr_to_rec= ptr_to_rec;
gpos->next_key=0; gpos->hash_of_key= hash_of_key;
gpos->next_key= 0;
} }
if ((flag & (HIGHFIND | HIGHUSED)) == HIGHFIND) if ((flag & (HIGHFIND | HIGHUSED)) == HIGHFIND)
{ {
gpos2->ptr_to_rec=ptr_to_rec2; gpos2->ptr_to_rec= ptr_to_rec2;
gpos2->next_key=0; gpos2->hash_of_key= hash_of_key2;
gpos2->next_key= 0;
} }
} }
/* Check if we are at the empty position */ /* Check if we are at the empty position */
pos=hp_find_hash(&keyinfo->block, hp_mask(hp_rec_hashnr(keyinfo, record), hash_of_key= hp_rec_hashnr(keyinfo, record);
share->blength, share->records + 1)); pos=hp_find_hash(&keyinfo->block,
hp_mask(hash_of_key, share->blength, share->records + 1));
if (pos == empty) if (pos == empty)
{ {
pos->ptr_to_rec=recpos; pos->ptr_to_rec= recpos;
pos->next_key=0; pos->hash_of_key= hash_of_key;
pos->next_key= 0;
keyinfo->hash_buckets++; keyinfo->hash_buckets++;
} }
else else
...@@ -352,18 +365,17 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, ...@@ -352,18 +365,17 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
/* Check if more records in same hash-nr family */ /* Check if more records in same hash-nr family */
empty[0]=pos[0]; empty[0]=pos[0];
gpos=hp_find_hash(&keyinfo->block, 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)); share->blength, share->records + 1));
pos->ptr_to_rec= recpos;
pos->hash_of_key= hash_of_key;
if (pos == gpos) if (pos == gpos)
{
pos->ptr_to_rec=recpos;
pos->next_key=empty; pos->next_key=empty;
}
else else
{ {
keyinfo->hash_buckets++; keyinfo->hash_buckets++;
pos->ptr_to_rec=recpos; pos->next_key= 0;
pos->next_key=0;
hp_movelink(pos, gpos, empty); hp_movelink(pos, gpos, empty);
} }
......
...@@ -1337,11 +1337,12 @@ int _ma_update_state_lsns(MARIA_SHARE *share, LSN lsn, TrID create_trid, ...@@ -1337,11 +1337,12 @@ int _ma_update_state_lsns(MARIA_SHARE *share, LSN lsn, TrID create_trid,
my_bool do_sync, my_bool update_create_rename_lsn) my_bool do_sync, my_bool update_create_rename_lsn)
{ {
int res; int res;
DBUG_ENTER("_ma_update_state_lsns");
pthread_mutex_lock(&share->intern_lock); pthread_mutex_lock(&share->intern_lock);
res= _ma_update_state_lsns_sub(share, lsn, create_trid, do_sync, res= _ma_update_state_lsns_sub(share, lsn, create_trid, do_sync,
update_create_rename_lsn); update_create_rename_lsn);
pthread_mutex_unlock(&share->intern_lock); pthread_mutex_unlock(&share->intern_lock);
return res; DBUG_RETURN(res);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment