diff --git a/heap/hp_hash.c b/heap/hp_hash.c index 519779d330df0b256606fdc45334f4f742a73114..2ca33e5b78264d3c8c54e0fb93916183683d5689 100644 --- a/heap/hp_hash.c +++ b/heap/hp_hash.c @@ -151,7 +151,8 @@ void _hp_movelink(HASH_INFO *pos, HASH_INFO *next_link, HASH_INFO *newlink) ulong _hp_hashnr(register HP_KEYDEF *keydef, register const byte *key) { - register ulong nr=1, nr2=4; + /*register*/ + ulong nr=1, nr2=4; HP_KEYSEG *seg,*endseg; for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) @@ -170,6 +171,10 @@ ulong _hp_hashnr(register HP_KEYDEF *keydef, register const byte *key) } if (seg->type == HA_KEYTYPE_TEXT) { + if (default_charset_info->hash_sort) + default_charset_info->hash_sort(default_charset_info, + pos,((uchar*)key)-pos,&nr,&nr2); + else for (; pos < (uchar*) key ; pos++) { nr^=(ulong) ((((uint) nr & 63)+nr2) * @@ -193,7 +198,8 @@ ulong _hp_hashnr(register HP_KEYDEF *keydef, register const byte *key) ulong _hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec) { - register ulong nr=1, nr2=4; + /*register*/ + ulong nr=1, nr2=4; HP_KEYSEG *seg,*endseg; for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) @@ -209,6 +215,10 @@ ulong _hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec) } if (seg->type == HA_KEYTYPE_TEXT) { + if (default_charset_info->hash_sort) + default_charset_info->hash_sort(default_charset_info, + pos,end-pos,&nr,&nr2); + else for (; pos < end ; pos++) { nr^=(ulong) ((((uint) nr & 63)+nr2)* diff --git a/include/m_ctype.h b/include/m_ctype.h index d52f86430d29373312b6126a713f91924f77dfa9..6e116b9542851c21f7dd71ae75b99cfbb5c58c23 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -94,6 +94,8 @@ typedef struct charset_info_st /* Hash calculation */ uint (*hash_caseup)(struct charset_info_st *cs, const byte *key, uint len); + void (*hash_sort)(struct charset_info_st *cs, const uchar *key, uint len, ulong *nr1, ulong *nr2); + char max_sort_char; /* For LIKE otimization */ } CHARSET_INFO; @@ -279,7 +281,8 @@ int my_utf8_uni (CHARSET_INFO *cs, my_wc_t *p, const uchar *s, const uchar *e); int my_uni_utf8 (CHARSET_INFO *cs, my_wc_t wc, uchar *b, uchar *e); uint my_hash_caseup_utf8(struct charset_info_st *cs, const byte *key, uint len); - +void my_hash_sort_utf8(struct charset_info_st *cs, const uchar *key, uint len, ulong *nr1, ulong *nr2); + #endif #define _U 01 /* Upper case */ diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 62dcd9f6b877db4541b77ba476c93bce31ccbfe3..a4485e1ef503b18cdb90dae783a175e7abfe2e04 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -1754,6 +1754,26 @@ uint my_hash_caseup_utf8(CHARSET_INFO *cs, const byte *s, uint slen) return nr; } + +void my_hash_sort_utf8(CHARSET_INFO *cs, const uchar *s, uint slen, ulong *n1, ulong *n2) +{ + my_wc_t wc; + int res; + const uchar *e=s+slen; + + while ((s < e) && (res=my_utf8_uni(cs,&wc, (uchar *)s, (uchar*)e))>0 ) + { + int plane = (wc>>8) & 0xFF; + wc = uni_plane[plane] ? uni_plane[plane][wc & 0xFF].sort : wc; + n1[0]^= (((n1[0] & 63)+n2[0])*(wc & 0xFF))+ (n1[0] << 8); + n2[0]+=3; + n1[0]^= (((n1[0] & 63)+n2[0])*(wc >> 8))+ (n1[0] << 8); + n2[0]+=3; + s+=res; + } +} + + void my_caseup_str_utf8(CHARSET_INFO * cs, char * s) { my_caseup_utf8(cs, s, strlen(s)); diff --git a/strings/ctype.c b/strings/ctype.c index c4fb6f1388d5d146e261783c8b88c3398c11c381..0c20db35da217999aacfe198934c75e95c757e28 100644 --- a/strings/ctype.c +++ b/strings/ctype.c @@ -2830,6 +2830,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -2861,6 +2862,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_mb, my_strncasecmp_mb, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -2892,6 +2894,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -2923,6 +2926,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -2954,6 +2958,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -2985,6 +2990,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3016,6 +3022,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3047,6 +3054,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3078,6 +3086,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3109,6 +3118,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3140,6 +3150,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_mb, my_strncasecmp_mb, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3171,6 +3182,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_mb, my_strncasecmp_mb, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3202,6 +3214,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_mb, my_strncasecmp_mb, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3233,6 +3246,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3264,6 +3278,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3295,6 +3310,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3326,6 +3342,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3357,6 +3374,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3388,6 +3406,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3419,6 +3438,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3450,6 +3470,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3481,6 +3502,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3512,6 +3534,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3543,6 +3566,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3574,6 +3598,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3605,6 +3630,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3636,6 +3662,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_mb, my_strncasecmp_mb, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3667,6 +3694,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_utf8, my_strncasecmp_utf8, my_hash_caseup_utf8,/* hash_caseup */ + my_hash_sort_utf8, /* hash_sort */ 0 }, #endif @@ -3698,6 +3726,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3729,6 +3758,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3760,6 +3790,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3791,6 +3822,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3822,6 +3854,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3853,6 +3886,7 @@ CHARSET_INFO compiled_charsets[] = { my_strcasecmp_8bit, my_strncasecmp_8bit, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 }, #endif @@ -3885,6 +3919,7 @@ CHARSET_INFO compiled_charsets[] = { NULL, NULL, NULL, /* hash_caseup */ + NULL, /* hash_sort */ 0 } };