-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Further narrowing down has focused on the revision series r982.1.1
through r982.1.5.  Attached is the diff for that, and somewhere in there
is the regression.

Note that the goal here is not necessarily to undo Padraig's work on
standardizing Bitset, but to look into why/where specifically we're
seeing that regression on concurrency loads >128.  Remember, no shame,
no blame, many hands make light work. :)

Eyeballs please! :)

Cheers,

Jay

Jay Pipes wrote:
> So, the regression occurred somewhere in the 971.1.63 subtree:
> 
> +----------------+-------------+-------------+
> | version        | concurrency | tps         |
> +----------------+-------------+-------------+
> | trunk-971.1.62 |           2 | 1049.583333 |
> | trunk-971.1.62 |           4 | 1441.090000 |
> | trunk-971.1.62 |           8 | 1951.853333 |
> | trunk-971.1.62 |          16 | 2594.673333 |
> | trunk-971.1.62 |          32 | 3363.063333 |
> | trunk-971.1.62 |          64 | 3915.066667 |
> | trunk-971.1.62 |         128 | 3908.363333 |
> | trunk-971.1.62 |         256 | 2933.943333 |
> | trunk-971.1.62 |         512 | 1975.433333 |
> | trunk-971.1.62 |        1024 | 1284.683333 |
> | trunk-971.1.62 |        2048 |  603.176667 |
> | trunk-971.1.63 |           2 | 1041.916667 |
> | trunk-971.1.63 |           4 | 1435.300000 |
> | trunk-971.1.63 |           8 | 1902.173333 |
> | trunk-971.1.63 |          16 | 2583.553333 |
> | trunk-971.1.63 |          32 | 3358.056667 |
> | trunk-971.1.63 |          64 | 3889.813333 |
> | trunk-971.1.63 |         128 | 3853.060000 |
> | trunk-971.1.63 |         256 | 2344.860000 |
> | trunk-971.1.63 |         512 | 1843.083333 |
> | trunk-971.1.63 |        1024 | 1087.163333 |
> | trunk-971.1.63 |        2048 |  442.003333 |
> | trunk-989      |           2 | 1050.630000 |
> | trunk-989      |           4 | 1417.433333 |
> | trunk-989      |           8 | 1942.686667 |
> | trunk-989      |          16 | 2612.166667 |
> | trunk-989      |          32 | 3389.150000 |
> | trunk-989      |          64 | 3944.433333 |
> | trunk-989      |         128 | 3924.076667 |
> | trunk-989      |         256 | 2964.776667 |
> | trunk-989      |         512 | 1981.050000 |
> | trunk-989      |        1024 | 1273.133333 |
> | trunk-989      |        2048 |  563.350000 |
> +----------------+-------------+-------------+
> 
> A benchmark of 971.1.62 did *not* show the regression, so somewhere in
> the bitset patch is our regression.  I'll be digging further down into
> that subtree shortly, but it's good to know where the regression has
> been introduced.
> 
> Cheers!
> 
> jay
> 
> Jay Pipes wrote:
>> Brian Aker wrote:
>>> Hi!
>>> A few places to look:
>>> 971.1.47 (replication)
>> Hi again!  OK, so I had to make a few quick changes to the automation
>> suite to support non-integer revisions, but those have been made and I
>> am happy (and relieved) to report that replication (r971.1.47) is NOT
>> the cause of the regression... yeah, Jay! \o/
> 
>> +----------------+-------------+-------------+
>> | version        | concurrency | tps         |
>> +----------------+-------------+-------------+
>> | trunk-989      |           2 | 1050.630000 |
>> | trunk-989      |           4 | 1417.433333 |
>> | trunk-989      |           8 | 1942.686667 |
>> | trunk-989      |          16 | 2612.166667 |
>> | trunk-989      |          32 | 3389.150000 |
>> | trunk-989      |          64 | 3944.433333 |
>> | trunk-989      |         128 | 3924.076667 |
>> | trunk-989      |         256 | 2964.776667 |
>> | trunk-989      |         512 | 1981.050000 |
>> | trunk-989      |        1024 | 1273.133333 |
>> | trunk-989      |        2048 |  563.350000 |
>> | trunk-971.1.47 |           2 | 1049.383333 |
>> | trunk-971.1.47 |           4 | 1407.180000 |
>> | trunk-971.1.47 |           8 | 1930.036667 |
>> | trunk-971.1.47 |          16 | 2604.316667 |
>> | trunk-971.1.47 |          32 | 3379.230000 |
>> | trunk-971.1.47 |          64 | 3889.433333 |
>> | trunk-971.1.47 |         128 | 3910.143333 |
>> | trunk-971.1.47 |         256 | 2933.186667 |
>> | trunk-971.1.47 |         512 | 2021.323333 |
>> | trunk-971.1.47 |        1024 | 1282.256667 |
>> | trunk-971.1.47 |        2048 |  589.543333 |
>> +----------------+-------------+-------------+
> 
>>> 971.1.63 (first introduction of Bitmap)
>> Running this rev now...it may turn out to be the cause, and if so, I
>> will dig down into Padraig and Monty's Bitmap changes to see which
>> specific revision contains the culprit :)
> 
>> /me loves automated benching...
> 
>> Cheers,
> 
>> Jay
> 
>>> Cheers,
>>>     -Brian
> 
> 
>>> On May 1, 2009, at 9:11 PM, Jay Pipes wrote:
>>> Hi!
>>> Somewhere in r990, we have had a significant regression, most evident in
>>> concurrency levels greater than 128 concurrent connections:
>>> +-----------+-------------+-------------+
>>> | version   | concurrency | tps         |
>>> +-----------+-------------+-------------+
>>> | trunk-989 |           2 | 1050.630000 |
>>> | trunk-989 |           4 | 1417.433333 |
>>> | trunk-989 |           8 | 1942.686667 |
>>> | trunk-989 |          16 | 2612.166667 |
>>> | trunk-989 |          32 | 3389.150000 |
>>> | trunk-989 |          64 | 3944.433333 |
>>> | trunk-989 |         128 | 3924.076667 |
>>> | trunk-989 |         256 | 2964.776667 |
>>> | trunk-989 |         512 | 1981.050000 |
>>> | trunk-989 |        1024 | 1273.133333 |
>>> | trunk-989 |        2048 |  563.350000 |
>>> | trunk-990 |           2 | 1038.133333 |
>>> | trunk-990 |           4 | 1381.933333 |
>>> | trunk-990 |           8 | 1897.276667 |
>>> | trunk-990 |          16 | 2547.196667 |
>>> | trunk-990 |          32 | 3331.570000 |
>>> | trunk-990 |          64 | 3896.483333 |
>>> | trunk-990 |         128 | 3850.016667 |
>>> | trunk-990 |         256 | 2331.543333 |
>>> | trunk-990 |         512 | 1862.316667 |
>>> | trunk-990 |        1024 | 1103.903333 |
>>> | trunk-990 |        2048 |  436.976667 |
>>> +-----------+-------------+-------------+
>>> The above TPS column is the average of 3 iterations of a readonly
>>> sysbench workload for the revision/concurrency pair.
>>> Unfortunately, r990 was a very big revision with a lot of changes:
>>> http://bazaar.launchpad.net/~drizzle-developers/drizzle/development/revision/990
> 
>>> This makes it very difficult to tell what precisely has caused the
>>> regression.  I'd like to suggest that going forward, we really try to
>>> keep the size of merges and commits small so that it is easier to tell
>>> where regressions occur.
>>> Anyone interested in looking through the commit diff above is welcome to
>>> suggest ideas where regression may have occurred...but it might be, like
>>> Brian says, death by a thousand cuts...
>>> Cheers!
>>> Jay
>>> -- 
>>> _______________________________________________________
>>> Brian "Krow" Aker, brian at tangent.org
>>> Seattle, Washington
>>> http://krow.net/                     <-- Me
>>> http://tangent.org/                <-- Software
>>> _______________________________________________________
>>> You can't grep a dead tree.
> 
> 
> 
>>> _______________________________________________
>>> Mailing list: https://launchpad.net/~drizzle-discuss
>>> Post to     : [email protected]
>>> Unsubscribe : https://launchpad.net/~drizzle-discuss
>>> More help   : https://help.launchpad.net/ListHelp
> 
> _______________________________________________
> Mailing list: https://launchpad.net/~drizzle-discuss
> Post to     : [email protected]
> Unsubscribe : https://launchpad.net/~drizzle-discuss
> More help   : https://help.launchpad.net/ListHelp
> 
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkn8nMQACgkQ2upbWsB4UtF8LgCfdt7qrQzwMgMXuf1PnRyP9bzn
noIAnAhhNCrAGEQ1BdODDaDJGbkH/2MS
=D6rj
-----END PGP SIGNATURE-----
=== modified file 'drizzled/field/blob.cc'
--- drizzled/field/blob.cc	2009-04-07 03:23:49 +0000
+++ drizzled/field/blob.cc	2009-04-08 23:01:10 +0000
@@ -605,7 +605,7 @@
   uint32_t const master_packlength=
     param_data > 0 ? param_data & 0xFF : packlength;
   uint32_t const length= get_length(from, master_packlength, low_byte_first);
