#include <my_base.h>#include "heap.h"#include "my_tree.h"Include dependency graph for heapdef.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.
Definition at line 44 of file heapdef.h.
Referenced by check_one_key(), hp_delete_key(), hp_find_free_hash(), hp_search(), and hp_write_key().
| #define test_active | ( | info | ) |
Value:
if (!(info->update & HA_STATE_AKTIV))\ { my_errno=HA_ERR_NO_ACTIVE_RECORD; DBUG_RETURN(-1); }
Definition at line 41 of file heapdef.h.
Referenced by heap_delete(), heap_rsame(), and heap_update().
| typedef struct st_hp_hash_info HASH_INFO |
| void hp_clear | ( | HP_SHARE * | info | ) |
Definition at line 30 of file hp_clear.c.
References st_heap_share::blength, st_heap_share::block, st_heap_share::changed, st_heap_share::data_length, DBUG_ENTER, DBUG_VOID_RETURN, st_heap_share::del_link, st_heap_share::deleted, hp_clear_keys(), hp_free_level(), st_heap_block::levels, st_heap_share::records, st_heap_block::root, and VOID.
Referenced by heap_clear(), heap_clear_keys(), and hp_free().
00031 { 00032 DBUG_ENTER("hp_clear"); 00033 00034 if (info->block.levels) 00035 VOID(hp_free_level(&info->block,info->block.levels,info->block.root, 00036 (byte*) 0)); 00037 info->block.levels=0; 00038 hp_clear_keys(info); 00039 info->records=info->deleted=info->data_length=0; 00040 info->blength=1; 00041 info->changed=0; 00042 info->del_link=0; 00043 DBUG_VOID_RETURN; 00044 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void hp_clear_keys | ( | HP_SHARE * | info | ) |
Definition at line 81 of file hp_clear.c.
References yaSSL::block, DBUG_ENTER, delete_tree(), HA_KEY_ALG_BTREE, hp_free_level(), key, st_heap_share::keydef, keyinfo, st_heap_share::keys, and VOID.
Referenced by heap_disable_indexes(), and hp_clear().
00082 { 00083 uint key; 00084 DBUG_ENTER("hp_clear_keys"); 00085 00086 for (key=0 ; key < info->keys ; key++) 00087 { 00088 HP_KEYDEF *keyinfo = info->keydef + key; 00089 if (keyinfo->algorithm == HA_KEY_ALG_BTREE) 00090 { 00091 delete_tree(&keyinfo->rb_tree); 00092 } 00093 else 00094 { 00095 HP_BLOCK *block= &keyinfo->block; 00096 if (block->levels) 00097 VOID(hp_free_level(block,block->levels,block->root,(byte*) 0)); 00098 block->levels=0; 00099 block->last_allocated=0; 00100 keyinfo->hash_buckets= 0; 00101 } 00102 } 00103 info->index_length=0; 00104 DBUG_VOID_RETURN; 00105 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int hp_close | ( | register HP_INFO * | info | ) |
Definition at line 35 of file hp_close.c.
References DBUG_ENTER, DBUG_RETURN, error, HA_ERR_CRASHED, heap_check_heap(), heap_open_list, hp_free(), list_delete(), my_errno, my_free, and MYF.
Referenced by heap_close(), and heap_panic().
00036 { 00037 int error=0; 00038 DBUG_ENTER("hp_close"); 00039 #ifndef DBUG_OFF 00040 if (info->s->changed && heap_check_heap(info,0)) 00041 { 00042 error=my_errno=HA_ERR_CRASHED; 00043 } 00044 #endif 00045 info->s->changed=0; 00046 heap_open_list=list_delete(heap_open_list,&info->open_list); 00047 if (!--info->s->open_count && info->s->delete_on_close) 00048 hp_free(info->s); /* Table was deleted */ 00049 my_free((gptr) info,MYF(0)); 00050 DBUG_RETURN(error); 00051 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int hp_delete_key | ( | HP_INFO * | info, | |
| HP_KEYDEF * | keyinfo, | |||
| const byte * | record, | |||
| byte * | recpos, | |||
| int | flag | |||
| ) |
Definition at line 30 of file hp_block.c.
References yaSSL::block, reg1, and reg3.
Referenced by main().
00031 { 00032 reg1 int i; 00033 reg3 HP_PTRS *ptr; /* block base ptr */ 00034 00035 for (i=block->levels-1, ptr=block->root ; i > 0 ; i--) 00036 { 00037 ptr=(HP_PTRS*)ptr->blocks[pos/block->level_info[i].records_under_level]; 00038 pos%=block->level_info[i].records_under_level; 00039 } 00040 return (byte*) ptr+ pos*block->recbuffer; 00041 }
Here is the caller graph for this function:

| HP_SHARE* hp_find_named_heap | ( | const char * | name | ) |
Definition at line 73 of file hp_open.c.
References DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, heap_share_list, info, st_heap_share::name, pos(), and strcmp().
Referenced by heap_create(), heap_delete_table(), heap_open(), and heap_rename().
00074 { 00075 LIST *pos; 00076 HP_SHARE *info; 00077 DBUG_ENTER("heap_find"); 00078 DBUG_PRINT("enter",("name: %s",name)); 00079 00080 for (pos= heap_share_list; pos; pos= pos->next) 00081 { 00082 info= (HP_SHARE*) pos->data; 00083 if (!strcmp(name, info->name)) 00084 { 00085 DBUG_PRINT("exit", ("Old heap_database: 0x%lx",info)); 00086 DBUG_RETURN(info); 00087 } 00088 } 00089 DBUG_RETURN((HP_SHARE *) 0); 00090 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void hp_free | ( | HP_SHARE * | info | ) |
Definition at line 281 of file hp_create.c.
References heap_share_list, hp_clear(), list_delete(), my_free, MYF, st_heap_share::name, st_heap_share::open_list, pthread_mutex_destroy, thr_lock_delete(), and VOID.
Referenced by heap_create(), heap_panic(), heap_try_free(), and hp_close().
00282 { 00283 heap_share_list= list_delete(heap_share_list, &share->open_list); 00284 hp_clear(share); /* Remove blocks from memory */ 00285 #ifdef THREAD 00286 thr_lock_delete(&share->lock); 00287 VOID(pthread_mutex_destroy(&share->intern_lock)); 00288 #endif 00289 my_free((gptr) share->name, MYF(0)); 00290 my_free((gptr) share, MYF(0)); 00291 return; 00292 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 128 of file hp_block.c.
References yaSSL::block, hp_free_level(), HP_PTRS_IN_NOD, and pos().
Referenced by hp_clear(), hp_clear_keys(), and hp_free_level().
00129 { 00130 int i,max_pos; 00131 byte *next_ptr; 00132 00133 if (level == 1) 00134 next_ptr=(byte*) pos+block->recbuffer; 00135 else 00136 { 00137 max_pos= (block->level_info[level-1].last_blocks == pos) ? 00138 HP_PTRS_IN_NOD - block->level_info[level-1].free_ptrs_in_block : 00139 HP_PTRS_IN_NOD; 00140 00141 next_ptr=(byte*) (pos+1); 00142 for (i=0 ; i < max_pos ; i++) 00143 next_ptr=hp_free_level(block,level-1, 00144 (HP_PTRS*) pos->blocks[i],next_ptr); 00145 } 00146 if ((byte*) pos != last_pos) 00147 { 00148 my_free((gptr) pos,MYF(0)); 00149 return last_pos; 00150 } 00151 return next_ptr; /* next memory position */ 00152 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 57 of file hp_block.c.
References allow_break(), yaSSL::block, dont_break(), HP_PTRS_IN_NOD, my_malloc(), MYF, and reg1.
Referenced by hp_find_free_hash(), and next_free_record_pos().
00058 { 00059 reg1 uint i,j; 00060 HP_PTRS *root; 00061 00062 for (i=0 ; i < block->levels ; i++) 00063 if (block->level_info[i].free_ptrs_in_block) 00064 break; 00065 00066 /* 00067 Allocate space for leaf block plus space for upper level blocks up to 00068 first level that has a free slot to put the pointer. 00069 In some cases we actually allocate more then we need: 00070 Consider e.g. a situation where we have one level 1 block and one level 0 00071 block, the level 0 block is full and this function is called. We only 00072 need a leaf block in this case. Nevertheless, we will get here with i=1 00073 and will also allocate sizeof(HP_PTRS) for non-leaf block and will never 00074 use this space. 00075 This doesn't add much overhead - with current values of sizeof(HP_PTRS) 00076 and my_default_record_cache_size we get about 1/128 unused memory. 00077 */ 00078 *alloc_length=sizeof(HP_PTRS)*i+block->records_in_block* block->recbuffer; 00079 if (!(root=(HP_PTRS*) my_malloc(*alloc_length,MYF(0)))) 00080 return 1; 00081 00082 if (i == 0) 00083 { 00084 block->levels=1; 00085 block->root=block->level_info[0].last_blocks=root; 00086 } 00087 else 00088 { 00089 dont_break(); /* Dont allow SIGHUP or SIGINT */ 00090 if ((uint) i == block->levels) 00091 { 00092 /* Adding a new level on top of the existing ones. */ 00093 block->levels=i+1; 00094 /* 00095 Use first allocated HP_PTRS as a top-level block. Put the current 00096 block tree into the first slot of a new top-level block. 00097 */ 00098 block->level_info[i].free_ptrs_in_block=HP_PTRS_IN_NOD-1; 00099 ((HP_PTRS**) root)[0]= block->root; 00100 block->root=block->level_info[i].last_blocks= root++; 00101 } 00102 /* Occupy the free slot we've found at level i */ 00103 block->level_info[i].last_blocks-> 00104 blocks[HP_PTRS_IN_NOD - block->level_info[i].free_ptrs_in_block--]= 00105 (byte*) root; 00106 00107 /* Add a block subtree with each node having one left-most child */ 00108 for (j=i-1 ; j >0 ; j--) 00109 { 00110 block->level_info[j].last_blocks= root++; 00111 block->level_info[j].last_blocks->blocks[0]=(byte*) root; 00112 block->level_info[j].free_ptrs_in_block=HP_PTRS_IN_NOD-1; 00113 } 00114 00115 /* 00116 root now points to last (block->records_in_block* block->recbuffer) 00117 allocated bytes. Use it as a leaf block. 00118 */ 00119 block->level_info[0].last_blocks= root; 00120 allow_break(); /* Allow SIGHUP & SIGINT */ 00121 } 00122 return 0; 00123 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 902 of file hp_hash.c.
References st_hp_keydef::keysegs, st_HA_KEYSEG::null_bit, st_HA_KEYSEG::null_pos, and st_hp_keydef::seg.
Referenced by hp_write_key().
00903 { 00904 HA_KEYSEG *seg,*endseg; 00905 for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) 00906 { 00907 if (seg->null_bit && (record[seg->null_pos] & seg->null_bit)) 00908 return 1; 00909 } 00910 return 0; 00911 }
Here is the caller graph for this function:

Definition at line 581 of file hp_hash.c.
References bcmp, st_HA_KEYSEG::bit_start, st_HA_KEYSEG::charset, charset_info_st::coll, HA_KEYTYPE_TEXT, HA_KEYTYPE_VARTEXT1, st_hp_keydef::keysegs, st_HA_KEYSEG::length, charset_info_st::mbmaxlen, my_charpos, st_HA_KEYSEG::null_bit, st_HA_KEYSEG::null_pos, st_hp_keydef::seg, set_if_smaller, st_HA_KEYSEG::start, my_collation_handler_st::strnncollsp, test, st_HA_KEYSEG::type, and uint2korr.
Referenced by hp_search(), and hp_search_next().
00582 { 00583 HA_KEYSEG *seg,*endseg; 00584 00585 for (seg=keydef->seg,endseg=seg+keydef->keysegs ; 00586 seg < endseg ; 00587 key+= (seg++)->length) 00588 { 00589 if (seg->null_bit) 00590 { 00591 int found_null=test(rec[seg->null_pos] & seg->null_bit); 00592 if (found_null != (int) *key++) 00593 return 1; 00594 if (found_null) 00595 { 00596 /* Add key pack length (2) to key for VARCHAR segments */ 00597 if (seg->type == HA_KEYTYPE_VARTEXT1) 00598 key+= 2; 00599 continue; 00600 } 00601 } 00602 if (seg->type == HA_KEYTYPE_TEXT) 00603 { 00604 CHARSET_INFO *cs= seg->charset; 00605 uint char_length_key; 00606 uint char_length_rec; 00607 uchar *pos= (uchar*) rec + seg->start; 00608 if (cs->mbmaxlen > 1) 00609 { 00610 uint char_length= seg->length / cs->mbmaxlen; 00611 char_length_key= my_charpos(cs, key, key + seg->length, char_length); 00612 set_if_smaller(char_length_key, seg->length); 00613 char_length_rec= my_charpos(cs, pos, pos + seg->length, char_length); 00614 set_if_smaller(char_length_rec, seg->length); 00615 } 00616 else 00617 { 00618 char_length_key= seg->length; 00619 char_length_rec= seg->length; 00620 } 00621 00622 if (seg->charset->coll->strnncollsp(seg->charset, 00623 (uchar*) pos, char_length_rec, 00624 (uchar*) key, char_length_key, 0)) 00625 return 1; 00626 } 00627 else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */ 00628 { 00629 uchar *pos= (uchar*) rec + seg->start; 00630 CHARSET_INFO *cs= seg->charset; 00631 uint pack_length= seg->bit_start; 00632 uint char_length_rec= (pack_length == 1 ? (uint) *(uchar*) pos : 00633 uint2korr(pos)); 00634 /* Key segments are always packed with 2 bytes */ 00635 uint char_length_key= uint2korr(key); 00636 pos+= pack_length; 00637 key+= 2; /* skip key pack length */ 00638 if (cs->mbmaxlen > 1) 00639 { 00640 uint char_length1, char_length2; 00641 char_length1= char_length2= seg->length / cs->mbmaxlen; 00642 char_length1= my_charpos(cs, key, key + char_length_key, char_length1); 00643 set_if_smaller(char_length_key, char_length1); 00644 char_length2= my_charpos(cs, pos, pos + char_length_rec, char_length2); 00645 set_if_smaller(char_length_rec, char_length2); 00646 } 00647 00648 if (cs->coll->strnncollsp(seg->charset, 00649 (uchar*) pos, char_length_rec, 00650 (uchar*) key, char_length_key, 0)) 00651 return 1; 00652 } 00653 else 00654 { 00655 if (bcmp(rec+seg->start,key,seg->length)) 00656 return 1; 00657 } 00658 } 00659 return 0; 00660 }
Here is the caller graph for this function:

Definition at line 665 of file hp_hash.c.
References st_HA_KEYSEG::bit_start, st_HA_KEYSEG::charset, HA_KEYTYPE_VARTEXT1, st_hp_keydef::keysegs, st_HA_KEYSEG::length, charset_info_st::mbmaxlen, memcpy, my_charpos, st_HA_KEYSEG::null_bit, st_HA_KEYSEG::null_pos, st_hp_keydef::seg, set_if_smaller, st_HA_KEYSEG::start, test, and st_HA_KEYSEG::type.
Referenced by heap_rsame().
00666 { 00667 HA_KEYSEG *seg,*endseg; 00668 00669 for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) 00670 { 00671 CHARSET_INFO *cs= seg->charset; 00672 uint char_length= seg->length; 00673 uchar *pos= (uchar*) rec + seg->start; 00674 if (seg->null_bit) 00675 *key++= test(rec[seg->null_pos] & seg->null_bit); 00676 if (cs->mbmaxlen > 1) 00677 { 00678 char_length= my_charpos(cs, pos, pos + seg->length, 00679 char_length / cs->mbmaxlen); 00680 set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */ 00681 } 00682 if (seg->type == HA_KEYTYPE_VARTEXT1) 00683 char_length+= seg->bit_start; /* Copy also length */ 00684 memcpy(key,rec+seg->start,(size_t) char_length); 00685 key+= char_length; 00686 } 00687 }
Here is the caller graph for this function:

Definition at line 212 of file hp_hash.c.
Referenced by check_one_key(), hp_delete_key(), hp_search(), and hp_write_key().
00213 { 00214 if ((hashnr & (buffmax-1)) < maxlength) return (hashnr & (buffmax-1)); 00215 return (hashnr & ((buffmax >> 1) -1)); 00216 }
Here is the caller graph for this function:

Definition at line 226 of file hp_hash.c.
References st_hp_hash_info::next_key, and pos().
Referenced by hp_delete_key(), and hp_write_key().
00227 { 00228 HASH_INFO *old_link; 00229 do 00230 { 00231 old_link=next_link; 00232 } 00233 while ((next_link=next_link->next_key) != pos); 00234 old_link->next_key=newlink; 00235 return; 00236 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int hp_rb_delete_key | ( | HP_INFO * | info, | |
| HP_KEYDEF * | keyinfo, | |||
| const byte * | record, | |||
| byte * | recpos, | |||
| int | flag | |||
| ) |
Definition at line 697 of file hp_hash.c.
References st_HA_KEYSEG::bit_start, bzero, st_HA_KEYSEG::charset, charset_info_st::cset, my_charset_handler_st::fill, FIX_LENGTH, st_HA_KEYSEG::flag, float4get, float8get, HA_KEYTYPE_DOUBLE, HA_KEYTYPE_FLOAT, HA_SWAP_KEY, HA_VAR_LENGTH_PART, HAVE_ISNAN, isnan, st_hp_keydef::keysegs, st_HA_KEYSEG::length, charset_info_st::mbmaxlen, memcpy, my_charpos, st_HA_KEYSEG::null_bit, st_HA_KEYSEG::null_pos, st_hp_keydef::seg, set_if_smaller, st_HA_KEYSEG::start, store_key_length_inc, test, st_HA_KEYSEG::type, and uint2korr.
Referenced by check_one_rb_key(), hp_rb_delete_key(), and hp_rb_write_key().
00699 { 00700 byte *start_key= key; 00701 HA_KEYSEG *seg, *endseg; 00702 00703 for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++) 00704 { 00705 uint char_length; 00706 if (seg->null_bit) 00707 { 00708 if (!(*key++= 1 - test(rec[seg->null_pos] & seg->null_bit))) 00709 continue; 00710 } 00711 if (seg->flag & HA_SWAP_KEY) 00712 { 00713 uint length= seg->length; 00714 byte *pos= (byte*) rec + seg->start; 00715 00716 #ifdef HAVE_ISNAN 00717 if (seg->type == HA_KEYTYPE_FLOAT) 00718 { 00719 float nr; 00720 float4get(nr, pos); 00721 if (isnan(nr)) 00722 { 00723 /* Replace NAN with zero */ 00724 bzero(key, length); 00725 key+= length; 00726 continue; 00727 } 00728 } 00729 else if (seg->type == HA_KEYTYPE_DOUBLE) 00730 { 00731 double nr; 00732 float8get(nr, pos); 00733 if (isnan(nr)) 00734 { 00735 bzero(key, length); 00736 key+= length; 00737 continue; 00738 } 00739 } 00740 #endif 00741 pos+= length; 00742 while (length--) 00743 { 00744 *key++= *--pos; 00745 } 00746 continue; 00747 } 00748 00749 if (seg->flag & HA_VAR_LENGTH_PART) 00750 { 00751 uchar *pos= (uchar*) rec + seg->start; 00752 uint length= seg->length; 00753 uint pack_length= seg->bit_start; 00754 uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos : 00755 uint2korr(pos)); 00756 CHARSET_INFO *cs= seg->charset; 00757 char_length= length/cs->mbmaxlen; 00758 00759 pos+= pack_length; /* Skip VARCHAR length */ 00760 set_if_smaller(length,tmp_length); 00761 FIX_LENGTH(cs, pos, length, char_length); 00762 store_key_length_inc(key,char_length); 00763 memcpy((byte*) key,(byte*) pos,(size_t) char_length); 00764 key+= char_length; 00765 continue; 00766 } 00767 00768 char_length= seg->length; 00769 if (seg->charset->mbmaxlen > 1) 00770 { 00771 char_length= my_charpos(seg->charset, 00772 rec + seg->start, rec + seg->start + char_length, 00773 char_length / seg->charset->mbmaxlen); 00774 set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */ 00775 if (char_length < seg->length) 00776 seg->charset->cset->fill(seg->charset, (char*) key + char_length, 00777 seg->length - char_length, ' '); 00778 } 00779 memcpy(key, rec + seg->start, (size_t) char_length); 00780 key+= seg->length; 00781 } 00782 memcpy(key, &recpos, sizeof(byte*)); 00783 return (uint) (key - start_key); 00784 }
Here is the caller graph for this function:

Definition at line 860 of file hp_hash.c.
References st_hp_keydef::keysegs, st_HA_KEYSEG::length, st_HA_KEYSEG::null_bit, and st_hp_keydef::seg.
Referenced by heap_create().
00861 { 00862 const byte *start_key= key; 00863 HA_KEYSEG *seg, *endseg; 00864 00865 for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++) 00866 { 00867 if (seg->null_bit && !*key++) 00868 continue; 00869 key+= seg->length; 00870 } 00871 return (uint) (key - start_key); 00872 }
Here is the caller graph for this function:

Definition at line 787 of file hp_hash.c.
References st_HA_KEYSEG::charset, charset_info_st::cset, my_charset_handler_st::fill, FIX_LENGTH, st_HA_KEYSEG::flag, HA_BLOB_PART, HA_SWAP_KEY, HA_VAR_LENGTH_PART, st_hp_keydef::keysegs, st_HA_KEYSEG::length, charset_info_st::mbmaxlen, memcpy, my_charpos, st_HA_KEYSEG::null_bit, st_hp_keydef::seg, set_if_smaller, store_key_length_inc, and uint2korr.
Referenced by heap_rkey(), and hp_rb_records_in_range().
00789 { 00790 HA_KEYSEG *seg, *endseg; 00791 uchar *start_key= key; 00792 00793 for (seg= keydef->seg, endseg= seg + keydef->keysegs; 00794 seg < endseg && (int) k_len > 0; old+= seg->length, seg++) 00795 { 00796 uint char_length; 00797 if (seg->null_bit) 00798 { 00799 k_len--; 00800 if (!(*key++= (char) 1 - *old++)) 00801 { 00802 k_len-= seg->length; 00803 continue; 00804 } 00805 } 00806 if (seg->flag & HA_SWAP_KEY) 00807 { 00808 uint length= seg->length; 00809 byte *pos= (byte*) old + length; 00810 00811 k_len-= length; 00812 while (length--) 00813 { 00814 *key++= *--pos; 00815 } 00816 continue; 00817 } 00818 if (seg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART)) 00819 { 00820 /* Length of key-part used with heap_rkey() always 2 */ 00821 uint tmp_length=uint2korr(old); 00822 uint length= seg->length; 00823 CHARSET_INFO *cs= seg->charset; 00824 char_length= length/cs->mbmaxlen; 00825 00826 k_len-= 2+length; 00827 old+= 2; 00828 set_if_smaller(length,tmp_length); /* Safety */ 00829 FIX_LENGTH(cs, old, length, char_length); 00830 store_key_length_inc(key,char_length); 00831 memcpy((byte*) key, old,(size_t) char_length); 00832 key+= char_length; 00833 continue; 00834 } 00835 char_length= seg->length; 00836 if (seg->charset->mbmaxlen > 1) 00837 { 00838 char_length= my_charpos(seg->charset, old, old+char_length, 00839 char_length / seg->charset->mbmaxlen); 00840 set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */ 00841 if (char_length < seg->length) 00842 seg->charset->cset->fill(seg->charset, (char*) key + char_length, 00843 seg->length - char_length, ' '); 00844 } 00845 memcpy(key, old, (size_t) char_length); 00846 key+= seg->length; 00847 k_len-= seg->length; 00848 } 00849 return (uint) (key - start_key); 00850 }
Here is the caller graph for this function:

Definition at line 875 of file hp_hash.c.
References st_HA_KEYSEG::flag, get_key_length, HA_BLOB_PART, HA_VAR_LENGTH_PART, st_hp_keydef::keysegs, st_HA_KEYSEG::length, st_HA_KEYSEG::null_bit, and st_hp_keydef::seg.
Referenced by heap_create().
00876 { 00877 const byte *start_key= key; 00878 HA_KEYSEG *seg, *endseg; 00879 00880 for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++) 00881 { 00882 uint length= seg->length; 00883 if (seg->null_bit && !*key++) 00884 continue; 00885 if (seg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART)) 00886 { 00887 get_key_length(length, key); 00888 } 00889 key+= length; 00890 } 00891 return (uint) (key - start_key); 00892 }
Here is the caller graph for this function:

Definition at line 97 of file hp_write.c.
References st_mi_keydef::flag, HA_ERR_FOUND_DUPP_KEY, HA_NOSAME, hp_rb_make_key(), st_heap_share::index_length, heap_rb_param::key_length, keyinfo, heap_rb_param::keyseg, st_heap_info::last_pos, my_errno, NULL, st_heap_info::recbuf, st_heap_info::s, SEARCH_FIND, heap_rb_param::search_flag, SEARCH_SAME, SEARCH_UPDATE, st_mi_keydef::seg, tree_insert(), and TREE_NO_DUPS.
00099 { 00100 heap_rb_param custom_arg; 00101 uint old_allocated; 00102 00103 info->last_pos= NULL; /* For heap_rnext/heap_rprev */ 00104 custom_arg.keyseg= keyinfo->seg; 00105 custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos); 00106 if (keyinfo->flag & HA_NOSAME) 00107 { 00108 custom_arg.search_flag= SEARCH_FIND | SEARCH_UPDATE; 00109 keyinfo->rb_tree.flag= TREE_NO_DUPS; 00110 } 00111 else 00112 { 00113 custom_arg.search_flag= SEARCH_SAME; 00114 keyinfo->rb_tree.flag= 0; 00115 } 00116 old_allocated= keyinfo->rb_tree.allocated; 00117 if (!tree_insert(&keyinfo->rb_tree, (void*)info->recbuf, 00118 custom_arg.key_length, &custom_arg)) 00119 { 00120 my_errno= HA_ERR_FOUND_DUPP_KEY; 00121 return 1; 00122 } 00123 info->s->index_length+= (keyinfo->rb_tree.allocated-old_allocated); 00124 return 0; 00125 }
Here is the call graph for this function:

Referenced by check_one_key(), hp_delete_key(), hp_search(), and hp_write_key().
Here is the caller graph for this function:

| int hp_rec_key_cmp | ( | HP_KEYDEF * | keydef, | |
| const byte * | rec1, | |||
| const byte * | rec2, | |||
| my_bool | diff_if_only_endspace_difference | |||
| ) |
Definition at line 494 of file hp_hash.c.
References bcmp, st_HA_KEYSEG::bit_start, st_HA_KEYSEG::charset, charset_info_st::coll, st_HA_KEYSEG::flag, HA_END_SPACE_ARE_EQUAL, HA_KEYTYPE_TEXT, HA_KEYTYPE_VARTEXT1, st_hp_keydef::keysegs, st_HA_KEYSEG::length, charset_info_st::mbmaxlen, my_charpos, st_HA_KEYSEG::null_bit, st_HA_KEYSEG::null_pos, st_hp_keydef::seg, set_if_smaller, st_HA_KEYSEG::start, my_collation_handler_st::strnncollsp, st_HA_KEYSEG::type, and uint2korr.
Referenced by heap_update(), hp_delete_key(), and hp_write_key().
00496 { 00497 HA_KEYSEG *seg,*endseg; 00498 00499 for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) 00500 { 00501 if (seg->null_bit) 00502 { 00503 if ((rec1[seg->null_pos] & seg->null_bit) != 00504 (rec2[seg->null_pos] & seg->null_bit)) 00505 return 1; 00506 if (rec1[seg->null_pos] & seg->null_bit) 00507 continue; 00508 } 00509 if (seg->type == HA_KEYTYPE_TEXT) 00510 { 00511 CHARSET_INFO *cs= seg->charset; 00512 uint char_length1; 00513 uint char_length2; 00514 uchar *pos1= (uchar*)rec1 + seg->start; 00515 uchar *pos2= (uchar*)rec2 + seg->start; 00516 if (cs->mbmaxlen > 1) 00517 { 00518 uint char_length= seg->length / cs->mbmaxlen; 00519 char_length1= my_charpos(cs, pos1, pos1 + seg->length, char_length); 00520 set_if_smaller(char_length1, seg->length); 00521 char_length2= my_charpos(cs, pos2, pos2 + seg->length, char_length); 00522 set_if_smaller(char_length2, seg->length); 00523 } 00524 else 00525 { 00526 char_length1= char_length2= seg->length; 00527 } 00528 if (seg->charset->coll->strnncollsp(seg->charset, 00529 pos1,char_length1, 00530 pos2,char_length2, 0)) 00531 return 1; 00532 } 00533 else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */ 00534 { 00535 uchar *pos1= (uchar*) rec1 + seg->start; 00536 uchar *pos2= (uchar*) rec2 + seg->start; 00537 uint char_length1, char_length2; 00538 uint pack_length= seg->bit_start; 00539 CHARSET_INFO *cs= seg->charset; 00540 if (pack_length == 1) 00541 { 00542 char_length1= (uint) *(uchar*) pos1++; 00543 char_length2= (uint) *(uchar*) pos2++; 00544 } 00545 else 00546 { 00547 char_length1= uint2korr(pos1); 00548 char_length2= uint2korr(pos2); 00549 pos1+= 2; 00550 pos2+= 2; 00551 } 00552 if (cs->mbmaxlen > 1) 00553 { 00554 uint safe_length1= char_length1; 00555 uint safe_length2= char_length2; 00556 uint char_length= seg->length / cs->mbmaxlen; 00557 char_length1= my_charpos(cs, pos1, pos1 + char_length1, char_length); 00558 set_if_smaller(char_length1, safe_length1); 00559 char_length2= my_charpos(cs, pos2, pos2 + char_length2, char_length); 00560 set_if_smaller(char_length2, safe_length2); 00561 } 00562 00563 if (cs->coll->strnncollsp(seg->charset, 00564 pos1, char_length1, 00565 pos2, char_length2, 00566 seg->flag & HA_END_SPACE_ARE_EQUAL ? 00567 0 : diff_if_only_endspace_difference)) 00568 return 1; 00569 } 00570 else 00571 { 00572 if (bcmp(rec1+seg->start,rec2+seg->start,seg->length)) 00573 return 1; 00574 } 00575 } 00576 return 0; 00577 }
Here is the caller graph for this function:

Definition at line 101 of file hp_hash.c.
References st_heap_share::blength, st_heap_info::current_hash_ptr, st_heap_info::current_ptr, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, flag, HA_ERR_KEY_NOT_FOUND, HA_ERR_RECORD_CHANGED, hp_find_hash, hp_hashnr(), hp_key_cmp(), hp_mask(), hp_rec_hashnr(), keyinfo, my_errno, pos(), st_heap_share::records, reg1, and st_heap_info::s.
Referenced by heap_find(), heap_rkey(), heap_rnext(), heap_rprev(), and heap_rsame().
00103 { 00104 reg1 HASH_INFO *pos,*prev_ptr; 00105 int flag; 00106 uint old_nextflag; 00107 HP_SHARE *share=info->s; 00108 DBUG_ENTER("hp_search"); 00109 old_nextflag=nextflag; 00110 flag=1; 00111 prev_ptr=0; 00112 00113 if (share->records) 00114 { 00115 pos=hp_find_hash(&keyinfo->block, hp_mask(hp_hashnr(keyinfo, key), 00116 share->blength, share->records)); 00117 do 00118 { 00119 if (!hp_key_cmp(keyinfo, pos->ptr_to_rec, key)) 00120 { 00121 switch (nextflag) { 00122 case 0: /* Search after key */ 00123 DBUG_PRINT("exit",("found key at %d",pos->ptr_to_rec)); 00124 info->current_hash_ptr=pos; 00125 DBUG_RETURN(info->current_ptr= pos->ptr_to_rec); 00126 case 1: /* Search next */ 00127 if (pos->ptr_to_rec == info->current_ptr) 00128 nextflag=0; 00129 break; 00130 case 2: /* Search previous */ 00131 if (pos->ptr_to_rec == info->current_ptr) 00132 { 00133 my_errno=HA_ERR_KEY_NOT_FOUND; /* If gpos == 0 */ 00134 info->current_hash_ptr=prev_ptr; 00135 DBUG_RETURN(info->current_ptr=prev_ptr ? prev_ptr->ptr_to_rec : 0); 00136 } 00137 prev_ptr=pos; /* Prev. record found */ 00138 break; 00139 case 3: /* Search same */ 00140 if (pos->ptr_to_rec == info->current_ptr) 00141 { 00142 info->current_hash_ptr=pos; 00143 DBUG_RETURN(info->current_ptr); 00144 } 00145 } 00146 } 00147 if (flag) 00148 { 00149 flag=0; /* Reset flag */ 00150 if (hp_find_hash(&keyinfo->block, 00151 hp_mask(hp_rec_hashnr(keyinfo, pos->ptr_to_rec), 00152 share->blength, share->records)) != pos) 00153 break; /* Wrong link */ 00154 } 00155 } 00156 while ((pos=pos->next_key)); 00157 } 00158 my_errno=HA_ERR_KEY_NOT_FOUND; 00159 if (nextflag == 2 && ! info->current_ptr) 00160 { 00161 /* Do a previous from end */ 00162 info->current_hash_ptr=prev_ptr; 00163 DBUG_RETURN(info->current_ptr=prev_ptr ? prev_ptr->ptr_to_rec : 0); 00164 } 00165 00166 if (old_nextflag && nextflag) 00167 my_errno=HA_ERR_RECORD_CHANGED; /* Didn't find old record */ 00168 DBUG_PRINT("exit",("Error: %d",my_errno)); 00169 info->current_hash_ptr=0; 00170 DBUG_RETURN((info->current_ptr= 0)); 00171 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 179 of file hp_hash.c.
References st_heap_info::current_hash_ptr, st_heap_info::current_ptr, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, HA_ERR_KEY_NOT_FOUND, hp_key_cmp(), keyinfo, my_errno, and pos().
Referenced by heap_rnext().
00181 { 00182 DBUG_ENTER("hp_search_next"); 00183 00184 while ((pos= pos->next_key)) 00185 { 00186 if (! hp_key_cmp(keyinfo, pos->ptr_to_rec, key)) 00187 { 00188 info->current_hash_ptr=pos; 00189 DBUG_RETURN (info->current_ptr= pos->ptr_to_rec); 00190 } 00191 } 00192 my_errno=HA_ERR_KEY_NOT_FOUND; 00193 DBUG_PRINT("exit",("Error: %d",my_errno)); 00194 info->current_hash_ptr=0; 00195 DBUG_RETURN ((info->current_ptr= 0)); 00196 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 189 of file hp_write.c.
References st_heap_share::blength, DBUG_ENTER, DBUG_RETURN, empty, flag, st_mi_keydef::flag, HA_ERR_FOUND_DUPP_KEY, HA_NOSAME, HA_NULL_PART_KEY, HIGHFIND, HIGHUSED, hp_find_free_hash(), hp_find_hash, hp_if_null_in_key(), hp_mask(), hp_movelink(), hp_rec_hashnr(), hp_rec_key_cmp(), keyinfo, LINT_INIT, LOWFIND, LOWUSED, my_errno, st_hp_hash_info::next_key, pos(), st_hp_hash_info::ptr_to_rec, st_heap_share::records, and st_heap_info::s.
00191 { 00192 HP_SHARE *share = info->s; 00193 int flag; 00194 ulong halfbuff,hashnr,first_index; 00195 byte *ptr_to_rec,*ptr_to_rec2; 00196 HASH_INFO *empty,*gpos,*gpos2,*pos; 00197 DBUG_ENTER("hp_write_key"); 00198 00199 LINT_INIT(gpos); LINT_INIT(gpos2); 00200 LINT_INIT(ptr_to_rec); LINT_INIT(ptr_to_rec2); 00201 00202 flag=0; 00203 if (!(empty= hp_find_free_hash(share,&keyinfo->block,share->records))) 00204 DBUG_RETURN(-1); /* No more memory */ 00205 halfbuff= (long) share->blength >> 1; 00206 pos= hp_find_hash(&keyinfo->block,(first_index=share->records-halfbuff)); 00207 00208 /* 00209 We're about to add one more hash array position, with hash_mask=#records. 00210 The number of hash positions will change and some entries might need to 00211 be relocated to the newly added position. Those entries are currently 00212 members of the list that starts at #first_index position (this is 00213 guaranteed by properties of hp_mask(hp_rec_hashnr(X)) mapping function) 00214 At #first_index position currently there may be either: 00215 a) An entry with hashnr != first_index. We don't need to move it. 00216 or 00217 b) A list of items with hash_mask=first_index. The list contains entries 00218 of 2 types: 00219 1) entries that should be relocated to the list that starts at new 00220 position we're adding ('uppper' list) 00221 2) entries that should be left in the list starting at #first_index 00222 position ('lower' list) 00223 */ 00224 if (pos != empty) /* If some records */ 00225 { 00226 do 00227 { 00228 hashnr = hp_rec_hashnr(keyinfo, pos->ptr_to_rec); 00229 if (flag == 0) 00230 { 00231 /* 00232 First loop, bail out if we're dealing with case a) from above 00233 comment 00234 */ 00235 if (hp_mask(hashnr, share->blength, share->records) != first_index) 00236 break; 00237 } 00238 /* 00239 flag & LOWFIND - found a record that should be put into lower position 00240 flag & LOWUSED - lower position occupied by the record 00241 Same for HIGHFIND and HIGHUSED and 'upper' position 00242 00243 gpos - ptr to last element in lower position's list 00244 gpos2 - ptr to last element in upper position's list 00245 00246 ptr_to_rec - ptr to last entry that should go into lower list. 00247 ptr_to_rec2 - same for upper list. 00248 */ 00249 if (!(hashnr & halfbuff)) 00250 { 00251 /* Key should be put into 'lower' list */ 00252 if (!(flag & LOWFIND)) 00253 { 00254 /* key is the first element to go into lower position */ 00255 if (flag & HIGHFIND) 00256 { 00257 flag=LOWFIND | HIGHFIND; 00258 /* key shall be moved to the current empty position */ 00259 gpos=empty; 00260 ptr_to_rec=pos->ptr_to_rec; 00261 empty=pos; /* This place is now free */ 00262 } 00263 else 00264 { 00265 /* 00266 We can only get here at first iteration: key is at 'lower' 00267 position pos and should be left here. 00268 */ 00269 flag=LOWFIND | LOWUSED; 00270 gpos=pos; 00271 ptr_to_rec=pos->ptr_to_rec; 00272 } 00273 } 00274 else 00275 { 00276 /* Already have another key for lower position */ 00277 if (!(flag & LOWUSED)) 00278 { 00279 /* Change link of previous lower-list key */ 00280 gpos->ptr_to_rec=ptr_to_rec; 00281 gpos->next_key=pos; 00282 flag= (flag & HIGHFIND) | (LOWFIND | LOWUSED); 00283 } 00284 gpos=pos; 00285 ptr_to_rec=pos->ptr_to_rec; 00286 } 00287 } 00288 else 00289 { 00290 /* key will be put into 'higher' list */ 00291 if (!(flag & HIGHFIND)) 00292 { 00293 flag= (flag & LOWFIND) | HIGHFIND; 00294 /* key shall be moved to the last (empty) position */ 00295 gpos2= empty; 00296 empty= pos; 00297 ptr_to_rec2=pos->ptr_to_rec; 00298 } 00299 else 00300 { 00301 if (!(flag & HIGHUSED)) 00302 { 00303 /* Change link of previous upper-list key and save */ 00304 gpos2->ptr_to_rec=ptr_to_rec2; 00305 gpos2->next_key=pos; 00306 flag= (flag & LOWFIND) | (HIGHFIND | HIGHUSED); 00307 } 00308 gpos2=pos; 00309 ptr_to_rec2=pos->ptr_to_rec; 00310 } 00311 } 00312 } 00313 while ((pos=pos->next_key)); 00314 00315 if ((flag & (LOWFIND | HIGHFIND)) == (LOWFIND | HIGHFIND)) 00316 { 00317 /* 00318 If both 'higher' and 'lower' list have at least one element, now 00319 there are two hash buckets instead of one. 00320 */ 00321 keyinfo->hash_buckets++; 00322 } 00323 00324 if ((flag & (LOWFIND | LOWUSED)) == LOWFIND) 00325 { 00326 gpos->ptr_to_rec=ptr_to_rec; 00327 gpos->next_key=0; 00328 } 00329 if ((flag & (HIGHFIND | HIGHUSED)) == HIGHFIND) 00330 { 00331 gpos2->ptr_to_rec=ptr_to_rec2; 00332 gpos2->next_key=0; 00333 } 00334 } 00335 /* Check if we are at the empty position */ 00336 00337 pos=hp_find_hash(&keyinfo->block, hp_mask(hp_rec_hashnr(keyinfo, record), 00338 share->blength, share->records + 1)); 00339 if (pos == empty) 00340 { 00341 pos->ptr_to_rec=recpos; 00342 pos->next_key=0; 00343 keyinfo->hash_buckets++; 00344 } 00345 else 00346 { 00347 /* Check if more records in same hash-nr family */ 00348 empty[0]=pos[0]; 00349 gpos=hp_find_hash(&keyinfo->block, 00350 hp_mask(hp_rec_hashnr(keyinfo, pos->ptr_to_rec), 00351 share->blength, share->records + 1)); 00352 if (pos == gpos) 00353 { 00354 pos->ptr_to_rec=recpos; 00355 pos->next_key=empty; 00356 } 00357 else 00358 { 00359 keyinfo->hash_buckets++; 00360 pos->ptr_to_rec=recpos; 00361 pos->next_key=0; 00362 hp_movelink(pos, gpos, empty); 00363 } 00364 00365 /* Check if duplicated keys */ 00366 if ((keyinfo->flag & HA_NOSAME) && pos == gpos && 00367 (!(keyinfo->flag & HA_NULL_PART_KEY) || 00368 !hp_if_null_in_key(keyinfo, record))) 00369 { 00370 pos=empty; 00371 do 00372 { 00373 if (! hp_rec_key_cmp(keyinfo, record, pos->ptr_to_rec, 1)) 00374 { 00375 DBUG_RETURN(my_errno=HA_ERR_FOUND_DUPP_KEY); 00376 } 00377 } while ((pos=pos->next_key)); 00378 } 00379 } 00380 DBUG_RETURN(0); 00381 }
Here is the call graph for this function:

Definition at line 26 of file hp_static.c.
Referenced by heap_panic(), hp_find_named_heap(), and hp_free().
1.4.7

