~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/optimizer/sel_imerge.cc

Merged trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2008-2009 Sun Microsystems
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; version 2 of the License.
 
9
 *
 
10
 *  This program is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU General Public License
 
16
 *  along with this program; if not, write to the Free Software
 
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
18
 */
 
19
 
 
20
#include "config.h"
 
21
 
 
22
#include "drizzled/sql_base.h"
 
23
#include "drizzled/sql_select.h"
 
24
#include "drizzled/memory/sql_alloc.h"
 
25
#include "drizzled/optimizer/range.h"
 
26
#include "drizzled/optimizer/range_param.h"
 
27
#include "drizzled/optimizer/sel_arg.h"
 
28
#include "drizzled/optimizer/sel_tree.h"
 
29
#include "drizzled/optimizer/sel_imerge.h"
 
30
 
 
31
using namespace std;
 
32
using namespace drizzled;
 
33
 
 
34
optimizer::SEL_IMERGE::SEL_IMERGE() 
 
35
  :
 
36
    trees(&trees_prealloced[0]),
 
37
    trees_next(trees),
 
38
    trees_end(trees + PREALLOCED_TREES)
 
39
{}
 
40
 
 
41
 
 
42
int optimizer::SEL_IMERGE::or_sel_tree(optimizer::RangeParameter *param, optimizer::SEL_TREE *tree)
 
43
{
 
44
  if (trees_next == trees_end)
 
45
  {
 
46
    const int realloc_ratio= 2;         /* Double size for next round */
 
47
    uint32_t old_elements= (trees_end - trees);
 
48
    uint32_t old_size= sizeof(optimizer::SEL_TREE**) * old_elements;
 
49
    uint32_t new_size= old_size * realloc_ratio;
 
50
    optimizer::SEL_TREE **new_trees= NULL;
 
51
    if (! (new_trees= (optimizer::SEL_TREE**) alloc_root(param->mem_root, new_size)))
 
52
      return -1;
 
53
    memcpy(new_trees, trees, old_size);
 
54
    trees= new_trees;
 
55
    trees_next= trees + old_elements;
 
56
    trees_end= trees + old_elements * realloc_ratio;
 
57
  }
 
58
  *(trees_next++)= tree;
 
59
  return 0;
 
60
}
 
61
 
 
62
 
 
63
int optimizer::SEL_IMERGE::or_sel_tree_with_checks(optimizer::RangeParameter *param, optimizer::SEL_TREE *new_tree)
 
64
{
 
65
  for (optimizer::SEL_TREE** tree = trees;
 
66
       tree != trees_next;
 
67
       tree++)
 
68
  {
 
69
    if (sel_trees_can_be_ored(*tree, new_tree, param))
 
70
    {
 
71
      *tree = tree_or(param, *tree, new_tree);
 
72
      if (!*tree)
 
73
        return 1;
 
74
      if (((*tree)->type == optimizer::SEL_TREE::MAYBE) ||
 
75
          ((*tree)->type == optimizer::SEL_TREE::ALWAYS))
 
76
        return 1;
 
77
      /* optimizer::SEL_TREE::IMPOSSIBLE is impossible here */
 
78
      return 0;
 
79
    }
 
80
  }
 
81
 
 
82
  /* New tree cannot be combined with any of existing trees. */
 
83
  return or_sel_tree(param, new_tree);
 
84
}
 
85
 
 
86
 
 
87
int optimizer::SEL_IMERGE::or_sel_imerge_with_checks(optimizer::RangeParameter *param, optimizer::SEL_IMERGE* imerge)
 
88
{
 
89
  for (optimizer::SEL_TREE** tree= imerge->trees;
 
90
       tree != imerge->trees_next;
 
91
       tree++)
 
92
  {
 
93
    if (or_sel_tree_with_checks(param, *tree))
 
94
      return 1;
 
95
  }
 
96
  return 0;
 
97
}
 
98