-  bitmap_set_bit(table->write_set, field_index);
+  table->write_set->set(field_index);
   store(reinterpret_cast<const char*>(from) + master_packlength,
         length, field_charset);
   return(from + master_packlength + length);
@@ -677,11 +677,11 @@
 
 bool Field_blob::in_read_set()
 {
-  return bitmap_is_set(table->read_set, field_index);
+  return (table->read_set->test(field_index));
 }
 
 
 bool Field_blob::in_write_set()
 {
-  return bitmap_is_set(table->write_set, field_index);
+  return (table->write_set->test(field_index));
 }

=== modified file 'drizzled/function/set_user_var.cc'
--- drizzled/function/set_user_var.cc	2009-04-08 20:42:29 +0000
+++ drizzled/function/set_user_var.cc	2009-04-08 23:01:10 +0000
@@ -94,7 +94,7 @@
   {
     Table *table= (Table *) arg;
     if (result_field->table == table || !table)
-      bitmap_set_bit(result_field->table->read_set, result_field->field_index);
+      result_field->table->read_set->set(result_field->field_index);
     if (result_field->vcol_info && result_field->vcol_info->expr_item)
       return result_field->vcol_info->
                expr_item->walk(&Item::register_field_in_read_map, 1, arg);
@@ -113,7 +113,7 @@
   assert(bitmap);
   if (result_field)
   {
-    bitmap->set(field->field_index);
+    bitmap->set(result_field->field_index);
   }
   return 0;
 }

