52 ha_rows start_pos, end_pos;
53 HP_KEYDEF *keyinfo= info->s->keydef + inx;
54 TREE *rb_tree = &keyinfo->rb_tree;
56 DBUG_ENTER(
"hp_rb_records_in_range");
59 custom_arg.keyseg= keyinfo->seg;
60 custom_arg.search_flag= SEARCH_FIND | SEARCH_SAME;
63 custom_arg.key_length= hp_rb_pack_key(keyinfo, (uchar*) info->recbuf,
64 (uchar*) min_key->key,
65 min_key->keypart_map);
66 start_pos= tree_record_pos(rb_tree, info->recbuf, min_key->flag,
76 custom_arg.key_length= hp_rb_pack_key(keyinfo, (uchar*) info->recbuf,
77 (uchar*) max_key->key,
78 max_key->keypart_map);
79 end_pos= tree_record_pos(rb_tree, info->recbuf, max_key->flag,
84 end_pos= rb_tree->elements_in_tree + (ha_rows)1;
87 DBUG_PRINT(
"info",(
"start_pos: %lu end_pos: %lu", (ulong) start_pos,
89 if (start_pos == HA_POS_ERROR || end_pos == HA_POS_ERROR)
90 DBUG_RETURN(HA_POS_ERROR);
91 DBUG_RETURN(end_pos < start_pos ? (ha_rows) 0 :
92 (end_pos == start_pos ? (ha_rows) 1 : end_pos - start_pos));
107 DBUG_ENTER(
"hp_search");
108 old_nextflag=nextflag;
114 pos=hp_find_hash(&keyinfo->block, hp_mask(hp_hashnr(keyinfo, key),
115 share->blength, share->records));
118 if (!hp_key_cmp(keyinfo, pos->ptr_to_rec, key))
122 DBUG_PRINT(
"exit", (
"found key at 0x%lx", (
long) pos->ptr_to_rec));
123 info->current_hash_ptr=pos;
124 DBUG_RETURN(info->current_ptr= pos->ptr_to_rec);
126 if (pos->ptr_to_rec == info->current_ptr)
130 if (pos->ptr_to_rec == info->current_ptr)
132 my_errno=HA_ERR_KEY_NOT_FOUND;
133 info->current_hash_ptr=prev_ptr;
134 DBUG_RETURN(info->current_ptr=prev_ptr ? prev_ptr->ptr_to_rec : 0);
139 if (pos->ptr_to_rec == info->current_ptr)
141 info->current_hash_ptr=pos;
142 DBUG_RETURN(info->current_ptr);
149 if (hp_find_hash(&keyinfo->block,
150 hp_mask(hp_rec_hashnr(keyinfo, pos->ptr_to_rec),
151 share->blength, share->records)) != pos)
155 while ((pos=pos->next_key));
157 my_errno=HA_ERR_KEY_NOT_FOUND;
158 if (nextflag == 2 && ! info->current_ptr)
161 info->current_hash_ptr=prev_ptr;
162 DBUG_RETURN(info->current_ptr=prev_ptr ? prev_ptr->ptr_to_rec : 0);
165 if (old_nextflag && nextflag)
166 my_errno=HA_ERR_RECORD_CHANGED;
167 DBUG_PRINT(
"exit",(
"Error: %d",my_errno));
168 info->current_hash_ptr=0;
169 DBUG_RETURN((info->current_ptr= 0));
181 DBUG_ENTER(
"hp_search_next");
183 while ((pos= pos->next_key))
185 if (! hp_key_cmp(keyinfo, pos->ptr_to_rec, key))
187 info->current_hash_ptr=pos;
188 DBUG_RETURN (info->current_ptr= pos->ptr_to_rec);
191 my_errno=HA_ERR_KEY_NOT_FOUND;
192 DBUG_PRINT(
"exit",(
"Error: %d",my_errno));
193 info->current_hash_ptr=0;
194 DBUG_RETURN ((info->current_ptr= 0));
211 ulong hp_mask(ulong hashnr, ulong buffmax, ulong maxlength)
213 if ((hashnr & (buffmax-1)) < maxlength)
return (hashnr & (buffmax-1));
214 return (hashnr & ((buffmax >> 1) -1));
232 while ((next_link=next_link->next_key) != pos);
233 old_link->next_key=newlink;
237 #ifndef NEW_HASH_FUNCTION
241 ulong hp_hashnr(
register HP_KEYDEF *keydef,
register const uchar *key)
247 for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
249 uchar *pos=(uchar*) key;
258 if (seg->type == HA_KEYTYPE_VARTEXT1)
264 if (seg->type == HA_KEYTYPE_TEXT)
267 uint length= seg->length;
268 if (cs->mbmaxlen > 1)
271 char_length= my_charpos(cs, pos, pos + length, length/cs->mbmaxlen);
272 set_if_smaller(length, char_length);
274 cs->coll->hash_sort(cs, pos, length, &nr, &nr2);
276 else if (seg->type == HA_KEYTYPE_VARTEXT1)
280 uint length= uint2korr(pos);
281 if (cs->mbmaxlen > 1)
284 char_length= my_charpos(cs, pos +pack_length,
285 pos +pack_length + length,
286 seg->length/cs->mbmaxlen);
287 set_if_smaller(length, char_length);
289 cs->coll->hash_sort(cs, pos+pack_length, length, &nr, &nr2);
294 for (; pos < (uchar*) key ; pos++)
296 nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) *pos)) + (nr << 8);
301 DBUG_PRINT(
"exit", (
"hash: 0x%lx", nr));
307 ulong hp_rec_hashnr(
register HP_KEYDEF *keydef,
register const uchar *
rec)
312 for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
314 uchar *pos=(uchar*) rec+seg->start,*end=pos+seg->length;
317 if (rec[seg->null_pos] & seg->null_bit)
323 if (seg->type == HA_KEYTYPE_TEXT)
326 uint char_length= seg->length;
327 if (cs->mbmaxlen > 1)
329 char_length= my_charpos(cs, pos, pos + char_length,
330 char_length / cs->mbmaxlen);
331 set_if_smaller(char_length, seg->length);
333 cs->coll->hash_sort(cs, pos, char_length, &nr, &nr2);
335 else if (seg->type == HA_KEYTYPE_VARTEXT1)
338 uint pack_length= seg->bit_start;
339 uint length= (pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos));
340 if (cs->mbmaxlen > 1)
343 char_length= my_charpos(cs, pos + pack_length,
344 pos + pack_length + length,
345 seg->length/cs->mbmaxlen);
346 set_if_smaller(length, char_length);
348 cs->coll->hash_sort(cs, pos+pack_length, length, &nr, &nr2);
352 for (; pos < end ; pos++)
354 nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) *pos))+ (nr << 8);
359 DBUG_PRINT(
"exit", (
"hash: 0x%lx", nr));
380 ulong hp_hashnr(
register HP_KEYDEF *keydef,
register const uchar *key)
391 for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
393 uchar *pos=(uchar*) key;
402 if (seg->type == HA_KEYTYPE_VARTEXT1)
408 if (seg->type == HA_KEYTYPE_TEXT)
410 seg->charset->coll->hash_sort(seg->charset, pos, ((uchar*)key)-pos,
413 else if (seg->type == HA_KEYTYPE_VARTEXT1)
416 uint length= uint2korr(pos);
417 seg->charset->coll->hash_sort(seg->charset, pos+pack_length, length,
423 for ( ; pos < (uchar*) key ; pos++)
430 DBUG_PRINT(
"exit", (
"hash: 0x%lx", nr));
436 ulong hp_rec_hashnr(
register HP_KEYDEF *keydef,
register const uchar *rec)
441 for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
443 uchar *pos=(uchar*) rec+seg->start;
446 if (rec[seg->null_pos] & seg->null_bit)
452 if (seg->type == HA_KEYTYPE_TEXT)
454 uint char_length= seg->length;
455 seg->charset->coll->hash_sort(seg->charset, pos, char_length,
458 else if (seg->type == HA_KEYTYPE_VARTEXT1)
460 uint pack_length= seg->bit_start;
461 uint length= (pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos));
462 seg->charset->coll->hash_sort(seg->charset, pos+pack_length,
467 uchar *end= pos+seg->length;
468 for ( ; pos < end ; pos++)
475 DBUG_PRINT(
"exit", (
"hash: 0x%lx", nr));
502 int hp_rec_key_cmp(
HP_KEYDEF *keydef,
const uchar *rec1,
const uchar *
rec2,
503 my_bool diff_if_only_endspace_difference)
507 for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
511 if ((rec1[seg->null_pos] & seg->null_bit) !=
512 (rec2[seg->null_pos] & seg->null_bit))
514 if (rec1[seg->null_pos] & seg->null_bit)
517 if (seg->type == HA_KEYTYPE_TEXT)
522 uchar *pos1= (uchar*)rec1 + seg->start;
523 uchar *pos2= (uchar*)rec2 + seg->start;
524 if (cs->mbmaxlen > 1)
526 uint char_length= seg->length / cs->mbmaxlen;
527 char_length1= my_charpos(cs, pos1, pos1 + seg->length, char_length);
528 set_if_smaller(char_length1, seg->length);
529 char_length2= my_charpos(cs, pos2, pos2 + seg->length, char_length);
530 set_if_smaller(char_length2, seg->length);
534 char_length1= char_length2= seg->length;
536 if (seg->charset->coll->strnncollsp(seg->charset,
538 pos2,char_length2, 0))
541 else if (seg->type == HA_KEYTYPE_VARTEXT1)
543 uchar *pos1= (uchar*) rec1 + seg->start;
544 uchar *pos2= (uchar*) rec2 + seg->start;
545 uint char_length1, char_length2;
546 uint pack_length= seg->bit_start;
548 if (pack_length == 1)
550 char_length1= (uint) *(uchar*) pos1++;
551 char_length2= (uint) *(uchar*) pos2++;
555 char_length1= uint2korr(pos1);
556 char_length2= uint2korr(pos2);
560 if (cs->mbmaxlen > 1)
562 uint safe_length1= char_length1;
563 uint safe_length2= char_length2;
564 uint char_length= seg->length / cs->mbmaxlen;
565 char_length1= my_charpos(cs, pos1, pos1 + char_length1, char_length);
566 set_if_smaller(char_length1, safe_length1);
567 char_length2= my_charpos(cs, pos2, pos2 + char_length2, char_length);
568 set_if_smaller(char_length2, safe_length2);
571 if (cs->coll->strnncollsp(seg->charset,
574 seg->flag & HA_END_SPACE_ARE_EQUAL ?
575 0 : diff_if_only_endspace_difference))
580 if (memcmp(rec1+seg->start,rec2+seg->start,seg->length))
589 int hp_key_cmp(
HP_KEYDEF *keydef,
const uchar *rec,
const uchar *key)
593 for (seg=keydef->seg,endseg=seg+keydef->keysegs ;
595 key+= (seg++)->length)
599 int found_null=
test(rec[seg->null_pos] & seg->null_bit);
600 if (found_null != (
int) *key++)
605 if (seg->type == HA_KEYTYPE_VARTEXT1)
610 if (seg->type == HA_KEYTYPE_TEXT)
613 uint char_length_key;
614 uint char_length_rec;
615 uchar *pos= (uchar*) rec + seg->start;
616 if (cs->mbmaxlen > 1)
618 uint char_length= seg->length / cs->mbmaxlen;
619 char_length_key= my_charpos(cs, key, key + seg->length, char_length);
620 set_if_smaller(char_length_key, seg->length);
621 char_length_rec= my_charpos(cs, pos, pos + seg->length, char_length);
622 set_if_smaller(char_length_rec, seg->length);
626 char_length_key= seg->length;
627 char_length_rec= seg->length;
630 if (seg->charset->coll->strnncollsp(seg->charset,
631 (uchar*) pos, char_length_rec,
632 (uchar*) key, char_length_key, 0))
635 else if (seg->type == HA_KEYTYPE_VARTEXT1)
637 uchar *pos= (uchar*) rec + seg->start;
639 uint pack_length= seg->bit_start;
640 uint char_length_rec= (pack_length == 1 ? (uint) *(uchar*) pos :
643 uint char_length_key= uint2korr(key);
646 if (cs->mbmaxlen > 1)
648 uint char_length1, char_length2;
649 char_length1= char_length2= seg->length / cs->mbmaxlen;
650 char_length1= my_charpos(cs, key, key + char_length_key, char_length1);
651 set_if_smaller(char_length_key, char_length1);
652 char_length2= my_charpos(cs, pos, pos + char_length_rec, char_length2);
653 set_if_smaller(char_length_rec, char_length2);
657 set_if_smaller(char_length_rec, seg->length);
660 if (cs->coll->strnncollsp(seg->charset,
661 (uchar*) pos, char_length_rec,
662 (uchar*) key, char_length_key, 0))
667 if (memcmp(rec+seg->start,key,seg->length))
677 void hp_make_key(
HP_KEYDEF *keydef, uchar *key,
const uchar *rec)
681 for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
684 uint char_length= seg->length;
685 uchar *pos= (uchar*) rec + seg->start;
687 *key++=
test(rec[seg->null_pos] & seg->null_bit);
688 if (cs->mbmaxlen > 1)
690 char_length= my_charpos(cs, pos, pos + seg->length,
691 char_length / cs->mbmaxlen);
692 set_if_smaller(char_length, seg->length);
694 if (seg->type == HA_KEYTYPE_VARTEXT1)
695 char_length+= seg->bit_start;
696 memcpy(key,rec+seg->start,(
size_t) char_length);
701 #define FIX_LENGTH(cs, pos, length, char_length) \
703 if (length > char_length) \
704 char_length= my_charpos(cs, pos, pos+length, char_length); \
705 set_if_smaller(char_length,length); \
709 uint hp_rb_make_key(
HP_KEYDEF *keydef, uchar *key,
710 const uchar *rec, uchar *recpos)
712 uchar *start_key= key;
715 for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++)
720 if (!(*key++= 1 -
test(rec[seg->null_pos] & seg->null_bit)))
723 if (seg->flag & HA_SWAP_KEY)
725 uint length= seg->length;
726 uchar *pos= (uchar*) rec + seg->start;
729 if (seg->type == HA_KEYTYPE_FLOAT)
736 memset(key, 0, length);
741 else if (seg->type == HA_KEYTYPE_DOUBLE)
747 memset(key, 0, length);
761 if (seg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
763 uchar *pos= (uchar*) rec + seg->start;
764 uint length= seg->length;
765 uint pack_length= seg->bit_start;
766 uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos :
769 char_length= length/cs->mbmaxlen;
772 set_if_smaller(length,tmp_length);
773 FIX_LENGTH(cs, pos, length, char_length);
774 store_key_length_inc(key,char_length);
775 memcpy((uchar*) key,(uchar*) pos,(
size_t) char_length);
780 char_length= seg->length;
781 if (seg->charset->mbmaxlen > 1)
783 char_length= my_charpos(seg->charset,
784 rec + seg->start, rec + seg->start + char_length,
785 char_length / seg->charset->mbmaxlen);
786 set_if_smaller(char_length, seg->length);
787 if (char_length < seg->length)
788 seg->charset->cset->fill(seg->charset, (
char*) key + char_length,
789 seg->length - char_length,
' ');
791 memcpy(key, rec + seg->start, (
size_t) char_length);
794 memcpy(key, &recpos,
sizeof(uchar*));
795 return (uint) (key - start_key);
799 uint hp_rb_pack_key(
HP_KEYDEF *keydef, uchar *key,
const uchar *old,
800 key_part_map keypart_map)
803 uchar *start_key= key;
805 for (seg= keydef->seg, endseg= seg + keydef->keysegs;
806 seg < endseg && keypart_map; old+= seg->length, seg++)
813 if (!(*key++= (
char) 1 - *old++))
820 if (seg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
825 if (seg->flag & HA_SWAP_KEY)
827 uint length= seg->length;
828 uchar *pos= (uchar*) old + length;
836 if (seg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
839 uint tmp_length=uint2korr(old);
840 uint length= seg->length;
842 char_length= length/cs->mbmaxlen;
845 set_if_smaller(length,tmp_length);
846 FIX_LENGTH(cs, old, length, char_length);
847 store_key_length_inc(key,char_length);
848 memcpy((uchar*) key, old,(
size_t) char_length);
852 char_length= seg->length;
853 if (seg->charset->mbmaxlen > 1)
855 char_length= my_charpos(seg->charset, old, old+char_length,
856 char_length / seg->charset->mbmaxlen);
857 set_if_smaller(char_length, seg->length);
858 if (char_length < seg->length)
859 seg->charset->cset->fill(seg->charset, (
char*) key + char_length,
860 seg->length - char_length,
' ');
862 memcpy(key, old, (
size_t) char_length);
865 return (uint) (key - start_key);
870 const uchar *key __attribute__((unused)))
872 return keydef->length;
876 uint hp_rb_null_key_length(
HP_KEYDEF *keydef,
const uchar *key)
878 const uchar *start_key= key;
881 for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++)
883 if (seg->null_bit && !*key++)
887 return (uint) (key - start_key);
891 uint hp_rb_var_key_length(
HP_KEYDEF *keydef,
const uchar *key)
893 const uchar *start_key= key;
896 for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++)
898 uint length= seg->length;
899 if (seg->null_bit && !*key++)
901 if (seg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
903 get_key_length(length, key);
907 return (uint) (key - start_key);
921 for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
923 if (seg->null_bit && (record[seg->null_pos] & seg->null_bit))
944 void heap_update_auto_increment(
HP_INFO *info,
const uchar *record)
949 HA_KEYSEG *keyseg= info->s->keydef[info->s->auto_key - 1].seg;
950 const uchar *key= (uchar*) record + keyseg->start;
952 switch (info->s->auto_key_type) {
953 case HA_KEYTYPE_INT8:
954 s_value= (longlong) *(
char*)key;
956 case HA_KEYTYPE_BINARY:
957 value=(ulonglong) *(uchar*) key;
959 case HA_KEYTYPE_SHORT_INT:
960 s_value= (longlong) sint2korr(key);
962 case HA_KEYTYPE_USHORT_INT:
963 value=(ulonglong) uint2korr(key);
965 case HA_KEYTYPE_LONG_INT:
966 s_value= (longlong) sint4korr(key);
968 case HA_KEYTYPE_ULONG_INT:
969 value=(ulonglong) uint4korr(key);
971 case HA_KEYTYPE_INT24:
972 s_value= (longlong) sint3korr(key);
974 case HA_KEYTYPE_UINT24:
975 value=(ulonglong) uint3korr(key);
977 case HA_KEYTYPE_FLOAT:
982 value = (f_1 < (float) 0.0) ? 0 : (ulonglong) f_1;
985 case HA_KEYTYPE_DOUBLE:
990 value = (f_1 < 0.0) ? 0 : (ulonglong) f_1;
993 case HA_KEYTYPE_LONGLONG:
994 s_value= sint8korr(key);
996 case HA_KEYTYPE_ULONGLONG:
997 value= uint8korr(key);
1010 set_if_bigger(info->s->auto_increment,
1011 (s_value > 0) ? (ulonglong) s_value : value);