28
28
using namespace drizzled;
30
31
static uint32_t hp_hashnr(register HP_KEYDEF *keydef, register const unsigned char *key);
31
32
static int hp_key_cmp(HP_KEYDEF *keydef, const unsigned char *rec, const unsigned char *key);
34
Find out how many rows there is in the given range
37
hp_rb_records_in_range()
40
min_key Min key. Is = 0 if no min range
41
max_key Max key. Is = 0 if no max range
44
min_key.flag can have one of the following values:
45
HA_READ_KEY_EXACT Include the key in the range
46
HA_READ_AFTER_KEY Don't include key in range
48
max_key.flag can have one of the following values:
49
HA_READ_BEFORE_KEY Don't include key in range
50
HA_READ_AFTER_KEY Include all 'end_key' values in the range
53
HA_POS_ERROR Something is wrong with the index tree.
54
0 There is no matching keys in the given range
55
number > 0 There is approximately 'number' matching rows in
59
ha_rows hp_rb_records_in_range(HP_INFO *info, int inx, key_range *min_key,
62
ha_rows start_pos, end_pos;
63
HP_KEYDEF *keyinfo= info->s->keydef + inx;
64
TREE *rb_tree = &keyinfo->rb_tree;
65
heap_rb_param custom_arg;
68
custom_arg.keyseg= keyinfo->seg;
69
custom_arg.search_flag= SEARCH_FIND | SEARCH_SAME;
72
custom_arg.key_length= hp_rb_pack_key(keyinfo, (unsigned char*) info->recbuf,
73
(unsigned char*) min_key->key,
74
min_key->keypart_map);
75
start_pos= tree_record_pos(rb_tree, info->recbuf, min_key->flag,
85
custom_arg.key_length= hp_rb_pack_key(keyinfo, (unsigned char*) info->recbuf,
86
(unsigned char*) max_key->key,
87
max_key->keypart_map);
88
end_pos= tree_record_pos(rb_tree, info->recbuf, max_key->flag,
93
end_pos= rb_tree->elements_in_tree + (ha_rows)1;
96
if (start_pos == HA_POS_ERROR || end_pos == HA_POS_ERROR)
98
return(end_pos < start_pos ? (ha_rows) 0 :
99
(end_pos == start_pos ? (ha_rows) 1 : end_pos - start_pos));
103
35
/* Search after a record based on a key */
104
36
/* Sets info->current_ptr to found record */
579
511
set_if_smaller(char_length,length); \
583
uint32_t hp_rb_make_key(HP_KEYDEF *keydef, unsigned char *key,
584
const unsigned char *rec, unsigned char *recpos)
586
unsigned char *start_key= key;
587
HA_KEYSEG *seg, *endseg;
589
for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++)
591
uint32_t char_length;
594
if (!(*key++= 1 - test(rec[seg->null_pos] & seg->null_bit)))
597
if (seg->flag & HA_SWAP_KEY)
599
uint32_t length= seg->length;
600
unsigned char *pos= (unsigned char*) rec + seg->start;
602
if (seg->type == HA_KEYTYPE_DOUBLE)
608
memset(key, 0, length);
621
if (seg->flag & HA_VAR_LENGTH_PART)
623
unsigned char *pos= (unsigned char*) rec + seg->start;
624
uint32_t length= seg->length;
625
uint32_t pack_length= seg->bit_start;
626
uint32_t tmp_length= (pack_length == 1 ? (uint) *(unsigned char*) pos :
628
const CHARSET_INFO * const cs= seg->charset;
629
char_length= length/cs->mbmaxlen;
631
pos+= pack_length; /* Skip VARCHAR length */
632
set_if_smaller(length,tmp_length);
633
FIX_LENGTH(cs, pos, length, char_length);
634
store_key_length_inc(key,char_length);
635
memcpy(key,pos,(size_t) char_length);
640
char_length= seg->length;
641
if (seg->charset->mbmaxlen > 1)
643
char_length= my_charpos(seg->charset,
644
rec + seg->start, rec + seg->start + char_length,
645
char_length / seg->charset->mbmaxlen);
646
set_if_smaller(char_length, (uint32_t)seg->length); /* QQ: ok to remove? */
647
if (char_length < seg->length)
648
seg->charset->cset->fill(seg->charset, (char*) key + char_length,
649
seg->length - char_length, ' ');
651
memcpy(key, rec + seg->start, (size_t) char_length);
654
memcpy(key, &recpos, sizeof(unsigned char*));
655
return (uint32_t) (key - start_key);
659
uint32_t hp_rb_pack_key(HP_KEYDEF *keydef, unsigned char *key, const unsigned char *old,
660
key_part_map keypart_map)
662
HA_KEYSEG *seg, *endseg;
663
unsigned char *start_key= key;
665
for (seg= keydef->seg, endseg= seg + keydef->keysegs;
666
seg < endseg && keypart_map; old+= seg->length, seg++)
668
uint32_t char_length;
672
if (!(*key++= (char) 1 - *old++))
675
if (seg->flag & HA_SWAP_KEY)
677
uint32_t length= seg->length;
678
unsigned char *pos= (unsigned char*) old + length;
686
if (seg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
688
/* Length of key-part used with heap_rkey() always 2 */
689
uint32_t tmp_length=uint2korr(old);
690
uint32_t length= seg->length;
691
const CHARSET_INFO * const cs= seg->charset;
692
char_length= length/cs->mbmaxlen;
695
set_if_smaller(length,tmp_length); /* Safety */
696
FIX_LENGTH(cs, old, length, char_length);
697
store_key_length_inc(key,char_length);
698
memcpy(key, old,(size_t) char_length);
702
char_length= seg->length;
703
if (seg->charset->mbmaxlen > 1)
705
char_length= my_charpos(seg->charset, old, old+char_length,
706
char_length / seg->charset->mbmaxlen);
707
set_if_smaller(char_length, (uint32_t)seg->length); /* QQ: ok to remove? */
708
if (char_length < seg->length)
709
seg->charset->cset->fill(seg->charset, (char*) key + char_length,
710
seg->length - char_length, ' ');
712
memcpy(key, old, (size_t) char_length);
715
return (uint) (key - start_key);
719
uint32_t hp_rb_key_length(HP_KEYDEF *keydef, const unsigned char *not_used)
722
return keydef->length;
726
uint32_t hp_rb_null_key_length(HP_KEYDEF *keydef, const unsigned char *key)
728
const unsigned char *start_key= key;
729
HA_KEYSEG *seg, *endseg;
731
for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++)
733
if (seg->null_bit && !*key++)
737
return (uint) (key - start_key);
741
uint32_t hp_rb_var_key_length(HP_KEYDEF *keydef, const unsigned char *key)
743
const unsigned char *start_key= key;
744
HA_KEYSEG *seg, *endseg;
746
for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++)
748
uint32_t length= seg->length;
749
if (seg->null_bit && !*key++)
751
if (seg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
753
get_key_length(length, key);
757
return (uint) (key - start_key);
762
515
Test if any of the key parts are NULL.