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,
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);
......
......@@ -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 {
......
......@@ -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;
......
......@@ -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));
......
......@@ -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);
}
......
......@@ -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);
......
......@@ -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);
}
......
......@@ -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)
{
int res;
DBUG_ENTER("_ma_update_state_lsns");
pthread_mutex_lock(&share->intern_lock);
res= _ma_update_state_lsns_sub(share, lsn, create_trid, do_sync,
update_create_rename_lsn);
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