summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <ingo@mysql.com>2005-07-19 14:13:56 +0200
committerunknown <ingo@mysql.com>2005-07-19 14:13:56 +0200
commitf1d5c0489b03d924750ae7112ffaf34da5d6fe7b (patch)
tree003d6387fee9d1df4a7d4fbe316c3c68765105d4
parenta2df1eb821760daa0e3a57969be1e934b5b9abd9 (diff)
downloadmariadb-git-f1d5c0489b03d924750ae7112ffaf34da5d6fe7b.tar.gz
Bug#10932 - Building server with key limit of 128, makes test cases fail
This patch allows to configure MyISAM for 128 indexes per table. The main problem is the key_map, wich is implemented as an ulonglong. To get rid of the limit and keep the efficient and flexible implementation, the highest bit is now used for all upper keys. This means that the lower keys can be disabled and enabled individually as usual and the high keys can only be disabled and enabled as a block. That way the existing test suite is still applicable, while more keys work, though slightly less efficient. To really get more than 64 keys, some defines need to be changed. Another patch will address this. include/my_bitmap.h: Bug#10932 - Building server with key limit of 128, makes test cases fail Added the declaration for a function that extends the highest bit value to all upper bits of a bigger bitmap. include/myisam.h: Bug#10932 - Building server with key limit of 128, makes test cases fail Changed MI_MAX_POSSIBLE_KEY to what it was meant for. Added a bunch of macros to handle the MyISAM key_map. myisam/mi_check.c: Bug#10932 - Building server with key limit of 128, makes test cases fail Changed key_map access to use the new macros. myisam/mi_create.c: Bug#10932 - Building server with key limit of 128, makes test cases fail Changed key_map access to use the new macros. myisam/mi_delete.c: Bug#10932 - Building server with key limit of 128, makes test cases fail Changed key_map access to use the new macros. myisam/mi_extra.c: Bug#10932 - Building server with key limit of 128, makes test cases fail Changed key_map access to use the new macros. myisam/mi_open.c: Bug#10932 - Building server with key limit of 128, makes test cases fail Changed key_map access to use the new macros. Changed pointer types from signed char* to unsigned char*. myisam/mi_preload.c: Bug#10932 - Building server with key limit of 128, makes test cases fail Changed key_map access to use the new macros. myisam/mi_rsame.c: Bug#10932 - Building server with key limit of 128, makes test cases fail Changed key_map access to use the new macros. myisam/mi_rsamepos.c: Bug#10932 - Building server with key limit of 128, makes test cases fail Changed key_map access to use the new macros. myisam/mi_search.c: Bug#10932 - Building server with key limit of 128, makes test cases fail Changed key_map access to use the new macros. myisam/mi_update.c: Bug#10932 - Building server with key limit of 128, makes test cases fail Changed key_map access to use the new macros. myisam/mi_write.c: Bug#10932 - Building server with key limit of 128, makes test cases fail Changed key_map access to use the new macros. myisam/myisamchk.c: Bug#10932 - Building server with key limit of 128, makes test cases fail Changed key_map access to use the new macros. myisam/myisamdef.h: Bug#10932 - Building server with key limit of 128, makes test cases fail Changed pointer types from signed char* to unsigned char*. myisam/myisamlog.c: Bug#10932 - Building server with key limit of 128, makes test cases fail Changed key_map access to use the new macros. myisam/myisampack.c: Bug#10932 - Building server with key limit of 128, makes test cases fail Changed key_map access to use the new macros. myisam/sort.c: Bug#10932 - Building server with key limit of 128, makes test cases fail Changed key_map access to use the new macros. mysys/my_bitmap.c: Bug#10932 - Building server with key limit of 128, makes test cases fail Added a function that extends the highest bit value to all upper bits of a bigger bitmap. sql/ha_myisam.cc: Bug#10932 - Building server with key limit of 128, makes test cases fail Changed key_map access to use the new macros. sql/sql_bitmap.h: Bug#10932 - Building server with key limit of 128, makes test cases fail Added a method that extends the highest bit value to all upper bits of a bigger bitmap.
-rw-r--r--include/my_bitmap.h1
-rw-r--r--include/myisam.h81
-rw-r--r--myisam/mi_check.c33
-rw-r--r--myisam/mi_create.c2
-rw-r--r--myisam/mi_delete.c2
-rw-r--r--myisam/mi_extra.c4
-rw-r--r--myisam/mi_open.c16
-rw-r--r--myisam/mi_preload.c2
-rw-r--r--myisam/mi_rsame.c2
-rw-r--r--myisam/mi_rsamepos.c2
-rw-r--r--myisam/mi_search.c2
-rw-r--r--myisam/mi_update.c2
-rw-r--r--myisam/mi_write.c15
-rw-r--r--myisam/myisamchk.c16
-rw-r--r--myisam/myisamdef.h4
-rw-r--r--myisam/myisamlog.c2
-rw-r--r--myisam/myisampack.c12
-rw-r--r--myisam/sort.c2
-rw-r--r--mysys/my_bitmap.c31
-rw-r--r--sql/ha_myisam.cc10
-rw-r--r--sql/sql_bitmap.h9
21 files changed, 180 insertions, 70 deletions
diff --git a/include/my_bitmap.h b/include/my_bitmap.h
index 84a5d8bd18a..f4fe28266e4 100644
--- a/include/my_bitmap.h
+++ b/include/my_bitmap.h
@@ -54,6 +54,7 @@ extern void bitmap_clear_all(MY_BITMAP *map);
extern void bitmap_clear_bit(MY_BITMAP *map, uint bitmap_bit);
extern void bitmap_free(MY_BITMAP *map);
extern void bitmap_intersect(MY_BITMAP *map, const MY_BITMAP *map2);
+extern void bitmap_set_above(MY_BITMAP *map, uint from_byte, uint use_bit);
extern void bitmap_set_all(MY_BITMAP *map);
extern void bitmap_set_bit(MY_BITMAP *map, uint bitmap_bit);
extern void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size);
diff --git a/include/myisam.h b/include/myisam.h
index 7d3f0e0c801..03194fe42ae 100644
--- a/include/myisam.h
+++ b/include/myisam.h
@@ -35,14 +35,26 @@ extern "C" {
/* defines used by myisam-funktions */
-/* The following defines can be increased if necessary */
-#define MI_MAX_KEY 64 /* Max allowed keys */
-#define MI_MAX_KEY_SEG 16 /* Max segments for key */
-#define MI_MAX_KEY_LENGTH 1000
+/*
+ There is a hard limit for the maximum number of keys as there are only
+ 8 bits in the index file header for the number of keys in a table.
+ This means that 0..255 keys can exist for a table. The idea of
+ MI_MAX_POSSIBLE_KEY is to ensure that one can use myisamchk & tools on
+ a MyISAM table for which one has more keys than MyISAM is normally
+ compiled for. If you don't have this, you will get a core dump when
+ running myisamchk compiled for 128 keys on a table with 255 keys.
+*/
+#define MI_MAX_POSSIBLE_KEY 255 /* For myisam_chk */
+#define MI_MAX_POSSIBLE_KEY_BUFF (1024+6+6) /* For myisam_chk */
+/*
+ The following defines can be increased if necessary.
+ BUT: MI_MAX_KEY must be <= MI_MAX_POSSIBLE_KEY.
+*/
+#define MI_MAX_KEY 64 /* Max allowed keys */
+#define MI_MAX_KEY_SEG 16 /* Max segments for key */
+#define MI_MAX_KEY_LENGTH 1000
#define MI_MAX_KEY_BUFF (MI_MAX_KEY_LENGTH+MI_MAX_KEY_SEG*6+8+8)
-#define MI_MAX_POSSIBLE_KEY_BUFF (1024+6+6) /* For myisam_chk */
-#define MI_MAX_POSSIBLE_KEY 64 /* For myisam_chk */
#define MI_MAX_MSG_BUF 1024 /* used in CHECK TABLE, REPAIR TABLE */
#define MI_NAME_IEXT ".MYI"
#define MI_NAME_DEXT ".MYD"
@@ -56,6 +68,63 @@ extern "C" {
#define mi_portable_sizeof_char_ptr 8
+/*
+ In the following macros '_keyno_' is 0 .. keys-1.
+ If there can be more keys than bits in the key_map, the highest bit
+ is for all upper keys. They cannot be switched individually.
+ This means that clearing of high keys is ignored, setting one high key
+ sets all high keys.
+*/
+#define MI_KEYMAP_BITS (8 * SIZEOF_LONG_LONG)
+#define MI_KEYMAP_HIGH_MASK (ULL(1) << (MI_KEYMAP_BITS - 1))
+#define mi_get_mask_all_keys_active(_keys_) \
+ (((_keys_) < MI_KEYMAP_BITS) ? \
+ ((ULL(1) << (_keys_)) - ULL(1)) : \
+ (~ ULL(0)))
+
+#if MI_MAX_KEY > MI_KEYMAP_BITS
+
+#define mi_is_key_active(_keymap_,_keyno_) \
+ (((_keyno_) < MI_KEYMAP_BITS) ? \
+ test((_keymap_) & (ULL(1) << (_keyno_))) : \
+ test((_keymap_) & MI_KEYMAP_HIGH_MASK))
+#define mi_set_key_active(_keymap_,_keyno_) \
+ (_keymap_)|= (((_keyno_) < MI_KEYMAP_BITS) ? \
+ (ULL(1) << (_keyno_)) : \
+ MI_KEYMAP_HIGH_MASK)
+#define mi_clear_key_active(_keymap_,_keyno_) \
+ (_keymap_)&= (((_keyno_) < MI_KEYMAP_BITS) ? \
+ (~ (ULL(1) << (_keyno_))) : \
+ (~ (ULL(0))) /*ignore*/ )
+
+#else
+
+#define mi_is_key_active(_keymap_,_keyno_) \
+ test((_keymap_) & (ULL(1) << (_keyno_)))
+#define mi_set_key_active(_keymap_,_keyno_) \
+ (_keymap_)|= (ULL(1) << (_keyno_))
+#define mi_clear_key_active(_keymap_,_keyno_) \
+ (_keymap_)&= (~ (ULL(1) << (_keyno_)))
+
+#endif
+
+#define mi_is_any_key_active(_keymap_) \
+ test((_keymap_))
+#define mi_is_all_keys_active(_keymap_,_keys_) \
+ ((_keymap_) == mi_get_mask_all_keys_active(_keys_))
+#define mi_set_all_keys_active(_keymap_,_keys_) \
+ (_keymap_)= mi_get_mask_all_keys_active(_keys_)
+#define mi_clear_all_keys_active(_keymap_) \
+ (_keymap_)= 0
+#define mi_intersect_keys_active(_to_,_from_) \
+ (_to_)&= (_from_)
+#define mi_is_any_intersect_keys_active(_keymap1_,_keys_,_keymap2_) \
+ ((_keymap1_) & (_keymap2_) & \
+ mi_get_mask_all_keys_active(_keys_))
+#define mi_copy_keys_active(_to_,_maxkeys_,_from_) \
+ (_to_)= (mi_get_mask_all_keys_active(_maxkeys_) & \
+ (_from_))
+
/* Param to/from mi_info */
typedef struct st_mi_isaminfo /* Struct from h_info */
diff --git a/myisam/mi_check.c b/myisam/mi_check.c
index 9e003a18dac..1db829808a9 100644
--- a/myisam/mi_check.c
+++ b/myisam/mi_check.c
@@ -282,7 +282,7 @@ int chk_size(MI_CHECK *param, register MI_INFO *info)
if ((skr=(my_off_t) info->state->key_file_length) != size)
{
/* Don't give error if file generated by myisampack */
- if (skr > size && info->s->state.key_map)
+ if (skr > size && mi_is_any_key_active(info->s->state.key_map))
{
error=1;
mi_check_print_error(param,
@@ -379,7 +379,7 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
rec_per_key_part+=keyinfo->keysegs, key++, keyinfo++)
{
param->key_crc[key]=0;
- if (!(((ulonglong) 1 << key) & share->state.key_map))
+ if (! mi_is_key_active(share->state.key_map, key))
{
/* Remember old statistics for key */
memcpy((char*) rec_per_key_part,
@@ -507,7 +507,7 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
(int) ((my_off_t2double(key_totlength) -
my_off_t2double(all_keydata))*100.0/
my_off_t2double(key_totlength)));
- else if (all_totaldata != 0L && share->state.key_map)
+ else if (all_totaldata != 0L && mi_is_any_key_active(share->state.key_map))
puts("");
}
if (param->key_file_blocks != info->state->key_file_length &&
@@ -1034,7 +1034,7 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
for (key=0,keyinfo= info->s->keyinfo; key < info->s->base.keys;
key++,keyinfo++)
{
- if ((((ulonglong) 1 << key) & info->s->state.key_map))
+ if (mi_is_key_active(info->s->state.key_map, key))
{
if(!(keyinfo->flag & HA_FULLTEXT))
{
@@ -1298,8 +1298,8 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
*/
if (param->testflag & T_CREATE_MISSING_KEYS)
- share->state.key_map= ((((ulonglong) 1L << share->base.keys)-1) &
- param->keys_in_use);
+ mi_copy_keys_active(share->state.key_map, share->base.keys,
+ param->keys_in_use);
info->state->key_file_length=share->base.keystart;
@@ -1461,7 +1461,7 @@ static int writekeys(MI_CHECK *param, register MI_INFO *info, byte *buff,
key=info->lastkey+info->s->base.max_key_length;
for (i=0 ; i < info->s->base.keys ; i++)
{
- if (((ulonglong) 1 << i) & info->s->state.key_map)
+ if (mi_is_key_active(info->s->state.key_map, i))
{
if (info->s->keyinfo[i].flag & HA_FULLTEXT )
{
@@ -1492,7 +1492,7 @@ static int writekeys(MI_CHECK *param, register MI_INFO *info, byte *buff,
info->errkey=(int) i; /* This key was found */
while ( i-- > 0 )
{
- if (((ulonglong) 1 << i) & info->s->state.key_map)
+ if (mi_is_key_active(info->s->state.key_map, i))
{
if (info->s->keyinfo[i].flag & HA_FULLTEXT)
{
@@ -1529,7 +1529,7 @@ int movepoint(register MI_INFO *info, byte *record, my_off_t oldpos,
key=info->lastkey+info->s->base.max_key_length;
for (i=0 ; i < info->s->base.keys; i++)
{
- if (i != prot_key && (((ulonglong) 1 << i) & info->s->state.key_map))
+ if (i != prot_key && mi_is_key_active(info->s->state.key_map, i))
{
key_length=_mi_make_key(info,i,key,record,oldpos);
if (info->s->keyinfo[i].flag & HA_NOSAME)
@@ -1628,7 +1628,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
for (key= 0,keyinfo= &share->keyinfo[0]; key < share->base.keys ;
key++,keyinfo++)
{
- if (!(((ulonglong) 1 << key) & share->state.key_map))
+ if (! mi_is_key_active(info->s->state.key_map, key))
continue;
if (share->state.key_root[key] != HA_OFFSET_ERROR)
@@ -2023,7 +2023,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
sort_param.read_cache=param->read_cache;
sort_param.keyinfo=share->keyinfo+sort_param.key;
sort_param.seg=sort_param.keyinfo->seg;
- if (!(((ulonglong) 1 << sort_param.key) & key_map))
+ if (! mi_is_key_active(key_map, sort_param.key))
{
/* Remember old statistics for key */
memcpy((char*) rec_per_key_part,
@@ -2084,7 +2084,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
if (param->testflag & T_STATISTICS)
update_key_parts(sort_param.keyinfo, rec_per_key_part, sort_param.unique,
(ulonglong) info->state->records);
- share->state.key_map|=(ulonglong) 1 << sort_param.key;
+ mi_set_key_active(share->state.key_map, sort_param.key);
if (sort_param.fix_datafile)
{
@@ -2405,7 +2405,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
sort_param[i].key=key;
sort_param[i].keyinfo=share->keyinfo+key;
sort_param[i].seg=sort_param[i].keyinfo->seg;
- if (!(((ulonglong) 1 << key) & key_map))
+ if (! mi_is_key_active(key_map, key))
{
/* Remember old statistics for key */
memcpy((char*) rec_per_key_part,
@@ -3917,8 +3917,7 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
{
byte *record;
if (!info->s->base.auto_key ||
- !(((ulonglong) 1 << (info->s->base.auto_key-1)
- & info->s->state.key_map)))
+ ! mi_is_key_active(info->s->state.key_map, info->s->base.auto_key - 1))
{
if (!(param->testflag & T_VERY_SILENT))
mi_check_print_info(param,
@@ -4070,7 +4069,7 @@ void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows)
if (!(key->flag & (HA_NOSAME | HA_SPATIAL | HA_AUTO_KEY)) &&
! mi_too_big_key_for_sort(key,rows) && info->s->base.auto_key != i+1)
{
- share->state.key_map&= ~ ((ulonglong) 1 << i);
+ mi_clear_key_active(share->state.key_map, i);
info->update|= HA_STATE_CHANGED;
}
}
@@ -4094,7 +4093,7 @@ my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows,
mi_repair_by_sort only works if we have at least one key. If we don't
have any keys, we should use the normal repair.
*/
- if (!key_map)
+ if (! mi_is_any_key_active(key_map))
return FALSE; /* Can't use sort */
for (i=0 ; i < share->base.keys ; i++,key++)
{
diff --git a/myisam/mi_create.c b/myisam/mi_create.c
index 33b344405ec..560535f2933 100644
--- a/myisam/mi_create.c
+++ b/myisam/mi_create.c
@@ -508,7 +508,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
mi_int2store(share.state.header.key_parts,key_segs);
mi_int2store(share.state.header.unique_key_parts,unique_key_parts);
- share.state.key_map = ((ulonglong) 1 << keys)-1;
+ mi_set_all_keys_active(share.state.key_map, keys);
share.base.keystart = share.state.state.key_file_length=
MY_ALIGN(info_length, myisam_block_size);
share.base.max_key_block_length=max_key_block_length;
diff --git a/myisam/mi_delete.c b/myisam/mi_delete.c
index cc4a17182f7..60a07254e82 100644
--- a/myisam/mi_delete.c
+++ b/myisam/mi_delete.c
@@ -74,7 +74,7 @@ int mi_delete(MI_INFO *info,const byte *record)
old_key=info->lastkey2;
for (i=0 ; i < share->base.keys ; i++ )
{
- if (((ulonglong) 1 << i) & info->s->state.key_map)
+ if (mi_is_key_active(info->s->state.key_map, i))
{
info->s->keyinfo[i].version++;
if (info->s->keyinfo[i].flag & HA_FULLTEXT )
diff --git a/myisam/mi_extra.c b/myisam/mi_extra.c
index ba32bb9115a..bfe1748af01 100644
--- a/myisam/mi_extra.c
+++ b/myisam/mi_extra.c
@@ -244,7 +244,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
error=1; /* Not possibly if not lock */
break;
}
- if (share->state.key_map)
+ if (mi_is_any_key_active(share->state.key_map))
{
MI_KEYDEF *key=share->keyinfo;
uint i;
@@ -252,7 +252,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
{
if (!(key->flag & HA_NOSAME) && info->s->base.auto_key != i+1)
{
- share->state.key_map&= ~ ((ulonglong) 1 << i);
+ mi_clear_key_active(share->state.key_map, i);
info->update|= HA_STATE_CHANGED;
}
}
diff --git a/myisam/mi_open.c b/myisam/mi_open.c
index 74b97a65609..82663e0c318 100644
--- a/myisam/mi_open.c
+++ b/myisam/mi_open.c
@@ -192,14 +192,14 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
}
share->state_diff_length=len-MI_STATE_INFO_SIZE;
- mi_state_info_read(disk_cache, &share->state);
+ mi_state_info_read((uchar*) disk_cache, &share->state);
len= mi_uint2korr(share->state.header.base_info_length);
if (len != MI_BASE_INFO_SIZE)
{
DBUG_PRINT("warning",("saved_base_info_length: %d base_info_length: %d",
len,MI_BASE_INFO_SIZE))
}
- disk_pos=my_n_base_info_read(disk_cache+base_pos, &share->base);
+ disk_pos=my_n_base_info_read((uchar*) disk_cache + base_pos, &share->base);
share->state.state_length=base_pos;
if (!(open_flags & HA_OPEN_FOR_REPAIR) &&
@@ -863,7 +863,7 @@ uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
}
-char *mi_state_info_read(char *ptr, MI_STATE_INFO *state)
+char *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state)
{
uint i,keys,key_parts,key_blocks;
memcpy_fixed(&state->header,ptr, sizeof(state->header));
@@ -929,7 +929,7 @@ uint mi_state_info_read_dsk(File file, MI_STATE_INFO *state, my_bool pRead)
}
else if (my_read(file, buff, state->state_length,MYF(MY_NABP)))
return (MY_FILE_ERROR);
- mi_state_info_read(buff, state);
+ mi_state_info_read((uchar*) buff, state);
}
return 0;
}
@@ -974,7 +974,7 @@ uint mi_base_info_write(File file, MI_BASE_INFO *base)
}
-char *my_n_base_info_read(char *ptr, MI_BASE_INFO *base)
+char *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base)
{
base->keystart = mi_sizekorr(ptr); ptr +=8;
base->max_data_file_length = mi_sizekorr(ptr); ptr +=8;
@@ -1204,7 +1204,7 @@ int mi_disable_indexes(MI_INFO *info)
{
MYISAM_SHARE *share= info->s;
- share->state.key_map= 0;
+ mi_clear_all_keys_active(share->state.key_map);
return 0;
}
@@ -1240,7 +1240,7 @@ int mi_enable_indexes(MI_INFO *info)
error= HA_ERR_CRASHED;
}
else
- share->state.key_map= ((ulonglong) 1L << share->base.keys) - 1;
+ mi_set_all_keys_active(share->state.key_map, share->base.keys);
return error;
}
@@ -1265,6 +1265,6 @@ int mi_indexes_are_disabled(MI_INFO *info)
{
MYISAM_SHARE *share= info->s;
- return (! share->state.key_map && share->base.keys);
+ return (! mi_is_any_key_active(share->state.key_map) && share->base.keys);
}
diff --git a/myisam/mi_preload.c b/myisam/mi_preload.c
index 317ab4ad7fe..d63399b519d 100644
--- a/myisam/mi_preload.c
+++ b/myisam/mi_preload.c
@@ -51,7 +51,7 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves)
my_off_t pos= share->base.keystart;
DBUG_ENTER("mi_preload");
- if (!keys || !key_map || key_file_length == pos)
+ if (!keys || !mi_is_any_key_active(key_map) || key_file_length == pos)
DBUG_RETURN(0);
block_length= keyinfo[0].block_length;
diff --git a/myisam/mi_rsame.c b/myisam/mi_rsame.c
index 56c8d1226ca..321097744b9 100644
--- a/myisam/mi_rsame.c
+++ b/myisam/mi_rsame.c
@@ -30,7 +30,7 @@ int mi_rsame(MI_INFO *info, byte *record, int inx)
{
DBUG_ENTER("mi_rsame");
- if (inx != -1 && ! (((ulonglong) 1 << inx) & info->s->state.key_map))
+ if (inx != -1 && ! mi_is_key_active(info->s->state.key_map, inx))
{
DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX);
}
diff --git a/myisam/mi_rsamepos.c b/myisam/mi_rsamepos.c
index a1d96fb7104..35cdd41e297 100644
--- a/myisam/mi_rsamepos.c
+++ b/myisam/mi_rsamepos.c
@@ -32,7 +32,7 @@ int mi_rsame_with_pos(MI_INFO *info, byte *record, int inx, my_off_t filepos)
{
DBUG_ENTER("mi_rsame_with_pos");
- if (inx < -1 || ! (((ulonglong) 1 << inx) & info->s->state.key_map))
+ if (inx < -1 || ! mi_is_key_active(info->s->state.key_map, inx))
{
DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX);
}
diff --git a/myisam/mi_search.c b/myisam/mi_search.c
index c669a8be8f8..ed61bbfe41a 100644
--- a/myisam/mi_search.c
+++ b/myisam/mi_search.c
@@ -29,7 +29,7 @@ int _mi_check_index(MI_INFO *info, int inx)
{
if (inx == -1) /* Use last index */
inx=info->lastinx;
- if (inx < 0 || ! (((ulonglong) 1 << inx) & info->s->state.key_map))
+ if (inx < 0 || ! mi_is_key_active(info->s->state.key_map, inx))
{
my_errno=HA_ERR_WRONG_INDEX;
return -1;
diff --git a/myisam/mi_update.c b/myisam/mi_update.c
index cda60694008..ab23f2e6da9 100644
--- a/myisam/mi_update.c
+++ b/myisam/mi_update.c
@@ -87,7 +87,7 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec)
changed=0;
for (i=0 ; i < share->base.keys ; i++)
{
- if (((ulonglong) 1 << i) & share->state.key_map)
+ if (mi_is_key_active(share->state.key_map, i))
{
if (share->keyinfo[i].flag & HA_FULLTEXT )
{
diff --git a/myisam/mi_write.c b/myisam/mi_write.c
index dd062b79769..c8f9aa84a41 100644
--- a/myisam/mi_write.c
+++ b/myisam/mi_write.c
@@ -101,7 +101,7 @@ int mi_write(MI_INFO *info, byte *record)
buff=info->lastkey2;
for (i=0 ; i < share->base.keys ; i++)
{
- if (((ulonglong) 1 << i) & share->state.key_map)
+ if (mi_is_key_active(share->state.key_map, i))
{
bool local_lock_tree= (lock_tree &&
!(info->bulk_insert &&
@@ -175,7 +175,7 @@ err:
info->errkey= (int) i;
while ( i-- > 0)
{
- if (((ulonglong) 1 << i) & share->state.key_map)
+ if (mi_is_key_active(share->state.key_map, i))
{
bool local_lock_tree= (lock_tree &&
!(info->bulk_insert &&
@@ -944,20 +944,21 @@ int mi_init_bulk_insert(MI_INFO *info, ulong cache_size, ha_rows rows)
MI_KEYDEF *key=share->keyinfo;
bulk_insert_param *params;
uint i, num_keys, total_keylength;
- ulonglong key_map=0;
+ ulonglong key_map;
DBUG_ENTER("_mi_init_bulk_insert");
DBUG_PRINT("enter",("cache_size: %lu", cache_size));
DBUG_ASSERT(!info->bulk_insert &&
(!rows || rows >= MI_MIN_ROWS_TO_USE_BULK_INSERT));
+ mi_clear_all_keys_active(key_map);
for (i=total_keylength=num_keys=0 ; i < share->base.keys ; i++)
{
- if (!(key[i].flag & HA_NOSAME) && share->base.auto_key != i+1
- && test(share->state.key_map & ((ulonglong) 1 << i)))
+ if (! (key[i].flag & HA_NOSAME) && (share->base.auto_key != i + 1) &&
+ mi_is_key_active(share->state.key_map, i))
{
num_keys++;
- key_map |=((ulonglong) 1 << i);
+ mi_set_key_active(key_map, i);
total_keylength+=key[i].maxlength+TREE_ELEMENT_EXTRA_SIZE;
}
}
@@ -981,7 +982,7 @@ int mi_init_bulk_insert(MI_INFO *info, ulong cache_size, ha_rows rows)
params=(bulk_insert_param *)(info->bulk_insert+share->base.keys);
for (i=0 ; i < share->base.keys ; i++)
{
- if (test(key_map & ((ulonglong) 1 << i)))
+ if (mi_is_key_active(key_map, i))
{
params->info=info;
params->keynr=i;
diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c
index 519e123e9da..4856d93b320 100644
--- a/myisam/myisamchk.c
+++ b/myisam/myisamchk.c
@@ -871,8 +871,8 @@ static int myisamchk(MI_CHECK *param, my_string filename)
MI_STATE_INFO_SIZE ||
mi_uint2korr(share->state.header.base_info_length) !=
MI_BASE_INFO_SIZE ||
- ((param->keys_in_use & ~share->state.key_map) &
- (((ulonglong) 1L << share->base.keys)-1)) ||
+ mi_is_any_intersect_keys_active(param->keys_in_use, share->base.keys,
+ ~share->state.key_map) ||
test_if_almost_full(info) ||
info->s->state.header.file_version[3] != myisam_file_magic[3] ||
(set_collation &&
@@ -939,8 +939,8 @@ static int myisamchk(MI_CHECK *param, my_string filename)
if (param->testflag & T_REP_ANY)
{
ulonglong tmp=share->state.key_map;
- share->state.key_map= (((ulonglong) 1 << share->base.keys)-1)
- & param->keys_in_use;
+ mi_copy_keys_active(share->state.key_map, share->base.keys,
+ param->keys_in_use);
if (tmp != share->state.key_map)
info->update|=HA_STATE_CHANGED;
}
@@ -961,7 +961,7 @@ static int myisamchk(MI_CHECK *param, my_string filename)
if (!error)
{
if ((param->testflag & (T_REP_BY_SORT | T_REP_PARALLEL)) &&
- (share->state.key_map ||
+ (mi_is_any_key_active(share->state.key_map) ||
(rep_quick && !param->keys_in_use && !recreate)) &&
mi_test_if_sort_rep(info, info->state->records,
info->s->state.key_map,
@@ -1037,7 +1037,7 @@ static int myisamchk(MI_CHECK *param, my_string filename)
llstr(info->state->records,llbuff),
llstr(info->state->del,llbuff2));
error =chk_status(param,info);
- share->state.key_map &=param->keys_in_use;
+ mi_intersect_keys_active(share->state.key_map, param->keys_in_use);
error =chk_size(param,info);
if (!error || !(param->testflag & (T_FAST | T_FORCE_CREATE)))
error|=chk_del(param, info,param->testflag);
@@ -1266,7 +1266,7 @@ static void descript(MI_CHECK *param, register MI_INFO *info, my_string name)
}
printf("Recordlength: %13d\n",(int) share->base.pack_reclength);
- if (share->state.key_map != (((ulonglong) 1 << share->base.keys) -1))
+ if (! mi_is_all_keys_active(share->state.key_map, share->base.keys))
{
longlong2str(share->state.key_map,buff,2);
printf("Using only keys '%s' of %d possibly keys\n",
@@ -1448,7 +1448,7 @@ static int mi_sort_records(MI_CHECK *param,
temp_buff=0;
new_file= -1;
- if (!(((ulonglong) 1 << sort_key) & share->state.key_map))
+ if (! mi_is_key_active(share->state.key_map, sort_key))
{
mi_check_print_warning(param,
"Can't sort table '%s' on key %d; No such key",
diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h
index 5688b377d3d..74463ec065a 100644
--- a/myisam/myisamdef.h
+++ b/myisam/myisamdef.h
@@ -676,10 +676,10 @@ extern void _mi_unmap_file(MI_INFO *info);
extern uint save_pack_length(byte *block_buff,ulong length);
uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite);
-char *mi_state_info_read(char *ptr, MI_STATE_INFO *state);
+char *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state);
uint mi_state_info_read_dsk(File file, MI_STATE_INFO *state, my_bool pRead);
uint mi_base_info_write(File file, MI_BASE_INFO *base);
-char *my_n_base_info_read(char *ptr, MI_BASE_INFO *base);
+char *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base);
int mi_keyseg_write(File file, const HA_KEYSEG *keyseg);
char *mi_keyseg_read(char *ptr, HA_KEYSEG *keyseg);
uint mi_keydef_write(File file, MI_KEYDEF *keydef);
diff --git a/myisam/myisamlog.c b/myisam/myisamlog.c
index dc98d813266..de55b86252c 100644
--- a/myisam/myisamlog.c
+++ b/myisam/myisamlog.c
@@ -810,7 +810,7 @@ static int find_record_with_key(struct file_info *file_info, byte *record)
for (key=0 ; key < info->s->base.keys ; key++)
{
- if ((((ulonglong) 1 << key) & info->s->state.key_map) &&
+ if (mi_is_key_active(info->s->state.key_map, key) &&
info->s->keyinfo[key].flag & HA_NOSAME)
{
VOID(_mi_make_key(info,key,tmp_key,record,0L));
diff --git a/myisam/myisampack.c b/myisam/myisampack.c
index daf2bbdf85c..ba48cbf1b62 100644
--- a/myisam/myisampack.c
+++ b/myisam/myisampack.c
@@ -441,9 +441,9 @@ static bool open_isam_files(PACK_MRG_INFO *mrg,char **names,uint count)
if (!(mrg->file[i]=open_isam_file(names[i],O_RDONLY)))
goto error;
- mrg->src_file_has_indexes_disabled|= ((mrg->file[i]->s->state.key_map !=
- (((ulonglong) 1) <<
- mrg->file[i]->s->base. keys) - 1));
+ mrg->src_file_has_indexes_disabled|=
+ ! mi_is_all_keys_active(mrg->file[i]->s->state.key_map,
+ mrg->file[i]->s->base.keys);
}
/* Check that files are identical */
for (j=0 ; j < count-1 ; j++)
@@ -2941,7 +2941,7 @@ static int save_state(MI_INFO *isam_file,PACK_MRG_INFO *mrg,my_off_t new_length,
share->state.dellink= HA_OFFSET_ERROR;
share->state.split=(ha_rows) mrg->records;
share->state.version=(ulong) time((time_t*) 0);
- if (share->state.key_map != (ULL(1) << share->base.keys) - 1)
+ if (! mi_is_all_keys_active(share->state.key_map, share->base.keys))
{
/*
Some indexes are disabled, cannot use current key_file_length value
@@ -2955,7 +2955,7 @@ static int save_state(MI_INFO *isam_file,PACK_MRG_INFO *mrg,my_off_t new_length,
original file so "myisamchk -rq" can use this value (this is necessary
because index size cannot be easily calculated for fulltext keys)
*/
- share->state.key_map=0;
+ mi_clear_all_keys_active(share->state.key_map);
for (key=0 ; key < share->base.keys ; key++)
share->state.key_root[key]= HA_OFFSET_ERROR;
for (key=0 ; key < share->state.header.max_block_size ; key++)
@@ -2995,7 +2995,7 @@ static int save_state_mrg(File file,PACK_MRG_INFO *mrg,my_off_t new_length,
}
state.dellink= HA_OFFSET_ERROR;
state.version=(ulong) time((time_t*) 0);
- state.key_map=0;
+ mi_clear_all_keys_active(state.key_map);
state.checksum=crc;
if (isam_file->s->base.keys)
isamchk_neaded=1;
diff --git a/myisam/sort.c b/myisam/sort.c
index 9d2af2e8c70..f2f8c8ef7ec 100644
--- a/myisam/sort.c
+++ b/myisam/sort.c
@@ -479,7 +479,7 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
}
if (!got_error)
{
- share->state.key_map|=(ulonglong) 1 << sinfo->key;
+ mi_set_key_active(share->state.key_map, sinfo->key);
if (param->testflag & T_STATISTICS)
update_key_parts(sinfo->keyinfo, rec_per_key_part,
sinfo->unique, (ulonglong) info->state->records);
diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c
index c70c0fa0754..4a917fc8287 100644
--- a/mysys/my_bitmap.c
+++ b/mysys/my_bitmap.c
@@ -339,6 +339,37 @@ void bitmap_intersect(MY_BITMAP *map, const MY_BITMAP *map2)
}
+/*
+ Set/clear all bits above a bit.
+
+ SYNOPSIS
+ bitmap_set_above()
+ map RETURN The bitmap to change.
+ from_byte The bitmap buffer byte offset to start with.
+ use_bit The bit value (1/0) to use for all upper bits.
+
+ NOTE
+ You can only set/clear full bytes.
+ The function is meant for the situation that you copy a smaller bitmap
+ to a bigger bitmap. Bitmap lengths are always multiple of eigth (the
+ size of a byte). Using 'from_byte' saves multiplication and division
+ by eight during parameter passing.
+
+ RETURN
+ void
+*/
+
+void bitmap_set_above(MY_BITMAP *map, uint from_byte, uint use_bit)
+{
+ uchar use_byte= use_bit ? 0xff : 0;
+ uchar *to= map->bitmap + from_byte;
+ uchar *end= map->bitmap + map->bitmap_size;
+
+ while (to < end)
+ *to++= use_byte;
+}
+
+
void bitmap_subtract(MY_BITMAP *map, const MY_BITMAP *map2)
{
uchar *to=map->bitmap, *from=map2->bitmap, *end;
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index 0d9c32adbfa..e94b697e0bb 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -602,7 +602,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
!(share->state.changed & STATE_NOT_OPTIMIZED_KEYS))))
{
ulonglong key_map= ((local_testflag & T_CREATE_MISSING_KEYS) ?
- ((ulonglong) 1L << share->base.keys)-1 :
+ mi_get_mask_all_keys_active(share->base.keys) :
share->state.key_map);
uint testflag=param.testflag;
if (mi_test_if_sort_rep(file,file->state->records,key_map,0) &&
@@ -903,7 +903,7 @@ int ha_myisam::enable_indexes(uint mode)
{
int error;
- if (file->s->state.key_map == set_bits(ulonglong, file->s->base.keys))
+ if (mi_is_all_keys_active(file->s->state.key_map, file->s->base.keys))
{
/* All indexes are enabled already. */
return 0;
@@ -1002,8 +1002,8 @@ void ha_myisam::start_bulk_insert(ha_rows rows)
if (! rows || (rows > MI_MIN_ROWS_TO_USE_WRITE_CACHE))
mi_extra(file, HA_EXTRA_WRITE_CACHE, (void*) &size);
- can_enable_indexes= (file->s->state.key_map ==
- set_bits(ulonglong, file->s->base.keys));
+ can_enable_indexes= mi_is_all_keys_active(file->s->state.key_map,
+ file->s->base.keys);
if (!(specialflag & SPECIAL_SAFE_MODE))
{
@@ -1256,7 +1256,7 @@ void ha_myisam::info(uint flag)
share->db_options_in_use= info.options;
block_size= myisam_block_size;
share->keys_in_use.set_prefix(share->keys);
- share->keys_in_use.intersect(info.key_map);
+ share->keys_in_use.intersect_extended(info.key_map);
share->keys_for_keyread.intersect(share->keys_in_use);
share->db_record_offset= info.record_offset;
if (share->key_parts)
diff --git a/sql/sql_bitmap.h b/sql/sql_bitmap.h
index bc1484b4fb0..0f5b6dcd35e 100644
--- a/sql/sql_bitmap.h
+++ b/sql/sql_bitmap.h
@@ -51,6 +51,14 @@ public:
bitmap_init(&map2, (uchar *)&map2buff, sizeof(ulonglong)*8, 0);
bitmap_intersect(&map, &map2);
}
+ /* Use highest bit for all bits above sizeof(ulonglong)*8. */
+ void intersect_extended(ulonglong map2buff)
+ {
+ intersect(map2buff);
+ if (map.bitmap_size > sizeof(ulonglong))
+ bitmap_set_above(&map, sizeof(ulonglong),
+ test(map2buff & (LL(1) << (sizeof(ulonglong) * 8 - 1))));
+ }
void subtract(Bitmap& map2) { bitmap_subtract(&map, &map2.map); }
void merge(Bitmap& map2) { bitmap_union(&map, &map2.map); }
my_bool is_set(uint n) const { return bitmap_is_set(&map, n); }
@@ -116,6 +124,7 @@ public:
void clear_all() { map=(ulonglong)0; }
void intersect(Bitmap<64>& map2) { map&= map2.map; }
void intersect(ulonglong map2) { map&= map2; }
+ void intersect_extended(ulonglong map2) { map&= map2; }
void subtract(Bitmap<64>& map2) { map&= ~map2.map; }
void merge(Bitmap<64>& map2) { map|= map2.map; }
my_bool is_set(uint n) const { return test(map & (((ulonglong)1) << n)); }