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, Inc.
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
21
#include "drizzled/optimizer/range.h"
22
#include "drizzled/optimizer/range_param.h"
23
#include "drizzled/optimizer/sel_arg.h"
24
#include "drizzled/util/test.h"
29
/* Functions to fix up the tree after insert and delete */
30
static void left_rotate(optimizer::SEL_ARG **root, optimizer::SEL_ARG *leaf)
32
optimizer::SEL_ARG *y= leaf->right;
34
if (y->left != &optimizer::null_element)
35
y->left->parent= leaf;
36
if (! (y->parent=leaf->parent))
39
*leaf->parent_ptr()= y;
45
static void right_rotate(optimizer::SEL_ARG **root, optimizer::SEL_ARG *leaf)
47
optimizer::SEL_ARG *y= leaf->left;
49
if (y->right != &optimizer::null_element)
50
y->right->parent= leaf;
51
if (! (y->parent=leaf->parent))
54
*leaf->parent_ptr()= y;
60
/* Get overlapping range */
61
optimizer::SEL_ARG *optimizer::SEL_ARG::clone_and(optimizer::SEL_ARG *arg)
63
unsigned char *new_min= NULL;
64
unsigned char *new_max= NULL;
68
if (cmp_min_to_min(arg) >= 0)
75
new_min=arg->min_value; flag_min=arg->min_flag;
77
if (cmp_max_to_max(arg) <= 0)
84
new_max= arg->max_value;
85
flag_max= arg->max_flag;
87
return (new SEL_ARG(field,
93
test(maybe_flag && arg->maybe_flag)));
97
/* min <= X , arg->min */
98
optimizer::SEL_ARG *optimizer::SEL_ARG::clone_first(optimizer::SEL_ARG *arg)
100
return (new SEL_ARG(field,part,
104
arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX,
105
maybe_flag | arg->maybe_flag));
109
/* min <= X <= key_max */
110
optimizer::SEL_ARG *optimizer::SEL_ARG::clone_last(optimizer::SEL_ARG *arg)
112
return (new SEL_ARG(field,
118
maybe_flag | arg->maybe_flag));
122
/* Get overlapping range */
123
bool optimizer::SEL_ARG::copy_min(optimizer::SEL_ARG *arg)
125
if (cmp_min_to_min(arg) > 0)
127
min_value= arg->min_value;
128
min_flag=arg->min_flag;
129
if ((max_flag & (NO_MAX_RANGE | NO_MIN_RANGE)) ==
130
(NO_MAX_RANGE | NO_MIN_RANGE))
132
return 1; // Full range
135
maybe_flag|= arg->maybe_flag;
139
/* Get overlapping range */
140
bool optimizer::SEL_ARG::copy_max(optimizer::SEL_ARG *arg)
142
if (cmp_max_to_max(arg) <= 0)
144
max_value= arg->max_value;
145
max_flag= arg->max_flag;
146
if ((max_flag & (NO_MAX_RANGE | NO_MIN_RANGE)) ==
147
(NO_MAX_RANGE | NO_MIN_RANGE))
149
return 1; // Full range
152
maybe_flag|= arg->maybe_flag;
156
void optimizer::SEL_ARG::copy_min_to_min(optimizer::SEL_ARG *arg)
158
min_value= arg->min_value;
159
min_flag= arg->min_flag;
163
void optimizer::SEL_ARG::copy_min_to_max(optimizer::SEL_ARG *arg)
165
max_value= arg->min_value;
166
max_flag= arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX;
169
void optimizer::SEL_ARG::copy_max_to_min(optimizer::SEL_ARG *arg)
171
min_value= arg->max_value;
172
min_flag= arg->max_flag & NEAR_MAX ? 0 : NEAR_MIN;
176
int optimizer::SEL_ARG::store_min(uint32_t length, unsigned char **min_key, uint32_t min_key_flag)
178
/* "(kp1 > c1) AND (kp2 OP c2) AND ..." -> (kp1 > c1) */
179
if ((! (min_flag & NO_MIN_RANGE) &&
180
! (min_key_flag & (NO_MIN_RANGE | NEAR_MIN))))
182
if (maybe_null && *min_value)
185
memset(*min_key+1, 0, length-1);
189
memcpy(*min_key,min_value,length);
198
int optimizer::SEL_ARG::store_max(uint32_t length, unsigned char **max_key, uint32_t max_key_flag)
200
if (! (max_flag & NO_MAX_RANGE) &&
201
! (max_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
203
if (maybe_null && *max_value)
206
memset(*max_key + 1, 0, length-1);
210
memcpy(*max_key,max_value,length);
219
int optimizer::SEL_ARG::store_min_key(KEY_PART *key, unsigned char **range_key, uint32_t *range_key_flag)
221
optimizer::SEL_ARG *key_tree= first();
222
uint32_t res= key_tree->store_min(key[key_tree->part].store_length,
225
*range_key_flag|= key_tree->min_flag;
227
if (key_tree->next_key_part &&
228
key_tree->next_key_part->part == key_tree->part+1 &&
229
! (*range_key_flag & (NO_MIN_RANGE | NEAR_MIN)) &&
230
key_tree->next_key_part->type == optimizer::SEL_ARG::KEY_RANGE)
232
res+= key_tree->next_key_part->store_min_key(key,
239
int optimizer::SEL_ARG::store_max_key(KEY_PART *key, unsigned char **range_key, uint32_t *range_key_flag)
241
SEL_ARG *key_tree= last();
242
uint32_t res= key_tree->store_max(key[key_tree->part].store_length,
245
(*range_key_flag)|= key_tree->max_flag;
246
if (key_tree->next_key_part &&
247
key_tree->next_key_part->part == key_tree->part+1 &&
248
! (*range_key_flag & (NO_MAX_RANGE | NEAR_MAX)) &&
249
key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
250
res+= key_tree->next_key_part->store_max_key(key,
256
optimizer::SEL_ARG::SEL_ARG(optimizer::SEL_ARG &arg)
261
min_flag= arg.min_flag;
262
max_flag= arg.max_flag;
263
maybe_flag= arg.maybe_flag;
264
maybe_null= arg.maybe_null;
267
min_value= arg.min_value;
268
max_value= arg.max_value;
269
next_key_part= arg.next_key_part;
275
void optimizer::SEL_ARG::make_root()
277
left= right= &optimizer::null_element;
284
optimizer::SEL_ARG::SEL_ARG(Field *f,
285
const unsigned char *min_value_arg,
286
const unsigned char *max_value_arg)
291
maybe_null(f->real_maybe_null()),
295
min_value((unsigned char*) min_value_arg),
296
max_value((unsigned char*) max_value_arg),
303
left= right= &optimizer::null_element;
306
optimizer::SEL_ARG::SEL_ARG(Field *field_,
308
unsigned char *min_value_,
309
unsigned char *max_value_,
316
maybe_flag(maybe_flag_),
318
maybe_null(field_->real_maybe_null()),
322
min_value(min_value_),
323
max_value(max_value_),
330
left= right= &optimizer::null_element;
333
optimizer::SEL_ARG *optimizer::SEL_ARG::clone(RangeParameter *param,
334
optimizer::SEL_ARG *new_parent,
335
optimizer::SEL_ARG **next_arg)
337
optimizer::SEL_ARG *tmp= NULL;
339
/* Bail out if we have already generated too many SEL_ARGs */
340
if (++param->alloced_sel_args > MAX_SEL_ARGS)
343
if (type != KEY_RANGE)
345
if (! (tmp= new (param->mem_root) optimizer::SEL_ARG(type)))
346
return 0; // out of memory
347
tmp->prev= *next_arg; // Link into next/prev chain
348
(*next_arg)->next= tmp;
353
if (! (tmp= new (param->mem_root) optimizer::SEL_ARG(field,
361
tmp->parent= new_parent;
362
tmp->next_key_part= next_key_part;
363
if (left != &optimizer::null_element)
364
if (! (tmp->left= left->clone(param, tmp, next_arg)))
367
tmp->prev= *next_arg; // Link into next/prev chain
368
(*next_arg)->next= tmp;
371
if (right != &optimizer::null_element)
372
if (! (tmp->right= right->clone(param, tmp, next_arg)))
375
increment_use_count(1);
377
tmp->elements= this->elements;
381
optimizer::SEL_ARG *optimizer::SEL_ARG::first()
383
optimizer::SEL_ARG *next_arg= this;
384
if (! next_arg->left)
385
return 0; // MAYBE_KEY
386
while (next_arg->left != &optimizer::null_element)
387
next_arg= next_arg->left;
391
optimizer::SEL_ARG *optimizer::SEL_ARG::last()
393
SEL_ARG *next_arg= this;
394
if (! next_arg->right)
395
return 0; // MAYBE_KEY
396
while (next_arg->right != &optimizer::null_element)
397
next_arg=next_arg->right;
402
optimizer::SEL_ARG *optimizer::SEL_ARG::clone_tree(RangeParameter *param)
404
optimizer::SEL_ARG tmp_link;
405
optimizer::SEL_ARG*next_arg= NULL;
406
optimizer::SEL_ARG *root= NULL;
408
if (! (root= clone(param, (SEL_ARG *) 0, &next_arg)))
410
next_arg->next= 0; // Fix last link
411
tmp_link.next->prev= 0; // Fix first link
412
if (root) // If not OOM
419
optimizer::SEL_ARG::insert(optimizer::SEL_ARG *key)
421
optimizer::SEL_ARG *element= NULL;
422
optimizer::SEL_ARG **par= NULL;
423
optimizer::SEL_ARG *last_element= NULL;
425
for (element= this; element != &optimizer::null_element; )
427
last_element= element;
428
if (key->cmp_min_to_min(element) > 0)
430
par= &element->right; element= element->right;
434
par= &element->left; element= element->left;
438
key->parent= last_element;
440
if (par == &last_element->left)
442
key->next= last_element;
443
if ((key->prev=last_element->prev))
444
key->prev->next= key;
445
last_element->prev= key;
449
if ((key->next= last_element->next))
450
key->next->prev= key;
451
key->prev= last_element;
452
last_element->next= key;
454
key->left= key->right= &optimizer::null_element;
455
optimizer::SEL_ARG *root= rb_insert(key); // rebalance tree
456
root->use_count= this->use_count; // copy root info
457
root->elements= this->elements+1;
458
root->maybe_flag= this->maybe_flag;
464
** Find best key with min <= given key
465
** Because the call context this should never return 0 to get_range
468
optimizer::SEL_ARG::find_range(optimizer::SEL_ARG *key)
470
optimizer::SEL_ARG *element= this;
471
optimizer::SEL_ARG *found= NULL;
475
if (element == &optimizer::null_element)
477
int cmp= element->cmp_min_to_min(key);
483
element= element->right;
486
element= element->left;
492
Remove a element from the tree
496
key Key that is to be deleted from tree (this)
499
This also frees all sub trees that is used by the element
502
root of new tree (with key deleted)
505
optimizer::SEL_ARG::tree_delete(optimizer::SEL_ARG *key)
507
enum leaf_color remove_color;
508
optimizer::SEL_ARG *root= NULL;
509
optimizer::SEL_ARG *nod= NULL;
510
optimizer::SEL_ARG **par= NULL;
511
optimizer::SEL_ARG *fix_par= NULL;
516
/* Unlink from list */
518
key->prev->next= key->next;
520
key->next->prev= key->prev;
521
key->increment_use_count(-1);
525
par= key->parent_ptr();
527
if (key->left == &optimizer::null_element)
529
*par= nod= key->right;
530
fix_par= key->parent;
531
if (nod != &optimizer::null_element)
532
nod->parent= fix_par;
533
remove_color= key->color;
535
else if (key->right == &optimizer::null_element)
537
*par= nod= key->left;
538
nod->parent= fix_par= key->parent;
539
remove_color= key->color;
543
optimizer::SEL_ARG *tmp= key->next; // next bigger key (exist!)
544
nod= *tmp->parent_ptr()= tmp->right; // unlink tmp from tree
545
fix_par= tmp->parent;
546
if (nod != &optimizer::null_element)
547
nod->parent= fix_par;
548
remove_color= tmp->color;
550
tmp->parent= key->parent; // Move node in place of key
551
(tmp->left= key->left)->parent= tmp;
552
if ((tmp->right=key->right) != &optimizer::null_element)
553
tmp->right->parent= tmp;
554
tmp->color= key->color;
556
if (fix_par == key) // key->right == key->next
557
fix_par= tmp; // new parent of nod
560
if (root == &optimizer::null_element)
561
return 0; // Maybe root later
562
if (remove_color == BLACK)
563
root= rb_delete_fixup(root, nod, fix_par);
565
root->use_count= this->use_count; // Fix root counters
566
root->elements= this->elements-1;
567
root->maybe_flag= this->maybe_flag;
573
optimizer::SEL_ARG::rb_insert(optimizer::SEL_ARG *leaf)
575
optimizer::SEL_ARG *y= NULL;
576
optimizer::SEL_ARG *par= NULL;
577
optimizer::SEL_ARG *par2= NULL;
578
optimizer::SEL_ARG *root= NULL;
584
while (leaf != root && (par= leaf->parent)->color == RED)
585
{ // This can't be root or 1 level under
586
if (par == (par2= leaf->parent->parent)->left)
594
leaf->color= RED; /* And the loop continues */
598
if (leaf == par->right)
600
left_rotate(&root,leaf->parent);
601
par= leaf; /* leaf is now parent to old leaf */
605
right_rotate(&root, par2);
617
leaf->color= RED; /* And the loop continues */
621
if (leaf == par->left)
623
right_rotate(&root,par);
628
left_rotate(&root, par2);
639
optimizer::SEL_ARG *optimizer::rb_delete_fixup(optimizer::SEL_ARG *root,
640
optimizer::SEL_ARG *key,
641
optimizer::SEL_ARG *par)
643
optimizer::SEL_ARG *x= NULL;
644
optimizer::SEL_ARG *w= NULL;
648
while (x != root && x->color == optimizer::SEL_ARG::BLACK)
653
if (w->color == optimizer::SEL_ARG::RED)
655
w->color= optimizer::SEL_ARG::BLACK;
656
par->color= optimizer::SEL_ARG::RED;
657
left_rotate(&root, par);
660
if (w->left->color == optimizer::SEL_ARG::BLACK &&
661
w->right->color == optimizer::SEL_ARG::BLACK)
663
w->color= optimizer::SEL_ARG::RED;
668
if (w->right->color == optimizer::SEL_ARG::BLACK)
670
w->left->color= optimizer::SEL_ARG::BLACK;
671
w->color= optimizer::SEL_ARG::RED;
672
right_rotate(&root, w);
675
w->color= par->color;
676
par->color= optimizer::SEL_ARG::BLACK;
677
w->right->color= optimizer::SEL_ARG::BLACK;
678
left_rotate(&root, par);
686
if (w->color == optimizer::SEL_ARG::RED)
688
w->color= optimizer::SEL_ARG::BLACK;
689
par->color= optimizer::SEL_ARG::RED;
690
right_rotate(&root, par);
693
if (w->right->color == optimizer::SEL_ARG::BLACK &&
694
w->left->color == optimizer::SEL_ARG::BLACK)
696
w->color= optimizer::SEL_ARG::RED;
701
if (w->left->color == SEL_ARG::BLACK)
703
w->right->color= optimizer::SEL_ARG::BLACK;
704
w->color= optimizer::SEL_ARG::RED;
705
left_rotate(&root, w);
708
w->color= par->color;
709
par->color= optimizer::SEL_ARG::BLACK;
710
w->left->color= optimizer::SEL_ARG::BLACK;
711
right_rotate(&root, par);
718
x->color= optimizer::SEL_ARG::BLACK;
723
} /* namespace drizzled */