List:Internals« Previous MessageNext Message »
From:ingo Date:July 19 2005 2:14pm
Subject:bk commit into 5.0 tree (ingo:1.1955) BUG#10932
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of mydev. When mydev does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.1955 05/07/19 14:13:56 ingo@stripped +21 -0
  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.

  sql/sql_bitmap.h
    1.10 05/07/19 14:13:38 ingo@stripped +9 -0
    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.

  sql/ha_myisam.cc
    1.154 05/07/19 14:13:38 ingo@stripped +5 -5
    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
    1.28 05/07/19 14:13:38 ingo@stripped +31 -0
    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.

  myisam/sort.c
    1.46 05/07/19 14:13:38 ingo@stripped +1 -1
    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
    1.44 05/07/19 14:13:38 ingo@stripped +6 -6
    Bug#10932 - Building server with key limit of 128, makes test cases fail
    Changed key_map access to use the new macros.

  myisam/myisamlog.c
    1.30 05/07/19 14:13:38 ingo@stripped +1 -1
    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
    1.77 05/07/19 14:13:37 ingo@stripped +2 -2
    Bug#10932 - Building server with key limit of 128, makes test cases fail
    Changed pointer types from signed char* to unsigned char*.

  myisam/myisamchk.c
    1.113 05/07/19 14:13:37 ingo@stripped +8 -8
    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
    1.53 05/07/19 14:13:37 ingo@stripped +8 -7
    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
    1.18 05/07/19 14:13:37 ingo@stripped +1 -1
    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
    1.55 05/07/19 14:13:37 ingo@stripped +1 -1
    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
    1.5 05/07/19 14:13:37 ingo@stripped +1 -1
    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
    1.7 05/07/19 14:13:37 ingo@stripped +1 -1
    Bug#10932 - Building server with key limit of 128, makes test cases fail
    Changed key_map access to use the new macros.

  myisam/mi_preload.c
    1.10 05/07/19 14:13:37 ingo@stripped +1 -1
    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
    1.93 05/07/19 14:13:37 ingo@stripped +8 -8
    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_extra.c
    1.45 05/07/19 14:13:37 ingo@stripped +2 -2
    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
    1.34 05/07/19 14:13:37 ingo@stripped +1 -1
    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
    1.49 05/07/19 14:13:37 ingo@stripped +1 -1
    Bug#10932 - Building server with key limit of 128, makes test cases fail
    Changed key_map access to use the new macros.

  myisam/mi_check.c
    1.133 05/07/19 14:13:37 ingo@stripped +16 -17
    Bug#10932 - Building server with key limit of 128, makes test cases fail
    Changed key_map access to use the new macros.

  include/myisam.h
    1.67 05/07/19 14:13:36 ingo@stripped +75 -6
    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.

  include/my_bitmap.h
    1.13 05/07/19 14:13:36 ingo@stripped +1 -0
    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.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	ingo
# Host:	chilla.local
# Root:	/home/mydev/mysql-5.0-bug10932

--- 1.66/include/myisam.h	2005-05-13 11:08:02 +02:00
+++ 1.67/include/myisam.h	2005-07-19 14:13:36 +02:00
@@ -35,14 +35,26 @@
 
 	/* 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"
@@ -55,6 +67,63 @@
 #define MI_MAX_KEY_BLOCK_LENGTH	16384
 
 #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 */
 

--- 1.132/myisam/mi_check.c	2005-06-09 18:01:24 +02:00
+++ 1.133/myisam/mi_check.c	2005-07-19 14:13:37 +02:00
@@ -282,7 +282,7 @@
   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 @@
        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) ((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 @@
       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 @@
   */
 
   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 @@
   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 @@
     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 @@
   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 @@
   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 @@
     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 @@
     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 @@
     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 @@
 {
   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 @@
     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 @@
     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++)
   {

--- 1.48/myisam/mi_create.c	2005-07-03 11:32:01 +02:00
+++ 1.49/myisam/mi_create.c	2005-07-19 14:13:37 +02:00
@@ -508,7 +508,7 @@
   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;

--- 1.33/myisam/mi_delete.c	2004-12-31 02:47:50 +01:00
+++ 1.34/myisam/mi_delete.c	2005-07-19 14:13:37 +02:00
@@ -74,7 +74,7 @@
   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 )

--- 1.44/myisam/mi_extra.c	2005-02-23 23:25:45 +01:00
+++ 1.45/myisam/mi_extra.c	2005-07-19 14:13:37 +02:00
@@ -244,7 +244,7 @@
       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 @@
       {
         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;
         }
       }

--- 1.92/myisam/mi_open.c	2005-07-03 11:32:01 +02:00
+++ 1.93/myisam/mi_open.c	2005-07-19 14:13:37 +02:00
@@ -192,14 +192,14 @@
     }
     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 @@
 }
 
 