=== modified file 'drizzled/handler.cc'
--- drizzled/handler.cc	2009-04-08 03:29:53 +0000
+++ drizzled/handler.cc	2009-04-08 23:01:10 +0000
@@ -4257,11 +4257,7 @@
 */
 int handler::ha_reset()
 {
-  /* Check that we have called all proper deallocation functions */
-  assert((unsigned char*) table->def_read_set.bitmap +
-              table->s->column_bitmap_size ==
-              (unsigned char*) table->def_write_set.bitmap);
-  assert(bitmap_is_set_all(&table->s->all_set));
+  assert(table->s->all_set.size() == table->s->all_set.count());
   assert(table->key_read == 0);
   /* ensure that ha_index_end / ha_rnd_end has been called */
   assert(inited == NONE);

=== modified file 'drizzled/item/field.cc'
--- drizzled/item/field.cc	2009-04-08 20:42:29 +0000
+++ drizzled/item/field.cc	2009-04-08 23:01:10 +0000
@@ -110,7 +110,7 @@
 {
   Table *table= (Table *) arg;
   if (field->table == table || !table)
-    bitmap_set_bit(field->table->read_set, field->field_index);
+    field->table->read_set->set(field->field_index);
   if (field->vcol_info && field->vcol_info->expr_item)
     return field->vcol_info->expr_item->walk(&Item::register_field_in_read_map,
                                              1, arg);
@@ -903,7 +903,7 @@
   else if (session->mark_used_columns != MARK_COLUMNS_NONE)
   {
     Table *table= field->table;
-    MY_BITMAP *current_bitmap, *other_bitmap;
+    bitset<MAX_FIELDS> *current_bitmap, *other_bitmap;
     if (session->mark_used_columns == MARK_COLUMNS_READ)
     {
       current_bitmap= table->read_set;
@@ -914,9 +914,11 @@
       current_bitmap= table->write_set;
       other_bitmap=   table->read_set;
     }
-    if (!bitmap_fast_test_and_set(current_bitmap, field->field_index))
+    /* TODO: is this equivalent to bitmap test and set? don't think so... */
+    if (!current_bitmap->test(field->field_index))
     {
-      if (!bitmap_is_set(other_bitmap, field->field_index))
+      current_bitmap->set(field->field_index);
+      if (!other_bitmap->test(field->field_index))
       {
         /* First usage of column */
         table->used_fields++;                     // Used to optimize loops
@@ -925,6 +927,7 @@
         /* purecov: end */
       }
     }
+    current_bitmap->set(field->field_index);
   }
   fixed= 1;
 mark_non_agg_field:

=== modified file 'drizzled/key.cc'
--- drizzled/key.cc	2009-04-08 20:42:29 +0000
+++ drizzled/key.cc	2009-04-08 23:01:10 +0000
@@ -22,6 +22,7 @@
 #include "drizzled/field/blob.h"
 
 #include <string>
+#include <bitset>
 
 using namespace std;
 
@@ -389,12 +390,13 @@
     FALSE  Otherwise
 */
 
-bool is_key_used(Table *table, uint32_t idx, const bitmap<MAX_FIELDS> *fields)
+bool is_key_used(Table *table, uint32_t idx, const bitset<MAX_FIELDS> *fields)
 {
   table->tmp_set.reset();
   table->mark_columns_used_by_index_no_reset(idx, &table->tmp_set);
-  /* TODO: change this to use std::bitset */
-  if (bitmap_is_overlapping(&table->tmp_set, fields))
+  /* Check if 2 bitsets are overlapping */
+  bitset<MAX_FIELDS> tmp= *fields & table->tmp_set;
+  if (tmp.any())
     return 1;
 
   /*

=== modified file 'drizzled/opt_range.cc'
--- drizzled/opt_range.cc	2009-04-08 20:42:29 +0000
+++ drizzled/opt_range.cc	2009-04-09 02:55:10 +0000
@@ -114,6 +114,7 @@
 #include "drizzled/temporal.h" /* Needed in get_mm_leaf() for timestamp -> datetime comparisons */
 
 #include <string>
+#include <bitset>
 
 using namespace std;
 
@@ -126,6 +127,19 @@
     return static_cast<ha_rows>(x);
 }
 
+/*
+ * This helper function returns true if map1 is a subset of
+ * map2; otherwise it returns false.
+ */
+static bool is_bitmap_subset(const bitset<MAX_FIELDS> *map1, const bitset<MAX_FIELDS> *map2)
+{
+  bitset<MAX_FIELDS> tmp1= *map2;
+  tmp1.flip();
+  bitset<MAX_FIELDS> tmp2= *map1 & tmp1;
+  return (!tmp2.any());
+}
+
+
 static int sel_cmp(Field *f,unsigned char *a,unsigned char *b,uint8_t a_flag,uint8_t b_flag);
 
 static unsigned char is_null_string[2]= {1,0};
@@ -698,8 +712,8 @@
   bool quick;				// Don't calulate possible keys
 
   uint32_t fields_bitmap_size;
-  MY_BITMAP needed_fields;    /* bitmask of fields needed by the query */
-  MY_BITMAP tmp_covered_fields;
+  bitset<MAX_FIELDS> needed_fields; /* bitmask of fields needed by the query */
+  bitset<MAX_FIELDS> tmp_covered_fields;
 
   key_map *needed_reg;        /* ptr to SQL_SELECT::needed_reg */
 
@@ -1090,12 +1104,9 @@
 {}
 
 QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(Session *session, Table *table, uint32_t key_nr,
-                                       bool no_alloc, MEM_ROOT *parent_alloc,
-                                       bool *create_error)
+                                       bool no_alloc, MEM_ROOT *parent_alloc)
   :free_file(0),cur_range(NULL),last_range(0),dont_free(0)
 {
-  my_bitmap_map *bitmap;
-
   in_ror_merged_scan= 0;
   sorted= 0;
   index= key_nr;
@@ -1120,14 +1131,6 @@
   save_read_set= head->read_set;
   save_write_set= head->write_set;
 
-  /* Allocate a bitmap for used columns (Q: why not on MEM_ROOT?) */
-  if (!(bitmap= (my_bitmap_map*) malloc(head->s->column_bitmap_size)))
-  {
-    column_bitmap.bitmap= 0;
-    *create_error= 1;
-  }
-  else
-    bitmap_init(&column_bitmap, bitmap, head->s->fields, false);
   return;
 }
 
@@ -1169,7 +1172,6 @@
     }
     delete_dynamic(&ranges); /* ranges are allocated in alloc */
     free_root(&alloc,MYF(0));
-    free((char*) column_bitmap.bitmap);
   }
   head->column_bitmaps_set(save_read_set, save_write_set);
   if (mrr_buf_desc)
@@ -1355,7 +1357,7 @@
   }
   head->prepare_for_position();
   head->file= org_file;
-  bitmap_copy(&column_bitmap, head->read_set);
+  column_bitmap= *(head->read_set);
   head->column_bitmaps_set(&column_bitmap, &column_bitmap);
 
   return 0;
@@ -2096,17 +2098,11 @@
 static int fill_used_fields_bitmap(PARAM *param)
 {
   Table *table= param->table;
-  my_bitmap_map *tmp;
   uint32_t pk;
-  param->tmp_covered_fields.bitmap= 0;
   param->fields_bitmap_size= table->s->column_bitmap_size;
-  if (!(tmp= (my_bitmap_map*) alloc_root(param->mem_root,
-                                  param->fields_bitmap_size)) ||
-      bitmap_init(&param->needed_fields, tmp, table->s->fields, false))
-    return 1;
 
-  bitmap_copy(&param->needed_fields, table->read_set);
-  bitmap_union(&param->needed_fields, table->write_set);
+  param->needed_fields = *(table->read_set);
+  param->needed_fields |= *(table->write_set);
 
   pk= param->table->s->primary_key;
   if (pk != MAX_KEY && param->table->file->primary_key_is_clustered())
@@ -2116,7 +2112,7 @@
     KEY_PART_INFO *key_part_end= key_part +
                                  param->table->key_info[pk].key_parts;
     for (;key_part != key_part_end; ++key_part)
-      bitmap_clear_bit(&param->needed_fields, key_part->fieldnr-1);
+      param->needed_fields.reset(key_part->fieldnr-1);
   }
   return 0;
 }
@@ -2739,7 +2735,7 @@
   SEL_ARG   *sel_arg;
 
   /* Fields used in the query and covered by this ROR scan. */
-  MY_BITMAP covered_fields;
+  bitset<MAX_FIELDS> covered_fields;
   uint32_t      used_fields_covered; /* # of set bits in covered_fields */
   int       key_rec_length; /* length of key record (including rowid) */
 
@@ -2790,18 +2786,15 @@
                                                 param->fields_bitmap_size)))
     return NULL;
 
-  if (bitmap_init(&ror_scan->covered_fields, bitmap_buf,
-                  param->table->s->fields, false))
-    return NULL;
-  bitmap_clear_all(&ror_scan->covered_fields);
+  ror_scan->covered_fields.reset();
 
   KEY_PART_INFO *key_part= param->table->key_info[keynr].key_part;
   KEY_PART_INFO *key_part_end= key_part +
                                param->table->key_info[keynr].key_parts;
   for (;key_part != key_part_end; ++key_part)
   {
-    if (bitmap_is_set(&param->needed_fields, key_part->fieldnr-1))
-      bitmap_set_bit(&ror_scan->covered_fields, key_part->fieldnr-1);
+    if (param->needed_fields.test(key_part->fieldnr-1))
+      ror_scan->covered_fields.set(key_part->fieldnr-1);
   }
   double rows= rows2double(param->table->quick_rows[ror_scan->keynr]);
   ror_scan->index_read_cost=
@@ -2869,7 +2862,7 @@
 typedef struct
 {
   const PARAM *param;
-  MY_BITMAP covered_fields; /* union of fields covered by all scans */
+  bitset<MAX_FIELDS> covered_fields; /* union of fields covered by all scans */
   /*
     Fraction of table records that satisfies conditions of all scans.
     This is the number of full records that will be retrieved if a
@@ -2901,30 +2894,22 @@
 ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param)
 {
   ROR_INTERSECT_INFO *info;
-  my_bitmap_map* buf;
   if (!(info= (ROR_INTERSECT_INFO*)alloc_root(param->mem_root,
                                               sizeof(ROR_INTERSECT_INFO))))
     return NULL;
   info->param= param;
-  if (!(buf= (my_bitmap_map*) alloc_root(param->mem_root,
-                                         param->fields_bitmap_size)))
-    return NULL;
-  if (bitmap_init(&info->covered_fields, buf, param->table->s->fields,
-                  false))
-    return NULL;
   info->is_covering= false;
   info->index_scan_costs= 0.0;
   info->index_records= 0;
   info->out_rows= (double) param->table->file->stats.records;
-  bitmap_clear_all(&info->covered_fields);
+  info->covered_fields.reset();
   return info;
 }
 
 void ror_intersect_cpy(ROR_INTERSECT_INFO *dst, const ROR_INTERSECT_INFO *src)
 {
   dst->param= src->param;
-  memcpy(dst->covered_fields.bitmap, src->covered_fields.bitmap,
-         no_bytes_in_map(&src->covered_fields));
+  dst->covered_fields= src->covered_fields;
   dst->out_rows= src->out_rows;
   dst->is_covering= src->is_covering;
   dst->index_records= src->index_records;
@@ -3033,8 +3018,7 @@
   SEL_ARG *sel_arg, *tuple_arg= NULL;
   key_part_map keypart_map= 0;
   bool cur_covered;
-  bool prev_covered= test(bitmap_is_set(&info->covered_fields,
-                                        key_part->fieldnr-1));
+  bool prev_covered= test(info->covered_fields.test(key_part->fieldnr-1));
   key_range min_range;
   key_range max_range;
   min_range.key= key_val;
@@ -3046,8 +3030,7 @@
   for (sel_arg= scan->sel_arg; sel_arg;
        sel_arg= sel_arg->next_key_part)
   {
-    cur_covered= test(bitmap_is_set(&info->covered_fields,
-                                    key_part[sel_arg->part].fieldnr-1));
+    cur_covered= test(info->covered_fields.test(key_part[sel_arg->part].fieldnr-1));
     if (cur_covered != prev_covered)
     {
       /* create (part1val, ..., part{n-1}val) tuple. */
@@ -3159,8 +3142,8 @@
   {
     info->index_records += info->param->table->quick_rows[ror_scan->keynr];
     info->index_scan_costs += ror_scan->index_read_cost;
-    bitmap_union(&info->covered_fields, &ror_scan->covered_fields);
-    if (!info->is_covering && bitmap_is_subset(&info->param->needed_fields,
+    info->covered_fields |= ror_scan->covered_fields;
+    if (!info->is_covering && is_bitmap_subset(&info->param->needed_fields,
                                                &info->covered_fields))
     {
       info->is_covering= true;
@@ -3450,15 +3433,8 @@
   /*I=set of all covering indexes */
   ror_scan_mark= tree->ror_scans;
 
-  MY_BITMAP *covered_fields= &param->tmp_covered_fields;
-  if (!covered_fields->bitmap)
-    covered_fields->bitmap= (my_bitmap_map*)alloc_root(param->mem_root,
-                                               param->fields_bitmap_size);
-  if (!covered_fields->bitmap ||
-      bitmap_init(covered_fields, covered_fields->bitmap,
-                  param->table->s->fields, false))
-    return 0;
-  bitmap_clear_all(covered_fields);
+  bitset<MAX_FIELDS> *covered_fields= &param->tmp_covered_fields;
+  covered_fields->reset();
 
   double total_cost= 0.0f;
   ha_rows records=0;
@@ -3477,11 +3453,20 @@
     */
     for (ROR_SCAN_INFO **scan= ror_scan_mark; scan != ror_scans_end; ++scan)
     {
-      bitmap_subtract(&(*scan)->covered_fields, covered_fields);
-      (*scan)->used_fields_covered=
-        bitmap_bits_set(&(*scan)->covered_fields);
-      (*scan)->first_uncovered_field=
-        bitmap_get_first(&(*scan)->covered_fields);
+      /* subtract a bitset */
+      (*scan)->covered_fields &= covered_fields->flip();
+      covered_fields->flip();
+      (*scan)->used_fields_covered= (*scan)->covered_fields.count();
+      uint32_t first_bit_on= MY_BIT_NONE;
+      for (int idx= 0; idx < MAX_FIELDS; idx++)
+      {
+        if ((*scan)->covered_fields.test(idx))
+        {
+          first_bit_on= idx;
+          break;
+        }
+      }
+      (*scan)->first_uncovered_field= first_bit_on;
     }
 
     my_qsort(ror_scan_mark, ror_scans_end-ror_scan_mark, sizeof(ROR_SCAN_INFO*),
@@ -3497,8 +3482,8 @@
     if (total_cost > read_time)
       return NULL;
     /* F=F-covered by first(I) */
-    bitmap_union(covered_fields, &(*ror_scan_mark)->covered_fields);
-    all_covered= bitmap_is_subset(&param->needed_fields, covered_fields);
+    *covered_fields |= (*ror_scan_mark)->covered_fields;
+    all_covered= is_bitmap_subset(&param->needed_fields, covered_fields);
   } while ((++ror_scan_mark < ror_scans_end) && !all_covered);
 
   if (!all_covered || (ror_scan_mark - tree->ror_scans) == 1)
@@ -6482,7 +6467,7 @@
 
   quick=new QUICK_RANGE_SELECT(param->session, param->table,
                                param->real_keynr[idx],
-                               test(parent_alloc), NULL, &create_err);
+                               test(parent_alloc), NULL);
 
   if (quick)
   {
@@ -6746,7 +6731,7 @@
 
   old_root= session->mem_root;
   /* The following call may change session->mem_root */
-  quick= new QUICK_RANGE_SELECT(session, table, ref->key, 0, 0, &create_err);
+  quick= new QUICK_RANGE_SELECT(session, table, ref->key, 0, 0);
   /* save mem_root set by QUICK_RANGE_SELECT constructor */
   alloc= session->mem_root;
   /*
@@ -8101,7 +8086,7 @@
           If the field is used in the current query ensure that it's
           part of 'cur_index'
         */
-        if (bitmap_is_set(table->read_set, cur_field->field_index) &&
+        if (table->read_set->test(cur_field->field_index) &&
             !cur_field->part_of_key_not_clustered.is_set(cur_index))
           goto next_index;                  // Field was not part of key
       }
@@ -8273,7 +8258,7 @@
                 (min_max_arg_part && (min_max_arg_part < last_part));
       for (; cur_part != last_part; cur_part++)
       {
-        if (bitmap_is_set(table->read_set, cur_part->field->field_index))
+        if (table->read_set->test(cur_part->field->field_index))
           goto next_index;
       }
     }

=== modified file 'drizzled/opt_range.h'
--- drizzled/opt_range.h	2009-04-08 20:42:29 +0000
+++ drizzled/opt_range.h	2009-04-08 23:01:10 +0000
@@ -324,7 +324,7 @@
   MEM_ROOT alloc;
 
   QUICK_RANGE_SELECT(Session *session, Table *table,uint32_t index_arg,bool no_alloc,
-                     MEM_ROOT *parent_alloc, bool *create_err);
+                     MEM_ROOT *parent_alloc);
   ~QUICK_RANGE_SELECT();
 
   int init();

=== modified file 'drizzled/show.cc'
--- drizzled/show.cc	2009-04-08 20:42:29 +0000
+++ drizzled/show.cc	2009-04-08 23:01:10 +0000
@@ -2288,7 +2288,7 @@
     int table_open_method= 0, field_indx= 0;
     for (ptr=tables->table->field; (field= *ptr) ; ptr++)
     {
-      if (bitmap_is_set(tables->table->read_set, field->field_index))
+      if (tables->table->read_set->test(field->field_index))
         table_open_method|= schema_table->fields_info[field_indx].open_method;
       field_indx++;
     }

=== modified file 'drizzled/sj_tmp_table.cc'
--- drizzled/sj_tmp_table.cc	2009-03-24 18:05:25 +0000
+++ drizzled/sj_tmp_table.cc	2009-04-08 23:01:10 +0000
@@ -215,7 +215,7 @@
     table->record[1]= table->record[0]+alloc_length;
     share->default_values= table->record[1]+alloc_length;
   }
-  table->setup_tmp_table_column_bitmaps(bitmaps);
+  table->setup_tmp_table_column_bitmaps();
 
   recinfo= start_recinfo;
   null_flags=(unsigned char*) table->record[0];

=== modified file 'drizzled/sql_base.cc'
--- drizzled/sql_base.cc	2009-04-08 20:42:29 +0000
+++ drizzled/sql_base.cc	2009-04-08 23:01:10 +0000
@@ -3637,13 +3637,14 @@
       other_bitmap=   table->read_set;
     }
 
-    /* TODO: does this do test and set appropriately? */
-    if (current_bitmap->test(field->field_index) && current_bitmap->set(field->field_index))
+    if (current_bitmap->test(field->field_index))
     {
+      current_bitmap->set(field->field_index);
       if (session->mark_used_columns == MARK_COLUMNS_WRITE)
         session->dup_field= field;
       return;
     }
+    current_bitmap->set(field->field_index);
     if (table->get_fields_in_item_tree)
       field->flags|= GET_FIXED_FIELDS_FLAG;
     table->used_fields++;
@@ -3792,7 +3793,7 @@
         */
         if ((session->mark_used_columns != MARK_COLUMNS_WRITE) &&
             (not (*field_ptr)->is_stored))
-          bitmap_set_bit((*field_ptr)->table->write_set, (*field_ptr)->field_index);
+          (*field_ptr)->table->write_set->set((*field_ptr)->field_index);
       }
     }
     *cached_field_index_ptr= field_ptr - table->field;
@@ -3972,9 +3973,9 @@
         {
           Table *table= field_to_set->table;
           if (session->mark_used_columns == MARK_COLUMNS_READ)
-            bitmap_set_bit(table->read_set, field_to_set->field_index);
+            table->read_set->set(field_to_set->field_index);
           else
-            bitmap_set_bit(table->write_set, field_to_set->field_index);
+            table->write_set->set(field_to_set->field_index);
         }
       }
   }
@@ -4722,7 +4723,7 @@
       {
         Table *table_1= nj_col_1->table_ref->table;
         /* Mark field_1 used for table cache. */
-        bitmap_set_bit(table_1->read_set, field_1->field_index);
+        table_1->read_set->set(field_1->field_index);
         table_1->covering_keys.intersect(field_1->part_of_key);
         table_1->merge_keys.merge(field_1->part_of_key);
       }
@@ -4730,7 +4731,7 @@
       {
         Table *table_2= nj_col_2->table_ref->table;
         /* Mark field_2 used for table cache. */
-        bitmap_set_bit(table_2->read_set, field_2->field_index);
+        table_2->read_set->set(field_2->field_index);
         table_2->covering_keys.intersect(field_2->part_of_key);
         table_2->merge_keys.merge(field_2->part_of_key);
       }
@@ -5524,7 +5525,7 @@
       if ((field= field_iterator.field()))
       {
         /* Mark fields as used to allow storage engine to optimze access */
-        bitmap_set_bit(field->table->read_set, field->field_index);
+        field->table->read_set->set(field->field_index);
         /*
           Mark virtual fields for write and others that the virtual fields
           depend on for read.
@@ -5534,7 +5535,7 @@
           Item *vcol_item= field->vcol_info->expr_item;
           assert(vcol_item);
           vcol_item->walk(&Item::register_field_in_read_map, 1, (unsigned char *) 0);
-          bitmap_set_bit(field->table->write_set, field->field_index);
+          field->table->write_set->set(field->field_index);
         }
         if (table)
         {

=== modified file 'drizzled/sql_insert.cc'
--- drizzled/sql_insert.cc	2009-04-08 20:42:29 +0000
+++ drizzled/sql_insert.cc	2009-04-08 23:01:10 +0000
@@ -79,7 +79,7 @@
       No fields are provided so all fields must be provided in the values.
       Thus we set all bits in the write set.
     */
-    bitmap_set_all(table->write_set);
+    table->write_set->set();
   }
   else
   {						// Part field list
@@ -120,14 +120,12 @@
     }
     if (table->timestamp_field)	// Don't automaticly set timestamp if used
     {
-      if (bitmap_is_set(table->write_set,
-                        table->timestamp_field->field_index))
+      if (table->write_set->test(table->timestamp_field->field_index))
         clear_timestamp_auto_bits(table->timestamp_field_type,
                                   TIMESTAMP_AUTO_SET_ON_INSERT);
       else
       {
-        bitmap_set_bit(table->write_set,
-                       table->timestamp_field->field_index);
+        table->write_set->set(table->timestamp_field->field_index);
       }
     }
     /* Mark all virtual columns for write*/
@@ -171,8 +169,8 @@
       Unmark the timestamp field so that we can check if this is modified
       by update_fields
     */
-    timestamp_mark= bitmap_test_and_clear(table->write_set,
-                                          table->timestamp_field->field_index);
+    timestamp_mark= table->write_set->test(table->timestamp_field->field_index);
+    table->write_set->reset(table->timestamp_field->field_index);
   }
 
   /* Check the fields we are going to modify */
@@ -182,13 +180,11 @@
   if (table->timestamp_field)
   {
     /* Don't set timestamp column if this is modified. */
-    if (bitmap_is_set(table->write_set,
-                      table->timestamp_field->field_index))
+    if (table->write_set->test(table->timestamp_field->field_index))
       clear_timestamp_auto_bits(table->timestamp_field_type,
                                 TIMESTAMP_AUTO_SET_ON_UPDATE);
     if (timestamp_mark)
-      bitmap_set_bit(table->write_set,
-                     table->timestamp_field->field_index);
+      table->write_set->set(table->timestamp_field->field_index);
   }
   return 0;
 }
@@ -695,6 +691,18 @@
 
 
 /*
+ * This helper function returns true if map1 is a subset of
+ * map2; otherwise it returns false.
+ */
+static bool is_bitmap_subset(bitset<MAX_FIELDS> *map1, bitset<MAX_FIELDS> *map2)
+{
+  bitset<MAX_FIELDS> tmp1= *map2;
+  tmp1.flip();
+  bitset<MAX_FIELDS> tmp2= *map1 & tmp1;
+  return (!tmp2.any());
+}
+
+/*
   Write a record to table with optional deleting of conflicting records,
   invoke proper triggers if needed.
 
@@ -832,7 +840,7 @@
             table->next_number_field->val_int());
         info->touched++;
         if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ &&
-             !bitmap_is_subset(table->write_set, table->read_set)) ||
+             !is_bitmap_subset(table->write_set, table->read_set)) ||
             table->compare_record())
         {
           if ((error=table->file->ha_update_row(table->record[1],
@@ -1671,7 +1679,7 @@
 
   /* Mark all fields that are given values */
   for (Field **f= field ; *f ; f++)
-    bitmap_set_bit(table->write_set, (*f)->field_index);
+    table->write_set->set((*f)->field_index);
 
   /* Don't set timestamp if used */
   table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;

=== modified file 'drizzled/sql_load.cc'
--- drizzled/sql_load.cc	2009-04-03 22:18:21 +0000
+++ drizzled/sql_load.cc	2009-04-08 23:01:10 +0000
@@ -166,7 +166,7 @@
     Field **field;
     for (field=table->field; *field ; field++)
       fields_vars.push_back(new Item_field(*field));
-    bitmap_set_all(table->write_set);
+    table->write_set->set();
     table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
     /*
       Let us also prepare SET clause, altough it is probably empty
@@ -189,13 +189,11 @@
     */
     if (table->timestamp_field)
     {
-      if (bitmap_is_set(table->write_set,
-                        table->timestamp_field->field_index))
+      if (table->write_set->test(table->timestamp_field->field_index))
         table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
       else
       {
-        bitmap_set_bit(table->write_set,
-                       table->timestamp_field->field_index);
+        table->write_set->set(table->timestamp_field->field_index);
       }
     }
     /* Fix the expressions in SET clause */

=== modified file 'drizzled/sql_update.cc'
--- drizzled/sql_update.cc	2009-04-08 20:42:29 +0000
+++ drizzled/sql_update.cc	2009-04-09 01:10:42 +0000
@@ -25,6 +25,10 @@
 #include <drizzled/sql_base.h>
 #include <drizzled/field/timestamp.h>
 
+#include <bitset>
+
+using namespace std;
+
 /*
   check that all fields are real fields
 
@@ -61,6 +65,19 @@
   return false;
 }
 
+/*
+ * This helper function returns true if map1 is a subset of
+ * map2; otherwise it returns false.
+ */
+static bool is_bitmap_subset(bitset<MAX_FIELDS> *map1, bitset<MAX_FIELDS> *map2)
+{
+  bitset<MAX_FIELDS> tmp1= *map2;
+  tmp1.flip();
+  bitset<MAX_FIELDS> tmp2= *map1 & tmp1;
+  return (!tmp2.any());
+}
+
+
 
 /**
   Re-read record if more columns are needed for error message.
@@ -79,7 +96,7 @@
   Field **field_p;
   Field *field;
   uint32_t keynr;
-  bitmap<MAX_FIELDS> unique_map; /* Fields in offended unique */
+  bitset<MAX_FIELDS> unique_map; /* Fields in offended unique */
 
   /*
     Only duplicate key errors print the key value.
@@ -100,10 +117,10 @@
   table->mark_columns_used_by_index_no_reset(keynr, &unique_map);
 
   /* Subtract read_set and write_set. */
-  unique_map &= table->read_set.flip();
-  unique_map &= table->write_set.flip();
-  table->read_set.flip();
-  table->write_set.flip();
+  unique_map &= table->read_set->flip();
+  unique_map &= table->write_set->flip();
+  table->read_set->flip();
+  table->write_set->flip();
 
   /*
     If the unique index uses columns that are neither in read_set
@@ -116,7 +133,7 @@
   /* Get identifier of last read record into table->file->ref. */
   table->file->position(table->record[0]);
   /* Add all fields used by unique index to read_set. */
-  table->read_set |= unique_map;
+  *(table->read_set) |= unique_map;
   /* Tell the engine about the new set. */
   table->file->column_bitmaps_signal();
   /* Read record that is identified by table->file->ref. */
@@ -209,15 +226,13 @@
   if (table->timestamp_field)
   {
     // Don't set timestamp column if this is modified
-    if (bitmap_is_set(table->write_set,
-                      table->timestamp_field->field_index))
+    if (table->write_set->test(table->timestamp_field->field_index))
       table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
     else
     {
       if (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
           table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH)
-        bitmap_set_bit(table->write_set,
-                       table->timestamp_field->field_index);
+        table->write_set->set(table->timestamp_field->field_index);
     }
   }
 
@@ -251,7 +266,7 @@
       table->timestamp_field &&
       (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
        table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH))
-    bitmap_union(table->read_set, table->write_set);
+    *(table->read_set) |= *(table->write_set);
   // Don't count on usage of 'only index' when calculating which key to use
   table->covering_keys.clear_all();
 
@@ -482,7 +497,7 @@
   */
   can_compare_record= (!(table->file->ha_table_flags() &
                          HA_PARTIAL_COLUMN_READ) ||
-                       bitmap_is_subset(table->write_set, table->read_set));
+                       is_bitmap_subset(table->write_set, table->read_set));
 
   while (!(error=info.read_record(&info)) && !session->killed)
   {
@@ -848,8 +863,7 @@
     Table *table= tl->table;
     /* Only set timestamp column if this is not modified */
     if (table->timestamp_field &&
-        bitmap_is_set(table->write_set,
-                      table->timestamp_field->field_index))
+        table->write_set->test(table->timestamp_field->field_index))
       table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
 
     /* if table will be updated then check that it is unique */
@@ -1322,7 +1336,7 @@
       bool can_compare_record;
       can_compare_record= (!(table->file->ha_table_flags() &
                              HA_PARTIAL_COLUMN_READ) ||
-                           bitmap_is_subset(table->write_set,
+                           is_bitmap_subset(table->write_set,
                                             table->read_set));
       table->status|= STATUS_UPDATED;
       store_record(table,record[1]);
@@ -1522,7 +1536,7 @@
 
     can_compare_record= (!(table->file->ha_table_flags() &
                            HA_PARTIAL_COLUMN_READ) ||
-                         bitmap_is_subset(table->write_set,
+                         is_bitmap_subset(table->write_set,
                                           table->read_set));
 
     for (;;)

=== modified file 'drizzled/table.cc'
--- drizzled/table.cc	2009-04-08 20:42:29 +0000
+++ drizzled/table.cc	2009-04-08 23:01:10 +0000
@@ -1380,8 +1380,7 @@
   if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
                                              share->column_bitmap_size)))
     goto err;
-  bitmap_init(&share->all_set, bitmaps, share->fields, false);
-  bitmap_set_all(&share->all_set);
+  share->all_set.set();
 
   if(handler_file)
     delete handler_file;
@@ -1776,9 +1775,9 @@
                           Table *outparam, open_table_mode open_mode)
 {
   int error;
-  uint32_t records, i, bitmap_size;
+  uint32_t records, i;
   bool error_reported= false;
-  unsigned char *record, *bitmaps;
+  unsigned char *record;
   Field **field_ptr, **vfield_ptr;
 
   /* Parsing of partitioning information from .frm needs session->lex set up. */
@@ -2467,8 +2466,6 @@
 
 void Table::setup_tmp_table_column_bitmaps()
 {
-  uint32_t field_count= s->fields;
-
   /* write_set and all_set are copies of read_set */
   def_write_set= def_read_set;
   s->all_set= def_read_set;
@@ -3150,7 +3147,7 @@
   bitset<MAX_FIELDS> *bitmap= &tmp_set;
 
   (void) file->extra(HA_EXTRA_KEYREAD);
-  bitmap->reset()
+  bitmap->reset();
   mark_columns_used_by_index_no_reset(index, bitmap);
   column_bitmaps_set(bitmap, bitmap);
   return;
@@ -3191,7 +3188,7 @@
                                 key_info[index].key_parts);
   for (;key_part != key_part_end; key_part++)
   {
-    bitmap.set(key_part->fieldnr-1);
+    bitmap->set(key_part->fieldnr-1);
     if (key_part->field->vcol_info &&
         key_part->field->vcol_info->expr_item)
       key_part->field->vcol_info->
@@ -4113,7 +4110,7 @@
   copy_func[0]=0;				// End marker
   param->func_count= copy_func - param->items_to_copy;
 
-  table->setup_tmp_table_column_bitmaps(bitmaps);
+  table->setup_tmp_table_column_bitmaps();
 
   recinfo=param->start_recinfo;
   null_flags=(unsigned char*) table->record[0];
@@ -4466,7 +4463,7 @@
   share->blob_field= blob_field;
   share->fields= field_count;
   share->blob_ptr_size= portable_sizeof_char_ptr;
-  table->setup_tmp_table_column_bitmaps(bitmaps);
+  table->setup_tmp_table_column_bitmaps();
 
   /* Create all fields and calculate the total length of record */
   List_iterator_fast<Create_field> it(field_list);
@@ -4839,7 +4836,7 @@
 bitset<MAX_FIELDS> *Table::use_all_columns(bitset<MAX_FIELDS> *bitmap)
 {
   bitset<MAX_FIELDS> *old= bitmap;
-  bitmap= s->all_set;
+  bitmap= &s->all_set;
   return old;
 }
 
@@ -4901,7 +4898,7 @@
   /* Compare updated fields */
   for (Field **ptr= field ; *ptr ; ptr++)
   {
-    if (bitmap_is_set(write_set, (*ptr)->field_index) &&
+    if (write_set->test((*ptr)->field_index) &&
 	(*ptr)->cmp_binary_offset(s->rec_buff_length))
       return true;
   }
@@ -4974,7 +4971,7 @@
       Only update those fields that are marked in the write_set bitmap
       and not _already_ physically stored in the database.
     */
-    if (bitmap_is_set(table->write_set, vfield->field_index) &&
+    if (table->write_set->test(vfield->field_index) &&
         (not (ignore_stored && vfield->is_stored))
        )
     {

=== modified file 'drizzled/table.h'
--- drizzled/table.h	2009-04-08 20:42:29 +0000
+++ drizzled/table.h	2009-04-08 23:01:10 +0000
@@ -95,7 +95,7 @@
 
   /* For TMP tables, should be pulled out as a class */
   void updateCreateInfo(HA_CREATE_INFO *create_info);
-  void setup_tmp_table_column_bitmaps(unsigned char *bitmaps);
+  void setup_tmp_table_column_bitmaps();
   bool create_myisam_tmp_table(KEY *keyinfo,
                                MI_COLUMNDEF *start_recinfo,
                                MI_COLUMNDEF **recinfo,

=== modified file 'drizzled/table_share.h'
--- drizzled/table_share.h	2009-04-08 03:20:31 +0000
+++ drizzled/table_share.h	2009-04-08 21:34:26 +0000
@@ -18,6 +18,8 @@
  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#include <bitset>
+
 /*
   This class is shared between different table objects. There is one
   instance of table share per one table in the database.
@@ -52,7 +54,7 @@
   LEX_STRING comment;			/* Comment about table */
   const CHARSET_INFO *table_charset; /* Default charset of string fields */
 
-  MY_BITMAP all_set;
+  std::bitset<MAX_FIELDS> all_set;
   /*
     Key which is used for looking-up table in table cache and in the list
     of thread's temporary tables. Has the form of:

=== modified file 'storage/csv/ha_tina.cc'
--- storage/csv/ha_tina.cc	2009-03-26 08:22:57 +0000
+++ storage/csv/ha_tina.cc	2009-04-08 21:34:26 +0000
@@ -600,7 +600,7 @@
     return(HA_ERR_END_OF_FILE);
 
   /* We must read all columns in case a table is opened for update */
-  read_all= !bitmap_is_clear_all(table->write_set);
+  read_all= !table->write_set->none();
   error= HA_ERR_CRASHED_ON_USAGE;
 
   memset(buf, 0, table->s->null_bytes);
@@ -670,7 +670,7 @@
       }
     }
 
-    if (read_all || bitmap_is_set(table->read_set, (*field)->field_index))
+    if (read_all || table->read_set->test((*field)->field_index))
     {
       if ((*field)->store(buffer.ptr(), buffer.length(), buffer.charset(),
                           CHECK_FIELD_WARN))

=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- storage/innobase/handler/ha_innodb.cc	2009-04-01 01:14:16 +0000
+++ storage/innobase/handler/ha_innodb.cc	2009-04-08 21:34:26 +0000
@@ -3670,8 +3670,8 @@
 				goto include_field;
 			}
 
-                        if (bitmap_is_set(table->read_set, sql_idx) ||
-                            bitmap_is_set(table->write_set, sql_idx)) {
+                        if (table->read_set->test(sql_idx) ||
+                            table->write_set->test(sql_idx)) {
 				/* This field is needed in the query */
 
 				goto include_field;

_______________________________________________
Mailing list: https://launchpad.net/~drizzle-discuss
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~drizzle-discuss
More help   : https://help.launchpad.net/ListHelp

Reply via email to