diff options
author | Sergei Golubchik <sergii@pisem.net> | 2012-10-19 20:38:59 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2012-10-19 20:38:59 +0200 |
commit | e1f681c99b3e5462c033aaafa94ac295e626cde2 (patch) | |
tree | 2da5eff1a0d03831c2d85b32a7bc3df6ec37b522 /storage/heap | |
parent | 52c84d144d3b07966d9b3bab8694eb012eef69ce (diff) | |
parent | 807fef40fffbbb8e92564a52b902b504ba8cfcdc (diff) | |
download | mariadb-git-e1f681c99b3e5462c033aaafa94ac295e626cde2.tar.gz |
10.0-base -> 10.0-monty
Diffstat (limited to 'storage/heap')
-rw-r--r-- | storage/heap/hp_block.c | 23 | ||||
-rw-r--r-- | storage/heap/hp_create.c | 23 | ||||
-rw-r--r-- | storage/heap/hp_hash.c | 9 |
3 files changed, 38 insertions, 17 deletions
diff --git a/storage/heap/hp_block.c b/storage/heap/hp_block.c index 90efeeb7924..01978e2b4e8 100644 --- a/storage/heap/hp_block.c +++ b/storage/heap/hp_block.c @@ -64,18 +64,19 @@ int hp_get_new_block(HP_BLOCK *block, size_t *alloc_length) 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. + Allocate space for leaf block (data) plus space for upper level blocks + up to first level that has a free slot to put the pointer. + If this is a new level, we have to allocate pointers to all future + lower levels. + + For example, for level 0, we allocate data for X rows. + When level 0 is full, we allocate data for HPTRS_IN_NODE + X rows. + Next time we allocate data for X rows. + When level 1 is full, we allocate data for HPTRS_IN_NODE at level 2 and 1 + + X rows at level 0. */ - *alloc_length=sizeof(HP_PTRS)*i+block->records_in_block* block->recbuffer; + *alloc_length= (sizeof(HP_PTRS)* ((i == block->levels) ? i : i - 1) + + block->records_in_block* block->recbuffer); if (!(root=(HP_PTRS*) my_malloc(*alloc_length,MYF(MY_WME)))) return 1; diff --git a/storage/heap/hp_create.c b/storage/heap/hp_create.c index 22ab9b54a85..d170d1abc65 100644 --- a/storage/heap/hp_create.c +++ b/storage/heap/hp_create.c @@ -245,21 +245,32 @@ static void init_block(HP_BLOCK *block, uint reclength, ulong min_records, { uint i,recbuffer,records_in_block; - max_records= max(min_records,max_records); + /* + If not min_records and max_records are given, optimize for 1000 rows + */ + if (!min_records) + min_records= min(1000, max_records); if (!max_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; + max_records= max(min_records, 1000); /* 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); + records_in_block= max(1000, min_records); + records_in_block= min(records_in_block, max_records); + /* If big max_records is given, allocate bigger blocks */ + records_in_block= max(records_in_block, max_records / 10); + /* We don't want too few blocks per row either */ if (records_in_block < 10) records_in_block= 10; - /* The + 1 is there to ensure that we get at least 1 row per level */ + recbuffer= (uint) (reclength + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1); + /* + Don't allocate more than my_default_record_cache_size per level. + The + 1 is there to ensure that we get at least 1 row per level (for + the exceptional case of very long rows) + */ 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) * diff --git a/storage/heap/hp_hash.c b/storage/heap/hp_hash.c index d44726ba762..2abed55459c 100644 --- a/storage/heap/hp_hash.c +++ b/storage/heap/hp_hash.c @@ -348,6 +348,8 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const uchar *rec) seg->length/cs->mbmaxlen); set_if_smaller(length, char_length); } + else + set_if_smaller(length, seg->length); cs->coll->hash_sort(cs, pos+pack_length, length, &nr, &nr2); } else @@ -593,6 +595,11 @@ int hp_rec_key_cmp(HP_KEYDEF *keydef, const uchar *rec1, const uchar *rec2, char_length2= my_charpos(cs, pos2, pos2 + char_length2, char_length); set_if_smaller(char_length2, safe_length2); } + else + { + set_if_smaller(char_length1, seg->length); + set_if_smaller(char_length2, seg->length); + } if (cs->coll->strnncollsp(seg->charset, pos1, char_length1, @@ -689,6 +696,8 @@ int hp_key_cmp(HP_KEYDEF *keydef, const uchar *rec, const uchar *key) char_length2= my_charpos(cs, pos, pos + char_length_rec, char_length2); set_if_smaller(char_length_rec, char_length2); } + else + set_if_smaller(char_length_rec, seg->length); if (cs->coll->strnncollsp(seg->charset, (uchar*) pos, char_length_rec, |