diff options
author | unknown <bar@gw.udmsearch.izhnet.ru> | 2002-04-25 13:36:55 +0500 |
---|---|---|
committer | unknown <bar@gw.udmsearch.izhnet.ru> | 2002-04-25 13:36:55 +0500 |
commit | 139a73cade4827ca2a41d6cfc9db379b2c696fa3 (patch) | |
tree | 5b8a058772659a40e41e2025e66f79531e604613 /heap/hp_hash.c | |
parent | 0e4445850dd29493d61e06650a7b2a430ca42ec8 (diff) | |
download | mariadb-git-139a73cade4827ca2a41d6cfc9db379b2c696fa3.tar.gz |
RB-Tree indexes support in HEAP tables
Renamed _hp_func -> hp_func
mi_key_cmp moved to /mysys/my_handler.c
New tests for HEAP tables
heap/_check.c:
RB-tree index
Renamed _hp_func -> hp_func
heap/_rectest.c:
RB-tree index
Renamed _hp_func -> hp_func
heap/heapdef.h:
RB-tree index
Renamed _hp_func -> hp_func
heap/hp_block.c:
RB-tree index
Renamed _hp_func -> hp_func
heap/hp_clear.c:
RB-tree index
Renamed _hp_func -> hp_func
heap/hp_close.c:
RB-tree index
Renamed _hp_func -> hp_func
heap/hp_create.c:
RB-tree index
Renamed _hp_func -> hp_func
heap/hp_delete.c:
RB-tree index
Renamed _hp_func -> hp_func
heap/hp_hash.c:
RB-tree index
Renamed _hp_func -> hp_func
heap/hp_open.c:
RB-tree index
Renamed _hp_func -> hp_func
heap/hp_panic.c:
RB-tree index
Renamed _hp_func -> hp_func
heap/hp_rename.c:
RB-tree index
Renamed _hp_func -> hp_func
heap/hp_rfirst.c:
RB-tree index
Renamed _hp_func -> hp_func
heap/hp_rkey.c:
RB-tree index
Renamed _hp_func -> hp_func
heap/hp_rlast.c:
RB-tree index
Renamed _hp_func -> hp_func
heap/hp_rnext.c:
RB-tree index
Renamed _hp_func -> hp_func
heap/hp_rprev.c:
RB-tree index
Renamed _hp_func -> hp_func
heap/hp_rrnd.c:
RB-tree index
Renamed _hp_func -> hp_func
heap/hp_rsame.c:
RB-tree index
Renamed _hp_func -> hp_func
heap/hp_scan.c:
RB-tree index
Renamed _hp_func -> hp_func
heap/hp_test1.c:
RB-tree index
Renamed _hp_func -> hp_func
heap/hp_test2.c:
RB-tree index
Renamed _hp_func -> hp_func
heap/hp_update.c:
RB-tree index
Renamed _hp_func -> hp_func
heap/hp_write.c:
RB-tree index
Renamed _hp_func -> hp_func
include/Makefile.am:
New include
include/heap.h:
RB-Tree index
include/my_tree.h:
new search functions
new custom_arg argument
include/myisam.h:
Removed MI_KEYSEG
isam/isamlog.c:
Add custom_arg
isam/pack_isam.c:
Add custom_arg
myisam/ft_nlq_search.c:
Add custom_arg
myisam/ft_parser.c:
Add custom_arg
myisam/ft_stopwords.c:
Add custom_arg
myisam/mi_search.c:
Remove mi_key_cmp
myisam/mi_write.c:
Add custom_arg
myisam/myisamdef.h:
Remove mi_key_cmp
myisam/myisamlog.c:
Add custom_arg
myisam/myisampack.c:
Add custom_arg
mysys/Makefile.am:
New file my_handler.c
mysys/tree.c:
custom_arg
new search functions
sql/ha_heap.cc:
RBTree
sql/ha_myisam.cc:
RBTree
sql/item_sum.cc:
custom_arg
sql/sql_analyse.cc:
custom_arg
sql/sql_class.h:
custom_arg
sql/sql_table.cc:
Remove duplicate code
sql/sql_yacc.yy:
UNDEF by default
sql/table.cc:
Remove dirty hack
Diffstat (limited to 'heap/hp_hash.c')
-rw-r--r-- | heap/hp_hash.c | 146 |
1 files changed, 113 insertions, 33 deletions
diff --git a/heap/hp_hash.c b/heap/hp_hash.c index 2ca33e5b782..b13ce786f6d 100644 --- a/heap/hp_hash.c +++ b/heap/hp_hash.c @@ -19,30 +19,72 @@ #include "heapdef.h" #include <m_ctype.h> +ha_rows hp_rb_records_in_range(HP_INFO *info, int inx, const byte *start_key, + uint start_key_len, + enum ha_rkey_function start_search_flag, + const byte *end_key, uint end_key_len, + enum ha_rkey_function end_search_flag) +{ + ha_rows start_pos, end_pos; + TREE *rb_tree = &info->s->keydef[inx].rb_tree; + heap_rb_param custom_arg; + + info->lastinx = inx; + custom_arg.keyseg = info->s->keydef[inx].seg; + custom_arg.search_flag = SEARCH_FIND | SEARCH_SAME; + custom_arg.key_length = start_key_len; + if (start_key) + { + hp_rb_pack_key(info, inx, info->recbuf, start_key, start_key_len); + start_pos= tree_record_pos(rb_tree, info->recbuf, start_search_flag, + &custom_arg); + } + else + { + start_pos= 0; + } + + custom_arg.key_length = end_key_len; + if (end_key) + { + hp_rb_pack_key(info, inx, info->recbuf, end_key, end_key_len); + end_pos= tree_record_pos(rb_tree, info->recbuf, end_search_flag, + &custom_arg); + } + else + { + end_pos= rb_tree->elements_in_tree + (ha_rows)1; + } + + if (start_pos == HA_POS_ERROR || end_pos == HA_POS_ERROR) + return HA_POS_ERROR; + return end_pos < start_pos ? (ha_rows) 0 : + (end_pos == start_pos ? (ha_rows) 1 : end_pos - start_pos); +} + /* Search after a record based on a key */ /* Sets info->current_ptr to found record */ /* next_flag: Search=0, next=1, prev =2, same =3 */ -byte *_hp_search(HP_INFO *info, HP_KEYDEF *keyinfo, const byte *key, +byte *hp_search(HP_INFO *info, HP_KEYDEF *keyinfo, const byte *key, uint nextflag) { reg1 HASH_INFO *pos,*prev_ptr; int flag; uint old_nextflag; HP_SHARE *share=info->s; - DBUG_ENTER("_hp_search"); - + DBUG_ENTER("hp_search"); old_nextflag=nextflag; flag=1; prev_ptr=0; if (share->records) { - pos=hp_find_hash(&keyinfo->block,_hp_mask(_hp_hashnr(keyinfo,key), - share->blength,share->records)); + pos=hp_find_hash(&keyinfo->block, hp_mask(hp_hashnr(keyinfo, key), + share->blength, share->records)); do { - if (!_hp_key_cmp(keyinfo,pos->ptr_to_rec,key)) + if (!hp_key_cmp(keyinfo, pos->ptr_to_rec, key)) { switch (nextflag) { case 0: /* Search after key */ @@ -74,8 +116,8 @@ byte *_hp_search(HP_INFO *info, HP_KEYDEF *keyinfo, const byte *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(hp_rec_hashnr(keyinfo, pos->ptr_to_rec), + share->blength, share->records)) != pos) break; /* Wrong link */ } } @@ -102,14 +144,14 @@ byte *_hp_search(HP_INFO *info, HP_KEYDEF *keyinfo, const byte *key, since last read ! */ -byte *_hp_search_next(HP_INFO *info, HP_KEYDEF *keyinfo, const byte *key, +byte *hp_search_next(HP_INFO *info, HP_KEYDEF *keyinfo, const byte *key, HASH_INFO *pos) { - DBUG_ENTER("_hp_search_next"); + DBUG_ENTER("hp_search_next"); while ((pos= pos->next_key)) { - if (!_hp_key_cmp(keyinfo,pos->ptr_to_rec,key)) + if (! hp_key_cmp(keyinfo, pos->ptr_to_rec, key)) { info->current_hash_ptr=pos; DBUG_RETURN (info->current_ptr= pos->ptr_to_rec); @@ -124,7 +166,7 @@ byte *_hp_search_next(HP_INFO *info, HP_KEYDEF *keyinfo, const byte *key, /* Calculate pos according to keys */ -ulong _hp_mask(ulong hashnr, ulong buffmax, ulong maxlength) +ulong hp_mask(ulong hashnr, ulong buffmax, ulong maxlength) { if ((hashnr & (buffmax-1)) < maxlength) return (hashnr & (buffmax-1)); return (hashnr & ((buffmax >> 1) -1)); @@ -133,7 +175,7 @@ ulong _hp_mask(ulong hashnr, ulong buffmax, ulong maxlength) /* Change link from pos to new_link */ -void _hp_movelink(HASH_INFO *pos, HASH_INFO *next_link, HASH_INFO *newlink) +void hp_movelink(HASH_INFO *pos, HASH_INFO *next_link, HASH_INFO *newlink) { HASH_INFO *old_link; do @@ -149,11 +191,11 @@ void _hp_movelink(HASH_INFO *pos, HASH_INFO *next_link, HASH_INFO *newlink) /* Calc hashvalue for a key */ -ulong _hp_hashnr(register HP_KEYDEF *keydef, register const byte *key) +ulong hp_hashnr(register HP_KEYDEF *keydef, register const byte *key) { /*register*/ ulong nr=1, nr2=4; - HP_KEYSEG *seg,*endseg; + MI_KEYSEG *seg,*endseg; for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) { @@ -196,11 +238,11 @@ ulong _hp_hashnr(register HP_KEYDEF *keydef, register const byte *key) /* Calc hashvalue for a key in a record */ -ulong _hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec) +ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec) { /*register*/ ulong nr=1, nr2=4; - HP_KEYSEG *seg,*endseg; + MI_KEYSEG *seg,*endseg; for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) { @@ -255,10 +297,10 @@ ulong _hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec) * far, and works well on both numbers and strings. */ -ulong _hp_hashnr(register HP_KEYDEF *keydef, register const byte *key) +ulong hp_hashnr(register HP_KEYDEF *keydef, register const byte *key) { register ulong nr=0; - HP_KEYSEG *seg,*endseg; + MI_KEYSEG *seg,*endseg; for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) { @@ -296,10 +338,10 @@ ulong _hp_hashnr(register HP_KEYDEF *keydef, register const byte *key) /* Calc hashvalue for a key in a record */ -ulong _hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec) +ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec) { register ulong nr=0; - HP_KEYSEG *seg,*endseg; + MI_KEYSEG *seg,*endseg; for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) { @@ -337,9 +379,9 @@ ulong _hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec) /* Compare keys for two records. Returns 0 if they are identical */ -int _hp_rec_key_cmp(HP_KEYDEF *keydef, const byte *rec1, const byte *rec2) +int hp_rec_key_cmp(HP_KEYDEF *keydef, const byte *rec1, const byte *rec2) { - HP_KEYSEG *seg,*endseg; + MI_KEYSEG *seg,*endseg; for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) { @@ -351,13 +393,14 @@ int _hp_rec_key_cmp(HP_KEYDEF *keydef, const byte *rec1, const byte *rec2) if (rec1[seg->null_pos] & seg->null_bit) continue; } - if (seg->type == HA_KEYTYPE_TEXT) - { + switch (seg->type) { + case HA_KEYTYPE_END: + return 0; + case HA_KEYTYPE_TEXT: if (my_sortcmp(default_charset_info,rec1+seg->start,rec2+seg->start,seg->length)) return 1; - } - else - { + break; + default: if (bcmp(rec1+seg->start,rec2+seg->start,seg->length)) return 1; } @@ -367,9 +410,9 @@ int _hp_rec_key_cmp(HP_KEYDEF *keydef, const byte *rec1, const byte *rec2) /* Compare a key in a record to a whole key */ -int _hp_key_cmp(HP_KEYDEF *keydef, const byte *rec, const byte *key) +int hp_key_cmp(HP_KEYDEF *keydef, const byte *rec, const byte *key) { - HP_KEYSEG *seg,*endseg; + MI_KEYSEG *seg,*endseg; for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; @@ -405,9 +448,9 @@ int _hp_key_cmp(HP_KEYDEF *keydef, const byte *rec, const byte *key) /* Copy a key from a record to a keybuffer */ -void _hp_make_key(HP_KEYDEF *keydef, byte *key, const byte *rec) +void hp_make_key(HP_KEYDEF *keydef, byte *key, const byte *rec) { - HP_KEYSEG *seg,*endseg; + MI_KEYSEG *seg,*endseg; for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) { @@ -418,7 +461,44 @@ void _hp_make_key(HP_KEYDEF *keydef, byte *key, const byte *rec) } } +void hp_rb_make_key(HP_KEYDEF *keydef, byte *key, + const byte *rec, byte *recpos) +{ + MI_KEYSEG *seg, *endseg; + + /* -1 means that HA_KEYTYPE_END segment will not copy */ + for (seg= keydef->seg, endseg= seg + keydef->keysegs - 1; seg < endseg; + seg++) + { + if (seg->null_bit) + *key++= 1 - test(rec[seg->null_pos] & seg->null_bit); + memcpy(key, rec + seg->start, (size_t) seg->length); + key+= seg->length; + } + memcpy(key, &recpos, sizeof(byte*)); +} +uint hp_rb_pack_key(HP_INFO *info, uint inx, uchar *key, const uchar *old, + uint k_length) +{ + MI_KEYSEG *seg, *endseg; + uchar *start_key= key; + HP_KEYDEF *keydef= info->s->keydef + inx; + + for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; + old+= seg->length, seg++) + { + if (seg->null_bit) + { + if (!(*key++= (char) 1 - *old++)) + continue; + } + memcpy((byte*) key, old, seg->length); + key+= seg->length; + } + return key - start_key; +} + /* Test if any of the key parts are NULL. Return: @@ -428,7 +508,7 @@ void _hp_make_key(HP_KEYDEF *keydef, byte *key, const byte *rec) my_bool hp_if_null_in_key(HP_KEYDEF *keydef, const byte *record) { - HP_KEYSEG *seg,*endseg; + MI_KEYSEG *seg,*endseg; for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) { if (seg->null_bit && (record[seg->null_pos] & seg->null_bit)) |