BTREE heap key structure is now the same as MyISAM
_mi_compare_text -> mi_compate_text Changes according Monty's suggestions heap/heapdef.h: BTREE heap key structure is now the same as MyISAM heap/hp_delete.c: BTREE heap key structure is now the same as MyISAM heap/hp_hash.c: BTREE heap key structure is now the same as MyISAM heap/hp_open.c: BTREE heap key structure is now the same as MyISAM heap/hp_rfirst.c: BTREE heap key structure is now the same as MyISAM heap/hp_rkey.c: BTREE heap key structure is now the same as MyISAM heap/hp_rlast.c: BTREE heap key structure is now the same as MyISAM heap/hp_rnext.c: BTREE heap key structure is now the same as MyISAM heap/hp_rprev.c: BTREE heap key structure is now the same as MyISAM heap/hp_write.c: BTREE heap key structure is now the same as MyISAM include/heap.h: BTREE heap key structure is now the same as MyISAM include/my_handler.h: Removed hp_rb_key_cmp() _mi_compare_text -> mi_compate_text include/my_tree.h: Fixed typo myisam/ft_boolean_search.c: _mi_compare_text -> mi_compate_text myisam/ft_nlq_search.c: _mi_compare_text -> mi_compate_text myisam/ft_parser.c: _mi_compare_text -> mi_compate_text myisam/ft_stopwords.c: _mi_compare_text -> mi_compate_text myisam/ft_update.c: _mi_compare_text -> mi_compate_text mysys/my_handler.c: Removed hp_rb_key_cmp() _mi_compare_text -> mi_compate_text mysys/tree.c: BTREE heap key structure is now the same as MyISAM sql/ha_heap.cc: BTREE heap key structure is now the same as MyISAM
This commit is contained in:
parent
1b49cd8ca1
commit
c811538f89
@ -79,8 +79,9 @@ extern int hp_rec_key_cmp(HP_KEYDEF *keydef,const byte *rec1,
|
|||||||
extern int hp_key_cmp(HP_KEYDEF *keydef,const byte *rec,
|
extern int hp_key_cmp(HP_KEYDEF *keydef,const byte *rec,
|
||||||
const byte *key);
|
const byte *key);
|
||||||
extern void hp_make_key(HP_KEYDEF *keydef,byte *key,const byte *rec);
|
extern void hp_make_key(HP_KEYDEF *keydef,byte *key,const byte *rec);
|
||||||
extern void hp_rb_make_key(HP_KEYDEF *keydef, byte *key,
|
extern uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key,
|
||||||
const byte *rec, byte *recpos);
|
const byte *rec, byte *recpos);
|
||||||
|
extern uint hp_rb_key_length(HP_KEYDEF *keydef, const byte *key);
|
||||||
extern my_bool hp_if_null_in_key(HP_KEYDEF *keyinfo, const byte *record);
|
extern my_bool hp_if_null_in_key(HP_KEYDEF *keyinfo, const byte *record);
|
||||||
extern int hp_close(register HP_INFO *info);
|
extern int hp_close(register HP_INFO *info);
|
||||||
extern void hp_clear(HP_SHARE *info);
|
extern void hp_clear(HP_SHARE *info);
|
||||||
|
@ -65,12 +65,11 @@ int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
|
|||||||
heap_rb_param custom_arg;
|
heap_rb_param custom_arg;
|
||||||
|
|
||||||
if (flag)
|
if (flag)
|
||||||
info->last_pos = NULL; /* For heap_rnext/heap_rprev */
|
info->last_pos= NULL; /* For heap_rnext/heap_rprev */
|
||||||
|
|
||||||
hp_rb_make_key(keyinfo, info->recbuf, record, recpos);
|
custom_arg.keyseg= keyinfo->seg;
|
||||||
custom_arg.keyseg = keyinfo->seg;
|
custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos);
|
||||||
custom_arg.key_length = keyinfo->length;
|
custom_arg.search_flag= SEARCH_SAME;
|
||||||
custom_arg.search_flag = SEARCH_SAME;
|
|
||||||
return tree_delete(&keyinfo->rb_tree, info->recbuf, &custom_arg);
|
return tree_delete(&keyinfo->rb_tree, info->recbuf, &custom_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,14 +391,13 @@ int hp_rec_key_cmp(HP_KEYDEF *keydef, const byte *rec1, const byte *rec2)
|
|||||||
if (rec1[seg->null_pos] & seg->null_bit)
|
if (rec1[seg->null_pos] & seg->null_bit)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
switch (seg->type) {
|
if (seg->type == HA_KEYTYPE_TEXT)
|
||||||
case HA_KEYTYPE_END:
|
{
|
||||||
return 0;
|
|
||||||
case HA_KEYTYPE_TEXT:
|
|
||||||
if (my_sortcmp(seg->charset,rec1+seg->start,rec2+seg->start,seg->length))
|
if (my_sortcmp(seg->charset,rec1+seg->start,rec2+seg->start,seg->length))
|
||||||
return 1;
|
return 1;
|
||||||
break;
|
}
|
||||||
default:
|
else
|
||||||
|
{
|
||||||
if (bcmp(rec1+seg->start,rec2+seg->start,seg->length))
|
if (bcmp(rec1+seg->start,rec2+seg->start,seg->length))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -454,21 +453,24 @@ void hp_make_key(HP_KEYDEF *keydef, byte *key, const byte *rec)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hp_rb_make_key(HP_KEYDEF *keydef, byte *key,
|
uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key,
|
||||||
const byte *rec, byte *recpos)
|
const byte *rec, byte *recpos)
|
||||||
{
|
{
|
||||||
|
byte *start_key= key;
|
||||||
HA_KEYSEG *seg, *endseg;
|
HA_KEYSEG *seg, *endseg;
|
||||||
|
|
||||||
/* -1 means that HA_KEYTYPE_END segment will not copy */
|
for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++)
|
||||||
for (seg= keydef->seg, endseg= seg + keydef->keysegs - 1; seg < endseg;
|
|
||||||
seg++)
|
|
||||||
{
|
{
|
||||||
if (seg->null_bit)
|
if (seg->null_bit)
|
||||||
*key++= 1 - test(rec[seg->null_pos] & seg->null_bit);
|
{
|
||||||
|
if (!(*key++= 1 - test(rec[seg->null_pos] & seg->null_bit)))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
memcpy(key, rec + seg->start, (size_t) seg->length);
|
memcpy(key, rec + seg->start, (size_t) seg->length);
|
||||||
key+= seg->length;
|
key+= seg->length;
|
||||||
}
|
}
|
||||||
memcpy(key, &recpos, sizeof(byte*));
|
memcpy(key, &recpos, sizeof(byte*));
|
||||||
|
return key - start_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint hp_rb_pack_key(HP_INFO *info, uint inx, uchar *key, const uchar *old,
|
uint hp_rb_pack_key(HP_INFO *info, uint inx, uchar *key, const uchar *old,
|
||||||
@ -482,12 +484,39 @@ uint hp_rb_pack_key(HP_INFO *info, uint inx, uchar *key, const uchar *old,
|
|||||||
old+= seg->length, seg++)
|
old+= seg->length, seg++)
|
||||||
{
|
{
|
||||||
if (seg->null_bit)
|
if (seg->null_bit)
|
||||||
*key++= 1 - *old++;
|
{
|
||||||
|
if (!(*key++= (char) 1 - *old++))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
memcpy((byte*) key, old, seg->length);
|
memcpy((byte*) key, old, seg->length);
|
||||||
key+= seg->length;
|
key+= seg->length;
|
||||||
}
|
}
|
||||||
return key - start_key;
|
return key - start_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint hp_rb_key_length(HP_KEYDEF *keydef, const byte *key)
|
||||||
|
{
|
||||||
|
const byte *start_key= key;
|
||||||
|
HA_KEYSEG *seg, *endseg;
|
||||||
|
|
||||||
|
if (keydef->flag & HA_NULL_PART_KEY)
|
||||||
|
{
|
||||||
|
for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++)
|
||||||
|
{
|
||||||
|
if (seg->null_bit)
|
||||||
|
{
|
||||||
|
if (!*key++)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
key += seg->length;
|
||||||
|
}
|
||||||
|
return key - start_key;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return keydef->length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Test if any of the key parts are NULL.
|
Test if any of the key parts are NULL.
|
||||||
|
111
heap/hp_open.c
111
heap/hp_open.c
@ -26,8 +26,8 @@
|
|||||||
static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2)
|
static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2)
|
||||||
{
|
{
|
||||||
uint not_used;
|
uint not_used;
|
||||||
return hp_rb_key_cmp(param->keyseg, key1, key2, param->key_length,
|
return ha_key_cmp(param->keyseg, key1, key2, param->key_length,
|
||||||
param->search_flag, ¬_used);
|
param->search_flag, ¬_used);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_block(HP_BLOCK *block,uint reclength,ulong min_records,
|
static void init_block(HP_BLOCK *block,uint reclength,ulong min_records,
|
||||||
@ -52,25 +52,28 @@ HP_INFO *heap_open(const char *name, int mode, uint keys, HP_KEYDEF *keydef,
|
|||||||
for (i=key_segs=max_length=0 ; i < keys ; i++)
|
for (i=key_segs=max_length=0 ; i < keys ; i++)
|
||||||
{
|
{
|
||||||
key_segs+= keydef[i].keysegs;
|
key_segs+= keydef[i].keysegs;
|
||||||
|
if (keydef[i].algorithm == HA_KEY_ALG_BTREE)
|
||||||
|
key_segs++;
|
||||||
bzero((char*) &keydef[i].block,sizeof(keydef[i].block));
|
bzero((char*) &keydef[i].block,sizeof(keydef[i].block));
|
||||||
bzero((char*) &keydef[i].rb_tree ,sizeof(keydef[i].rb_tree));
|
bzero((char*) &keydef[i].rb_tree ,sizeof(keydef[i].rb_tree));
|
||||||
for (j=length=0 ; j < keydef[i].keysegs; j++)
|
for (j=length=0 ; j < keydef[i].keysegs; j++)
|
||||||
{
|
{
|
||||||
length+=keydef[i].seg[j].length;
|
length+=keydef[i].seg[j].length;
|
||||||
if (keydef[i].seg[j].null_bit &&
|
if (keydef[i].seg[j].null_bit)
|
||||||
!(keydef[i].flag & HA_NULL_ARE_EQUAL))
|
{
|
||||||
keydef[i].flag |= HA_NULL_PART_KEY;
|
if (!(keydef[i].flag & HA_NULL_ARE_EQUAL))
|
||||||
if (keydef[i].algorithm == HA_KEY_ALG_BTREE &&
|
keydef[i].flag |= HA_NULL_PART_KEY;
|
||||||
keydef[i].seg[j].null_bit)
|
if (keydef[i].algorithm == HA_KEY_ALG_BTREE)
|
||||||
keydef[i].rb_tree.size_of_element++;
|
keydef[i].rb_tree.size_of_element++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
keydef[i].length= length;
|
keydef[i].length= length;
|
||||||
keydef[i].ref_offs= length + keydef[i].rb_tree.size_of_element -
|
length+= keydef[i].rb_tree.size_of_element +
|
||||||
sizeof(byte*);
|
((keydef[i].algorithm == HA_KEY_ALG_BTREE) ? sizeof(byte*) : 0);
|
||||||
if (length + keydef[i].rb_tree.size_of_element > max_length)
|
if (length > max_length)
|
||||||
max_length= length + keydef[i].rb_tree.size_of_element;
|
max_length= length;
|
||||||
}
|
}
|
||||||
if (!(share = (HP_SHARE*) my_malloc((uint) sizeof(HP_SHARE)+
|
if (!(share= (HP_SHARE*) my_malloc((uint) sizeof(HP_SHARE)+
|
||||||
keys*sizeof(HP_KEYDEF)+
|
keys*sizeof(HP_KEYDEF)+
|
||||||
key_segs*sizeof(HA_KEYSEG),
|
key_segs*sizeof(HA_KEYSEG),
|
||||||
MYF(MY_ZEROFILL))))
|
MYF(MY_ZEROFILL))))
|
||||||
@ -78,44 +81,46 @@ HP_INFO *heap_open(const char *name, int mode, uint keys, HP_KEYDEF *keydef,
|
|||||||
pthread_mutex_unlock(&THR_LOCK_heap);
|
pthread_mutex_unlock(&THR_LOCK_heap);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
share->keydef=(HP_KEYDEF*) (share+1);
|
share->keydef= (HP_KEYDEF*) (share + 1);
|
||||||
keyseg=(HA_KEYSEG*) (share->keydef+keys);
|
keyseg= (HA_KEYSEG*) (share->keydef + keys);
|
||||||
init_block(&share->block,reclength+1,min_records,max_records);
|
init_block(&share->block, reclength + 1, min_records, max_records);
|
||||||
/* Fix keys */
|
/* Fix keys */
|
||||||
memcpy(share->keydef,keydef,(size_t) (sizeof(keydef[0])*keys));
|
memcpy(share->keydef, keydef, (size_t) (sizeof(keydef[0]) * keys));
|
||||||
for (i=0 ; i < keys ; i++)
|
for (i= 0; i < keys; i++)
|
||||||
{
|
{
|
||||||
HP_KEYDEF *keyinfo = share->keydef + i;
|
HP_KEYDEF *keyinfo= share->keydef + i;
|
||||||
keyinfo->seg = keyseg;
|
uint nsegs= keydef[i].keysegs;
|
||||||
memcpy(keyseg, keydef[i].seg,
|
|
||||||
(size_t) (sizeof(keyseg[0]) * keydef[i].keysegs));
|
|
||||||
keyseg += keydef[i].keysegs;
|
|
||||||
if (keydef[i].algorithm == HA_KEY_ALG_BTREE)
|
if (keydef[i].algorithm == HA_KEY_ALG_BTREE)
|
||||||
{
|
{
|
||||||
init_tree(&keyinfo->rb_tree, 0, 0, keydef[i].length +
|
init_tree(&keyinfo->rb_tree, 0, 0, 0, (qsort_cmp2)keys_compare, 1,
|
||||||
keydef[i].rb_tree.size_of_element,
|
NULL, NULL);
|
||||||
(qsort_cmp2)keys_compare, 1, NULL, NULL);
|
keyinfo->delete_key= hp_rb_delete_key;
|
||||||
keyinfo->delete_key = hp_rb_delete_key;
|
keyinfo->write_key= hp_rb_write_key;
|
||||||
keyinfo->write_key = hp_rb_write_key;
|
nsegs++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
init_block(&keyinfo->block, sizeof(HASH_INFO), min_records,
|
init_block(&keyinfo->block, sizeof(HASH_INFO), min_records,
|
||||||
max_records);
|
max_records);
|
||||||
keyinfo->delete_key = hp_delete_key;
|
keyinfo->delete_key= hp_delete_key;
|
||||||
keyinfo->write_key = hp_write_key;
|
keyinfo->write_key= hp_write_key;
|
||||||
}
|
}
|
||||||
|
keyinfo->seg= keyseg;
|
||||||
|
memcpy(keyseg, keydef[i].seg,
|
||||||
|
(size_t) (sizeof(keyseg[0]) * nsegs));
|
||||||
|
keyseg+= nsegs;
|
||||||
}
|
}
|
||||||
|
|
||||||
share->min_records=min_records;
|
share->min_records= min_records;
|
||||||
share->max_records=max_records;
|
share->max_records= max_records;
|
||||||
share->data_length=share->index_length=0;
|
share->data_length= share->index_length= 0;
|
||||||
share->reclength=reclength;
|
share->reclength= reclength;
|
||||||
share->blength=1;
|
share->blength= 1;
|
||||||
share->keys=keys;
|
share->keys= keys;
|
||||||
share->max_key_length=max_length;
|
share->max_key_length= max_length;
|
||||||
share->changed=0;
|
share->changed= 0;
|
||||||
if (!(share->name=my_strdup(name,MYF(0))))
|
if (!(share->name= my_strdup(name,MYF(0))))
|
||||||
{
|
{
|
||||||
my_free((gptr) share,MYF(0));
|
my_free((gptr) share,MYF(0));
|
||||||
pthread_mutex_unlock(&THR_LOCK_heap);
|
pthread_mutex_unlock(&THR_LOCK_heap);
|
||||||
@ -125,8 +130,8 @@ HP_INFO *heap_open(const char *name, int mode, uint keys, HP_KEYDEF *keydef,
|
|||||||
thr_lock_init(&share->lock);
|
thr_lock_init(&share->lock);
|
||||||
VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST));
|
VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST));
|
||||||
#endif
|
#endif
|
||||||
share->open_list.data=(void*) share;
|
share->open_list.data= (void*) share;
|
||||||
heap_share_list=list_add(heap_share_list,&share->open_list);
|
heap_share_list= list_add(heap_share_list,&share->open_list);
|
||||||
}
|
}
|
||||||
if (!(info= (HP_INFO*) my_malloc((uint) sizeof(HP_INFO)+
|
if (!(info= (HP_INFO*) my_malloc((uint) sizeof(HP_INFO)+
|
||||||
2 * share->max_key_length,
|
2 * share->max_key_length,
|
||||||
@ -139,21 +144,21 @@ HP_INFO *heap_open(const char *name, int mode, uint keys, HP_KEYDEF *keydef,
|
|||||||
#ifdef THREAD
|
#ifdef THREAD
|
||||||
thr_lock_data_init(&share->lock,&info->lock,NULL);
|
thr_lock_data_init(&share->lock,&info->lock,NULL);
|
||||||
#endif
|
#endif
|
||||||
info->open_list.data=(void*) info;
|
info->open_list.data= (void*) info;
|
||||||
heap_open_list=list_add(heap_open_list,&info->open_list);
|
heap_open_list= list_add(heap_open_list,&info->open_list);
|
||||||
pthread_mutex_unlock(&THR_LOCK_heap);
|
pthread_mutex_unlock(&THR_LOCK_heap);
|
||||||
|
|
||||||
info->s=share;
|
info->s= share;
|
||||||
info->lastkey=(byte*) (info+1);
|
info->lastkey= (byte*) (info + 1);
|
||||||
info->recbuf = (byte*) (info->lastkey + share->max_key_length);
|
info->recbuf= (byte*) (info->lastkey + share->max_key_length);
|
||||||
info->mode=mode;
|
info->mode= mode;
|
||||||
info->current_record= (ulong) ~0L; /* No current record */
|
info->current_record= (ulong) ~0L; /* No current record */
|
||||||
info->current_ptr=0;
|
info->current_ptr= 0;
|
||||||
info->current_hash_ptr=0;
|
info->current_hash_ptr= 0;
|
||||||
info->lastinx= info->errkey= -1;
|
info->lastinx= info->errkey= -1;
|
||||||
info->update=0;
|
info->update= 0;
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
info->opt_flag=READ_CHECK_USED; /* Check when changing */
|
info->opt_flag= READ_CHECK_USED; /* Check when changing */
|
||||||
#endif
|
#endif
|
||||||
DBUG_PRINT("exit",("heap: %lx reclength: %d records_in_block: %d",
|
DBUG_PRINT("exit",("heap: %lx reclength: %d records_in_block: %d",
|
||||||
info,share->reclength,share->block.records_in_block));
|
info,share->reclength,share->block.records_in_block));
|
||||||
|
@ -31,7 +31,7 @@ int heap_rfirst(HP_INFO *info, byte *record, int inx)
|
|||||||
if ((pos = tree_search_edge(&keyinfo->rb_tree, info->parents,
|
if ((pos = tree_search_edge(&keyinfo->rb_tree, info->parents,
|
||||||
&info->last_pos, offsetof(TREE_ELEMENT, left))))
|
&info->last_pos, offsetof(TREE_ELEMENT, left))))
|
||||||
{
|
{
|
||||||
memcpy(&pos, pos + keyinfo->ref_offs, sizeof(byte*));
|
memcpy(&pos, pos + hp_rb_key_length(keyinfo, pos), sizeof(byte*));
|
||||||
info->current_ptr = pos;
|
info->current_ptr = pos;
|
||||||
memcpy(record, pos, (size_t)share->reclength);
|
memcpy(record, pos, (size_t)share->reclength);
|
||||||
info->update = HA_STATE_AKTIV;
|
info->update = HA_STATE_AKTIV;
|
||||||
|
@ -55,7 +55,7 @@ int heap_rkey(HP_INFO *info, byte *record, int inx, const byte *key,
|
|||||||
info->update = 0;
|
info->update = 0;
|
||||||
DBUG_RETURN(my_errno = HA_ERR_KEY_NOT_FOUND);
|
DBUG_RETURN(my_errno = HA_ERR_KEY_NOT_FOUND);
|
||||||
}
|
}
|
||||||
memcpy(&pos, pos + keyinfo->ref_offs, sizeof(byte*));
|
memcpy(&pos, pos + hp_rb_key_length(keyinfo, pos), sizeof(byte*));
|
||||||
info->current_ptr = pos;
|
info->current_ptr = pos;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -32,7 +32,7 @@ int heap_rlast(HP_INFO *info, byte *record, int inx)
|
|||||||
if ((pos = tree_search_edge(&keyinfo->rb_tree, info->parents,
|
if ((pos = tree_search_edge(&keyinfo->rb_tree, info->parents,
|
||||||
&info->last_pos, offsetof(TREE_ELEMENT, right))))
|
&info->last_pos, offsetof(TREE_ELEMENT, right))))
|
||||||
{
|
{
|
||||||
memcpy(&pos, pos + keyinfo->ref_offs, sizeof(byte*));
|
memcpy(&pos, pos + hp_rb_key_length(keyinfo, pos), sizeof(byte*));
|
||||||
info->current_ptr = pos;
|
info->current_ptr = pos;
|
||||||
memcpy(record, pos, (size_t)share->reclength);
|
memcpy(record, pos, (size_t)share->reclength);
|
||||||
info->update = HA_STATE_AKTIV;
|
info->update = HA_STATE_AKTIV;
|
||||||
|
@ -47,7 +47,7 @@ int heap_rnext(HP_INFO *info, byte *record)
|
|||||||
}
|
}
|
||||||
if (pos)
|
if (pos)
|
||||||
{
|
{
|
||||||
memcpy(&pos, pos + keyinfo->ref_offs, sizeof(byte*));
|
memcpy(&pos, pos + hp_rb_key_length(keyinfo, pos), sizeof(byte*));
|
||||||
info->current_ptr = pos;
|
info->current_ptr = pos;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -47,7 +47,7 @@ int heap_rprev(HP_INFO *info, byte *record)
|
|||||||
}
|
}
|
||||||
if (pos)
|
if (pos)
|
||||||
{
|
{
|
||||||
memcpy(&pos, pos + keyinfo->ref_offs, sizeof(byte*));
|
memcpy(&pos, pos + hp_rb_key_length(keyinfo, pos), sizeof(byte*));
|
||||||
info->current_ptr = pos;
|
info->current_ptr = pos;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -93,25 +93,25 @@ int hp_rb_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, const byte *record,
|
|||||||
{
|
{
|
||||||
heap_rb_param custom_arg;
|
heap_rb_param custom_arg;
|
||||||
|
|
||||||
info->last_pos = NULL; /* For heap_rnext/heap_rprev */
|
info->last_pos= NULL; /* For heap_rnext/heap_rprev */
|
||||||
hp_rb_make_key(keyinfo, info->recbuf, record, recpos);
|
custom_arg.keyseg= keyinfo->seg;
|
||||||
custom_arg.keyseg = keyinfo->seg;
|
custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos);
|
||||||
custom_arg.key_length = keyinfo->length;
|
|
||||||
if ((keyinfo->flag & HA_NOSAME) &&
|
if ((keyinfo->flag & HA_NOSAME) &&
|
||||||
(!(keyinfo->flag & HA_NULL_PART_KEY) ||
|
(!(keyinfo->flag & HA_NULL_PART_KEY) ||
|
||||||
!hp_if_null_in_key(keyinfo, record)))
|
!hp_if_null_in_key(keyinfo, record)))
|
||||||
{
|
{
|
||||||
custom_arg.search_flag = SEARCH_FIND | SEARCH_SAME;
|
custom_arg.search_flag= SEARCH_FIND | SEARCH_SAME;
|
||||||
if (tree_search_key(&keyinfo->rb_tree, info->recbuf, info->parents,
|
if (tree_search_key(&keyinfo->rb_tree, info->recbuf, info->parents,
|
||||||
&info->last_pos, 0, &custom_arg))
|
&info->last_pos, 0, &custom_arg))
|
||||||
{
|
{
|
||||||
my_errno = HA_ERR_FOUND_DUPP_KEY;
|
my_errno= HA_ERR_FOUND_DUPP_KEY;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
custom_arg.search_flag = SEARCH_SAME;
|
custom_arg.search_flag= SEARCH_SAME;
|
||||||
return tree_insert(&keyinfo->rb_tree, (void*)info->recbuf, keyinfo->length +
|
return tree_insert(&keyinfo->rb_tree, (void*)info->recbuf,
|
||||||
sizeof(byte*), &custom_arg) ? 0 : 1;
|
custom_arg.key_length + sizeof(byte*),
|
||||||
|
&custom_arg) ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find where to place new record */
|
/* Find where to place new record */
|
||||||
|
@ -84,7 +84,6 @@ typedef struct st_hp_keydef /* Key definition with open */
|
|||||||
uint keysegs; /* Number of key-segment */
|
uint keysegs; /* Number of key-segment */
|
||||||
uint length; /* Length of key (automatic) */
|
uint length; /* Length of key (automatic) */
|
||||||
uint8 algorithm; /* HASH / BTREE */
|
uint8 algorithm; /* HASH / BTREE */
|
||||||
uint ref_offs; /* Data reference offset */
|
|
||||||
HA_KEYSEG *seg;
|
HA_KEYSEG *seg;
|
||||||
HP_BLOCK block; /* Where keys are saved */
|
HP_BLOCK block; /* Where keys are saved */
|
||||||
TREE rb_tree;
|
TREE rb_tree;
|
||||||
@ -131,7 +130,7 @@ typedef struct st_heap_info
|
|||||||
byte *lastkey; /* Last used key with rkey */
|
byte *lastkey; /* Last used key with rkey */
|
||||||
byte *recbuf; /* Record buffer for rb-tree keys */
|
byte *recbuf; /* Record buffer for rb-tree keys */
|
||||||
enum ha_rkey_function last_find_flag;
|
enum ha_rkey_function last_find_flag;
|
||||||
TREE_ELEMENT *parents[MAX_TREE_HIGHT+1];
|
TREE_ELEMENT *parents[MAX_TREE_HEIGHT+1];
|
||||||
TREE_ELEMENT **last_pos;
|
TREE_ELEMENT **last_pos;
|
||||||
uint lastkey_len;
|
uint lastkey_len;
|
||||||
#ifdef THREAD
|
#ifdef THREAD
|
||||||
|
@ -50,14 +50,10 @@ typedef struct st_HA_KEYSEG /* Key-portion */
|
|||||||
{ length=mi_uint2korr((key)+1); (key)+=3; length_pack=3; } \
|
{ length=mi_uint2korr((key)+1); (key)+=3; length_pack=3; } \
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int _mi_compare_text(CHARSET_INFO *, uchar *, uint, uchar *, uint ,
|
extern int mi_compare_text(CHARSET_INFO *, uchar *, uint, uchar *, uint ,
|
||||||
my_bool);
|
my_bool);
|
||||||
extern int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
extern int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||||
register uchar *b, uint key_length, uint nextflag,
|
register uchar *b, uint key_length, uint nextflag,
|
||||||
uint *diff_pos);
|
uint *diff_pos);
|
||||||
|
|
||||||
extern int hp_rb_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
|
||||||
register uchar *b, uint key_length, uint nextflag,
|
|
||||||
uint *diff_pos);
|
|
||||||
|
|
||||||
#endif /* _my_handler_h */
|
#endif /* _my_handler_h */
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_TREE_HIGHT 40 /* = max 1048576 leafs in tree */
|
#define MAX_TREE_HEIGHT 40 /* = max 1048576 leafs in tree */
|
||||||
#define ELEMENT_KEY(tree,element)\
|
#define ELEMENT_KEY(tree,element)\
|
||||||
(tree->offset_to_key ? (void*)((byte*) element+tree->offset_to_key) :\
|
(tree->offset_to_key ? (void*)((byte*) element+tree->offset_to_key) :\
|
||||||
*((void**) (element+1)))
|
*((void**) (element+1)))
|
||||||
@ -52,7 +52,7 @@ typedef struct st_tree_element {
|
|||||||
|
|
||||||
typedef struct st_tree {
|
typedef struct st_tree {
|
||||||
TREE_ELEMENT *root,null_element;
|
TREE_ELEMENT *root,null_element;
|
||||||
TREE_ELEMENT **parents[MAX_TREE_HIGHT];
|
TREE_ELEMENT **parents[MAX_TREE_HEIGHT];
|
||||||
uint offset_to_key,elements_in_tree,size_of_element,memory_limit,allocated;
|
uint offset_to_key,elements_in_tree,size_of_element,memory_limit,allocated;
|
||||||
qsort_cmp2 compare;
|
qsort_cmp2 compare;
|
||||||
void* custom_arg;
|
void* custom_arg;
|
||||||
|
@ -104,7 +104,7 @@ int FTB_WORD_cmp(void *v __attribute__((unused)), FTB_WORD *a, FTB_WORD *b)
|
|||||||
int FTB_WORD_cmp_list(void *v __attribute__((unused)), FTB_WORD **a, FTB_WORD **b)
|
int FTB_WORD_cmp_list(void *v __attribute__((unused)), FTB_WORD **a, FTB_WORD **b)
|
||||||
{
|
{
|
||||||
/* ORDER BY word DESC, ndepth DESC */
|
/* ORDER BY word DESC, ndepth DESC */
|
||||||
int i=_mi_compare_text(default_charset_info, (*b)->word+1,(*b)->len-1,
|
int i= mi_compare_text(default_charset_info, (*b)->word+1,(*b)->len-1,
|
||||||
(*a)->word+1,(*a)->len-1,0);
|
(*a)->word+1,(*a)->len-1,0);
|
||||||
if (!i)
|
if (!i)
|
||||||
i=CMP_NUM((*b)->ndepth,(*a)->ndepth);
|
i=CMP_NUM((*b)->ndepth,(*a)->ndepth);
|
||||||
@ -203,7 +203,7 @@ void _ftb_init_index_search(FT_INFO *ftb)
|
|||||||
SEARCH_FIND | SEARCH_BIGGER, keyroot);
|
SEARCH_FIND | SEARCH_BIGGER, keyroot);
|
||||||
if (!r)
|
if (!r)
|
||||||
{
|
{
|
||||||
r=_mi_compare_text(default_charset_info,
|
r= mi_compare_text(default_charset_info,
|
||||||
info->lastkey + (ftbw->flags&FTB_FLAG_TRUNC),
|
info->lastkey + (ftbw->flags&FTB_FLAG_TRUNC),
|
||||||
ftbw->len - (ftbw->flags&FTB_FLAG_TRUNC),
|
ftbw->len - (ftbw->flags&FTB_FLAG_TRUNC),
|
||||||
ftbw->word + (ftbw->flags&FTB_FLAG_TRUNC),
|
ftbw->word + (ftbw->flags&FTB_FLAG_TRUNC),
|
||||||
@ -359,7 +359,7 @@ int ft_boolean_read_next(FT_INFO *ftb, char *record)
|
|||||||
SEARCH_BIGGER , keyroot);
|
SEARCH_BIGGER , keyroot);
|
||||||
if (!r)
|
if (!r)
|
||||||
{
|
{
|
||||||
r=_mi_compare_text(default_charset_info,
|
r= mi_compare_text(default_charset_info,
|
||||||
info->lastkey + (ftbw->flags&FTB_FLAG_TRUNC),
|
info->lastkey + (ftbw->flags&FTB_FLAG_TRUNC),
|
||||||
ftbw->len - (ftbw->flags&FTB_FLAG_TRUNC),
|
ftbw->len - (ftbw->flags&FTB_FLAG_TRUNC),
|
||||||
ftbw->word + (ftbw->flags&FTB_FLAG_TRUNC),
|
ftbw->word + (ftbw->flags&FTB_FLAG_TRUNC),
|
||||||
@ -443,7 +443,7 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length)
|
|||||||
for (a=0, b=ftb->queue.elements, c=(a+b)/2; b-a>1; c=(a+b)/2)
|
for (a=0, b=ftb->queue.elements, c=(a+b)/2; b-a>1; c=(a+b)/2)
|
||||||
{
|
{
|
||||||
ftbw=(FTB_WORD *)(ftb->list[c]);
|
ftbw=(FTB_WORD *)(ftb->list[c]);
|
||||||
if (_mi_compare_text(default_charset_info, word.pos,word.len,
|
if (mi_compare_text(default_charset_info, word.pos,word.len,
|
||||||
(uchar*) ftbw->word+1,ftbw->len-1,
|
(uchar*) ftbw->word+1,ftbw->len-1,
|
||||||
(ftbw->flags&FTB_FLAG_TRUNC) ) >0)
|
(ftbw->flags&FTB_FLAG_TRUNC) ) >0)
|
||||||
b=c;
|
b=c;
|
||||||
@ -453,7 +453,7 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length)
|
|||||||
for (; c>=0; c--)
|
for (; c>=0; c--)
|
||||||
{
|
{
|
||||||
ftbw=(FTB_WORD *)(ftb->list[c]);
|
ftbw=(FTB_WORD *)(ftb->list[c]);
|
||||||
if (_mi_compare_text(default_charset_info, word.pos,word.len,
|
if (mi_compare_text(default_charset_info, word.pos,word.len,
|
||||||
(uchar*) ftbw->word+1,ftbw->len-1,
|
(uchar*) ftbw->word+1,ftbw->len-1,
|
||||||
(ftbw->flags&FTB_FLAG_TRUNC) ))
|
(ftbw->flags&FTB_FLAG_TRUNC) ))
|
||||||
break;
|
break;
|
||||||
|
@ -93,9 +93,9 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
|
|||||||
|
|
||||||
while(!r)
|
while(!r)
|
||||||
{
|
{
|
||||||
if (_mi_compare_text(default_charset_info,
|
if (mi_compare_text(default_charset_info,
|
||||||
aio->info->lastkey,keylen,
|
aio->info->lastkey,keylen,
|
||||||
aio->keybuff,keylen,0)) break;
|
aio->keybuff,keylen,0)) break;
|
||||||
|
|
||||||
#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT
|
#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT
|
||||||
#ifdef EVAL_RUN
|
#ifdef EVAL_RUN
|
||||||
|
@ -37,10 +37,10 @@ typedef struct st_ft_docstat {
|
|||||||
|
|
||||||
static int FT_WORD_cmp(void* cmp_arg, FT_WORD *w1, FT_WORD *w2)
|
static int FT_WORD_cmp(void* cmp_arg, FT_WORD *w1, FT_WORD *w2)
|
||||||
{
|
{
|
||||||
return _mi_compare_text(default_charset_info,
|
return mi_compare_text(default_charset_info,
|
||||||
(uchar*) w1->pos, w1->len,
|
(uchar*) w1->pos, w1->len,
|
||||||
(uchar*) w2->pos, w2->len,
|
(uchar*) w2->pos, w2->len,
|
||||||
(my_bool) (cmp_arg != 0));
|
(my_bool) (cmp_arg != 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int walk_and_copy(FT_WORD *word,uint32 count,FT_DOCSTAT *docstat)
|
static int walk_and_copy(FT_WORD *word,uint32 count,FT_DOCSTAT *docstat)
|
||||||
|
@ -28,9 +28,9 @@ static TREE *stopwords3=NULL;
|
|||||||
static int FT_STOPWORD_cmp(void* cmp_arg __attribute__((unused)),
|
static int FT_STOPWORD_cmp(void* cmp_arg __attribute__((unused)),
|
||||||
FT_STOPWORD *w1, FT_STOPWORD *w2)
|
FT_STOPWORD *w1, FT_STOPWORD *w2)
|
||||||
{
|
{
|
||||||
return _mi_compare_text(default_charset_info,
|
return mi_compare_text(default_charset_info,
|
||||||
(uchar *)w1->pos,w1->len,
|
(uchar *)w1->pos,w1->len,
|
||||||
(uchar *)w2->pos,w2->len,0);
|
(uchar *)w2->pos,w2->len,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ft_init_stopwords(const char **sws)
|
int ft_init_stopwords(const char **sws)
|
||||||
|
@ -160,7 +160,7 @@ int _mi_ft_cmp(MI_INFO *info, uint keynr, const byte *rec1, const byte *rec2)
|
|||||||
{
|
{
|
||||||
if ((ftsi1.pos != ftsi2.pos) &&
|
if ((ftsi1.pos != ftsi2.pos) &&
|
||||||
(!ftsi1.pos || !ftsi2.pos ||
|
(!ftsi1.pos || !ftsi2.pos ||
|
||||||
_mi_compare_text(default_charset_info,
|
mi_compare_text(default_charset_info,
|
||||||
(uchar*) ftsi1.pos,ftsi1.len,
|
(uchar*) ftsi1.pos,ftsi1.len,
|
||||||
(uchar*) ftsi2.pos,ftsi2.len,0)))
|
(uchar*) ftsi2.pos,ftsi2.len,0)))
|
||||||
return THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT;
|
return THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT;
|
||||||
@ -185,7 +185,7 @@ int _mi_ft_update(MI_INFO *info, uint keynr, byte *keybuf,
|
|||||||
error=0;
|
error=0;
|
||||||
while(old_word->pos && new_word->pos)
|
while(old_word->pos && new_word->pos)
|
||||||
{
|
{
|
||||||
cmp=_mi_compare_text(default_charset_info,
|
cmp= mi_compare_text(default_charset_info,
|
||||||
(uchar*) old_word->pos,old_word->len,
|
(uchar*) old_word->pos,old_word->len,
|
||||||
(uchar*) new_word->pos,new_word->len,0);
|
(uchar*) new_word->pos,new_word->len,0);
|
||||||
cmp2= cmp ? 0 : (fabs(old_word->weight - new_word->weight) > 1.e-5);
|
cmp2= cmp ? 0 : (fabs(old_word->weight - new_word->weight) > 1.e-5);
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
|
|
||||||
#include "my_handler.h"
|
#include "my_handler.h"
|
||||||
|
|
||||||
int _mi_compare_text(CHARSET_INFO *charset_info, uchar *a, uint a_length,
|
int mi_compare_text(CHARSET_INFO *charset_info, uchar *a, uint a_length,
|
||||||
uchar *b, uint b_length, my_bool part_key)
|
uchar *b, uint b_length, my_bool part_key)
|
||||||
{
|
{
|
||||||
int flag;
|
int flag;
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
|||||||
get_key_pack_length(b_length,pack_length,b);
|
get_key_pack_length(b_length,pack_length,b);
|
||||||
next_key_length=key_length-b_length-pack_length;
|
next_key_length=key_length-b_length-pack_length;
|
||||||
|
|
||||||
if ((flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
|
if ((flag= mi_compare_text(keyseg->charset,a,a_length,b,b_length,
|
||||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
||||||
next_key_length <= 0))))
|
next_key_length <= 0))))
|
||||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||||
@ -133,7 +133,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
|||||||
while (b_length && b[b_length-1] == ' ')
|
while (b_length && b[b_length-1] == ' ')
|
||||||
b_length--;
|
b_length--;
|
||||||
}
|
}
|
||||||
if ((flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
|
if ((flag= mi_compare_text(keyseg->charset,a,a_length,b,b_length,
|
||||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
||||||
next_key_length <= 0))))
|
next_key_length <= 0))))
|
||||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||||
@ -175,7 +175,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
|||||||
get_key_pack_length(b_length,pack_length,b);
|
get_key_pack_length(b_length,pack_length,b);
|
||||||
next_key_length=key_length-b_length-pack_length;
|
next_key_length=key_length-b_length-pack_length;
|
||||||
|
|
||||||
if ((flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
|
if ((flag= mi_compare_text(keyseg->charset,a,a_length,b,b_length,
|
||||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
||||||
next_key_length <= 0))))
|
next_key_length <= 0))))
|
||||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||||
@ -385,333 +385,4 @@ end:
|
|||||||
return (flag < 0 ? -1 : 1); /* read previous */
|
return (flag < 0 ? -1 : 1); /* read previous */
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
} /* my_key_cmp */
|
} /* ha_key_cmp */
|
||||||
|
|
||||||
/*
|
|
||||||
Compare two keys
|
|
||||||
Returns <0, 0, >0 acording to which is bigger
|
|
||||||
Key_length specifies length of key to use. Number-keys can't be splited
|
|
||||||
If flag <> SEARCH_FIND compare also position
|
|
||||||
*/
|
|
||||||
int hp_rb_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
|
||||||
register uchar *b, uint key_length, uint nextflag,
|
|
||||||
uint *diff_pos)
|
|
||||||
{
|
|
||||||
int flag;
|
|
||||||
int16 s_1,s_2;
|
|
||||||
int32 l_1,l_2;
|
|
||||||
uint32 u_1,u_2;
|
|
||||||
float f_1,f_2;
|
|
||||||
double d_1,d_2;
|
|
||||||
uint next_key_length;
|
|
||||||
|
|
||||||
*diff_pos=0;
|
|
||||||
for ( ; (int) key_length >0 ; key_length=next_key_length, keyseg++)
|
|
||||||
{
|
|
||||||
uchar *end;
|
|
||||||
(*diff_pos)++;
|
|
||||||
|
|
||||||
/* Handle NULL part */
|
|
||||||
if (keyseg->null_bit)
|
|
||||||
{
|
|
||||||
key_length--;
|
|
||||||
if (*a != *b)
|
|
||||||
{
|
|
||||||
flag = (int) *a - (int) *b;
|
|
||||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
||||||
}
|
|
||||||
b++;
|
|
||||||
if (!*a++) /* If key was NULL */
|
|
||||||
{
|
|
||||||
if (nextflag == (SEARCH_FIND | SEARCH_UPDATE))
|
|
||||||
nextflag=SEARCH_SAME; /* Allow duplicate keys */
|
|
||||||
next_key_length=key_length;
|
|
||||||
a+= keyseg->length;
|
|
||||||
b+= keyseg->length;
|
|
||||||
key_length-= keyseg->length;
|
|
||||||
continue; /* To next key part */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end= a+ min(keyseg->length,key_length);
|
|
||||||
next_key_length=key_length-keyseg->length;
|
|
||||||
|
|
||||||
switch ((enum ha_base_keytype) keyseg->type) {
|
|
||||||
case HA_KEYTYPE_TEXT: /* Ascii; Key is converted */
|
|
||||||
if (keyseg->flag & HA_SPACE_PACK)
|
|
||||||
{
|
|
||||||
int a_length,b_length,pack_length;
|
|
||||||
get_key_length(a_length,a);
|
|
||||||
get_key_pack_length(b_length,pack_length,b);
|
|
||||||
next_key_length=key_length-b_length-pack_length;
|
|
||||||
|
|
||||||
if ((flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
|
|
||||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
|
||||||
next_key_length <= 0))))
|
|
||||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
||||||
a+=a_length;
|
|
||||||
b+=b_length;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uint length=(uint) (end-a), a_length=length, b_length=length;
|
|
||||||
if (!(nextflag & SEARCH_PREFIX))
|
|
||||||
{
|
|
||||||
while (a_length && a[a_length-1] == ' ')
|
|
||||||
a_length--;
|
|
||||||
while (b_length && b[b_length-1] == ' ')
|
|
||||||
b_length--;
|
|
||||||
}
|
|
||||||
if ((flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
|
|
||||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
|
||||||
next_key_length <= 0))))
|
|
||||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
||||||
a=end;
|
|
||||||
b+=length;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case HA_KEYTYPE_BINARY:
|
|
||||||
if (keyseg->flag & HA_SPACE_PACK)
|
|
||||||
{
|
|
||||||
int a_length,b_length,pack_length;
|
|
||||||
get_key_length(a_length,a);
|
|
||||||
get_key_pack_length(b_length,pack_length,b);
|
|
||||||
next_key_length=key_length-b_length-pack_length;
|
|
||||||
|
|
||||||
if ((flag=compare_bin(a,a_length,b,b_length,
|
|
||||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
|
||||||
next_key_length <= 0))))
|
|
||||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
||||||
a+=a_length;
|
|
||||||
b+=b_length;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uint length=keyseg->length;
|
|
||||||
if ((flag=compare_bin(a,length,b,length,
|
|
||||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
|
||||||
next_key_length <= 0))))
|
|
||||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
||||||
a+=length;
|
|
||||||
b+=length;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case HA_KEYTYPE_VARTEXT:
|
|
||||||
{
|
|
||||||
int a_length,b_length,pack_length;
|
|
||||||
get_key_length(a_length,a);
|
|
||||||
get_key_pack_length(b_length,pack_length,b);
|
|
||||||
next_key_length=key_length-b_length-pack_length;
|
|
||||||
|
|
||||||
if ((flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
|
|
||||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
|
||||||
next_key_length <= 0))))
|
|
||||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
||||||
a+=a_length;
|
|
||||||
b+=b_length;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case HA_KEYTYPE_VARBINARY:
|
|
||||||
{
|
|
||||||
int a_length,b_length,pack_length;
|
|
||||||
get_key_length(a_length,a);
|
|
||||||
get_key_pack_length(b_length,pack_length,b);
|
|
||||||
next_key_length=key_length-b_length-pack_length;
|
|
||||||
|
|
||||||
if ((flag=compare_bin(a,a_length,b,b_length,
|
|
||||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
|
||||||
next_key_length <= 0))))
|
|
||||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
||||||
a+=a_length;
|
|
||||||
b+=b_length;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case HA_KEYTYPE_INT8:
|
|
||||||
{
|
|
||||||
int i_1= (int) *((signed char*) a);
|
|
||||||
int i_2= (int) *((signed char*) b);
|
|
||||||
if ((flag = CMP(i_1,i_2)))
|
|
||||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
||||||
a= end;
|
|
||||||
b++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case HA_KEYTYPE_SHORT_INT:
|
|
||||||
s_1= mi_sint2korr(a);
|
|
||||||
s_2= mi_sint2korr(b);
|
|
||||||
if ((flag = CMP(s_1,s_2)))
|
|
||||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
||||||
a= end;
|
|
||||||
b+= 2; /* sizeof(short int); */
|
|
||||||
break;
|
|
||||||
case HA_KEYTYPE_USHORT_INT:
|
|
||||||
{
|
|
||||||
uint16 us_1,us_2;
|
|
||||||
us_1= mi_sint2korr(a);
|
|
||||||
us_2= mi_sint2korr(b);
|
|
||||||
if ((flag = CMP(us_1,us_2)))
|
|
||||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
||||||
a= end;
|
|
||||||
b+=2; /* sizeof(short int); */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case HA_KEYTYPE_LONG_INT:
|
|
||||||
l_1= mi_sint4korr(a);
|
|
||||||
l_2= mi_sint4korr(b);
|
|
||||||
if ((flag = CMP(l_1,l_2)))
|
|
||||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
||||||
a= end;
|
|
||||||
b+= 4; /* sizeof(long int); */
|
|
||||||
break;
|
|
||||||
case HA_KEYTYPE_ULONG_INT:
|
|
||||||
u_1= mi_sint4korr(a);
|
|
||||||
u_2= mi_sint4korr(b);
|
|
||||||
if ((flag = CMP(u_1,u_2)))
|
|
||||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
||||||
a= end;
|
|
||||||
b+= 4; /* sizeof(long int); */
|
|
||||||
break;
|
|
||||||
case HA_KEYTYPE_INT24:
|
|
||||||
l_1=mi_sint3korr(a);
|
|
||||||
l_2=mi_sint3korr(b);
|
|
||||||
if ((flag = CMP(l_1,l_2)))
|
|
||||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
||||||
a= end;
|
|
||||||
b+= 3;
|
|
||||||
break;
|
|
||||||
case HA_KEYTYPE_UINT24:
|
|
||||||
l_1=mi_uint3korr(a);
|
|
||||||
l_2=mi_uint3korr(b);
|
|
||||||
if ((flag = CMP(l_1,l_2)))
|
|
||||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
||||||
a= end;
|
|
||||||
b+= 3;
|
|
||||||
break;
|
|
||||||
case HA_KEYTYPE_FLOAT:
|
|
||||||
mi_float4get(f_1,a);
|
|
||||||
mi_float4get(f_2,b);
|
|
||||||
if ((flag = CMP(f_1,f_2)))
|
|
||||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
||||||
a= end;
|
|
||||||
b+= 4; /* sizeof(float); */
|
|
||||||
break;
|
|
||||||
case HA_KEYTYPE_DOUBLE:
|
|
||||||
mi_float8get(d_1,a);
|
|
||||||
mi_float8get(d_2,b);
|
|
||||||
if ((flag = CMP(d_1,d_2)))
|
|
||||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
||||||
a= end;
|
|
||||||
b+= 8; /* sizeof(double); */
|
|
||||||
break;
|
|
||||||
case HA_KEYTYPE_NUM: /* Numeric key */
|
|
||||||
{
|
|
||||||
int swap_flag= 0;
|
|
||||||
int alength,blength;
|
|
||||||
|
|
||||||
if (keyseg->flag & HA_REVERSE_SORT)
|
|
||||||
{
|
|
||||||
swap(uchar*,a,b);
|
|
||||||
swap_flag=1; /* Remember swap of a & b */
|
|
||||||
end= a+ (int) (end-b);
|
|
||||||
}
|
|
||||||
if (keyseg->flag & HA_SPACE_PACK)
|
|
||||||
{
|
|
||||||
alength= *a++; blength= *b++;
|
|
||||||
end=a+alength;
|
|
||||||
next_key_length=key_length-blength-1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
alength= (int) (end-a);
|
|
||||||
blength=keyseg->length;
|
|
||||||
/* remove pre space from keys */
|
|
||||||
for ( ; alength && *a == ' ' ; a++, alength--) ;
|
|
||||||
for ( ; blength && *b == ' ' ; b++, blength--) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*a == '-')
|
|
||||||
{
|
|
||||||
if (*b != '-')
|
|
||||||
return -1;
|
|
||||||
a++; b++;
|
|
||||||
swap(uchar*,a,b);
|
|
||||||
swap(int,alength,blength);
|
|
||||||
swap_flag=1-swap_flag;
|
|
||||||
alength--; blength--;
|
|
||||||
end=a+alength;
|
|
||||||
}
|
|
||||||
else if (*b == '-')
|
|
||||||
return 1;
|
|
||||||
while (alength && (*a == '+' || *a == '0'))
|
|
||||||
{
|
|
||||||
a++; alength--;
|
|
||||||
}
|
|
||||||
while (blength && (*b == '+' || *b == '0'))
|
|
||||||
{
|
|
||||||
b++; blength--;
|
|
||||||
}
|
|
||||||
if (alength != blength)
|
|
||||||
return (alength < blength) ? -1 : 1;
|
|
||||||
while (a < end)
|
|
||||||
if (*a++ != *b++)
|
|
||||||
return ((int) a[-1] - (int) b[-1]);
|
|
||||||
|
|
||||||
if (swap_flag) /* Restore pointers */
|
|
||||||
swap(uchar*,a,b);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#ifdef HAVE_LONG_LONG
|
|
||||||
case HA_KEYTYPE_LONGLONG:
|
|
||||||
{
|
|
||||||
longlong ll_a,ll_b;
|
|
||||||
ll_a= mi_sint8korr(a);
|
|
||||||
ll_b= mi_sint8korr(b);
|
|
||||||
if ((flag = CMP(ll_a,ll_b)))
|
|
||||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
||||||
a= end;
|
|
||||||
b+= 8;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case HA_KEYTYPE_ULONGLONG:
|
|
||||||
{
|
|
||||||
ulonglong ll_a,ll_b;
|
|
||||||
ll_a= mi_uint8korr(a);
|
|
||||||
ll_b= mi_uint8korr(b);
|
|
||||||
if ((flag = CMP(ll_a,ll_b)))
|
|
||||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
|
||||||
a= end;
|
|
||||||
b+= 8;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
case HA_KEYTYPE_END: /* Ready */
|
|
||||||
goto end; /* diff_pos is incremented */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(*diff_pos)++;
|
|
||||||
end:
|
|
||||||
if (!(nextflag & SEARCH_FIND))
|
|
||||||
{
|
|
||||||
uint i;
|
|
||||||
if (nextflag & (SEARCH_NO_FIND | SEARCH_LAST)) /* Find record after key */
|
|
||||||
return (nextflag & (SEARCH_BIGGER | SEARCH_LAST)) ? -1 : 1;
|
|
||||||
flag=0;
|
|
||||||
for (i=keyseg->length ; i-- > 0 ; )
|
|
||||||
{
|
|
||||||
if (*a++ != *b++)
|
|
||||||
{
|
|
||||||
flag= FCMP(a[-1],b[-1]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (nextflag & SEARCH_SAME)
|
|
||||||
return (flag); /* read same */
|
|
||||||
if (nextflag & SEARCH_BIGGER)
|
|
||||||
return (flag <= 0 ? -1 : 1); /* read next */
|
|
||||||
return (flag < 0 ? -1 : 1); /* read previous */
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
} /* my_key_cmp */
|
|
||||||
|
64
mysys/tree.c
64
mysys/tree.c
@ -380,17 +380,17 @@ void *tree_search_key(TREE *tree, const void *key,
|
|||||||
Search first (the most left) or last (the most right) tree element
|
Search first (the most left) or last (the most right) tree element
|
||||||
*/
|
*/
|
||||||
void *tree_search_edge(TREE *tree, TREE_ELEMENT **parents,
|
void *tree_search_edge(TREE *tree, TREE_ELEMENT **parents,
|
||||||
TREE_ELEMENT ***last_pos, int child_offs)
|
TREE_ELEMENT ***last_pos, int child_offs)
|
||||||
{
|
{
|
||||||
TREE_ELEMENT *element = tree->root;
|
TREE_ELEMENT *element= tree->root;
|
||||||
|
|
||||||
*parents = &tree->null_element;
|
*parents= &tree->null_element;
|
||||||
while (element != &tree->null_element)
|
while (element != &tree->null_element)
|
||||||
{
|
{
|
||||||
*++parents = element;
|
*++parents= element;
|
||||||
element = ELEMENT_CHILD(element, child_offs);
|
element= ELEMENT_CHILD(element, child_offs);
|
||||||
}
|
}
|
||||||
*last_pos = parents;
|
*last_pos= parents;
|
||||||
return **last_pos != &tree->null_element ?
|
return **last_pos != &tree->null_element ?
|
||||||
ELEMENT_KEY(tree, **last_pos) : NULL;
|
ELEMENT_KEY(tree, **last_pos) : NULL;
|
||||||
}
|
}
|
||||||
@ -398,26 +398,26 @@ void *tree_search_edge(TREE *tree, TREE_ELEMENT **parents,
|
|||||||
void *tree_search_next(TREE *tree, TREE_ELEMENT ***last_pos, int l_offs,
|
void *tree_search_next(TREE *tree, TREE_ELEMENT ***last_pos, int l_offs,
|
||||||
int r_offs)
|
int r_offs)
|
||||||
{
|
{
|
||||||
TREE_ELEMENT *x = **last_pos;
|
TREE_ELEMENT *x= **last_pos;
|
||||||
|
|
||||||
if (ELEMENT_CHILD(x, r_offs) != &tree->null_element)
|
if (ELEMENT_CHILD(x, r_offs) != &tree->null_element)
|
||||||
{
|
{
|
||||||
x = ELEMENT_CHILD(x, r_offs);
|
x= ELEMENT_CHILD(x, r_offs);
|
||||||
*++*last_pos = x;
|
*++*last_pos= x;
|
||||||
while (ELEMENT_CHILD(x, l_offs) != &tree->null_element)
|
while (ELEMENT_CHILD(x, l_offs) != &tree->null_element)
|
||||||
{
|
{
|
||||||
x = ELEMENT_CHILD(x, l_offs);
|
x= ELEMENT_CHILD(x, l_offs);
|
||||||
*++*last_pos = x;
|
*++*last_pos= x;
|
||||||
}
|
}
|
||||||
return ELEMENT_KEY(tree, x);
|
return ELEMENT_KEY(tree, x);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TREE_ELEMENT *y = *--*last_pos;
|
TREE_ELEMENT *y= *--*last_pos;
|
||||||
while (y != &tree->null_element && x == ELEMENT_CHILD(y, r_offs))
|
while (y != &tree->null_element && x == ELEMENT_CHILD(y, r_offs))
|
||||||
{
|
{
|
||||||
x = y;
|
x= y;
|
||||||
y = *--*last_pos;
|
y= *--*last_pos;
|
||||||
}
|
}
|
||||||
return y == &tree->null_element ? NULL : ELEMENT_KEY(tree, y);
|
return y == &tree->null_element ? NULL : ELEMENT_KEY(tree, y);
|
||||||
}
|
}
|
||||||
@ -431,28 +431,26 @@ uint tree_record_pos(TREE *tree, const void *key,
|
|||||||
enum ha_rkey_function flag, void *custom_arg)
|
enum ha_rkey_function flag, void *custom_arg)
|
||||||
{
|
{
|
||||||
int cmp;
|
int cmp;
|
||||||
TREE_ELEMENT *element = tree->root;
|
TREE_ELEMENT *element= tree->root;
|
||||||
uint left = 1;
|
double left= 1;
|
||||||
uint right = tree->elements_in_tree;
|
double right= tree->elements_in_tree;
|
||||||
uint last_left_step_pos = tree->elements_in_tree;
|
uint last_equal_pos= HA_POS_ERROR;
|
||||||
uint last_right_step_pos = 1;
|
|
||||||
uint last_equal_pos = HA_POS_ERROR;
|
|
||||||
|
|
||||||
while (element != &tree->null_element)
|
while (element != &tree->null_element)
|
||||||
{
|
{
|
||||||
if ((cmp = (*tree->compare)(custom_arg, ELEMENT_KEY(tree, element),
|
if ((cmp= (*tree->compare)(custom_arg, ELEMENT_KEY(tree, element),
|
||||||
key)) == 0)
|
key)) == 0)
|
||||||
{
|
{
|
||||||
switch (flag) {
|
switch (flag) {
|
||||||
case HA_READ_KEY_EXACT:
|
case HA_READ_KEY_EXACT:
|
||||||
last_equal_pos = (left + right) >> 1;
|
last_equal_pos= (left + right) / 2;
|
||||||
cmp = 1;
|
cmp= 1;
|
||||||
break;
|
break;
|
||||||
case HA_READ_BEFORE_KEY:
|
case HA_READ_BEFORE_KEY:
|
||||||
cmp = 1;
|
cmp= 1;
|
||||||
break;
|
break;
|
||||||
case HA_READ_AFTER_KEY:
|
case HA_READ_AFTER_KEY:
|
||||||
cmp = -1;
|
cmp= -1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return HA_POS_ERROR;
|
return HA_POS_ERROR;
|
||||||
@ -460,24 +458,22 @@ uint tree_record_pos(TREE *tree, const void *key,
|
|||||||
}
|
}
|
||||||
if (cmp < 0) /* element < key */
|
if (cmp < 0) /* element < key */
|
||||||
{
|
{
|
||||||
last_right_step_pos = (left + right) >> 1;
|
element= element->right;
|
||||||
element = element->right;
|
left= (left + right) / 2;
|
||||||
left = last_right_step_pos;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
last_left_step_pos = (left + right) >> 1;
|
element= element->left;
|
||||||
element = element->left;
|
right= (left + right) / 2;
|
||||||
right = last_left_step_pos;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (flag) {
|
switch (flag) {
|
||||||
case HA_READ_KEY_EXACT:
|
case HA_READ_KEY_EXACT:
|
||||||
return last_equal_pos;
|
return last_equal_pos;
|
||||||
case HA_READ_BEFORE_KEY:
|
case HA_READ_BEFORE_KEY:
|
||||||
return last_right_step_pos;
|
return (uint) right;
|
||||||
case HA_READ_AFTER_KEY:
|
case HA_READ_AFTER_KEY:
|
||||||
return last_left_step_pos;
|
return (uint) left;
|
||||||
default:
|
default:
|
||||||
return HA_POS_ERROR;
|
return HA_POS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -42,9 +42,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked)
|
|||||||
{
|
{
|
||||||
parts+=table->key_info[key].key_parts;
|
parts+=table->key_info[key].key_parts;
|
||||||
if (table->key_info[key].algorithm == HA_KEY_ALG_BTREE)
|
if (table->key_info[key].algorithm == HA_KEY_ALG_BTREE)
|
||||||
{
|
|
||||||
parts++; /* additional HA_KEYTYPE_END keyseg */
|
parts++; /* additional HA_KEYTYPE_END keyseg */
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(keydef=(HP_KEYDEF*) my_malloc(table->keys*sizeof(HP_KEYDEF)+
|
if (!(keydef=(HP_KEYDEF*) my_malloc(table->keys*sizeof(HP_KEYDEF)+
|
||||||
@ -55,7 +53,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked)
|
|||||||
{
|
{
|
||||||
KEY *pos=table->key_info+key;
|
KEY *pos=table->key_info+key;
|
||||||
KEY_PART_INFO *key_part= pos->key_part;
|
KEY_PART_INFO *key_part= pos->key_part;
|
||||||
KEY_PART_INFO *key_part_end= key_part+pos->key_parts;
|
KEY_PART_INFO *key_part_end= key_part + pos->key_parts;
|
||||||
|
|
||||||
mem_per_row+= (pos->key_length + (sizeof(char*) * 2));
|
mem_per_row+= (pos->key_length + (sizeof(char*) * 2));
|
||||||
|
|
||||||
@ -94,14 +92,13 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
seg->null_bit=0;
|
seg->null_bit= 0;
|
||||||
seg->null_pos=0;
|
seg->null_pos= 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pos->algorithm == HA_KEY_ALG_BTREE)
|
if (pos->algorithm == HA_KEY_ALG_BTREE)
|
||||||
{
|
{
|
||||||
/* additional HA_KEYTYPE_END keyseg */
|
/* additional HA_KEYTYPE_END keyseg */
|
||||||
keydef[key].keysegs++;
|
|
||||||
seg->type= HA_KEYTYPE_END;
|
seg->type= HA_KEYTYPE_END;
|
||||||
seg->length= sizeof(byte*);
|
seg->length= sizeof(byte*);
|
||||||
seg->flag= 0;
|
seg->flag= 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user