summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/my_bitmap.h7
-rw-r--r--mysql-test/r/range.result8
-rw-r--r--mysys/my_bitmap.c175
-rw-r--r--sql/field.cc3
-rw-r--r--sql/field.h6
-rw-r--r--sql/ha_berkeley.h2
-rw-r--r--sql/ha_innodb.h2
-rw-r--r--sql/ha_myisam.cc3
-rw-r--r--sql/handler.h2
-rw-r--r--sql/mysql_priv.h102
-rw-r--r--sql/opt_range.cc21
-rw-r--r--sql/opt_range.h2
-rw-r--r--sql/sql_bitmap.h108
-rw-r--r--sql/sql_select.cc34
-rw-r--r--sql/table.cc6
15 files changed, 236 insertions, 245 deletions
diff --git a/include/my_bitmap.h b/include/my_bitmap.h
index d3fcece290b..cff2295f45c 100644
--- a/include/my_bitmap.h
+++ b/include/my_bitmap.h
@@ -25,14 +25,13 @@ typedef struct st_bitmap
{
uchar *bitmap;
uint bitmap_size;
- my_bool thread_safe; /* set if several threads access the bitmap */
/*
mutex will be acquired for the duration of each bitmap operation if
- thread_safe flag is set. Otherwise, we optimize by not acquiring the
- mutex
+ thread_safe flag in bitmap_init was set. Otherwise, we optimize by not
+ acquiring the mutex
*/
#ifdef THREAD
- pthread_mutex_t mutex;
+ pthread_mutex_t *mutex;
#endif
} MY_BITMAP;
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index 9f76676ee1a..8c363ef3c89 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -240,11 +240,11 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select * from t1, t1 t2 where t1.y = 2 and t2.x between t1.y-1 and t1.y+1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref y y 5 const 1 Using where
-1 SIMPLE t2 ALL x NULL NULL NULL 9 Range checked for each record (index map: 1)
+1 SIMPLE t2 ALL x NULL NULL NULL 9 Range checked for each record (index map: 0x1)
explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= t1.y-1 and t2.x <= t1.y+1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref y y 5 const 1 Using where
-1 SIMPLE t2 ALL x NULL NULL NULL 9 Range checked for each record (index map: 1)
+1 SIMPLE t2 ALL x NULL NULL NULL 9 Range checked for each record (index map: 0x1)
explain select * from t1, t1 t2 where t1.y = 2 and t2.x between 0 and t1.y;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref y y 5 const 1 Using where
@@ -267,11 +267,11 @@ INSERT INTO t2 VALUES (0),(0),(1),(1),(2),(2);
explain select * from t1, t2 where (t1.key1 <t2.keya + 1) and t2.keya=3;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref j1 j1 4 const 1 Using where; Using index
-1 SIMPLE t1 ALL i1,i2 NULL NULL NULL 4 Range checked for each record (index map: 3)
+1 SIMPLE t1 ALL i1,i2 NULL NULL NULL 4 Range checked for each record (index map: 0x3)
explain select * from t1 force index(i2), t2 where (t1.key1 <t2.keya + 1) and t2.keya=3;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref j1 j1 4 const 1 Using where; Using index
-1 SIMPLE t1 ALL i2 NULL NULL NULL 4 Range checked for each record (index map: 2)
+1 SIMPLE t1 ALL i2 NULL NULL NULL 4 Range checked for each record (index map: 0x2)
DROP TABLE t1,t2;
create table t1 (id int(10) primary key);
insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9);
diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c
index 70b15eaa1d8..af9b3843060 100644
--- a/mysys/my_bitmap.c
+++ b/mysys/my_bitmap.c
@@ -30,63 +30,67 @@
inline void bitmap_lock(MY_BITMAP *map)
{
#ifdef THREAD
- if (map->thread_safe)
- pthread_mutex_lock(&map->mutex);
+ if (map->mutex)
+ pthread_mutex_lock(map->mutex);
#endif
}
inline void bitmap_unlock(MY_BITMAP *map)
{
#ifdef THREAD
- if (map->thread_safe)
- pthread_mutex_unlock(&map->mutex);
+ if (map->mutex)
+ pthread_mutex_unlock(map->mutex);
#endif
}
my_bool bitmap_init(MY_BITMAP *map, uchar *buf, uint bitmap_size, my_bool thread_safe)
{
+ // for efficiency reasons - MY_BITMAP is heavily used
+ DBUG_ASSERT((bitmap_size & 7) == 0);
+ bitmap_size/=8;
if (!(map->bitmap=buf) &&
- !(map->bitmap=(uchar*) my_malloc((bitmap_size+7)/8,
- MYF(MY_WME | MY_ZEROFILL))))
+ !(map->bitmap=(uchar*)my_malloc(bitmap_size + sizeof(pthread_mutex_t),
+ MYF(MY_WME | MY_ZEROFILL))))
return 1;
- DBUG_ASSERT(bitmap_size != ~(uint) 0);
+ map->bitmap_size=bitmap_size;
#ifdef THREAD
- if ((map->thread_safe = thread_safe))
- pthread_mutex_init(&map->mutex, MY_MUTEX_INIT_FAST);
+ if (thread_safe)
+ {
+ map->mutex=(pthread_mutex_t *)(map->bitmap+bitmap_size);
+ pthread_mutex_init(map->mutex, MY_MUTEX_INIT_FAST);
+ }
+ else
+ map->mutex=0;
#endif
- map->bitmap_size=bitmap_size;
return 0;
}
void bitmap_free(MY_BITMAP *map)
{
+#ifdef THREAD
+ if (map->mutex)
+ pthread_mutex_destroy(map->mutex);
+#endif
if (map->bitmap)
{
my_free((char*) map->bitmap, MYF(0));
map->bitmap=0;
-#ifdef THREAD
- if (map->thread_safe)
- pthread_mutex_destroy(&map->mutex);
-#endif
}
}
void bitmap_set_bit(MY_BITMAP *map, uint bitmap_bit)
{
- DBUG_ASSERT(map->bitmap);
- if (bitmap_bit < map->bitmap_size)
- {
- bitmap_lock(map);
- map->bitmap[bitmap_bit / 8] |= (1 << (bitmap_bit & 7));
- bitmap_unlock(map);
- }
+ DBUG_ASSERT(map->bitmap && bitmap_bit < map->bitmap_size*8);
+ bitmap_lock(map);
+ map->bitmap[bitmap_bit / 8] |= (1 << (bitmap_bit & 7));
+ bitmap_unlock(map);
}
uint bitmap_set_next(MY_BITMAP *map)
{
uchar *bitmap=map->bitmap;
uint bit_found = MY_BIT_NONE;
- uint bitmap_size=map->bitmap_size;
+ uint bitmap_size=map->bitmap_size*8;
uint i;
DBUG_ASSERT(map->bitmap);
@@ -114,28 +118,25 @@ uint bitmap_set_next(MY_BITMAP *map)
void bitmap_clear_bit(MY_BITMAP *map, uint bitmap_bit)
{
- DBUG_ASSERT(map->bitmap);
- if (bitmap_bit < map->bitmap_size)
- {
- bitmap_lock(map);
- map->bitmap[bitmap_bit / 8] &= ~ (1 << (bitmap_bit & 7));
- bitmap_unlock(map);
- }
+ DBUG_ASSERT(map->bitmap && bitmap_bit < map->bitmap_size*8);
+ bitmap_lock(map);
+ map->bitmap[bitmap_bit / 8] &= ~ (1 << (bitmap_bit & 7));
+ bitmap_unlock(map);
}
void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size)
{
- uint l, m;
+ uint prefix_bytes, prefix_bits;
DBUG_ASSERT(map->bitmap);
bitmap_lock(map);
- set_if_smaller(prefix_size, map->bitmap_size);
- if ((l=prefix_size / 8))
- memset(map->bitmap, 0xff, l);
- if ((m=prefix_size & 7))
- map->bitmap[l++]= (1 << m)-1;
- if (l < (m=(map->bitmap_size+7)/8))
- bzero(map->bitmap+l, m-l);
+ set_if_smaller(prefix_size, map->bitmap_size*8);
+ if ((prefix_bytes= prefix_size / 8))
+ memset(map->bitmap, 0xff, prefix_bytes);
+ if ((prefix_bits= prefix_size & 7))
+ map->bitmap[prefix_bytes++]= (1 << prefix_bits)-1;
+ if (prefix_bytes < map->bitmap_size)
+ bzero(map->bitmap+prefix_bytes, map->bitmap_size-prefix_bytes);
bitmap_unlock(map);
}
@@ -146,27 +147,27 @@ void bitmap_clear_all(MY_BITMAP *map)
void bitmap_set_all(MY_BITMAP *map)
{
- bitmap_set_prefix(map, map->bitmap_size);
+ bitmap_set_prefix(map, ~0);
}
my_bool bitmap_is_prefix(MY_BITMAP *map, uint prefix_size)
{
- uint l=prefix_size/8, m=prefix_size & 7, i, res=0;
+ uint prefix_bits= prefix_size & 7, res= 0;
+ uchar *m= map->bitmap, *end_prefix= map->bitmap+prefix_size/8,
+ *end= map->bitmap+map->bitmap_size;
- DBUG_ASSERT(map->bitmap);
- if (prefix_size > map->bitmap_size)
- return 0;
+ DBUG_ASSERT(map->bitmap && prefix_size <= map->bitmap_size*8);
bitmap_lock(map);
- for (i=0; i < l; i++)
- if (map->bitmap[i] != 0xff)
+ while (m < end_prefix)
+ if (*m++ != 0xff)
goto ret;
- if (m && map->bitmap[i++] != (1 << m)-1)
+ if (prefix_bits && *m++ != (1 << prefix_bits)-1)
goto ret;
- for (m=(map->bitmap_size+7)/8; i < m; i++)
- if (map->bitmap[i] != 0)
+ while (m < end)
+ if (m++ != 0)
goto ret;
res=1;
@@ -182,38 +183,31 @@ my_bool bitmap_is_clear_all(MY_BITMAP *map)
my_bool bitmap_is_set_all(MY_BITMAP *map)
{
- return bitmap_is_prefix(map, map->bitmap_size);
+ return bitmap_is_prefix(map, map->bitmap_size*8);
}
my_bool bitmap_is_set(MY_BITMAP *map, uint bitmap_bit)
{
- DBUG_ASSERT(map->bitmap);
- return (bitmap_bit < map->bitmap_size) ?
- (map->bitmap[bitmap_bit / 8] & (1 << (bitmap_bit & 7))) : 0;
+ DBUG_ASSERT(map->bitmap && bitmap_bit < map->bitmap_size*8);
+ return map->bitmap[bitmap_bit / 8] & (1 << (bitmap_bit & 7));
}
my_bool bitmap_is_subset(MY_BITMAP *map1, MY_BITMAP *map2)
{
- uint l1, l2, i, res=0;
- uchar *m1=map1->bitmap, *m2=map2->bitmap;
+ uint length, res=0;
+ uchar *m1=map1->bitmap, *m2=map2->bitmap, *end;
- DBUG_ASSERT(map1->bitmap);
- DBUG_ASSERT(map2->bitmap);
+ DBUG_ASSERT(map1->bitmap && map2->bitmap &&
+ map1->bitmap_size==map2->bitmap_size);
bitmap_lock(map1);
bitmap_lock(map2);
- l1=(map1->bitmap_size+7)/8;
- l2=(map2->bitmap_size+7)/8;
- set_if_smaller(l2, l1);
+ end= m1+map1->bitmap_size;
- for (i=0; i < l2; i++)
+ while (m1 < end)
if ((*m1++) & ~(*m2++))
goto ret;
- for (; i < l1; i++)
- if (*m1++)
- goto ret;
-
res=1;
ret:
bitmap_unlock(map2);
@@ -225,13 +219,12 @@ my_bool bitmap_cmp(MY_BITMAP *map1, MY_BITMAP *map2)
{
uint res;
- DBUG_ASSERT(map1->bitmap);
- DBUG_ASSERT(map2->bitmap);
+ DBUG_ASSERT(map1->bitmap && map2->bitmap &&
+ map1->bitmap_size==map2->bitmap_size);
bitmap_lock(map1);
bitmap_lock(map2);
- res= map1->bitmap_size == map2->bitmap_size &&
- memcmp(map1->bitmap, map2->bitmap, (map1->bitmap_size+7)/8)==0;
+ res= memcmp(map1->bitmap, map2->bitmap, map1->bitmap_size)==0;
bitmap_unlock(map2);
bitmap_unlock(map1);
@@ -240,23 +233,17 @@ my_bool bitmap_cmp(MY_BITMAP *map1, MY_BITMAP *map2)
void bitmap_intersect(MY_BITMAP *map, MY_BITMAP *map2)
{
- uint l1, l2, i;
- uchar *m=map->bitmap, *m2=map2->bitmap;
+ uchar *to=map->bitmap, *from=map2->bitmap, *end;
- DBUG_ASSERT(map->bitmap);
- DBUG_ASSERT(map2->bitmap);
+ DBUG_ASSERT(map->bitmap && map2->bitmap &&
+ map->bitmap_size==map2->bitmap_size);
bitmap_lock(map);
bitmap_lock(map2);
- l1=(map->bitmap_size+7)/8;
- l2=(map2->bitmap_size+7)/8;
- set_if_smaller(l2, l1);
+ end= to+map->bitmap_size;
- for (i=0; i < l2; i++)
- *m++ &= *m2++;
-
- if (l1 > l2)
- bzero(m, l1-l2);
+ while (to < end)
+ *to++ &= *from++;
bitmap_unlock(map2);
bitmap_unlock(map);
@@ -264,20 +251,17 @@ void bitmap_intersect(MY_BITMAP *map, MY_BITMAP *map2)
void bitmap_subtract(MY_BITMAP *map, MY_BITMAP *map2)
{
- uint l1, l2, i;
- uchar *m=map->bitmap, *m2=map2->bitmap;
+ uchar *to=map->bitmap, *from=map2->bitmap, *end;
- DBUG_ASSERT(map->bitmap);
- DBUG_ASSERT(map2->bitmap);
+ DBUG_ASSERT(map->bitmap && map2->bitmap &&
+ map->bitmap_size==map2->bitmap_size);
bitmap_lock(map);
bitmap_lock(map2);
- l1=(map->bitmap_size+7)/8;
- l2=(map2->bitmap_size+7)/8;
- set_if_smaller(l2, l1);
+ end= to+map->bitmap_size;
- for (i=0; i < l2; i++)
- *m++ &= ~(*m2++);
+ while (to < end)
+ *to++ &= ~(*from++);
bitmap_unlock(map2);
bitmap_unlock(map);
@@ -285,20 +269,17 @@ void bitmap_subtract(MY_BITMAP *map, MY_BITMAP *map2)
void bitmap_union(MY_BITMAP *map, MY_BITMAP *map2)
{
- uint l1, l2, i;
- uchar *m=map->bitmap, *m2=map2->bitmap;
+ uchar *to=map->bitmap, *from=map2->bitmap, *end;
- DBUG_ASSERT(map->bitmap);
- DBUG_ASSERT(map2->bitmap);
+ DBUG_ASSERT(map->bitmap && map2->bitmap &&
+ map->bitmap_size==map2->bitmap_size);
bitmap_lock(map);
bitmap_lock(map2);
- l1=(map->bitmap_size+7)/8;
- l2=(map2->bitmap_size+7)/8;
- set_if_smaller(l2, l1);
+ end= to+map->bitmap_size;
- for (i=0; i < l2; i++)
- *m++ |= *m2++;
+ while (to < end)
+ *to++ |= *from++;
bitmap_unlock(map2);
bitmap_unlock(map);
diff --git a/sql/field.cc b/sql/field.cc
index 98eb0e01f56..c30c06c6395 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -181,7 +181,8 @@ Field::Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
:ptr(ptr_arg),null_ptr(null_ptr_arg),
table(table_arg),table_name(table_arg ? table_arg->table_name : 0),
field_name(field_name_arg),
- query_id(0),unireg_check(unireg_check_arg),
+ query_id(0), key_start(0), part_of_key(0), part_of_sortkey(0),
+ unireg_check(unireg_check_arg),
field_length(length_arg),null_bit(null_bit_arg),abs_offset(0)
{
flags=null_ptr ? 0: NOT_NULL_FLAG;
diff --git a/sql/field.h b/sql/field.h
index eb0af881121..e7d4bb2416a 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -151,9 +151,9 @@ public:
if (tmp->table->maybe_null)
tmp->flags&= ~NOT_NULL_FLAG;
tmp->table= new_table;
- tmp->key_start.init().clear_all();
- tmp->part_of_key.init().clear_all();
- tmp->part_of_sortkey.init().clear_all();
+ tmp->key_start.init(0);
+ tmp->part_of_key.init(0);
+ tmp->part_of_sortkey.init(0);
tmp->unireg_check=Field::NONE;
tmp->flags&= (NOT_NULL_FLAG | BLOB_FLAG | UNSIGNED_FLAG |
ZEROFILL_FLAG | BINARY_FLAG | ENUM_FLAG | SET_FLAG);
diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h
index 850be48258a..79e52ea71af 100644
--- a/sql/ha_berkeley.h
+++ b/sql/ha_berkeley.h
@@ -107,7 +107,7 @@ class ha_berkeley: public handler
uint extra_rec_buf_length() { return BDB_HIDDEN_PRIMARY_KEY_LENGTH; }
ha_rows estimate_number_of_rows();
bool fast_key_read() { return 1;}
- const key_map& keys_to_use_for_scanning() { return key_map_full; }
+ const key_map *keys_to_use_for_scanning() { return &key_map_full; }
bool has_transactions() { return 1;}
int open(const char *name, int mode, uint test_if_locked);
diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h
index 9ef47a105d6..2fa70f27128 100644
--- a/sql/ha_innodb.h
+++ b/sql/ha_innodb.h
@@ -125,7 +125,7 @@ class ha_innobase: public handler
uint max_key_length() const { return((MAX_KEY_LENGTH <= 3500) ?
MAX_KEY_LENGTH : 3500);}
bool fast_key_read() { return 1;}
- const key_map& keys_to_use_for_scanning() { return key_map_full; }
+ const key_map *keys_to_use_for_scanning() { return &key_map_full; }
bool has_transactions() { return 1;}
int open(const char *name, int mode, uint test_if_locked);
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index ea356a4f17c..a23e4c55618 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -1023,7 +1023,8 @@ void ha_myisam::info(uint flag)
ref_length=info.reflength;
table->db_options_in_use = info.options;
block_size=myisam_block_size;
- table->keys_in_use.set_prefix(table->keys).intersect(info.key_map);
+ table->keys_in_use.set_prefix(table->keys);
+ table->keys_in_use.intersect(info.key_map);
table->keys_for_keyread= table->keys_in_use;
table->keys_for_keyread.subtract(table->read_only_keys);
table->db_record_offset=info.record_offset;
diff --git a/sql/handler.h b/sql/handler.h
index 26671bb5b11..29dea7f213b 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -241,7 +241,7 @@ public:
virtual double read_time(uint index, uint ranges, ha_rows rows)
{ return rows2double(ranges+rows); }
virtual bool fast_key_read() { return 0;}
- virtual const key_map& keys_to_use_for_scanning() { return key_map_empty; }
+ virtual const key_map *keys_to_use_for_scanning() { return &key_map_empty; }
virtual bool has_transactions(){ return 0;}
virtual uint extra_rec_buf_length() { return 0; }
virtual ha_rows estimate_number_of_rows() { return records+EXTRA_RECORDS; }
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 6bc1031739d..c22ca1c2d3c 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -23,113 +23,13 @@
#include <signal.h>
#include <thr_lock.h>
#include <my_base.h> /* Needed by field.h */
-#include <my_bitmap.h>
+#include <sql_bitmap.h>
#include <assert.h>
#ifdef __EMX__
#undef write /* remove pthread.h macro definition for EMX */
#endif
-template <uint default_width> class Bitmap
-{
- MY_BITMAP map;
- uchar buffer[(default_width+7)/8];
-public:
- Bitmap(uint prefix_to_set=0) { init(); set_prefix(prefix_to_set); }
- Bitmap& init()
- {
- bitmap_init(&map, buffer, default_width, 0);
- return *this;
- }
- uint length() const { return default_width; }
- Bitmap& operator=(const Bitmap& map2)
- {
- init();
- memcpy(buffer, map2.buffer, sizeof(buffer));
- return *this;
- }
- Bitmap& set_bit(uint n) { bitmap_set_bit(&map, n); return *this; }
- Bitmap& clear_bit(uint n) { bitmap_clear_bit(&map, n); return *this; }
- Bitmap& set_prefix(uint n) { bitmap_set_prefix(&map, n); return *this; }
- Bitmap& set_all() { bitmap_set_all(&map); return *this;}
- Bitmap& clear_all() { bitmap_clear_all(&map); return *this; }
- Bitmap& intersect(Bitmap& map2) { bitmap_intersect(&map, &map2.map); return *this; }
- Bitmap& intersect(ulonglong map2buff)
- {
- MY_BITMAP map2;
- bitmap_init(&map2, (uchar *)&map2buff, sizeof(ulonglong)*8, 0);
- bitmap_intersect(&map, &map2);
- return *this;
- }
- Bitmap& subtract(Bitmap& map2) { bitmap_subtract(&map, &map2.map); return *this; }
- Bitmap& merge(Bitmap& map2) { bitmap_union(&map, &map2.map); return *this; }
- my_bool is_set(uint n) const { return bitmap_is_set((MY_BITMAP*)&map, n); }
- my_bool is_prefix(uint n) const { return bitmap_is_prefix((MY_BITMAP*)&map, n); }
- my_bool is_clear_all() const { return bitmap_is_clear_all((MY_BITMAP*)&map); }
- my_bool is_set_all() const { return bitmap_is_set_all((MY_BITMAP*)&map); }
- my_bool is_subset(const Bitmap& map2) const { return bitmap_is_subset((MY_BITMAP*)&map, (MY_BITMAP*)&map2.map); }
- my_bool operator==(const Bitmap& map2) const { return bitmap_cmp((MY_BITMAP*)&map, (MY_BITMAP*)&map2.map); }
- char *print(char *buf) const
- {
- char *s=buf; int i;
- for (i=sizeof(buffer)-1; i>=0 ; i--)
- {
- if ((*s=_dig_vec[buffer[i] >> 4]) != '0')
- break;
- if ((*s=_dig_vec[buffer[i] & 15]) != '0')
- break;
- }
- for (s++, i-- ; i>=0 ; i--)
- {
- *s++=_dig_vec[buffer[i] >> 4];
- *s++=_dig_vec[buffer[i] & 15];
- }
- *s=0;
- return buf;
- }
- ulonglong to_ulonglong() const
- {
- if (sizeof(buffer) >= sizeof(ulonglong))
- return *(ulonglong*)buffer;
- ulonglong x=0;
- memcpy(&x, buffer, sizeof(buffer));
- return x;
- }
-};
-
-template <> class Bitmap<64>
-{
- ulonglong map;
-public:
- Bitmap(uint prefix_to_set=0) { set_prefix(prefix_to_set); }
- Bitmap<64>& init() { return *this; }
- uint length() const { return 64; }
- Bitmap<64>& set_bit(uint n) { map|= ((ulonglong)1) << n; return *this; }
- Bitmap<64>& clear_bit(uint n) { map&= ~(((ulonglong)1) << n); return *this; }
- Bitmap<64>& set_prefix(uint n)
- {
- if (n >= length())
- set_all();
- else
- map= (((ulonglong)1) << n)-1;
- return *this;
- }
- Bitmap<64>& set_all() { map=~(ulonglong)0; return *this;}
- Bitmap<64>& clear_all() { map=(ulonglong)0; return *this; }
- Bitmap<64>& intersect(Bitmap<64>& map2) { map&= map2.map; return *this; }
- Bitmap<64>& intersect(ulonglong map2) { map&= map2; return *this; }
- Bitmap<64>& subtract(Bitmap<64>& map2) { map&= ~map2.map; return *this; }
- Bitmap<64>& merge(Bitmap<64>& map2) { map|= map2.map; return *this; }
- my_bool is_set(uint n) const { return test(map & (((ulonglong)1) << n)); }
- my_bool is_prefix(uint n) const { return map == (((ulonglong)1) << n)-1; }
- my_bool is_clear_all() const { return map == (ulonglong)0; }
- my_bool is_set_all() const { return map == ~(ulonglong)0; }
- my_bool is_subset(const Bitmap<64>& map2) const { return !(map & ~map2.map); }
- my_bool operator==(const Bitmap<64>& map2) const { return map == map2.map; }
- char *print(char *buf) const { longlong2str(map,buf,16); return buf; }
- ulonglong to_ulonglong() const { return map; }
-};
-
/* TODO convert all these three maps to Bitmap classes */
typedef ulonglong table_map; /* Used for table bits in join */
typedef Bitmap<64> key_map; /* Used for finding keys */
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index cf1838489d0..da6ede8586f 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -305,7 +305,7 @@ static ha_rows check_quick_keys(PARAM *param,uint index,SEL_ARG *key_tree,
static QUICK_SELECT *get_quick_select(PARAM *param,uint index,
SEL_ARG *key_tree);
#ifndef DBUG_OFF
-static void print_quick(QUICK_SELECT *quick,const key_map& needed_reg);
+static void print_quick(QUICK_SELECT *quick,const key_map* needed_reg);
#endif
static SEL_TREE *tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
static SEL_TREE *tree_or(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
@@ -364,6 +364,7 @@ SQL_SELECT *make_select(TABLE *head, table_map const_tables,
SQL_SELECT::SQL_SELECT() :quick(0),cond(0),free_cond(0)
{
+ quick_keys.clear_all(); needed_reg.clear_all();
my_b_clear(&file);
}
@@ -588,9 +589,9 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
uint idx;
double scan_time;
DBUG_ENTER("test_quick_select");
-/* DBUG_PRINT("enter",("keys_to_use: %lu prev_tables: %lu const_tables: %lu",
- (ulong) keys_to_use, (ulong) prev_tables,
- (ulong) const_tables));*/
+ DBUG_PRINT("enter",("keys_to_use: %lu prev_tables: %lu const_tables: %lu",
+ keys_to_use.to_ulonglong(), (ulong) prev_tables,
+ (ulong) const_tables));
delete quick;
quick=0;
@@ -622,7 +623,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
SEL_TREE *tree;
KEY_PART *key_parts;
PARAM param;
-
+
/* set up parameter that is passed to all functions */
param.thd= thd;
param.baseflag=basflag;
@@ -743,7 +744,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
my_pthread_setspecific_ptr(THR_MALLOC,old_root);
thd->no_errors=0;
}
- DBUG_EXECUTE("info",print_quick(quick,needed_reg););
+ DBUG_EXECUTE("info",print_quick(quick,&needed_reg););
/*
Assume that if the user is using 'limit' we will only need to scan
limit rows if we are using a key
@@ -2853,7 +2854,7 @@ print_key(KEY_PART *key_part,const char *key,uint used_length)
fputc('/',DBUG_FILE);
if (field->real_maybe_null())
{
- length++; // null byte is not in part_length
+ length++; // null byte is not in part_length
if (*key++)
{
fwrite("NULL",sizeof(char),4,DBUG_FILE);
@@ -2869,7 +2870,7 @@ print_key(KEY_PART *key_part,const char *key,uint used_length)
}
}
-static void print_quick(QUICK_SELECT *quick,const key_map& needed_reg)
+static void print_quick(QUICK_SELECT *quick,const key_map* needed_reg)
{
QUICK_RANGE *range;
char buf[MAX_KEY/8+1];
@@ -2879,8 +2880,8 @@ static void print_quick(QUICK_SELECT *quick,const key_map& needed_reg)
List_iterator<QUICK_RANGE> li(quick->ranges);
DBUG_LOCK_FILE;
- fprintf(DBUG_FILE,"Used quick_range on key: %d (other_keys: %s):\n",
- quick->index, needed_reg.print(buf));
+ fprintf(DBUG_FILE,"Used quick_range on key: %d (other_keys: 0x%s):\n",
+ quick->index, needed_reg->print(buf));
while ((range=li++))
{
if (!(range->flag & NO_MIN_RANGE))
diff --git a/sql/opt_range.h b/sql/opt_range.h
index b4d855c0faa..1c209dc7027 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -128,7 +128,7 @@ class SQL_SELECT :public Sql_alloc {
SQL_SELECT();
~SQL_SELECT();
bool check_quick(THD *thd, bool force_quick_range, ha_rows limit)
- { return test_quick_select(thd, key_map(~0L),0,limit, force_quick_range) < 0; }
+ { return test_quick_select(thd, key_map(~0), 0, limit, force_quick_range) < 0; }
inline bool skipp_record() { return cond ? cond->val_int() == 0 : 0; }
int test_quick_select(THD *thd, key_map keys, table_map prev_tables,
ha_rows limit, bool force_quick_range=0);
diff --git a/sql/sql_bitmap.h b/sql/sql_bitmap.h
new file mode 100644
index 00000000000..b8e163ce24a
--- /dev/null
+++ b/sql/sql_bitmap.h
@@ -0,0 +1,108 @@
+#include <my_global.h>
+//#include <mysql_version.h>
+//#include <mysql_embed.h>
+//#include <my_sys.h>
+//#include <m_string.h>
+//#include <hash.h>
+//#include <signal.h>
+//#include <thr_lock.h>
+//#include <my_base.h>
+#include <my_bitmap.h>
+#include <assert.h>
+
+template <uint default_width> class Bitmap
+{
+ MY_BITMAP map;
+ uchar buffer[(default_width+7)/8];
+public:
+ Bitmap() { init(); }
+ Bitmap(uint prefix_to_set) { init(prefix_to_set); }
+ void init() { bitmap_init(&map, buffer, default_width, 0); }
+ void init(uint prefix_to_set) { init(); set_prefix(prefix_to_set); }
+ uint length() const { return default_width; }
+ Bitmap& operator=(const Bitmap& map2)
+ {
+ init();
+ memcpy(buffer, map2.buffer, sizeof(buffer));
+ }
+ void set_bit(uint n) { bitmap_set_bit(&map, n); }
+ void clear_bit(uint n) { bitmap_clear_bit(&map, n); }
+ void set_prefix(uint n) { bitmap_set_prefix(&map, n); }
+ void set_all() { bitmap_set_all(&map); }
+ void clear_all() { bitmap_clear_all(&map); }
+ void intersect(Bitmap& map2) { bitmap_intersect(&map, &map2.map); }
+ void intersect(ulonglong map2buff)
+ {
+ MY_BITMAP map2;
+ bitmap_init(&map2, (uchar *)&map2buff, sizeof(ulonglong)*8, 0);
+ bitmap_intersect(&map, &map2);
+ }
+ 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); }
+ my_bool is_prefix(uint n) const { return bitmap_is_prefix(&map, n); }
+ my_bool is_clear_all() const { return bitmap_is_clear_all(&map); }
+ my_bool is_set_all() const { return bitmap_is_set_all(&map); }
+ my_bool is_subset(const Bitmap& map2) const { return bitmap_is_subset(&map, &map2.map); }
+ my_bool operator==(const Bitmap& map2) const { return bitmap_cmp(&map, &map2.map); }
+ char *print(char *buf) const
+ {
+ char *s=buf; int i;
+ for (i=sizeof(buffer)-1; i>=0 ; i--)
+ {
+ if ((*s=_dig_vec[buffer[i] >> 4]) != '0')
+ break;
+ if ((*s=_dig_vec[buffer[i] & 15]) != '0')
+ break;
+ }
+ for (s++, i-- ; i>=0 ; i--)
+ {
+ *s++=_dig_vec[buffer[i] >> 4];
+ *s++=_dig_vec[buffer[i] & 15];
+ }
+ *s=0;
+ return buf;
+ }
+ ulonglong to_ulonglong() const
+ {
+ if (sizeof(buffer) >= 8)
+ return uint8korr(buffer);
+ DBUG_ASSERT(sizeof(buffer) >= 4);
+ uint4korr(buffer);
+ }
+};
+
+template <> class Bitmap<64>
+{
+ ulonglong map;
+public:
+ Bitmap<64>() { }
+ Bitmap<64>(uint prefix_to_set) { set_prefix(prefix_to_set); }
+ void init() { }
+ void init(uint prefix_to_set) { set_prefix(prefix_to_set); }
+ uint length() const { return 64; }
+ void set_bit(uint n) { map|= ((ulonglong)1) << n; }
+ void clear_bit(uint n) { map&= ~(((ulonglong)1) << n); }
+ void set_prefix(uint n)
+ {
+ if (n >= length())
+ set_all();
+ else
+ map= (((ulonglong)1) << n)-1;
+ }
+ void set_all() { map=~(ulonglong)0; }
+ void clear_all() { map=(ulonglong)0; }
+ void intersect(Bitmap<64>& map2) { map&= map2.map; }
+ void intersect(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)); }
+ my_bool is_prefix(uint n) const { return map == (((ulonglong)1) << n)-1; }
+ my_bool is_clear_all() const { return map == (ulonglong)0; }
+ my_bool is_set_all() const { return map == ~(ulonglong)0; }
+ my_bool is_subset(const Bitmap<64>& map2) const { return !(map & ~map2.map); }
+ my_bool operator==(const Bitmap<64>& map2) const { return map == map2.map; }
+ char *print(char *buf) const { longlong2str(map,buf,16); return buf; }
+ ulonglong to_ulonglong() const { return map; }
+};
+
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index f25b012a0fa..5c784422bc4 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -117,7 +117,7 @@ static int join_read_next_same_or_null(READ_RECORD *info);
static COND *make_cond_for_table(COND *cond,table_map table,
table_map used_table);
static Item* part_of_refkey(TABLE *form,Field *field);
-static uint find_shortest_key(TABLE *table, const key_map& usable_keys);
+static uint find_shortest_key(TABLE *table, const key_map *usable_keys);
static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,
ha_rows select_limit, bool no_changes);
static int create_sort_index(THD *thd, JOIN *join, ORDER *order,
@@ -529,7 +529,7 @@ JOIN::optimize()
conds= optimize_cond(conds,&cond_value);
if (thd->net.report_error)
{
- error= 1;
+ error= 1;
DBUG_PRINT("error",("Error from optimize_cond"));
DBUG_RETURN(1);
}
@@ -559,7 +559,7 @@ JOIN::optimize()
if (res < 0)
{
zero_result_cause= "No matching min/max row";
- error=0;
+ error=0;
DBUG_RETURN(0);
}
zero_result_cause= "Select tables optimized away";
@@ -706,7 +706,7 @@ JOIN::optimize()
/*
Force MySQL to read the table in sorted order to get result in
ORDER BY order.
- */
+ */
tmp_table_param.quick_group=0;
}
order=0;
@@ -768,7 +768,7 @@ JOIN::optimize()
make_join_readinfo(this,
(select_options & (SELECT_DESCRIBE |
SELECT_NO_JOIN_CACHE)) |
- (select_lex->ftfunc_list->elements ?
+ (select_lex->ftfunc_list->elements ?
SELECT_NO_JOIN_CACHE : 0));
/*
@@ -1497,7 +1497,7 @@ JOIN::cleanup()
int
mysql_select(THD *thd, Item ***rref_pointer_array,
- TABLE_LIST *tables, uint wild_num, List<Item> &fields,
+ TABLE_LIST *tables, uint wild_num, List<Item> &fields,
COND *conds, uint og_num, ORDER *order, ORDER *group,
Item *having, ORDER *proc_param, ulong select_options,
select_result *result, SELECT_LEX_UNIT *unit,
@@ -3257,13 +3257,13 @@ make_simple_join(JOIN *join,TABLE *tmp_table)
join->row_limit=join->unit->select_limit_cnt;
join->do_send_rows = (join->row_limit) ? 1 : 0;
- join_tab->cache.buff=0; /* No cacheing */
+ join_tab->cache.buff=0; /* No caching */
join_tab->table=tmp_table;
join_tab->select=0;
join_tab->select_cond=0;
join_tab->quick=0;
join_tab->type= JT_ALL; /* Map through all records */
- join_tab->keys.init().set_all(); /* test everything in quick */
+ join_tab->keys.init(~0); /* test everything in quick */
join_tab->info=0;
join_tab->on_expr=0;
join_tab->ref.key = -1;
@@ -3591,7 +3591,7 @@ make_join_readinfo(JOIN *join, uint options)
}
else if (!table->used_keys.is_clear_all() && ! (tab->select && tab->select->quick))
{ // Only read index tree
- tab->index=find_shortest_key(table, table->used_keys);
+ tab->index=find_shortest_key(table, & table->used_keys);
tab->table->file->index_init(tab->index);
tab->read_first_record= join_read_first;
tab->type=JT_NEXT; // Read with index_first / index_next
@@ -6605,15 +6605,15 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
return reverse;
}
-static uint find_shortest_key(TABLE *table, const key_map& usable_keys)
+static uint find_shortest_key(TABLE *table, const key_map *usable_keys)
{
uint min_length= (uint) ~0;
uint best= MAX_KEY;
- if (!usable_keys.is_clear_all())
+ if (!usable_keys->is_clear_all())
{
- for (uint nr=0; nr < usable_keys.length() ; nr++)
+ for (uint nr=0; nr < table->keys ; nr++)
{
- if (usable_keys.is_set(nr))
+ if (usable_keys->is_set(nr))
{
if (table->key_info[nr].key_length < min_length)
{
@@ -6674,7 +6674,7 @@ test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts,
KEY_PART_INFO *ref_key_part= table->key_info[ref].key_part;
KEY_PART_INFO *ref_key_part_end= ref_key_part + ref_key_parts;
- for (nr= 0; nr < usable_keys.length(); nr++)
+ for (nr= 0 ; nr < table->keys ; nr++)
{
if (usable_keys.is_set(nr) &&
table->key_info[nr].key_length < min_length &&
@@ -6840,7 +6840,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
*/
if (select_limit >= table->file->records)
{
- keys=table->file->keys_to_use_for_scanning();
+ keys=*table->file->keys_to_use_for_scanning();
keys.merge(table->used_keys);
}
else
@@ -6848,7 +6848,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
keys.intersect(usable_keys);
- for (nr=0; nr < keys.length() ; nr++)
+ for (nr=0; nr < table->keys ; nr++)
{
uint not_used;
if (keys.is_set(nr))
@@ -8845,7 +8845,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
if (tab->use_quick == 2)
{
char buf[MAX_KEY/8+1];
- sprintf(buff_ptr,"; Range checked for each record (index map: %s)",
+ sprintf(buff_ptr,"; Range checked for each record (index map: 0x%s)",
tab->keys.print(buf));
buff_ptr=strend(buff_ptr);
}
diff --git a/sql/table.cc b/sql/table.cc
index 24c5b941c0b..ebe1b51248e 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -166,9 +166,9 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
outparam->keys= keys= disk_buff[0];
outparam->key_parts= key_parts= disk_buff[1];
}
- outparam->keys_for_keyread.init().set_prefix(keys);
- outparam->keys_in_use.init().set_prefix(keys);
- outparam->read_only_keys.init().clear_all();
+ outparam->keys_for_keyread.init(keys);
+ outparam->keys_in_use.init(keys);
+ outparam->read_only_keys.init(0);
outparam->quick_keys.init();
outparam->used_keys.init();
outparam->keys_in_use_for_query.init();