-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 @@
     }
     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 @@
 }
 
 
-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 @@
 {
   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 @@
     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 @@
 {
   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);
 }
 

--- 1.6/myisam/mi_rsame.c	2001-12-06 13:10:40 +01:00
+++ 1.7/myisam/mi_rsame.c	2005-07-19 14:13:37 +02:00
@@ -30,7 +30,7 @@
 {
   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);
   }

--- 1.4/myisam/mi_rsamepos.c	2001-12-06 13:10:40 +01:00
+++ 1.5/myisam/mi_rsamepos.c	2005-07-19 14:13:37 +02:00
@@ -32,7 +32,7 @@
 {
   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);
   }

--- 1.54/myisam/mi_search.c	2005-04-16 17:57:14 +02:00
+++ 1.55/myisam/mi_search.c	2005-07-19 14:13:37 +02:00
@@ -29,7 +29,7 @@
 {
   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;

--- 1.17/myisam/mi_update.c	2004-12-31 02:47:50 +01:00
+++ 1.18/myisam/mi_update.c	2005-07-19 14:13:37 +02:00
@@ -87,7 +87,7 @@
   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 )
       {

--- 1.52/myisam/mi_write.c	2005-05-13 11:08:02 +02:00
+++ 1.53/myisam/mi_write.c	2005-07-19 14:13:37 +02:00
@@ -101,7 +101,7 @@
   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 @@
     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 @@
   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 @@
   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;

--- 1.112/myisam/myisamchk.c	2005-03-25 07:39:02 +01:00
+++ 1.113/myisam/myisamchk.c	2005-07-19 14:13:37 +02:00
@@ -871,8 +871,8 @@
        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 @@
       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 @@
       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 @@
 	       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 @@
   }
 
   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 @@
   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",

--- 1.76/myisam/myisamdef.h	2005-05-13 11:08:02 +02:00
+++ 1.77/myisam/myisamdef.h	2005-07-19 14:13:37 +02:00
@@ -676,10 +676,10 @@
 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);

--- 1.29/myisam/myisamlog.c	2005-02-10 00:41:22 +01:00
+++ 1.30/myisam/myisamlog.c	2005-07-19 14:13:38 +02:00
@@ -810,7 +810,7 @@
 
   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));

--- 1.43/myisam/myisampack.c	2005-07-04 02:42:05 +02:00
+++ 1.44/myisam/myisampack.c	2005-07-19 14:13:38 +02:00
@@ -441,9 +441,9 @@
     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 @@
   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 @@
     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 @@
   }
   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;

--- 1.45/myisam/sort.c	2005-01-24 18:57:30 +01:00
+++ 1.46/myisam/sort.c	2005-07-19 14:13:38 +02:00
@@ -479,7 +479,7 @@
     }
     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);

--- 1.153/sql/ha_myisam.cc	2005-06-13 12:41:07 +02:00
+++ 1.154/sql/ha_myisam.cc	2005-07-19 14:13:38 +02:00
@@ -602,7 +602,7 @@
 	!(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 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 @@
   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 @@
     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)

--- 1.9/myisam/mi_preload.c	2005-02-12 00:05:05 +01:00
+++ 1.10/myisam/mi_preload.c	2005-07-19 14:13:37 +02:00
@@ -51,7 +51,7 @@
   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;

--- 1.12/include/my_bitmap.h	2005-07-01 06:05:34 +02:00
+++ 1.13/include/my_bitmap.h	2005-07-19 14:13:36 +02:00
@@ -54,6 +54,7 @@
 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);

--- 1.27/mysys/my_bitmap.c	2005-07-18 14:31:58 +02:00
+++ 1.28/mysys/my_bitmap.c	2005-07-19 14:13:38 +02:00
@@ -339,6 +339,37 @@
 }
 
 
+/*
+  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;

--- 1.9/sql/sql_bitmap.h	2005-06-05 16:08:44 +02:00
+++ 1.10/sql/sql_bitmap.h	2005-07-19 14:13:38 +02:00
@@ -51,6 +51,14 @@
     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 @@
   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)); }
Thread
bk commit into 5.0 tree (ingo:1.1955) BUG#10932ingo19 Jul