ulong hp_rec_hashnr(HP_KEYDEF *keydef, const uchar *rec) { ulong nr=1, nr2=4; HA_KEYSEG *seg,*endseg; for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) { uchar *pos=(uchar*) rec+seg->start,*end=pos+seg->length; if (seg->null_bit) { if (rec[seg->null_pos] & seg->null_bit) { nr^= (nr << 1) | 1; continue; } } if (seg->type == HA_KEYTYPE_TEXT) { const CHARSET_INFO *cs= seg->charset; size_t char_length= seg->length; if (cs->mbmaxlen > 1) { char_length= my_charpos(cs, pos, pos + char_length, char_length / cs->mbmaxlen); set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */ } cs->coll->hash_sort(cs, pos, char_length, &nr, &nr2); } else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */ { const CHARSET_INFO *cs= seg->charset; uint pack_length= seg->bit_start; size_t length= (pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos)); if (cs->mbmaxlen > 1) { size_t char_length; char_length= my_charpos(cs, pos + pack_length, pos + pack_length + length, seg->length/cs->mbmaxlen); set_if_smaller(length, char_length); } cs->coll->hash_sort(cs, pos+pack_length, length, &nr, &nr2); } else { for (; pos < end ; pos++) { nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) *pos))+ (nr << 8); nr2+=3; } } } DBUG_PRINT("exit", ("hash: 0x%lx", nr)); return(nr); }
void hp_make_key(HP_KEYDEF *keydef, uchar *key, const uchar *rec) { HA_KEYSEG *seg,*endseg; for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) { CHARSET_INFO *cs= seg->charset; uint char_length= seg->length; uchar *pos= (uchar*) rec + seg->start; if (seg->null_bit) *key++= MY_TEST(rec[seg->null_pos] & seg->null_bit); if (cs->mbmaxlen > 1) { char_length= my_charpos(cs, pos, pos + seg->length, char_length / cs->mbmaxlen); set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */ } if (seg->type == HA_KEYTYPE_VARTEXT1) char_length+= seg->bit_start; /* Copy also length */ else if (seg->type == HA_KEYTYPE_BIT && seg->bit_length) { *key++= get_rec_bits(rec + seg->bit_pos, seg->bit_start, seg->bit_length); char_length--; } memcpy(key,rec+seg->start,(size_t) char_length); key+= char_length; } }
void hp_make_key(HP_KEYDEF *keydef, uchar *key, const uchar *rec) { HA_KEYSEG *seg,*endseg; for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) { const CHARSET_INFO *cs= seg->charset; uint char_length= seg->length; const uchar *pos= rec + seg->start; if (seg->null_bit) *key++= MY_TEST(rec[seg->null_pos] & seg->null_bit); if (seg->flag & HA_BLOB_PART) { uint tmp_length= hp_calc_blob_length(seg->bit_start, pos); uint length= MY_MIN(seg->length, tmp_length); memcpy(&pos, rec + seg->bit_start, sizeof(char *)); if (cs->mbmaxlen > 1) { char_length= my_charpos(cs, pos, pos + seg->length, char_length / cs->mbmaxlen); set_if_smaller(char_length, length); /* QQ: ok to remove? */ } store_key_length_inc(key, char_length); } else { if (cs->mbmaxlen > 1) { char_length= my_charpos(cs, pos, pos + seg->length, char_length / cs->mbmaxlen); set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */ } if (seg->type == HA_KEYTYPE_VARTEXT1) char_length+= seg->bit_start; /* Copy also length */ } memcpy(key, pos, (size_t) char_length); key+= char_length; } }
int resize_queue(QUEUE *queue, uint max_elements) { uchar **new_root; DBUG_ENTER("resize_queue"); if (queue->max_elements == max_elements) DBUG_RETURN(0); if ((new_root= (uchar **) my_realloc((void *)queue->root, (max_elements+1)*sizeof(void*), MYF(MY_WME))) == 0) DBUG_RETURN(1); set_if_smaller(queue->elements, max_elements); queue->max_elements= max_elements; queue->root= new_root; DBUG_RETURN(0); }
uint _mi_ft_convert_to_ft2(MI_INFO *info, uint keynr, uchar *key) { my_off_t root; DYNAMIC_ARRAY *da=info->ft1_to_ft2; MI_KEYDEF *keyinfo=&info->s->ft2_keyinfo; uchar *key_ptr= (uchar*) dynamic_array_ptr(da, 0), *end; uint length, key_length; DBUG_ENTER("_mi_ft_convert_to_ft2"); /* we'll generate one pageful at once, and insert the rest one-by-one */ /* calculating the length of this page ...*/ length=(keyinfo->block_length-2) / keyinfo->keylength; set_if_smaller(length, da->elements); length=length * keyinfo->keylength; get_key_full_length_rdonly(key_length, key); while (_mi_ck_delete(info, keynr, key, key_length) == 0) { /* nothing to do here. _mi_ck_delete() will populate info->ft1_to_ft2 with deleted keys */ } /* creating pageful of keys */ mi_putint(info->buff,length+2,0); memcpy(info->buff+2, key_ptr, length); info->buff_used=info->page_changed=1; /* info->buff is used */ if ((root= _mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR || _mi_write_keypage(info,keyinfo,root,DFLT_INIT_HITS,info->buff)) DBUG_RETURN(-1); /* inserting the rest of key values */ end= (uchar*) dynamic_array_ptr(da, da->elements); for (key_ptr+=length; key_ptr < end; key_ptr+=keyinfo->keylength) if(_mi_ck_real_write_btree(info, keyinfo, key_ptr, 0, &root, SEARCH_SAME)) DBUG_RETURN(-1); /* now, writing the word key entry */ ft_intXstore(key+key_length, - (int) da->elements); _mi_dpointer(info, key+key_length+HA_FT_WLEN, root); DBUG_RETURN(_mi_ck_real_write_btree(info, info->s->keyinfo+keynr, key, 0, &info->s->state.key_root[keynr], SEARCH_SAME)); }
size_t my_strnxfrm_simple(CHARSET_INFO * cs, uchar *dest, size_t len, const uchar *src, size_t srclen) { const uchar *map= cs->sort_order; size_t dstlen= len; set_if_smaller(len, srclen); if (dest != src) { const uchar *end; for ( end=src+len; src < end ; ) *dest++= map[*src++]; } else { const uchar *end; for ( end=dest+len; dest < end ; dest++) *dest= (char) map[(uchar) *dest]; } if (dstlen > len) bfill(dest, dstlen - len, ' '); return dstlen; }
MARIA_KEY *_ma_make_key(MARIA_HA *info, MARIA_KEY *int_key, uint keynr, uchar *key, const uchar *record, MARIA_RECORD_POS filepos, ulonglong trid) { const uchar *pos; reg1 HA_KEYSEG *keyseg; my_bool is_ft; DBUG_ENTER("_ma_make_key"); int_key->data= key; int_key->flag= 0; /* Always return full key */ int_key->keyinfo= info->s->keyinfo + keynr; is_ft= int_key->keyinfo->flag & HA_FULLTEXT; for (keyseg= int_key->keyinfo->seg ; keyseg->type ;keyseg++) { enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type; uint length=keyseg->length; uint char_length; CHARSET_INFO *cs=keyseg->charset; if (keyseg->null_bit) { if (record[keyseg->null_pos] & keyseg->null_bit) { *key++= 0; /* NULL in key */ continue; } *key++=1; /* Not NULL */ } char_length= ((!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length); pos= record+keyseg->start; if (type == HA_KEYTYPE_BIT) { if (keyseg->bit_length) { uchar bits= get_rec_bits(record + keyseg->bit_pos, keyseg->bit_start, keyseg->bit_length); *key++= (char) bits; length--; } memcpy(key, pos, length); key+= length; continue; } if (keyseg->flag & HA_SPACE_PACK) { if (type != HA_KEYTYPE_NUM) { length= (uint) cs->cset->lengthsp(cs, (const char*)pos, length); } else { const uchar *end= pos + length; while (pos < end && pos[0] == ' ') pos++; length= (uint) (end-pos); } FIX_LENGTH(cs, pos, length, char_length); store_key_length_inc(key,char_length); memcpy(key, pos, (size_t) char_length); key+=char_length; continue; } if (keyseg->flag & HA_VAR_LENGTH_PART) { uint pack_length= (keyseg->bit_start == 1 ? 1 : 2); uint tmp_length= (pack_length == 1 ? (uint) *pos : uint2korr(pos)); pos+= pack_length; /* Skip VARCHAR length */ set_if_smaller(length,tmp_length); FIX_LENGTH(cs, pos, length, char_length); store_key_length_inc(key,char_length); memcpy(key,pos,(size_t) char_length); key+= char_length; continue; } else if (keyseg->flag & HA_BLOB_PART) { uint tmp_length= _ma_calc_blob_length(keyseg->bit_start,pos); uchar *blob_pos; memcpy(&blob_pos, pos+keyseg->bit_start,sizeof(char*)); set_if_smaller(length,tmp_length); FIX_LENGTH(cs, blob_pos, length, char_length); store_key_length_inc(key,char_length); memcpy(key, blob_pos, (size_t) char_length); key+= char_length; continue; } else if (keyseg->flag & HA_SWAP_KEY) { /* Numerical column */ #ifdef HAVE_ISNAN if (type == HA_KEYTYPE_FLOAT) { float nr; float4get(nr,pos); if (isnan(nr)) { /* Replace NAN with zero */ bzero(key,length); key+=length; continue; } } else if (type == HA_KEYTYPE_DOUBLE) { double nr; float8get(nr,pos); if (isnan(nr)) { bzero(key,length); key+=length; continue; } } #endif pos+=length; while (length--) { *key++ = *--pos; } continue; } FIX_LENGTH(cs, pos, length, char_length); memcpy(key, pos, char_length); if (length > char_length) cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' '); key+= length; } _ma_dpointer(info->s, key, filepos); int_key->data_length= (key - int_key->data); int_key->ref_length= info->s->rec_reflength; int_key->flag= 0; if (_ma_have_versioning(info) && trid) { int_key->ref_length+= transid_store_packed(info, key + int_key->ref_length, (TrID) trid); int_key->flag|= SEARCH_USER_KEY_HAS_TRANSID; } DBUG_PRINT("exit",("keynr: %d",keynr)); DBUG_DUMP_KEY("key", int_key); DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE, int_key););
uint _mi_make_key(MI_INFO *info, uint keynr, uchar *key, const uchar *record, my_off_t filepos) { uchar *pos; uchar *start; HA_KEYSEG *keyseg; my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT; DBUG_ENTER("_mi_make_key"); if (info->s->keyinfo[keynr].flag & HA_SPATIAL) { /* TODO: nulls processing */ DBUG_RETURN(sp_make_key(info,keynr,key,record,filepos)); } start=key; for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++) { enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type; uint length=keyseg->length; uint char_length; const CHARSET_INFO *cs= keyseg->charset; if (keyseg->null_bit) { if (record[keyseg->null_pos] & keyseg->null_bit) { *key++= 0; /* NULL in key */ continue; } *key++=1; /* Not NULL */ } char_length= ((!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length); pos= (uchar*) record+keyseg->start; if (type == HA_KEYTYPE_BIT) { if (keyseg->bit_length) { uchar bits= get_rec_bits((uchar*) record + keyseg->bit_pos, keyseg->bit_start, keyseg->bit_length); *key++= bits; length--; } memcpy((uchar*) key, pos, length); key+= length; continue; } if (keyseg->flag & HA_SPACE_PACK) { if (type != HA_KEYTYPE_NUM) { length= cs->cset->lengthsp(cs, (char*) pos, length); } else { uchar *end= pos + length; while (pos < end && pos[0] == ' ') pos++; length=(uint) (end-pos); } FIX_LENGTH(cs, pos, length, char_length); store_key_length_inc(key,char_length); memcpy((uchar*) key,(uchar*) pos,(size_t) char_length); key+=char_length; continue; } if (keyseg->flag & HA_VAR_LENGTH_PART) { uint pack_length= (keyseg->bit_start == 1 ? 1 : 2); uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos)); pos+= pack_length; /* Skip VARCHAR length */ set_if_smaller(length,tmp_length); FIX_LENGTH(cs, pos, length, char_length); store_key_length_inc(key,char_length); memcpy((uchar*) key,(uchar*) pos,(size_t) char_length); key+= char_length; continue; } else if (keyseg->flag & HA_BLOB_PART) { uint tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos); memcpy(&pos,pos+keyseg->bit_start,sizeof(char*)); set_if_smaller(length,tmp_length); FIX_LENGTH(cs, pos, length, char_length); store_key_length_inc(key,char_length); memcpy((uchar*) key,(uchar*) pos,(size_t) char_length); key+= char_length; continue; } else if (keyseg->flag & HA_SWAP_KEY) { /* Numerical column */ if (type == HA_KEYTYPE_FLOAT) { float nr; float4get(&nr,pos); if (my_isnan(nr)) { /* Replace NAN with zero */ memset(key, 0, length); key+=length; continue; } } else if (type == HA_KEYTYPE_DOUBLE) { double nr; float8get(&nr,pos); if (my_isnan(nr)) { memset(key, 0, length); key+=length; continue; } } pos+=length; while (length--) { *key++ = *--pos; } continue; } FIX_LENGTH(cs, pos, length, char_length); memcpy((uchar*) key, pos, char_length); if (length > char_length) cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' '); key+= length; } _mi_dpointer(info,key,filepos); DBUG_PRINT("exit",("keynr: %d",keynr)); DBUG_DUMP("key",(uchar*) start,(uint) (key-start)+keyseg->length); DBUG_EXECUTE("key", _mi_print_key(DBUG_FILE,info->s->keyinfo[keynr].seg,start, (uint) (key-start)););
uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old, key_part_map keypart_map) { HA_KEYSEG *seg, *endseg; uchar *start_key= key; for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg && keypart_map; old+= seg->length, seg++) { uint char_length; keypart_map>>= 1; if (seg->null_bit) { /* Convert NULL from MySQL representation into HEAP's. */ if (!(*key++= (char) 1 - *old++)) { /* Add key pack length (2) to key for VARCHAR segments */ if (seg->type == HA_KEYTYPE_VARTEXT1) old+= 2; continue; } } if (seg->flag & HA_SWAP_KEY) { uint length= seg->length; uchar *pos= (uchar*) old + length; while (length--) { *key++= *--pos; } continue; } if (seg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART)) { /* Length of key-part used with heap_rkey() always 2 */ uint tmp_length=uint2korr(old); uint length= seg->length; CHARSET_INFO *cs= seg->charset; char_length= length/cs->mbmaxlen; old+= 2; set_if_smaller(length,tmp_length); /* Safety */ FIX_LENGTH(cs, old, length, char_length); store_key_length_inc(key,char_length); memcpy((uchar*) key, old,(size_t) char_length); key+= char_length; continue; } char_length= seg->length; if (seg->charset->mbmaxlen > 1) { char_length= my_charpos(seg->charset, old, old+char_length, char_length / seg->charset->mbmaxlen); set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */ if (char_length < seg->length) seg->charset->cset->fill(seg->charset, (char*) key + char_length, seg->length - char_length, ' '); } memcpy(key, old, (size_t) char_length); key+= seg->length; } return (uint) (key - start_key); }
uint hp_rb_make_key(HP_KEYDEF *keydef, uchar *key, const uchar *rec, uchar *recpos) { uchar *start_key= key; HA_KEYSEG *seg, *endseg; for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++) { uint char_length; if (seg->null_bit) { if (!(*key++= 1 - MY_TEST(rec[seg->null_pos] & seg->null_bit))) continue; } if (seg->flag & HA_SWAP_KEY) { uint length= seg->length; uchar *pos= (uchar*) rec + seg->start; DBUG_ASSERT(seg->type != HA_KEYTYPE_BIT); #ifdef HAVE_ISNAN if (seg->type == HA_KEYTYPE_FLOAT) { float nr; float4get(nr, pos); if (isnan(nr)) { /* Replace NAN with zero */ bzero(key, length); key+= length; continue; } } else if (seg->type == HA_KEYTYPE_DOUBLE) { double nr; float8get(nr, pos); if (isnan(nr)) { bzero(key, length); key+= length; continue; } } #endif pos+= length; while (length--) { *key++= *--pos; } continue; } if (seg->flag & HA_VAR_LENGTH_PART) { uchar *pos= (uchar*) rec + seg->start; uint length= seg->length; uint pack_length= seg->bit_start; uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos)); CHARSET_INFO *cs= seg->charset; char_length= length/cs->mbmaxlen; pos+= pack_length; /* Skip VARCHAR length */ set_if_smaller(length,tmp_length); FIX_LENGTH(cs, pos, length, char_length); store_key_length_inc(key,char_length); memcpy((uchar*) key,(uchar*) pos,(size_t) char_length); key+= char_length; continue; } char_length= seg->length; if (seg->charset->mbmaxlen > 1) { char_length= my_charpos(seg->charset, rec + seg->start, rec + seg->start + char_length, char_length / seg->charset->mbmaxlen); set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */ if (char_length < seg->length) seg->charset->cset->fill(seg->charset, (char*) key + char_length, seg->length - char_length, ' '); } if (seg->type == HA_KEYTYPE_BIT && seg->bit_length) { *key++= get_rec_bits(rec + seg->bit_pos, seg->bit_start, seg->bit_length); char_length--; } memcpy(key, rec + seg->start, (size_t) char_length); key+= seg->length; } memcpy(key, &recpos, sizeof(uchar*)); return (uint) (key - start_key); }
int hp_key_cmp(HP_KEYDEF *keydef, const uchar *rec, const uchar *key) { HA_KEYSEG *seg,*endseg; for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; key+= (seg++)->length) { if (seg->null_bit) { int found_null= MY_TEST(rec[seg->null_pos] & seg->null_bit); if (found_null != (int) *key++) return 1; if (found_null) { /* Add key pack length (2) to key for VARCHAR segments */ if (seg->type == HA_KEYTYPE_VARTEXT1) key+= 2; continue; } } if (seg->type == HA_KEYTYPE_TEXT) { CHARSET_INFO *cs= seg->charset; uint char_length_key; uint char_length_rec; uchar *pos= (uchar*) rec + seg->start; if (cs->mbmaxlen > 1) { uint char_length= seg->length / cs->mbmaxlen; char_length_key= my_charpos(cs, key, key + seg->length, char_length); set_if_smaller(char_length_key, seg->length); char_length_rec= my_charpos(cs, pos, pos + seg->length, char_length); set_if_smaller(char_length_rec, seg->length); } else { char_length_key= seg->length; char_length_rec= seg->length; } if (seg->charset->coll->strnncollsp(seg->charset, (uchar*) pos, char_length_rec, (uchar*) key, char_length_key, 0)) return 1; } else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */ { uchar *pos= (uchar*) rec + seg->start; CHARSET_INFO *cs= seg->charset; uint pack_length= seg->bit_start; uint char_length_rec= (pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos)); /* Key segments are always packed with 2 bytes */ uint char_length_key= uint2korr(key); pos+= pack_length; key+= 2; /* skip key pack length */ if (cs->mbmaxlen > 1) { uint char_length1, char_length2; char_length1= char_length2= seg->length / cs->mbmaxlen; char_length1= my_charpos(cs, key, key + char_length_key, char_length1); set_if_smaller(char_length_key, char_length1); char_length2= my_charpos(cs, pos, pos + char_length_rec, char_length2); set_if_smaller(char_length_rec, char_length2); } else set_if_smaller(char_length_rec, seg->length); if (cs->coll->strnncollsp(seg->charset, (uchar*) pos, char_length_rec, (uchar*) key, char_length_key, 0)) return 1; } else { uint dec= 0; if (seg->type == HA_KEYTYPE_BIT && seg->bit_length) { uchar bits= get_rec_bits(rec + seg->bit_pos, seg->bit_start, seg->bit_length); if (bits != (*key)) return 1; dec= 1; key++; } if (bcmp(rec + seg->start, key, seg->length - dec)) return 1; } } return 0; }
int hp_rec_key_cmp(HP_KEYDEF *keydef, const uchar *rec1, const uchar *rec2, my_bool diff_if_only_endspace_difference) { HA_KEYSEG *seg,*endseg; for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) { if (seg->null_bit) { if ((rec1[seg->null_pos] & seg->null_bit) != (rec2[seg->null_pos] & seg->null_bit)) return 1; if (rec1[seg->null_pos] & seg->null_bit) continue; } if (seg->type == HA_KEYTYPE_TEXT) { CHARSET_INFO *cs= seg->charset; uint char_length1; uint char_length2; uchar *pos1= (uchar*)rec1 + seg->start; uchar *pos2= (uchar*)rec2 + seg->start; if (cs->mbmaxlen > 1) { uint char_length= seg->length / cs->mbmaxlen; char_length1= my_charpos(cs, pos1, pos1 + seg->length, char_length); set_if_smaller(char_length1, seg->length); char_length2= my_charpos(cs, pos2, pos2 + seg->length, char_length); set_if_smaller(char_length2, seg->length); } else { char_length1= char_length2= seg->length; } if (seg->charset->coll->strnncollsp(seg->charset, pos1,char_length1, pos2,char_length2, 0)) return 1; } else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */ { uchar *pos1= (uchar*) rec1 + seg->start; uchar *pos2= (uchar*) rec2 + seg->start; uint char_length1, char_length2; uint pack_length= seg->bit_start; CHARSET_INFO *cs= seg->charset; if (pack_length == 1) { char_length1= (uint) *(uchar*) pos1++; char_length2= (uint) *(uchar*) pos2++; } else { char_length1= uint2korr(pos1); char_length2= uint2korr(pos2); pos1+= 2; pos2+= 2; } if (cs->mbmaxlen > 1) { uint safe_length1= char_length1; uint safe_length2= char_length2; uint char_length= seg->length / cs->mbmaxlen; char_length1= my_charpos(cs, pos1, pos1 + char_length1, char_length); set_if_smaller(char_length1, safe_length1); char_length2= my_charpos(cs, pos2, pos2 + char_length2, char_length); set_if_smaller(char_length2, safe_length2); } else { set_if_smaller(char_length1, seg->length); set_if_smaller(char_length2, seg->length); } if (cs->coll->strnncollsp(seg->charset, pos1, char_length1, pos2, char_length2, seg->flag & HA_END_SPACE_ARE_EQUAL ? 0 : diff_if_only_endspace_difference)) return 1; } else { uint dec= 0; if (seg->type == HA_KEYTYPE_BIT && seg->bit_length) { uchar bits1= get_rec_bits(rec1 + seg->bit_pos, seg->bit_start, seg->bit_length); uchar bits2= get_rec_bits(rec2 + seg->bit_pos, seg->bit_start, seg->bit_length); if (bits1 != bits2) return 1; dec= 1; } if (bcmp(rec1 + seg->start, rec2 + seg->start, seg->length - dec)) return 1; } } return 0; }
ulong hp_hashnr(register HP_KEYDEF *keydef, register const uchar *key) { /*register*/ ulong nr=1, nr2=4; HA_KEYSEG *seg,*endseg; for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) { uchar *pos=(uchar*) key; key+=seg->length; if (seg->null_bit) { key++; /* Skip null byte */ if (*pos) /* Found null */ { nr^= (nr << 1) | 1; /* Add key pack length (2) to key for VARCHAR segments */ if (seg->type == HA_KEYTYPE_VARTEXT1) key+= 2; continue; } pos++; } if (seg->type == HA_KEYTYPE_TEXT) { CHARSET_INFO *cs= seg->charset; uint length= seg->length; if (cs->mbmaxlen > 1) { uint char_length; char_length= my_charpos(cs, pos, pos + length, length/cs->mbmaxlen); set_if_smaller(length, char_length); } cs->coll->hash_sort(cs, pos, length, &nr, &nr2); } else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */ { CHARSET_INFO *cs= seg->charset; uint pack_length= 2; /* Key packing is constant */ uint length= uint2korr(pos); if (cs->mbmaxlen > 1) { uint char_length; char_length= my_charpos(cs, pos +pack_length, pos +pack_length + length, seg->length/cs->mbmaxlen); set_if_smaller(length, char_length); } cs->coll->hash_sort(cs, pos+pack_length, length, &nr, &nr2); key+= pack_length; } else { for (; pos < (uchar*) key ; pos++) { nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) *pos)) + (nr << 8); nr2+=3; } } } #ifdef ONLY_FOR_HASH_DEBUGGING DBUG_PRINT("exit", ("hash: 0x%lx", nr)); #endif return((ulong) nr); }
static void get_options( int argc, char *argv[]) { char *pos,*progname; DEBUGGER_OFF; progname= argv[0]; while (--argc >0 && *(pos = *(++argv)) == '-' ) { switch(*++pos) { case 'b': if (*++pos) nisam_block_size= MY_ALIGN(atoi(pos),512); set_if_bigger(nisam_block_size,8192); /* Max block size */ set_if_smaller(nisam_block_size,1024); break; case 'B': use_blob=1; break; case 'K': /* Use key cacheing */ key_cacheing=1; break; case 'W': /* Use write cacheing */ write_cacheing=1; if (*++pos) my_default_record_cache_size=atoi(pos); break; case 'i': if (*++pos) srand(atoi(pos)); break; case 'l': use_log=1; break; case 'L': locking=1; break; case 'A': /* use asyncron io */ async_io=1; if (*++pos) my_default_record_cache_size=atoi(pos); break; case 'v': /* verbose */ verbose=1; break; case 'm': /* records */ recant=atoi(++pos); break; case 'f': if ((first_key=atoi(++pos)) <0 || first_key >= NISAM_KEYS) first_key=0; break; case 'k': if ((keys=(uint) atoi(++pos)) < 1 || keys > (uint) (NISAM_KEYS-first_key)) keys=NISAM_KEYS-first_key; break; case 'P': pack_type=0; /* Don't use DIFF_LENGTH */ break; case 'R': /* Length of record pointer */ rec_pointer_size=atoi(++pos); if (rec_pointer_size > 3) rec_pointer_size=0; break; case 'S': pack_fields=0; /* Static-length-records */ break; case 't': testflag=atoi(++pos); /* testmod */ break; case '?': case 'I': case 'V': printf("%s Ver 1.4 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE); puts("TCX Datakonsult AB, by Monty, for your professional use\n"); printf("Usage: %s [-?ABIKLPRSVWltv] [-b#] [-k#] [-f#] [-m#] [-t#]\n",progname); exit(0); case '#': DEBUGGER_ON; DBUG_PUSH (++pos); break; default: printf("Illegal option: '%c'\n",*pos); break; } } return; } /* get options */
int hp_rec_key_cmp(HP_KEYDEF *keydef, const uchar *rec1, const uchar *rec2, my_bool diff_if_only_endspace_difference) { HA_KEYSEG *seg,*endseg; for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) { if (seg->null_bit) { if ((rec1[seg->null_pos] & seg->null_bit) != (rec2[seg->null_pos] & seg->null_bit)) return 1; if (rec1[seg->null_pos] & seg->null_bit) continue; } if (seg->type == HA_KEYTYPE_TEXT) { const CHARSET_INFO *cs= seg->charset; uint char_length1; uint char_length2; uchar *pos1= (uchar*)rec1 + seg->start; uchar *pos2= (uchar*)rec2 + seg->start; if (cs->mbmaxlen > 1) { uint char_length= seg->length / cs->mbmaxlen; char_length1= my_charpos(cs, pos1, pos1 + seg->length, char_length); set_if_smaller(char_length1, seg->length); char_length2= my_charpos(cs, pos2, pos2 + seg->length, char_length); set_if_smaller(char_length2, seg->length); } else { char_length1= char_length2= seg->length; } if (seg->charset->coll->strnncollsp(seg->charset, pos1,char_length1, pos2,char_length2, 0)) return 1; } else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */ { uchar *pos1= (uchar*) rec1 + seg->start; uchar *pos2= (uchar*) rec2 + seg->start; uint char_length1, char_length2; uint pack_length= seg->bit_start; const CHARSET_INFO *cs= seg->charset; char_length1= hp_calc_blob_length(pack_length, pos1); char_length2= hp_calc_blob_length(pack_length, pos2); pos1+= pack_length; pos2+= pack_length; if (seg->flag & HA_BLOB_PART) { memcpy(&pos1, pos1, sizeof(char *)); memcpy(&pos2, pos2, sizeof(char *)); } if (cs->mbmaxlen > 1) { uint safe_length1= char_length1; uint safe_length2= char_length2; uint char_length= seg->length / cs->mbmaxlen; char_length1= my_charpos(cs, pos1, pos1 + char_length1, char_length); set_if_smaller(char_length1, safe_length1); char_length2= my_charpos(cs, pos2, pos2 + char_length2, char_length); set_if_smaller(char_length2, safe_length2); } if (cs->coll->strnncollsp(seg->charset, pos1, char_length1, pos2, char_length2, seg->flag & HA_END_SPACE_ARE_EQUAL ? 0 : diff_if_only_endspace_difference)) return 1; } else { if (memcmp(rec1+seg->start,rec2+seg->start,seg->length)) return 1; } } return 0; }
uint _mi_make_key(register MI_INFO * info, uint keynr, uchar * key, const byte * record, my_off_t filepos) { byte *pos, *end; uchar *start; reg1 MI_KEYSEG *keyseg; DBUG_ENTER("_mi_make_key"); start = key; for (keyseg = info->s->keyinfo[keynr].seg; keyseg->type; keyseg++) { enum ha_base_keytype type = (enum ha_base_keytype)keyseg->type; uint length = keyseg->length; if (keyseg->null_bit) { if (record[keyseg->null_pos] & keyseg->null_bit) { *key++ = 0; /* NULL in key */ continue; } *key++ = 1; /* Not NULL */ } pos = (byte *) record + keyseg->start; if (keyseg->flag & HA_SPACE_PACK) { end = pos + length; if (type != HA_KEYTYPE_NUM) { while (end > pos && end[-1] == ' ') end--; } else { while (pos < end && pos[0] == ' ') pos++; } length = (uint) (end - pos); store_key_length_inc(key, length); memcpy((byte *) key, (byte *) pos, (size_t) length); key += length; continue; } if (keyseg->flag & HA_VAR_LENGTH) { uint tmp_length = uint2korr(pos); pos += 2; /* Skip VARCHAR length */ set_if_smaller(length, tmp_length); store_key_length_inc(key, length); } else if (keyseg->flag & HA_BLOB_PART) { uint tmp_length = _mi_calc_blob_length(keyseg->bit_start, pos); memcpy_fixed((byte *) & pos, pos + keyseg->bit_start, sizeof(char *)); set_if_smaller(length, tmp_length); store_key_length_inc(key, length); } else if (keyseg->flag & HA_SWAP_KEY) { /* Numerical column */ #ifdef NAN_TEST float float_nr; double dbl_nr; if (type == HA_KEYTYPE_FLOAT) { float_nr = float4get(pos); if (float_nr == (float)FLT_MAX) { float_nr = (float)FLT_MAX; pos = (byte *) & float_nr; } } else if (type == HA_KEYTYPE_DOUBLE) { dbl_nr = float8get(key); if (dbl_nr == DBL_MAX) { dbl_nr = DBL_MAX; pos = (byte *) & dbl_nr; } } #endif pos += length; while (length--) { *key++ = *--pos; } continue; } memcpy((byte *) key, pos, length); key += length; } _mi_dpointer(info, key, filepos); DBUG_PRINT("exit", ("keynr: %d", keynr)); DBUG_DUMP("key", (byte *) start, (uint) (key - start) + keyseg->length); DBUG_EXECUTE("key", _mi_print_key(DBUG_FILE, info->s->keyinfo[keynr].seg, start, (uint) (key - start)); );