1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008-2009 Sun Microsystems
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.
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.
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
20
#include "drizzled/server_includes.h"
21
#include "drizzled/optimizer/range.h"
22
#include "drizzled/optimizer/range_param.h"
23
#include "drizzled/optimizer/sel_arg.h"
25
using namespace drizzled;
28
/* Functions to fix up the tree after insert and delete */
29
static void left_rotate(optimizer::SEL_ARG **root, optimizer::SEL_ARG *leaf)
31
optimizer::SEL_ARG *y= leaf->right;
33
if (y->left != &optimizer::null_element)
34
y->left->parent= leaf;
35
if (! (y->parent=leaf->parent))
38
*leaf->parent_ptr()= y;
44
static void right_rotate(optimizer::SEL_ARG **root, optimizer::SEL_ARG *leaf)
46
optimizer::SEL_ARG *y= leaf->left;
48
if (y->right != &optimizer::null_element)
49
y->right->parent= leaf;
50
if (! (y->parent=leaf->parent))
53
*leaf->parent_ptr()= y;
59
/* Get overlapping range */
60
optimizer::SEL_ARG *optimizer::SEL_ARG::clone_and(optimizer::SEL_ARG *arg)
62
unsigned char *new_min= NULL;
63
unsigned char *new_max= NULL;
67
if (cmp_min_to_min(arg) >= 0)
74
new_min=arg->min_value; flag_min=arg->min_flag;
76
if (cmp_max_to_max(arg) <= 0)
83
new_max= arg->max_value;
84
flag_max= arg->max_flag;
86
return (new SEL_ARG(field,
92
test(maybe_flag && arg->maybe_flag)));
96
/* min <= X , arg->min */
97
optimizer::SEL_ARG *optimizer::SEL_ARG::clone_first(optimizer::SEL_ARG *arg)
99
return (new SEL_ARG(field,part,
103
arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX,
104
maybe_flag | arg->maybe_flag));
108
/* min <= X <= key_max */
109
optimizer::SEL_ARG *optimizer::SEL_ARG::clone_last(optimizer::SEL_ARG *arg)
111
return (new SEL_ARG(field,
117
maybe_flag | arg->maybe_flag));
121
/* Get overlapping range */
122
bool optimizer::SEL_ARG::copy_min(optimizer::SEL_ARG *arg)
124
if (cmp_min_to_min(arg) > 0)
126
min_value= arg->min_value;
127
min_flag=arg->min_flag;
128
if ((max_flag & (NO_MAX_RANGE | NO_MIN_RANGE)) ==
129
(NO_MAX_RANGE | NO_MIN_RANGE))
131
return 1; // Full range
134
maybe_flag|= arg->maybe_flag;
138
/* Get overlapping range */
139
bool optimizer::SEL_ARG::copy_max(optimizer::SEL_ARG *arg)
141
if (cmp_max_to_max(arg) <= 0)
143
max_value= arg->max_value;
144
max_flag= arg->max_flag;
145
if ((max_flag & (NO_MAX_RANGE | NO_MIN_RANGE)) ==
146
(NO_MAX_RANGE | NO_MIN_RANGE))
148
return 1; // Full range
151
maybe_flag|= arg->maybe_flag;
155
void optimizer::SEL_ARG::copy_min_to_min(optimizer::SEL_ARG *arg)
157
min_value= arg->min_value;
158
min_flag= arg->min_flag;
162
void optimizer::SEL_ARG::copy_min_to_max(optimizer::SEL_ARG *arg)
164
max_value= arg->min_value;
165
max_flag= arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX;
168
void optimizer::SEL_ARG::copy_max_to_min(optimizer::SEL_ARG *arg)
170
min_value= arg->max_value;
171
min_flag= arg->max_flag & NEAR_MAX ? 0 : NEAR_MIN;
175
int optimizer::SEL_ARG::store_min(uint32_t length, unsigned char **min_key, uint32_t min_key_flag)
177
/* "(kp1 > c1) AND (kp2 OP c2) AND ..." -> (kp1 > c1) */
178
if ((! (min_flag & NO_MIN_RANGE) &&
179
! (min_key_flag & (NO_MIN_RANGE | NEAR_MIN))))
181
if (maybe_null && *min_value)
184
memset(*min_key+1, 0, length-1);
188
memcpy(*min_key,min_value,length);
197
int optimizer::SEL_ARG::store_max(uint32_t length, unsigned char **max_key, uint32_t max_key_flag)
199
if (! (max_flag & NO_MAX_RANGE) &&
200
! (max_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
202
if (maybe_null && *max_value)
205
memset(*max_key + 1, 0, length-1);
209
memcpy(*max_key,max_value,length);
218
int optimizer::SEL_ARG::store_min_key(KEY_PART *key, unsigned char **range_key, uint32_t *range_key_flag)
220
optimizer::SEL_ARG *key_tree= first();
221
uint32_t res= key_tree->store_min(key[key_tree->part].store_length,
224
*range_key_flag|= key_tree->min_flag;
226
if (key_tree->next_key_part &&
227
key_tree->next_key_part->part == key_tree->part+1 &&
228
! (*range_key_flag & (NO_MIN_RANGE | NEAR_MIN)) &&
229
key_tree->next_key_part->type == optimizer::SEL_ARG::KEY_RANGE)
231
res+= key_tree->next_key_part->store_min_key(key,
238
int optimizer::SEL_ARG::store_max_key(KEY_PART *key, unsigned char **range_key, uint32_t *range_key_flag)
240
SEL_ARG *key_tree= last();
241
uint32_t res= key_tree->store_max(key[key_tree->part].store_length,
244
(*range_key_flag)|= key_tree->max_flag;
245
if (key_tree->next_key_part &&
246
key_tree->next_key_part->part == key_tree->part+1 &&
247
! (*range_key_flag & (NO_MAX_RANGE | NEAR_MAX)) &&
248
key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
249
res+= key_tree->next_key_part->store_max_key(key,
255
optimizer::SEL_ARG::SEL_ARG(optimizer::SEL_ARG &arg)
260
min_flag= arg.min_flag;
261
max_flag= arg.max_flag;
262
maybe_flag= arg.maybe_flag;
263
maybe_null= arg.maybe_null;
266
min_value= arg.min_value;
267
max_value= arg.max_value;
268
next_key_part= arg.next_key_part;
274
void optimizer::SEL_ARG::make_root()
276
left= right= &optimizer::null_element;
283
optimizer::SEL_ARG::SEL_ARG(Field *f,
284
const unsigned char *min_value_arg,
285
const unsigned char *max_value_arg)
290
maybe_null(f->real_maybe_null()),
294
min_value((unsigned char*) min_value_arg),
295
max_value((unsigned char*) max_value_arg),
302
left= right= &optimizer::null_element;
305
optimizer::SEL_ARG::SEL_ARG(Field *field_,
307
unsigned char *min_value_,
308
unsigned char *max_value_,
315
maybe_flag(maybe_flag_),
317
maybe_null(field_->real_maybe_null()),
321
min_value(min_value_),
322
max_value(max_value_),
329
left= right= &optimizer::null_element;
332
optimizer::SEL_ARG *optimizer::SEL_ARG::clone(RangeParameter *param,
333
optimizer::SEL_ARG *new_parent,
334
optimizer::SEL_ARG **next_arg)
336
optimizer::SEL_ARG *tmp= NULL;
338
/* Bail out if we have already generated too many SEL_ARGs */
339
if (++param->alloced_sel_args > MAX_SEL_ARGS)
342
if (type != KEY_RANGE)
344
if (! (tmp= new (param->mem_root) optimizer::SEL_ARG(type)))
345
return 0; // out of memory
346
tmp->prev= *next_arg; // Link into next/prev chain
347
(*next_arg)->next= tmp;
352
if (! (tmp= new (param->mem_root) optimizer::SEL_ARG(field,
360
tmp->parent= new_parent;
361
tmp->next_key_part= next_key_part;
362
if (left != &optimizer::null_element)
363
if (! (tmp->left= left->clone(param, tmp, next_arg)))
366
tmp->prev= *next_arg; // Link into next/prev chain
367
(*next_arg)->next= tmp;
370
if (right != &optimizer::null_element)
371
if (! (tmp->right= right->clone(param, tmp, next_arg)))
374
increment_use_count(1);
376
tmp->elements= this->elements;
380
optimizer::SEL_ARG *optimizer::SEL_ARG::first()
382
optimizer::SEL_ARG *next_arg= this;
383
if (! next_arg->left)
384
return 0; // MAYBE_KEY
385
while (next_arg->left != &optimizer::null_element)
386
next_arg= next_arg->left;
390
optimizer::SEL_ARG *optimizer::SEL_ARG::last()
392
SEL_ARG *next_arg= this;
393
if (! next_arg->right)
394
return 0; // MAYBE_KEY
395
while (next_arg->right != &optimizer::null_element)
396
next_arg=next_arg->right;
401
optimizer::SEL_ARG *optimizer::SEL_ARG::clone_tree(RangeParameter *param)
403
optimizer::SEL_ARG tmp_link;
404
optimizer::SEL_ARG*next_arg= NULL;
405
optimizer::SEL_ARG *root= NULL;
407
if (! (root= clone(param, (SEL_ARG *) 0, &next_arg)))
409
next_arg->next= 0; // Fix last link
410
tmp_link.next->prev= 0; // Fix first link
411
if (root) // If not OOM
418
optimizer::SEL_ARG::insert(optimizer::SEL_ARG *key)
420
optimizer::SEL_ARG *element= NULL;
421
optimizer::SEL_ARG **par= NULL;
422
optimizer::SEL_ARG *last_element= NULL;
424
for (element= this; element != &optimizer::null_element; )
426
last_element= element;
427
if (key->cmp_min_to_min(element) > 0)
429
par= &element->right; element= element->right;
433
par= &element->left; element= element->left;
437
key->parent= last_element;
439
if (par == &last_element->left)
441
key->next= last_element;
442
if ((key->prev=last_element->prev))
443
key->prev->next= key;
444
last_element->prev= key;
448
if ((key->next= last_element->next))
449
key->next->prev= key;
450
key->prev= last_element;
451
last_element->next= key;
453
key->left= key->right= &optimizer::null_element;
454
optimizer::SEL_ARG *root= rb_insert(key); // rebalance tree
455
root->use_count= this->use_count; // copy root info
456
root->elements= this->elements+1;
457
root->maybe_flag= this->maybe_flag;
463
** Find best key with min <= given key
464
** Because the call context this should never return 0 to get_range
467
optimizer::SEL_ARG::find_range(optimizer::SEL_ARG *key)
469
optimizer::SEL_ARG *element= this;
470
optimizer::SEL_ARG *found= NULL;
474
if (element == &optimizer::null_element)
476
int cmp= element->cmp_min_to_min(key);
482
element= element->right;
485
element= element->left;
491
Remove a element from the tree
495
key Key that is to be deleted from tree (this)
498
This also frees all sub trees that is used by the element
501
root of new tree (with key deleted)
504
optimizer::SEL_ARG::tree_delete(optimizer::SEL_ARG *key)
506
enum leaf_color remove_color;
507
optimizer::SEL_ARG *root= NULL;
508
optimizer::SEL_ARG *nod= NULL;
509
optimizer::SEL_ARG **par= NULL;
510
optimizer::SEL_ARG *fix_par= NULL;
515
/* Unlink from list */
517
key->prev->next= key->next;
519
key->next->prev= key->prev;
520
key->increment_use_count(-1);
524
par= key->parent_ptr();
526
if (key->left == &optimizer::null_element)
528
*par= nod= key->right;
529
fix_par= key->parent;
530
if (nod != &optimizer::null_element)
531
nod->parent= fix_par;
532
remove_color= key->color;
534
else if (key->right == &optimizer::null_element)
536
*par= nod= key->left;
537
nod->parent= fix_par= key->parent;
538
remove_color= key->color;
542
optimizer::SEL_ARG *tmp= key->next; // next bigger key (exist!)
543
nod= *tmp->parent_ptr()= tmp->right; // unlink tmp from tree
544
fix_par= tmp->parent;
545
if (nod != &optimizer::null_element)
546
nod->parent= fix_par;
547
remove_color= tmp->color;
549
tmp->parent= key->parent; // Move node in place of key
550
(tmp->left= key->left)->parent= tmp;
551
if ((tmp->right=key->right) != &optimizer::null_element)
552
tmp->right->parent= tmp;
553
tmp->color= key->color;
555
if (fix_par == key) // key->right == key->next
556
fix_par= tmp; // new parent of nod
559
if (root == &optimizer::null_element)
560
return 0; // Maybe root later
561
if (remove_color == BLACK)
562
root= rb_delete_fixup(root, nod, fix_par);
564
root->use_count= this->use_count; // Fix root counters
565
root->elements= this->elements-1;
566
root->maybe_flag= this->maybe_flag;
572
optimizer::SEL_ARG::rb_insert(optimizer::SEL_ARG *leaf)
574
optimizer::SEL_ARG *y= NULL;
575
optimizer::SEL_ARG *par= NULL;
576
optimizer::SEL_ARG *par2= NULL;
577
optimizer::SEL_ARG *root= NULL;
583
while (leaf != root && (par= leaf->parent)->color == RED)
584
{ // This can't be root or 1 level under
585
if (par == (par2= leaf->parent->parent)->left)
593
leaf->color= RED; /* And the loop continues */
597
if (leaf == par->right)
599
left_rotate(&root,leaf->parent);
600
par= leaf; /* leaf is now parent to old leaf */
604
right_rotate(&root, par2);
616
leaf->color= RED; /* And the loop continues */
620
if (leaf == par->left)
622
right_rotate(&root,par);
627
left_rotate(&root, par2);
638
optimizer::SEL_ARG *optimizer::rb_delete_fixup(optimizer::SEL_ARG *root,
639
optimizer::SEL_ARG *key,
640
optimizer::SEL_ARG *par)
642
optimizer::SEL_ARG *x= NULL;
643
optimizer::SEL_ARG *w= NULL;
647
while (x != root && x->color == optimizer::SEL_ARG::BLACK)
652
if (w->color == optimizer::SEL_ARG::RED)
654
w->color= optimizer::SEL_ARG::BLACK;
655
par->color= optimizer::SEL_ARG::RED;
656
left_rotate(&root, par);
659
if (w->left->color == optimizer::SEL_ARG::BLACK &&
660
w->right->color == optimizer::SEL_ARG::BLACK)
662
w->color= optimizer::SEL_ARG::RED;
667
if (w->right->color == optimizer::SEL_ARG::BLACK)
669
w->left->color= optimizer::SEL_ARG::BLACK;
670
w->color= optimizer::SEL_ARG::RED;
671
right_rotate(&root, w);
674
w->color= par->color;
675
par->color= optimizer::SEL_ARG::BLACK;
676
w->right->color= optimizer::SEL_ARG::BLACK;
677
left_rotate(&root, par);
685
if (w->color == optimizer::SEL_ARG::RED)
687
w->color= optimizer::SEL_ARG::BLACK;
688
par->color= optimizer::SEL_ARG::RED;
689
right_rotate(&root, par);
692
if (w->right->color == optimizer::SEL_ARG::BLACK &&
693
w->left->color == optimizer::SEL_ARG::BLACK)
695
w->color= optimizer::SEL_ARG::RED;
700
if (w->left->color == SEL_ARG::BLACK)
702
w->right->color= optimizer::SEL_ARG::BLACK;
703
w->color= optimizer::SEL_ARG::RED;
704
left_rotate(&root, w);
707
w->color= par->color;
708
par->color= optimizer::SEL_ARG::BLACK;
709
w->left->color= optimizer::SEL_ARG::BLACK;
710
right_rotate(&root, par);
717
x->color= optimizer::SEL_ARG::BLACK;