464
460
MAX_KEY if no such index was found.
467
uint32_t optimizer::get_index_for_order(Table *table, Order *order, ha_rows limit)
463
uint32_t optimizer::get_index_for_order(Table *table, order_st *order, ha_rows limit)
470
466
uint32_t match_key= MAX_KEY, match_key_len= MAX_KEY_LENGTH + 1;
473
469
for (ord= order; ord; ord= ord->next)
543
539
static int fill_used_fields_bitmap(optimizer::Parameter *param)
545
541
Table *table= param->table;
547
param->tmp_covered_fields.clear();
548
param->needed_fields.resize(table->getShare()->sizeFields());
549
param->needed_fields.reset();
544
param->tmp_covered_fields.setBitmap(0);
545
param->fields_bitmap_size= table->getShare()->column_bitmap_size;
546
if (!(tmp= (my_bitmap_map*) param->mem_root->alloc_root(param->fields_bitmap_size)) ||
547
param->needed_fields.init(tmp, table->getShare()->sizeFields()))
551
param->needed_fields|= *table->read_set;
552
param->needed_fields|= *table->write_set;
552
param->needed_fields= *table->read_set;
553
bitmap_union(¶m->needed_fields, table->write_set);
554
555
pk= param->table->getShare()->getPrimaryKey();
555
556
if (pk != MAX_KEY && param->table->cursor->primary_key_is_clustered())
559
560
KeyPartInfo *key_part_end= key_part +
560
561
param->table->key_info[pk].key_parts;
561
562
for (;key_part != key_part_end; ++key_part)
562
param->needed_fields.reset(key_part->fieldnr-1);
563
param->needed_fields.clearBit(key_part->fieldnr-1);
1182
typedef struct st_ror_scan_info
1184
uint32_t idx; /* # of used key in param->keys */
1185
uint32_t keynr; /* # of used key in table */
1186
ha_rows records; /* estimate of # records this scan will return */
1188
/* Set of intervals over key fields that will be used for row retrieval. */
1189
optimizer::SEL_ARG *sel_arg;
1191
/* Fields used in the query and covered by this ROR scan. */
1192
MyBitmap covered_fields;
1193
uint32_t used_fields_covered; /* # of set bits in covered_fields */
1194
int key_rec_length; /* length of key record (including rowid) */
1197
Cost of reading all index records with values in sel_arg intervals set
1198
(assuming there is no need to access full table records)
1200
double index_read_cost;
1201
uint32_t first_uncovered_field; /* first unused bit in covered_fields */
1202
uint32_t key_components; /* # of parts in the key */
1190
Create optimizer::RorScanInfo* structure with a single ROR scan on index idx using
1207
Create ROR_SCAN_INFO* structure with a single ROR scan on index idx using
1191
1208
sel_arg set of intervals.
1205
optimizer::RorScanInfo *make_ror_scan(const optimizer::Parameter *param, int idx, optimizer::SEL_ARG *sel_arg)
1222
ROR_SCAN_INFO *make_ror_scan(const optimizer::Parameter *param, int idx, optimizer::SEL_ARG *sel_arg)
1207
optimizer::RorScanInfo *ror_scan= NULL;
1224
ROR_SCAN_INFO *ror_scan;
1225
my_bitmap_map *bitmap_buf;
1209
1227
uint32_t keynr;
1211
if (!(ror_scan= (optimizer::RorScanInfo*)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo))))
1229
if (!(ror_scan= (ROR_SCAN_INFO*)param->mem_root->alloc_root(sizeof(ROR_SCAN_INFO))))
1214
1232
ror_scan->idx= idx;
1218
1236
ror_scan->sel_arg= sel_arg;
1219
1237
ror_scan->records= param->table->quick_rows[keynr];
1221
ror_scan->covered_fields_size= param->table->getShare()->sizeFields();
1222
boost::dynamic_bitset<> tmp_bitset(param->table->getShare()->sizeFields());
1239
if (!(bitmap_buf= (my_bitmap_map*) param->mem_root->alloc_root(param->fields_bitmap_size)))
1244
if (ror_scan->covered_fields.init(bitmap_buf, param->table->getShare()->sizeFields()))
1248
ror_scan->covered_fields.clearAll();
1225
1250
KeyPartInfo *key_part= param->table->key_info[keynr].key_part;
1226
1251
KeyPartInfo *key_part_end= key_part +
1227
1252
param->table->key_info[keynr].key_parts;
1228
for (; key_part != key_part_end; ++key_part)
1253
for (;key_part != key_part_end; ++key_part)
1230
if (param->needed_fields.test(key_part->fieldnr-1))
1231
tmp_bitset.set(key_part->fieldnr-1);
1255
if (param->needed_fields.isBitSet(key_part->fieldnr-1))
1256
ror_scan->covered_fields.setBit(key_part->fieldnr-1);
1233
1258
double rows= rows2double(param->table->quick_rows[ror_scan->keynr]);
1234
1259
ror_scan->index_read_cost=
1235
1260
param->table->cursor->index_only_read_time(ror_scan->keynr, rows);
1236
ror_scan->covered_fields= tmp_bitset.to_ulong();
1242
Compare two optimizer::RorScanInfo** by E(#records_matched) * key_record_length.
1266
Compare two ROR_SCAN_INFO** by E(#records_matched) * key_record_length.
1244
1268
cmp_ror_scan_info()
1245
1269
a ptr to first compared value
1254
static int cmp_ror_scan_info(optimizer::RorScanInfo** a, optimizer::RorScanInfo** b)
1278
static int cmp_ror_scan_info(ROR_SCAN_INFO** a, ROR_SCAN_INFO** b)
1256
1280
double val1= rows2double((*a)->records) * (*a)->key_rec_length;
1257
1281
double val2= rows2double((*b)->records) * (*b)->key_rec_length;
1296
1320
/* Auxiliary structure for incremental ROR-intersection creation */
1297
typedef struct st_ror_intersect_info
1299
st_ror_intersect_info()
1306
index_scan_costs(0.0),
1310
st_ror_intersect_info(const optimizer::Parameter *in_param)
1313
covered_fields(in_param->table->getShare()->sizeFields()),
1314
out_rows(in_param->table->cursor->stats.records),
1317
index_scan_costs(0.0),
1320
covered_fields.reset();
1323
1323
const optimizer::Parameter *param;
1324
boost::dynamic_bitset<> covered_fields; /* union of fields covered by all scans */
1324
MyBitmap covered_fields; /* union of fields covered by all scans */
1326
1326
Fraction of table records that satisfies conditions of all scans.
1327
1327
This is the number of full records that will be retrieved if a
1337
1337
} ROR_INTERSECT_INFO;
1341
Allocate a ROR_INTERSECT_INFO and initialize it to contain zero scans.
1344
ror_intersect_init()
1345
param Parameter from test_quick_select
1353
ROR_INTERSECT_INFO* ror_intersect_init(const optimizer::Parameter *param)
1355
ROR_INTERSECT_INFO *info;
1357
if (!(info= (ROR_INTERSECT_INFO*)param->mem_root->alloc_root(sizeof(ROR_INTERSECT_INFO))))
1360
if (!(buf= (my_bitmap_map*) param->mem_root->alloc_root(param->fields_bitmap_size)))
1362
if (info->covered_fields.init(buf, param->table->getShare()->sizeFields()))
1364
info->is_covering= false;
1365
info->index_scan_costs= 0.0;
1366
info->index_records= 0;
1367
info->out_rows= (double) param->table->cursor->stats.records;
1368
info->covered_fields.clearAll();
1340
1372
static void ror_intersect_cpy(ROR_INTERSECT_INFO *dst,
1341
1373
const ROR_INTERSECT_INFO *src)
1443
1475
static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info,
1444
const optimizer::RorScanInfo *scan)
1476
const ROR_SCAN_INFO *scan)
1446
1478
double selectivity_mult= 1.0;
1447
1479
KeyPartInfo *key_part= info->param->table->key_info[scan->keynr].key_part;
1464
1496
sel_arg= sel_arg->next_key_part)
1467
test(info->covered_fields.test(key_part[sel_arg->part].fieldnr-1));
1499
test(info->covered_fields.isBitSet(key_part[sel_arg->part].fieldnr-1));
1468
1500
if (cur_covered != prev_covered)
1470
1502
/* create (part1val, ..., part{n-1}val) tuple. */
1551
1583
static bool ror_intersect_add(ROR_INTERSECT_INFO *info,
1552
optimizer::RorScanInfo* ror_scan, bool is_cpk_scan)
1584
ROR_SCAN_INFO* ror_scan, bool is_cpk_scan)
1554
1586
double selectivity_mult= 1.0;
1577
1609
info->index_records += info->param->table->quick_rows[ror_scan->keynr];
1578
1610
info->index_scan_costs += ror_scan->index_read_cost;
1579
boost::dynamic_bitset<> tmp_bitset= ror_scan->bitsToBitset();
1580
info->covered_fields|= tmp_bitset;
1581
if (! info->is_covering && info->param->needed_fields.is_subset_of(info->covered_fields))
1611
bitmap_union(&info->covered_fields, &ror_scan->covered_fields);
1612
if (!info->is_covering && bitmap_is_subset(&info->param->needed_fields,
1613
&info->covered_fields))
1583
1615
info->is_covering= true;
1587
1619
info->total_cost= info->index_scan_costs;
1588
if (! info->is_covering)
1620
if (!info->is_covering)
1590
1622
optimizer::CostVector sweep_cost;
1591
1623
Join *join= info->param->session->lex->select_lex.join;
1636
1668
optimizer::SEL_TREE *tree,
1637
1669
double read_time)
1639
optimizer::RorScanInfo **ror_scan_mark;
1640
optimizer::RorScanInfo **ror_scans_end= tree->ror_scans_end;
1671
ROR_SCAN_INFO **ror_scan_mark;
1672
ROR_SCAN_INFO **ror_scans_end= tree->ror_scans_end;
1642
for (optimizer::RorScanInfo **scan= tree->ror_scans; scan != ror_scans_end; ++scan)
1674
for (ROR_SCAN_INFO **scan= tree->ror_scans; scan != ror_scans_end; ++scan)
1643
1675
(*scan)->key_components=
1644
1676
param->table->key_info[(*scan)->keynr].key_parts;
1651
1683
/*I=set of all covering indexes */
1652
1684
ror_scan_mark= tree->ror_scans;
1654
boost::dynamic_bitset<> *covered_fields= ¶m->tmp_covered_fields;
1655
if (covered_fields->empty())
1686
MyBitmap *covered_fields= ¶m->tmp_covered_fields;
1687
if (! covered_fields->getBitmap())
1657
covered_fields->resize(param->table->getShare()->sizeFields());
1689
my_bitmap_map *tmp_bitmap= (my_bitmap_map*)param->mem_root->alloc_root(param->fields_bitmap_size);
1690
covered_fields->setBitmap(tmp_bitmap);
1659
covered_fields->reset();
1692
if (! covered_fields->getBitmap() ||
1693
covered_fields->init(covered_fields->getBitmap(),
1694
param->table->getShare()->sizeFields()))
1696
covered_fields->clearAll();
1661
1698
double total_cost= 0.0f;
1662
1699
ha_rows records=0;
1670
1707
number of first not covered component
1671
1708
Calculate and save these values for each of remaining scans.
1673
for (optimizer::RorScanInfo **scan= ror_scan_mark; scan != ror_scans_end; ++scan)
1710
for (ROR_SCAN_INFO **scan= ror_scan_mark; scan != ror_scans_end; ++scan)
1675
/* subtract one bitset from the other */
1676
(*scan)->subtractBitset(*covered_fields);
1712
bitmap_subtract(&(*scan)->covered_fields, covered_fields);
1677
1713
(*scan)->used_fields_covered=
1678
(*scan)->getBitCount();
1679
(*scan)->first_uncovered_field= (*scan)->findFirstNotSet();
1714
(*scan)->covered_fields.getBitsSet();
1715
(*scan)->first_uncovered_field=
1716
(*scan)->covered_fields.getFirst();
1682
1719
internal::my_qsort(ror_scan_mark, ror_scans_end-ror_scan_mark,
1683
sizeof(optimizer::RorScanInfo*),
1720
sizeof(ROR_SCAN_INFO*),
1684
1721
(qsort_cmp)cmp_ror_scan_info_covering);
1686
1723
/* I=I-first(I) */
1689
1726
if (total_cost > read_time)
1691
1728
/* F=F-covered by first(I) */
1692
boost::dynamic_bitset<> tmp_bitset= (*ror_scan_mark)->bitsToBitset();
1693
*covered_fields|= tmp_bitset;
1694
all_covered= param->needed_fields.is_subset_of(*covered_fields);
1695
} while ((++ror_scan_mark < ror_scans_end) && ! all_covered);
1729
bitmap_union(covered_fields, &(*ror_scan_mark)->covered_fields);
1730
all_covered= bitmap_is_subset(¶m->needed_fields, covered_fields);
1731
} while ((++ror_scan_mark < ror_scans_end) && !all_covered);
1697
1733
if (!all_covered || (ror_scan_mark - tree->ror_scans) == 1)
1718
1754
uint32_t best_num= (ror_scan_mark - tree->ror_scans);
1719
if (!(trp->first_scan= (optimizer::RorScanInfo**)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo*)* best_num)))
1755
if (!(trp->first_scan= (ROR_SCAN_INFO**)param->mem_root->alloc_root(sizeof(ROR_SCAN_INFO*)* best_num)))
1721
memcpy(trp->first_scan, tree->ror_scans, best_num*sizeof(optimizer::RorScanInfo*));
1757
memcpy(trp->first_scan, tree->ror_scans, best_num*sizeof(ROR_SCAN_INFO*));
1722
1758
trp->last_scan= trp->first_scan + best_num;
1723
1759
trp->is_covering= true;
1724
1760
trp->read_cost= total_cost;
1810
Step1: Collect ROR-able SEL_ARGs and create optimizer::RorScanInfo for each of
1846
Step1: Collect ROR-able SEL_ARGs and create ROR_SCAN_INFO for each of
1811
1847
them. Also find and save clustered PK scan if there is one.
1813
optimizer::RorScanInfo **cur_ror_scan= NULL;
1814
optimizer::RorScanInfo *cpk_scan= NULL;
1849
ROR_SCAN_INFO **cur_ror_scan= NULL;
1850
ROR_SCAN_INFO *cpk_scan= NULL;
1815
1851
uint32_t cpk_no= 0;
1816
1852
bool cpk_scan_used= false;
1818
if (! (tree->ror_scans= (optimizer::RorScanInfo**)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo*)* param->keys)))
1854
if (! (tree->ror_scans= (ROR_SCAN_INFO**)param->mem_root->alloc_root(sizeof(ROR_SCAN_INFO*)* param->keys)))
1825
1861
for (idx= 0, cur_ror_scan= tree->ror_scans; idx < param->keys; idx++)
1827
optimizer::RorScanInfo *scan;
1863
ROR_SCAN_INFO *scan;
1828
1864
if (! tree->ror_scans_map.test(idx))
1830
if (! (scan= make_ror_scan(param, idx, tree->keys[idx])))
1866
if (!(scan= make_ror_scan(param, idx, tree->keys[idx])))
1832
1868
if (param->real_keynr[idx] == cpk_no)
1841
1877
tree->ror_scans_end= cur_ror_scan;
1843
1879
Ok, [ror_scans, ror_scans_end) is array of ptrs to initialized
1844
optimizer::RorScanInfo's.
1845
1881
Step 2: Get best ROR-intersection using an approximate algorithm.
1847
internal::my_qsort(tree->ror_scans, tree->n_ror_scans, sizeof(optimizer::RorScanInfo*),
1883
internal::my_qsort(tree->ror_scans, tree->n_ror_scans, sizeof(ROR_SCAN_INFO*),
1848
1884
(qsort_cmp)cmp_ror_scan_info);
1850
optimizer::RorScanInfo **intersect_scans= NULL; /* ROR scans used in index intersection */
1851
optimizer::RorScanInfo **intersect_scans_end= NULL;
1852
if (! (intersect_scans= (optimizer::RorScanInfo**)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo*) * tree->n_ror_scans)))
1886
ROR_SCAN_INFO **intersect_scans= NULL; /* ROR scans used in index intersection */
1887
ROR_SCAN_INFO **intersect_scans_end= NULL;
1888
if (! (intersect_scans= (ROR_SCAN_INFO**)param->mem_root->alloc_root(sizeof(ROR_SCAN_INFO*) * tree->n_ror_scans)))
1854
1890
intersect_scans_end= intersect_scans;
1856
1892
/* Create and incrementally update ROR intersection. */
1857
ROR_INTERSECT_INFO intersect(param);
1858
ROR_INTERSECT_INFO intersect_best(param);
1893
ROR_INTERSECT_INFO *intersect= NULL;
1894
ROR_INTERSECT_INFO *intersect_best= NULL;
1895
if (! (intersect= ror_intersect_init(param)) ||
1896
! (intersect_best= ror_intersect_init(param)))
1860
1899
/* [intersect_scans,intersect_scans_best) will hold the best intersection */
1861
optimizer::RorScanInfo **intersect_scans_best= NULL;
1900
ROR_SCAN_INFO **intersect_scans_best= NULL;
1862
1901
cur_ror_scan= tree->ror_scans;
1863
1902
intersect_scans_best= intersect_scans;
1864
while (cur_ror_scan != tree->ror_scans_end && ! intersect.is_covering)
1903
while (cur_ror_scan != tree->ror_scans_end && !intersect->is_covering)
1866
1905
/* S= S + first(R); R= R - first(R); */
1867
if (! ror_intersect_add(&intersect, *cur_ror_scan, false))
1906
if (!ror_intersect_add(intersect, *cur_ror_scan, false))
1869
1908
cur_ror_scan++;
1873
1912
*(intersect_scans_end++)= *(cur_ror_scan++);
1875
if (intersect.total_cost < min_cost)
1914
if (intersect->total_cost < min_cost)
1877
1916
/* Local minimum found, save it */
1878
ror_intersect_cpy(&intersect_best, &intersect);
1917
ror_intersect_cpy(intersect_best, intersect);
1879
1918
intersect_scans_best= intersect_scans_end;
1880
min_cost = intersect.total_cost;
1919
min_cost = intersect->total_cost;
1889
*are_all_covering= intersect.is_covering;
1928
*are_all_covering= intersect->is_covering;
1890
1929
uint32_t best_num= intersect_scans_best - intersect_scans;
1891
ror_intersect_cpy(&intersect, &intersect_best);
1930
ror_intersect_cpy(intersect, intersect_best);
1894
1933
Ok, found the best ROR-intersection of non-CPK key scans.
1895
1934
Check if we should add a CPK scan. If the obtained ROR-intersection is
1896
1935
covering, it doesn't make sense to add CPK scan.
1898
if (cpk_scan && ! intersect.is_covering)
1937
if (cpk_scan && !intersect->is_covering)
1900
if (ror_intersect_add(&intersect, cpk_scan, true) &&
1901
(intersect.total_cost < min_cost))
1939
if (ror_intersect_add(intersect, cpk_scan, true) &&
1940
(intersect->total_cost < min_cost))
1903
1942
cpk_scan_used= true;
1904
1943
intersect_best= intersect; //just set pointer here
1915
1954
if (! (trp->first_scan=
1916
(optimizer::RorScanInfo**)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo*)*best_num)))
1955
(ROR_SCAN_INFO**)param->mem_root->alloc_root(sizeof(ROR_SCAN_INFO*)*best_num)))
1918
memcpy(trp->first_scan, intersect_scans, best_num*sizeof(optimizer::RorScanInfo*));
1957
memcpy(trp->first_scan, intersect_scans, best_num*sizeof(ROR_SCAN_INFO*));
1919
1958
trp->last_scan= trp->first_scan + best_num;
1920
trp->is_covering= intersect_best.is_covering;
1921
trp->read_cost= intersect_best.total_cost;
1959
trp->is_covering= intersect_best->is_covering;
1960
trp->read_cost= intersect_best->total_cost;
1922
1961
/* Prevent divisons by zero */
1923
ha_rows best_rows = double2rows(intersect_best.out_rows);
1962
ha_rows best_rows = double2rows(intersect_best->out_rows);
1924
1963
if (! best_rows)
1926
1965
set_if_smaller(param->table->quick_condition_rows, best_rows);
1927
1966
trp->records= best_rows;
1928
trp->index_scan_costs= intersect_best.index_scan_costs;
1967
trp->index_scan_costs= intersect_best->index_scan_costs;
1929
1968
trp->cpk_scan= cpk_scan_used? cpk_scan: NULL;
2528
2567
field->setWriteSet();
2530
2569
Item_result cmp_type= field->cmp_type();
2531
if (!((ref_tables | field->getTable()->map) & param_comp))
2570
if (!((ref_tables | field->table->map) & param_comp))
2532
2571
ftree= get_func_mm_tree(param, cond_func, field, value, cmp_type, inv);
2533
2572
Item_equal *item_equal= field_item->item_equal;
2534
2573
if (item_equal)
2543
2582
if (field->eq(f))
2545
if (!((ref_tables | f->getTable()->map) & param_comp))
2584
if (!((ref_tables | f->table->map) & param_comp))
2547
2586
tree= get_func_mm_tree(param, cond_func, f, value, cmp_type, inv);
2548
2587
ftree= !ftree ? tree : tree_and(param, ftree, tree);
2603
/* Here when simple cond
2604
There are limits on what kinds of const items we can evaluate, grep for
2605
DontEvaluateMaterializedSubqueryTooEarly.
2607
if (cond->const_item() && !cond->is_expensive())
2642
/* Here when simple cond */
2643
if (cond->const_item())
2610
2646
During the cond->val_int() evaluation we can come across a subselect
2696
2732
field->setWriteSet();
2698
2734
Item_result cmp_type= field->cmp_type();
2699
if (!((ref_tables | field->getTable()->map) & param_comp))
2735
if (!((ref_tables | field->table->map) & param_comp))
2701
2737
tree= get_mm_parts(param, cond, field, Item_func::EQ_FUNC,
2702
2738
value,cmp_type);
2735
2771
Item_func::Functype type,
2736
2772
Item *value, Item_result)
2738
if (field->getTable() != param->table)
2774
if (field->table != param->table)
2741
2777
KEY_PART *key_part = param->key_parts;
2805
2841
param->session->mem_root= param->old_root;
2806
2842
if (!value) // IS NULL or IS NOT NULL
2808
if (field->getTable()->maybe_null) // Can't use a key on this
2844
if (field->table->maybe_null) // Can't use a key on this
2810
2846
if (!maybe_null) // Not null field
3122
3158
tree= &optimizer::null_element; // cmp with NULL is never true
3127
Any predicate except "<=>"(null-safe equality operator) involving NULL as a
3128
constant is always FALSE
3129
Put IMPOSSIBLE Tree(null_element) here.
3131
if (type != Item_func::EQUAL_FUNC && field->is_real_null())
3133
tree= &optimizer::null_element;
3137
3161
str= (unsigned char*) alloc->alloc_root(key_part->store_length+1);
3978
4002
uint32_t mrr_buf_size,
3979
4003
memory::Root *parent_alloc)
3981
optimizer::QuickRangeSelect *quick= new optimizer::QuickRangeSelect(param->session,
3983
param->real_keynr[idx],
4005
optimizer::QuickRangeSelect *quick= NULL;
4006
bool create_err= false;
4008
quick= new optimizer::QuickRangeSelect(param->session,
4010
param->real_keynr[idx],
3989
if (get_quick_keys(param,
4018
get_quick_keys(param,
3991
4020
param->key[idx],
4237
4266
table_reference_st *ref,
4238
4267
ha_rows records)
4240
memory::Root *old_root= NULL;
4241
memory::Root *alloc= NULL;
4269
memory::Root *old_root, *alloc;
4270
optimizer::QuickRangeSelect *quick= NULL;
4242
4271
KeyInfo *key_info = &table->key_info[ref->key];
4243
4272
KEY_PART *key_part;
4244
4273
optimizer::QuickRange *range= NULL;
4275
bool create_err= false;
4246
4276
optimizer::CostVector cost;
4248
4278
old_root= session->mem_root;
4249
4279
/* The following call may change session->mem_root */
4250
optimizer::QuickRangeSelect *quick= new optimizer::QuickRangeSelect(session, table, ref->key, 0, 0);
4280
quick= new optimizer::QuickRangeSelect(session, table, ref->key, 0, 0, &create_err);
4251
4281
/* save mem_root set by QuickRangeSelect constructor */
4252
4282
alloc= session->mem_root;
5570
uint32_t optimizer::RorScanInfo::findFirstNotSet() const
5572
boost::dynamic_bitset<> map= bitsToBitset();
5573
for (boost::dynamic_bitset<>::size_type i= 0; i < map.size(); i++)
5584
size_t optimizer::RorScanInfo::getBitCount() const
5586
boost::dynamic_bitset<> tmp_bitset= bitsToBitset();
5587
return tmp_bitset.count();
5591
void optimizer::RorScanInfo::subtractBitset(const boost::dynamic_bitset<>& in_bitset)
5593
boost::dynamic_bitset<> tmp_bitset= bitsToBitset();
5594
tmp_bitset-= in_bitset;
5595
covered_fields= tmp_bitset.to_ulong();
5599
boost::dynamic_bitset<> optimizer::RorScanInfo::bitsToBitset() const
5602
uint64_t conv= covered_fields;
5605
res.push_back((conv & 1) + '0');
5610
std::reverse(res.begin(), res.end());
5612
string final(covered_fields_size - res.length(), '0');
5614
return (boost::dynamic_bitset<>(final));
5618
5600
} /* namespace drizzled */