Commit 969be9a3 authored by unknown's avatar unknown

fixes to Bitmap class

parent b0fcdafd
......@@ -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;
......
......@@ -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);
......
......@@ -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);
......
......@@ -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;
......
......@@ -151,9 +151,9 @@ class Field
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);
......
......@@ -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);
......
......@@ -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);
......
......@@ -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;
......
......@@ -241,7 +241,7 @@ class handler :public Sql_alloc
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; }
......
......@@ -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 */
......
......@@ -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))
......
......@@ -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);
......
#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; }
};
......@@ -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);
}
......
......@@ -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();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment