YoushouldhavereceivedacopyoftheGNUGeneralPublicLicense alongwiththisprogram;ifnot,writetotheFreeSoftware
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
/* Search after key in page-block */ /* If packed key puts smaller or identical key in buff */ /* ret_pos point to where find or bigger key starts */ /* ARGSUSED */
int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
uchar *key, uint key_len, uint comp_flag, uchar **ret_pos,
uchar *buff __attribute__((unused)), my_bool *last_key)
{
reg4 int start,mid,end,save_end; int UNINIT_VAR(flag);
uint totlength,nod_flag,not_used[2];
DBUG_ENTER("_mi_bin_search");
get_key_pack_length(kseg_len,length_pack,kseg);
key_len_skip=length_pack+kseg_len;
key_len_left=(int) key_len- (int) key_len_skip; /* If key_len is 0, then length_pack is 1, then key_len_left is -1. */
cmplen=(key_len_left>=0) ? kseg_len : key_len-length_pack;
DBUG_PRINT("info",("key: '%.*s'",kseg_len,kseg));
if (packed)
{ if (suffix_len == 0)
{ /* == 0x80 or 0x8000, same key, prefix length == old key length. */
prefix_len=len;
} else
{ /* > 0x80 or 0x8000, this is prefix lgt, packed suffix lgt follows. */
prefix_len=suffix_len;
get_key_length(suffix_len,vseg);
}
} else
{ /* Not packed. No prefix used from last key. */
prefix_len=0;
}
if (sort_order)
{ for (my_flag=0;left;left--) if ((my_flag= (int) sort_order[*vseg++] - (int) sort_order[*k++])) break;
} else
{ for (my_flag=0;left;left--) if ((my_flag= (int) *vseg++ - (int) *k++)) break;
}
if (my_flag==0) /* match */
{ /* **lencmplenseg_left_lenmore_segs **<matched=len;continuesearch **>=prefix?found:(matched=len;continuesearch) **><-ok,found **=<-ok,found **==-ok,found **==+nextseg
*/ if (len < cmplen)
{ if ((keyinfo->seg->type != HA_KEYTYPE_TEXT &&
keyinfo->seg->type != HA_KEYTYPE_VARTEXT1 &&
keyinfo->seg->type != HA_KEYTYPE_VARTEXT2))
my_flag= -1; else
{ /* We have to compare k and vseg as if they were space extended */
uchar *k_end= k+ (cmplen - len); for ( ; k < k_end && *k == ' '; k++) ; if (k == k_end) goto cmp_rest; /* should never happen */
my_flag= (uchar)' ' - *k;
}
} elseif (len > cmplen)
{
uchar *vseg_end; if ((nextflag & SEARCH_PREFIX) && key_len_left == 0) goto fix_flag;
/* We have to compare k and vseg as if they were space extended */ for (vseg_end= vseg + (len-cmplen) ;
vseg < vseg_end && *vseg == (uchar) ' ';
vseg++, matched++) ;
DBUG_ASSERT(vseg < vseg_end);
switch (info->s->rec_reflength) { #if SIZEOF_OFF_T > 4 case8: mi_int8store(buff,pos); break; case7: mi_int7store(buff,pos); break; case6: mi_int6store(buff,pos); break; case5: mi_int5store(buff,pos); break; #else case8: *buff++=0; /* fall through */ case7: *buff++=0; /* fall through */ case6: *buff++=0; /* fall through */ case5: *buff++=0; /* fall through */ #endif case4: mi_int4store(buff,pos); break; case3: mi_int3store(buff,pos); break; case2: mi_int2store(buff,(uint) pos); break; default: abort(); /* Impossible */
}
} /* _mi_dpointer */
/* Get key from key-block */ /* page points at previous key; its advanced to point at next key */ /* key should contain previous key */ /* Returns length of found key + pointers */ /* nod_flag is a flag if we are on nod */
/* same as _mi_get_key but used with fixed length keys */
get_key_length()isamacro.Itgetstheprefixlengthfrom'page' andputsitinto'length'.Itincrements'page'by1or3,depending onthepackedlengthoftheprefixlength.
*/
get_key_length(length,page); if (length)
{ if (length > keyinfo->maxlength)
{
DBUG_PRINT("error",
("Found too long binary packed key: %u of %u at %p",
length, keyinfo->maxlength, *page_pos));
DBUG_DUMP("key", *page_pos, 16); goto crashed; /* Wrong key */
} /* Key is packed against prev key, take prefix from prev key. */
from= key;
from_end= key + length;
} else
{ /* Key is not packed against prev key, take all from page buffer. */
from= page;
from_end= page_end;
}
/* Thetroubleisthatkeycanbesplitintwoparts: Thefirstpart(prefix)isinfrom..from_end-1. Thesecondpartstartsatpage. Thesplitcanbeateverybyteposition.Soweneedtocheckfor theendofthefirstpartbeforeusingeverybyte.
*/ for (keyseg=keyinfo->seg ; keyseg->type ;keyseg++)
{ if (keyseg->flag & HA_NULL_PART)
{ /* If prefix is used up, switch to rest. */ if (from == from_end) { from=page; from_end=page_end; } if (!(*key++ = *from++)) continue; /* Null part */
} if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART | HA_SPACE_PACK))
{ /* If prefix is used up, switch to rest. */ if (from == from_end) { from=page; from_end=page_end; } /* Get length of dynamic length key part */ if ((length= (*key++ = *from++)) == 255)
{ /* If prefix is used up, switch to rest. */ if (from == from_end) { from=page; from_end=page_end; }
length= (uint) ((*key++ = *from++)) << 8; /* If prefix is used up, switch to rest. */ if (from == from_end) { from=page; from_end=page_end; }
length+= (uint) ((*key++ = *from++));
} if (length > keyseg->length) goto crashed;
} else
length=keyseg->length;
if ((tmp=(uint) (from_end-from)) <= length)
{
key+=tmp; /* Use old key */
length-=tmp;
from=page; from_end=page_end;
}
DBUG_PRINT("info",("key: %p from: %p length: %u",
key, from, length));
memmove((uchar*) key, (uchar*) from, (size_t) length);
key+=length;
from+=length;
} /* Lastsegment(type==0)containslengthofdatapointer. Ifwehavemixedkeyblockswithdatapointerandkeyblockpointer, wehavetocopyboth.
*/
length=keyseg->length+nod_flag; if ((tmp=(uint) (from_end-from)) <= length)
{ /* Remaining length is less or equal max possible length. */
memcpy(key+tmp,page,length-tmp); /* Get last part of key */
*page_pos= page+length-tmp;
} else
{ /* Remaininglengthisgreaterthanmaxpossiblelength. Thiscanhappenonlyifweswitchedtothenewkeybytesalready. 'page_end'iscalculatedwithMI_MAX_KEY_BUFF.Soitcanbefar behindtherealendofthekey.
*/ if (from_end != page_end)
{
DBUG_PRINT("error",("Error when unpacking key")); goto crashed; /* Error */
} /* Copy data pointer and, if appropriate, key block pointer. */
memcpy((uchar*) key,(uchar*) from,(size_t) length);
*page_pos= from+length;
}
DBUG_RETURN((uint) (key-start_key)+keyseg->length);
/* Force full read if we are at last key or if we are not on a leaf andthekeytreehaschangedsinceweuseditlasttime Notethatevenifthekeytreehaschangedsincelastread,wecanuse thelastreaddatafromtheleafifwehaven'tusedthebufferfor somethingelse.
*/
if (info->buff_used)
{ if (!_mi_fetch_keypage(info,keyinfo,info->last_search_keypage,
DFLT_INIT_HITS,info->buff,0))
DBUG_RETURN(-1);
info->buff_used=0;
}
/* Last used buffer is in info->buff */
nod_flag=mi_test_if_nod(info->buff);
if (nextflag & SEARCH_BIGGER) /* Next key */
{
my_off_t tmp_pos=_mi_kpos(nod_flag,info->int_keypos); if (tmp_pos != HA_OFFSET_ERROR)
{ if ((error=_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
nextflag | SEARCH_SAVE_BUFF, tmp_pos)) <=0)
DBUG_RETURN(error);
}
memcpy(lastkey,key,key_length); if (!(info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag,
&info->int_keypos,lastkey)))
DBUG_RETURN(-1);
} else/* Previous key */
{
uint length; /* Find start of previous key */
info->int_keypos=_mi_get_last_key(info,keyinfo,info->buff,lastkey,
info->int_keypos, &length); if (!info->int_keypos)
DBUG_RETURN(-1); if (info->int_keypos == info->buff+2)
DBUG_RETURN(_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
nextflag | SEARCH_SAVE_BUFF, pos)); if ((error=_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
nextflag | SEARCH_SAVE_BUFF,
_mi_kpos(nod_flag,info->int_keypos))) <= 0)
DBUG_RETURN(error);
/* QQ: We should be able to optimize away the following call */ if (! _mi_get_last_key(info,keyinfo,info->buff,lastkey,
info->int_keypos,&info->lastkey_length))
DBUG_RETURN(-1);
}
memcpy(info->lastkey,lastkey,info->lastkey_length);
info->lastpos=_mi_dpos(info,0,info->lastkey+info->lastkey_length);
DBUG_PRINT("exit",("found key at %lu",(ulong) info->lastpos));
DBUG_RETURN(0);
} /* _mi_search_next */
/* Search after position for the first row in an index */ /* This is stored in info->lastpos */
/* diff flag contains how many bytes is needed to pack key */ if (keyseg->length >= 127)
{
diff_flag=2;
pack_marker=32768;
} else
{
diff_flag= 1;
pack_marker=128;
}
s_temp->pack_marker=pack_marker;
/* Handle the case that the first part have NULL values */ if (keyseg->flag & HA_NULL_PART)
{ if (!*key++)
{
s_temp->key=key;
s_temp->key_length= 0;
s_temp->totlength=key_length-1+diff_flag;
s_temp->next_key_pos=0; /* No next key */ return (s_temp->totlength);
}
s_temp->store_not_null=1;
key_length--; /* We don't store NULL */ if (prev_key && !*prev_key++)
org_key=prev_key=0; /* Can't pack against prev */ elseif (org_key)
org_key++; /* Skip NULL */
} else
s_temp->store_not_null=0;
s_temp->prev_key=org_key;
/* The key part will start with a packed length */
/* Calc how many characters are identical between this and the prev. key */ if (prev_key)
{
get_key_length(org_key_length,prev_key);
s_temp->prev_key=prev_key; /* Pointer at data */ /* Don't use key-pack if length == 0 */ if (new_key_length && new_key_length == org_key_length)
same_length=1; elseif (new_key_length > org_key_length)
end=key + org_key_length;
if (sort_order) /* SerG */
{ while (key < end && sort_order[*key] == sort_order[*prev_key])
{
key++; prev_key++;
}
} else
{ while (key < end && *key == *prev_key)
{
key++; prev_key++;
}
}
}
if (packed)
{ /* If first key and next key is packed (only on delete) */ if (!prev_key && org_key)
{
get_key_length(org_key_length,org_key);
key=start; if (sort_order) /* SerG */
{ while (key < end && sort_order[*key] == sort_order[*org_key])
{
key++; org_key++;
}
} else
{ while (key < end && *key == *org_key)
{
key++; org_key++;
}
} if ((new_ref_length= (uint) (key - start)))
new_ref_length+=pack_marker;
}
ref_length=n_length; /* Get information about not packed key suffix */
get_key_pack_length(n_length,next_length_pack,next_key);
/* Test if new keys has fewer characters that match the previous key */ if (!new_ref_length)
{ /* Can't use prev key */
s_temp->part_of_prev_key= 0;
s_temp->prev_length= ref_length;
s_temp->n_ref_length= s_temp->n_length= n_length+ref_length; return (int) length+ref_length-next_length_pack;
} if (ref_length+pack_marker > new_ref_length)
{
uint new_pack_length=new_ref_length-pack_marker; /* We must copy characters from the original key to the next key */
s_temp->part_of_prev_key= new_ref_length;
s_temp->prev_length= ref_length - new_pack_length;
s_temp->n_ref_length=s_temp->n_length=n_length + s_temp->prev_length;
s_temp->prev_key+= new_pack_length;
length-= (next_length_pack - get_pack_length(s_temp->n_length)); return (int) length + s_temp->prev_length;
}
} else
{ /* Next key wasn't a prefix of previous key */
ref_length=0;
next_length_pack=0;
}
DBUG_PRINT("test",("length: %d next_key: %p", length,
next_key));
{
uint tmp_length;
key=(start+=ref_length); if (key+n_length < key_end) /* Normalize length based */
key_end=key+n_length; if (sort_order) /* SerG */
{ while (key < key_end && sort_order[*key] ==
sort_order[*next_key])
{
key++; next_key++;
}
} else
{ while (key < key_end && *key == *next_key)
{
key++; next_key++;
}
} if (!(tmp_length=(uint) (key-start)))
{ /* Key can't be re-packed */
s_temp->next_key_pos=0; return length;
}
ref_length+=tmp_length;
n_length-=tmp_length;
length-=tmp_length+next_length_pack; /* We gained these chars */
} if (n_length == 0 && ref_length == new_key_length)
{
s_temp->n_ref_length=pack_marker; /* Same as prev key */
} else
{
s_temp->n_ref_length=ref_length | pack_marker;
length+= get_pack_length(n_length);
s_temp->n_length=n_length;
}
}
} return length;
}
s_temp->totlength=key_length=_mi_keylength(keyinfo,key)+nod_flag; #ifdef HAVE_valgrind
s_temp->n_length= s_temp->n_ref_length=0; /* For valgrind */ #endif
s_temp->key=key;
s_temp->prev_key=org_key; if (prev_key) /* If not first key in block */
{ /* pack key against previous key */ /* Askeysmaybeidenticalwhenrunningasortinmyisamchk,we havetoguardagainstthecasewherekeysmaybeidentical
*/
uchar *end;
end=key+key_length; for ( ; *key == *prev_key && key < end; key++,prev_key++) ;
s_temp->ref_length= ref_length=(uint) (key-s_temp->key);
length=key_length - ref_length + get_pack_length(ref_length);
} else
{ /* No previous key */
s_temp->ref_length=ref_length=0;
length=key_length+1;
} if ((s_temp->next_key_pos=next_key)) /* If another key after */
{ /* pack key against next key */
uint next_length,next_length_pack;
get_key_pack_length(next_length,next_length_pack,next_key);
/* If first key and next key is packed (only on delete) */ if (!prev_key && org_key && next_length)
{
uchar *end; for (key= s_temp->key, end=key+next_length ;
*key == *org_key && key < end;
key++,org_key++) ;
ref_length= (uint) (key - s_temp->key);
}
if (next_length > ref_length)
{ /* We put a key with different case between two keys with the same prefix Extendnextkeytohavesameprefixas
this key */
s_temp->n_ref_length= ref_length;
s_temp->prev_length= next_length-ref_length;
s_temp->prev_key+= ref_length; return (int) (length+ s_temp->prev_length - next_length_pack +
get_pack_length(ref_length));
} /* Check how many characters are identical to next key */
key= s_temp->key+next_length;
s_temp->prev_length= 0; while (*key++ == *next_key++) ; if ((ref_length= (uint) (key - s_temp->key)-1) == next_length)
{
s_temp->next_key_pos=0; return length; /* can't pack next key */
}
s_temp->n_ref_length=ref_length; return (int) (length-(ref_length - next_length) - next_length_pack +
get_pack_length(ref_length));
} return (int) length;
}
if (s_temp->ref_length)
{ /* Packed against previous key */
store_pack_length(s_temp->pack_marker == 128,key_pos,s_temp->ref_length); /* If not same key after */ if (s_temp->ref_length != s_temp->pack_marker)
store_key_length_inc(key_pos,s_temp->key_length);
} else
{ /* Not packed against previous key */
store_pack_length(s_temp->pack_marker == 128,key_pos,s_temp->key_length);
}
bmove((uchar*) key_pos,(uchar*) s_temp->key,
(length=s_temp->totlength-(uint) (key_pos-start)));
if (!s_temp->next_key_pos) /* No following key */ return;
key_pos+=length;
if (s_temp->prev_length)
{ /* Extend next key because new key didn't have same prefix as prev key */ if (s_temp->part_of_prev_key)
{
store_pack_length(s_temp->pack_marker == 128,key_pos,
s_temp->part_of_prev_key);
store_key_length_inc(key_pos,s_temp->n_length);
} else
{
s_temp->n_length+= s_temp->store_not_null;
store_pack_length(s_temp->pack_marker == 128,key_pos,
s_temp->n_length);
}
memcpy(key_pos, s_temp->prev_key, s_temp->prev_length);
} elseif (s_temp->n_ref_length)
{
store_pack_length(s_temp->pack_marker == 128,key_pos,s_temp->n_ref_length); if (s_temp->n_ref_length == s_temp->pack_marker) return; /* Identical key */
store_key_length(key_pos,s_temp->n_length);
} elseif (s_temp->n_length)
{
s_temp->n_length+= s_temp->store_not_null;
store_pack_length(s_temp->pack_marker == 128,key_pos,s_temp->n_length);
}
}
if (s_temp->next_key_pos)
{
key_pos+=(uint) (s_temp->totlength-s_temp->ref_length);
store_key_length_inc(key_pos,s_temp->n_ref_length); if (s_temp->prev_length) /* If we must extend key */
{
memcpy(key_pos,s_temp->prev_key,s_temp->prev_length);
}
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.30 Sekunden
(vorverarbeitet am 2026-10-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.