16
16
/* The hash functions used for saveing keys */
18
#include "heap_priv.h"
20
#include "drizzled/charset_info.h"
20
#include <mystrings/m_ctype.h>
21
21
#include <drizzled/util/test.h>
24
23
#include <string.h>
28
using namespace drizzled;
30
static uint32_t hp_hashnr(register HP_KEYDEF *keydef, register const unsigned char *key);
31
static int hp_key_cmp(HP_KEYDEF *keydef, const unsigned char *rec, const unsigned char *key);
34
26
Find out how many rows there is in the given range
327
321
char_length= my_charpos(cs, pos, pos + char_length,
328
322
char_length / cs->mbmaxlen);
329
set_if_smaller(char_length, (uint32_t)seg->length); /* QQ: ok to remove? */
323
set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */
331
325
cs->coll->hash_sort(cs, pos, char_length, &nr, &nr2);
357
* Fowler/Noll/Vo hash
359
* The basis of the hash algorithm was taken from an idea sent by email to the
360
* IEEE Posix P1003.2 mailing list from Phong Vo (kpv@research.att.com) and
361
* Glenn Fowler (gsf@research.att.com). Landon Curt Noll (chongo@toad.com)
362
* later improved on their algorithm.
364
* The magic is in the interesting relationship between the special prime
365
* 16777619 (2^24 + 403) and 2^32 and 2^8.
367
* This hash produces the fewest collisions of any function that we've seen so
368
* far, and works well on both numbers and strings.
371
uint32_t hp_hashnr(register HP_KEYDEF *keydef, register const unsigned char *key)
374
Note, if a key consists of a combination of numeric and
375
a text columns, it most likely won't work well.
376
Making text columns work with NEW_HASH_FUNCTION
377
needs also changes in strings/ctype-xxx.c.
379
uint32_t nr= 1, nr2= 4;
380
HA_KEYSEG *seg,*endseg;
382
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
384
unsigned char *pos=(unsigned char*) key;
392
/* Add key pack length (2) to key for VARCHAR segments */
393
if (seg->type == HA_KEYTYPE_VARTEXT1)
399
if (seg->type == HA_KEYTYPE_TEXT)
401
seg->charset->coll->hash_sort(seg->charset, pos, ((unsigned char*)key)-pos,
404
else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */
406
uint32_t pack_length= 2; /* Key packing is constant */
407
uint32_t length= uint2korr(pos);
408
seg->charset->coll->hash_sort(seg->charset, pos+pack_length, length,
414
for ( ; pos < (unsigned char*) key ; pos++)
424
/* Calc hashvalue for a key in a record */
426
uint32_t hp_rec_hashnr(register HP_KEYDEF *keydef, register const unsigned char *rec)
428
uint32_t nr= 1, nr2= 4;
429
HA_KEYSEG *seg,*endseg;
431
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
433
unsigned char *pos=(unsigned char*) rec+seg->start;
436
if (rec[seg->null_pos] & seg->null_bit)
442
if (seg->type == HA_KEYTYPE_TEXT)
444
uint32_t char_length= seg->length; /* TODO: fix to use my_charpos() */
445
seg->charset->coll->hash_sort(seg->charset, pos, char_length,
448
else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */
450
uint32_t pack_length= seg->bit_start;
451
uint32_t length= (pack_length == 1 ? (uint) *(unsigned char*) pos : uint2korr(pos));
452
seg->charset->coll->hash_sort(seg->charset, pos+pack_length,
457
unsigned char *end= pos+seg->length;
458
for ( ; pos < end ; pos++)
361
472
Compare keys for two records. Returns 0 if they are identical
404
515
uint32_t char_length= seg->length / cs->mbmaxlen;
405
516
char_length1= my_charpos(cs, pos1, pos1 + seg->length, char_length);
406
set_if_smaller(char_length1, (uint32_t)seg->length);
517
set_if_smaller(char_length1, seg->length);
407
518
char_length2= my_charpos(cs, pos2, pos2 + seg->length, char_length);
408
set_if_smaller(char_length2, (uint32_t)seg->length);
519
set_if_smaller(char_length2, seg->length);
496
607
uint32_t char_length= seg->length / cs->mbmaxlen;
497
608
char_length_key= my_charpos(cs, key, key + seg->length, char_length);
498
set_if_smaller(char_length_key, (uint32_t)seg->length);
609
set_if_smaller(char_length_key, seg->length);
499
610
char_length_rec= my_charpos(cs, pos, pos + seg->length, char_length);
500
set_if_smaller(char_length_rec, (uint32_t)seg->length);
611
set_if_smaller(char_length_rec, seg->length);
564
675
char_length= my_charpos(cs, pos, pos + seg->length,
565
676
char_length / cs->mbmaxlen);
566
set_if_smaller(char_length, (uint32_t)seg->length); /* QQ: ok to remove? */
677
set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */
568
679
if (seg->type == HA_KEYTYPE_VARTEXT1)
569
680
char_length+= seg->bit_start; /* Copy also length */
643
768
char_length= my_charpos(seg->charset,
644
769
rec + seg->start, rec + seg->start + char_length,
645
770
char_length / seg->charset->mbmaxlen);
646
set_if_smaller(char_length, (uint32_t)seg->length); /* QQ: ok to remove? */
771
set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */
647
772
if (char_length < seg->length)
648
773
seg->charset->cset->fill(seg->charset, (char*) key + char_length,
649
774
seg->length - char_length, ' ');
705
830
char_length= my_charpos(seg->charset, old, old+char_length,
706
831
char_length / seg->charset->mbmaxlen);
707
set_if_smaller(char_length, (uint32_t)seg->length); /* QQ: ok to remove? */
832
set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */
708
833
if (char_length < seg->length)
709
834
seg->charset->cset->fill(seg->charset, (char*) key + char_length,
710
835
seg->length - char_length, ' ');
800
925
const unsigned char *key= (unsigned char*) record + keyseg->start;
802
927
switch (info->s->auto_key_type) {
928
case HA_KEYTYPE_INT8:
929
s_value= (int64_t) *(char*)key;
803
931
case HA_KEYTYPE_BINARY:
804
932
value=(uint64_t) *(unsigned char*) key;
934
case HA_KEYTYPE_SHORT_INT:
935
s_value= (int64_t) sint2korr(key);
937
case HA_KEYTYPE_USHORT_INT:
938
value=(uint64_t) uint2korr(key);
806
940
case HA_KEYTYPE_LONG_INT:
807
941
s_value= (int64_t) sint4korr(key);
809
943
case HA_KEYTYPE_ULONG_INT:
810
944
value=(uint64_t) uint4korr(key);
946
case HA_KEYTYPE_INT24:
947
s_value= (int64_t) sint3korr(key);
812
949
case HA_KEYTYPE_UINT24:
813
950
value=(uint64_t) uint3korr(key);
952
case HA_KEYTYPE_FLOAT: /* This shouldn't be used */
956
/* Ignore negative values */
957
value = (f_1 < (float) 0.0) ? 0 : (uint64_t) f_1;
815
960
case HA_KEYTYPE_DOUBLE: /* This shouldn't be used */