summaryrefslogtreecommitdiff
path: root/storage/heap
diff options
context:
space:
mode:
authorMichael Widenius <monty@askmonty.org>2012-03-23 18:11:29 +0200
committerMichael Widenius <monty@askmonty.org>2012-03-23 18:11:29 +0200
commitde1765fb64dda7c610217c27a6012955f01d88e4 (patch)
tree292516abaed11a44af3ddb838f7f7bfa70fe2478 /storage/heap
parentda9aabbbb653274de997763b7f833ac6822f81bf (diff)
downloadmariadb-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.c23
-rw-r--r--storage/heap/heapdef.h1
-rw-r--r--storage/heap/hp_create.c14
-rw-r--r--storage/heap/hp_delete.c9
-rw-r--r--storage/heap/hp_hash.c12
-rw-r--r--storage/heap/hp_test2.c4
-rw-r--r--storage/heap/hp_write.c60
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);
}