~drizzle-trunk/drizzle/development

1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
1999.6.1 by kalebral at gmail
update Copyright strings to a more common format to help with creating the master debian copyright file
4
 *  Copyright (C) 2008-2009 Sun Microsystems, Inc.
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
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
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
20
#include <config.h>
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>
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
25
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
26
namespace drizzled
27
{
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
28
29
/* Functions to fix up the tree after insert and delete */
30
static void left_rotate(optimizer::SEL_ARG **root, optimizer::SEL_ARG *leaf)
31
{
32
  optimizer::SEL_ARG *y= leaf->right;
33
  leaf->right= y->left;
34
  if (y->left != &optimizer::null_element)
35
    y->left->parent= leaf;
36
  if (! (y->parent=leaf->parent))
37
    *root= y;
38
  else
39
    *leaf->parent_ptr()= y;
40
  y->left= leaf;
41
  leaf->parent= y;
42
}
43
44
45
static void right_rotate(optimizer::SEL_ARG **root, optimizer::SEL_ARG *leaf)
46
{
47
  optimizer::SEL_ARG *y= leaf->left;
48
  leaf->left= y->right;
49
  if (y->right != &optimizer::null_element)
50
    y->right->parent= leaf;
51
  if (! (y->parent=leaf->parent))
52
    *root= y;
53
  else
54
    *leaf->parent_ptr()= y;
55
  y->right= leaf;
56
  leaf->parent= y;
57
}
58
59
60
/* Get overlapping range */
61
optimizer::SEL_ARG *optimizer::SEL_ARG::clone_and(optimizer::SEL_ARG *arg)
1240.3.1 by Brian Aker
Merge Padraig.
62
{
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
63
  unsigned char *new_min= NULL;
64
  unsigned char *new_max= NULL;
65
  uint8_t flag_min= 0;
66
  uint8_t flag_max= 0;
67
68
  if (cmp_min_to_min(arg) >= 0)
69
  {
70
    new_min= min_value;
71
    flag_min= min_flag;
72
  }
73
  else
74
  {
75
    new_min=arg->min_value; flag_min=arg->min_flag;
76
  }
77
  if (cmp_max_to_max(arg) <= 0)
78
  {
1240.3.1 by Brian Aker
Merge Padraig.
79
    new_max= max_value;
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
80
    flag_max= max_flag;
81
  }
82
  else
83
  {
1240.3.1 by Brian Aker
Merge Padraig.
84
    new_max= arg->max_value;
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
85
    flag_max= arg->max_flag;
86
  }
1240.3.1 by Brian Aker
Merge Padraig.
87
  return (new SEL_ARG(field,
88
                      part,
89
                      new_min,
90
                      new_max,
91
                      flag_min,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
92
                      flag_max,
93
                      test(maybe_flag && arg->maybe_flag)));
94
}
95
96
97
/* min <= X , arg->min */
98
optimizer::SEL_ARG *optimizer::SEL_ARG::clone_first(optimizer::SEL_ARG *arg)
99
{
1240.3.1 by Brian Aker
Merge Padraig.
100
  return (new SEL_ARG(field,part,
101
                      min_value,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
102
                      arg->min_value,
1240.3.1 by Brian Aker
Merge Padraig.
103
                      min_flag,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
104
                      arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX,
105
		                                     maybe_flag | arg->maybe_flag));
106
}
107
108
109
/* min <= X <= key_max */
110
optimizer::SEL_ARG *optimizer::SEL_ARG::clone_last(optimizer::SEL_ARG *arg)
111
{
1240.3.1 by Brian Aker
Merge Padraig.
112
  return (new SEL_ARG(field,
113
                      part,
114
                      min_value,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
115
                      arg->max_value,
1240.3.1 by Brian Aker
Merge Padraig.
116
                      min_flag,
117
                      arg->max_flag,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
118
                      maybe_flag | arg->maybe_flag));
119
}
120
121
122
/* Get overlapping range */
123
bool optimizer::SEL_ARG::copy_min(optimizer::SEL_ARG *arg)
124
{
125
  if (cmp_min_to_min(arg) > 0)
126
  {
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))
131
    {
132
      return 1;	// Full range
133
    }
134
  }
135
  maybe_flag|= arg->maybe_flag;
136
  return 0;
137
}
138
139
/* Get overlapping range */
140
bool optimizer::SEL_ARG::copy_max(optimizer::SEL_ARG *arg)
141
{
142
  if (cmp_max_to_max(arg) <= 0)
143
  {
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))
148
    {
149
      return 1;	// Full range
150
    }
151
  }
152
  maybe_flag|= arg->maybe_flag;
153
  return 0;
154
}
155
156
void optimizer::SEL_ARG::copy_min_to_min(optimizer::SEL_ARG *arg)
157
{
158
  min_value= arg->min_value;
159
  min_flag= arg->min_flag;
160
}
161
162
163
void optimizer::SEL_ARG::copy_min_to_max(optimizer::SEL_ARG *arg)
164
{
165
  max_value= arg->min_value;
166
  max_flag= arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX;
167
}
168
169
void optimizer::SEL_ARG::copy_max_to_min(optimizer::SEL_ARG *arg)
170
{
171
  min_value= arg->max_value;
172
  min_flag= arg->max_flag & NEAR_MAX ? 0 : NEAR_MIN;
173
}
174
175
176
int optimizer::SEL_ARG::store_min(uint32_t length, unsigned char **min_key, uint32_t min_key_flag)
177
{
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))))
181
  {
182
    if (maybe_null && *min_value)
183
    {
184
      **min_key= 1;
185
      memset(*min_key+1, 0, length-1);
186
    }
187
    else
188
    {
189
      memcpy(*min_key,min_value,length);
190
    }
191
    (*min_key)+= length;
192
    return 1;
193
  }
194
  return 0;
195
}
196
197
198
int optimizer::SEL_ARG::store_max(uint32_t length, unsigned char **max_key, uint32_t max_key_flag)
199
{
200
  if (! (max_flag & NO_MAX_RANGE) &&
201
      ! (max_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
202
  {
203
    if (maybe_null && *max_value)
204
    {
205
      **max_key= 1;
206
      memset(*max_key + 1, 0, length-1);
207
    }
208
    else
209
    {
210
      memcpy(*max_key,max_value,length);
211
    }
212
    (*max_key)+= length;
213
    return 1;
214
  }
215
  return 0;
216
}
217
218
219
int optimizer::SEL_ARG::store_min_key(KEY_PART *key, unsigned char **range_key, uint32_t *range_key_flag)
220
{
221
  optimizer::SEL_ARG *key_tree= first();
222
  uint32_t res= key_tree->store_min(key[key_tree->part].store_length,
1240.3.1 by Brian Aker
Merge Padraig.
223
                                    range_key,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
224
                                    *range_key_flag);
225
  *range_key_flag|= key_tree->min_flag;
226
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)
231
  {
1240.3.1 by Brian Aker
Merge Padraig.
232
    res+= key_tree->next_key_part->store_min_key(key,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
233
                                                 range_key,
234
                                                 range_key_flag);
235
  }
236
  return res;
237
}
238
239
int optimizer::SEL_ARG::store_max_key(KEY_PART *key, unsigned char **range_key, uint32_t *range_key_flag)
240
{
241
  SEL_ARG *key_tree= last();
242
  uint32_t res= key_tree->store_max(key[key_tree->part].store_length,
1240.3.1 by Brian Aker
Merge Padraig.
243
                                    range_key,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
244
                                    *range_key_flag);
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)
1240.3.1 by Brian Aker
Merge Padraig.
250
    res+= key_tree->next_key_part->store_max_key(key,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
251
                                                 range_key,
252
                                                 range_key_flag);
253
  return res;
254
}
255
256
optimizer::SEL_ARG::SEL_ARG(optimizer::SEL_ARG &arg)
257
  :
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
258
    memory::SqlAlloc()
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
259
{
260
  type= arg.type;
261
  min_flag= arg.min_flag;
262
  max_flag= arg.max_flag;
263
  maybe_flag= arg.maybe_flag;
264
  maybe_null= arg.maybe_null;
265
  part= arg.part;
266
  field= arg.field;
267
  min_value= arg.min_value;
268
  max_value= arg.max_value;
269
  next_key_part= arg.next_key_part;
1240.3.1 by Brian Aker
Merge Padraig.
270
  use_count=1;
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
271
  elements=1;
272
}
273
274
275
void optimizer::SEL_ARG::make_root()
276
{
277
  left= right= &optimizer::null_element;
278
  color= BLACK;
279
  next= prev =0;
1240.3.1 by Brian Aker
Merge Padraig.
280
  use_count= 0;
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
281
  elements= 1;
282
}
283
284
optimizer::SEL_ARG::SEL_ARG(Field *f,
285
                            const unsigned char *min_value_arg,
286
                            const unsigned char *max_value_arg)
287
  :
1240.3.1 by Brian Aker
Merge Padraig.
288
    min_flag(0),
289
    max_flag(0),
290
    maybe_flag(0),
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
291
    maybe_null(f->real_maybe_null()),
1240.3.1 by Brian Aker
Merge Padraig.
292
    elements(1),
293
    use_count(1),
294
    field(f),
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
295
    min_value((unsigned char*) min_value_arg),
1240.3.1 by Brian Aker
Merge Padraig.
296
    max_value((unsigned char*) max_value_arg),
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
297
    next(0),
298
    prev(0),
299
    next_key_part(0),
300
    color(BLACK),
301
    type(KEY_RANGE)
302
{
303
  left= right= &optimizer::null_element;
304
}
305
306
optimizer::SEL_ARG::SEL_ARG(Field *field_,
307
                            uint8_t part_,
1240.3.1 by Brian Aker
Merge Padraig.
308
                            unsigned char *min_value_,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
309
                            unsigned char *max_value_,
310
		            uint8_t min_flag_,
311
                            uint8_t max_flag_,
312
                            uint8_t maybe_flag_)
313
  :
314
    min_flag(min_flag_),
315
    max_flag(max_flag_),
316
    maybe_flag(maybe_flag_),
317
    part(part_),
1240.3.1 by Brian Aker
Merge Padraig.
318
    maybe_null(field_->real_maybe_null()),
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
319
    elements(1),
320
    use_count(1),
1240.3.1 by Brian Aker
Merge Padraig.
321
    field(field_),
322
    min_value(min_value_),
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
323
    max_value(max_value_),
324
    next(0),
325
    prev(0),
326
    next_key_part(0),
327
    color(BLACK),
328
    type(KEY_RANGE)
329
{
330
  left= right= &optimizer::null_element;
331
}
332
1240.3.1 by Brian Aker
Merge Padraig.
333
optimizer::SEL_ARG *optimizer::SEL_ARG::clone(RangeParameter *param,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
334
                                              optimizer::SEL_ARG *new_parent,
335
                                              optimizer::SEL_ARG **next_arg)
336
{
337
  optimizer::SEL_ARG *tmp= NULL;
338
339
  /* Bail out if we have already generated too many SEL_ARGs */
340
  if (++param->alloced_sel_args > MAX_SEL_ARGS)
341
    return 0;
342
343
  if (type != KEY_RANGE)
344
  {
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;
349
    (*next_arg)= tmp;
350
  }
351
  else
352
  {
353
    if (! (tmp= new (param->mem_root) optimizer::SEL_ARG(field,
1240.3.1 by Brian Aker
Merge Padraig.
354
                                                         part,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
355
                                                         min_value,
356
                                                         max_value,
1240.3.1 by Brian Aker
Merge Padraig.
357
                                                         min_flag,
358
                                                         max_flag,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
359
                                                         maybe_flag)))
360
      return 0; // OOM
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)))
365
	return 0; // OOM
366
367
    tmp->prev= *next_arg; // Link into next/prev chain
368
    (*next_arg)->next= tmp;
369
    (*next_arg)= tmp;
370
371
    if (right != &optimizer::null_element)
372
      if (! (tmp->right= right->clone(param, tmp, next_arg)))
373
	return 0; // OOM
374
  }
375
  increment_use_count(1);
376
  tmp->color= color;
377
  tmp->elements= this->elements;
378
  return tmp;
379
}
380
381
optimizer::SEL_ARG *optimizer::SEL_ARG::first()
382
{
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;
388
  return next_arg;
389
}
390
391
optimizer::SEL_ARG *optimizer::SEL_ARG::last()
392
{
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;
398
  return next_arg;
399
}
400
401
1237.13.7 by Padraig O'Sullivan
Renamed PARAM to Parameter and RANGE_OPT_PARAM to RangeParameter.
402
optimizer::SEL_ARG *optimizer::SEL_ARG::clone_tree(RangeParameter *param)
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
403
{
404
  optimizer::SEL_ARG tmp_link;
405
  optimizer::SEL_ARG*next_arg= NULL;
406
  optimizer::SEL_ARG *root= NULL;
407
  next_arg= &tmp_link;
408
  if (! (root= clone(param, (SEL_ARG *) 0, &next_arg)))
409
    return 0;
410
  next_arg->next= 0; // Fix last link
411
  tmp_link.next->prev= 0; // Fix first link
412
  if (root) // If not OOM
413
    root->use_count= 0;
414
  return root;
415
}
416
417
418
optimizer::SEL_ARG *
419
optimizer::SEL_ARG::insert(optimizer::SEL_ARG *key)
420
{
421
  optimizer::SEL_ARG *element= NULL;
422
  optimizer::SEL_ARG **par= NULL;
423
  optimizer::SEL_ARG *last_element= NULL;
424
425
  for (element= this; element != &optimizer::null_element; )
426
  {
427
    last_element= element;
428
    if (key->cmp_min_to_min(element) > 0)
429
    {
430
      par= &element->right; element= element->right;
431
    }
432
    else
433
    {
434
      par= &element->left; element= element->left;
435
    }
436
  }
437
  *par= key;
438
  key->parent= last_element;
439
	/* Link in list */
440
  if (par == &last_element->left)
441
  {
442
    key->next= last_element;
443
    if ((key->prev=last_element->prev))
444
      key->prev->next= key;
445
    last_element->prev= key;
446
  }
447
  else
448
  {
449
    if ((key->next= last_element->next))
450
      key->next->prev= key;
451
    key->prev= last_element;
452
    last_element->next= key;
453
  }
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;
459
  return root;
460
}
461
462
463
/*
464
** Find best key with min <= given key
465
** Because the call context this should never return 0 to get_range
466
*/
467
optimizer::SEL_ARG *
468
optimizer::SEL_ARG::find_range(optimizer::SEL_ARG *key)
469
{
470
  optimizer::SEL_ARG *element= this;
471
  optimizer::SEL_ARG *found= NULL;
472
473
  for (;;)
474
  {
475
    if (element == &optimizer::null_element)
476
      return found;
477
    int cmp= element->cmp_min_to_min(key);
478
    if (cmp == 0)
479
      return element;
480
    if (cmp < 0)
481
    {
482
      found= element;
483
      element= element->right;
484
    }
485
    else
486
      element= element->left;
487
  }
488
}
489
490
491
/*
492
  Remove a element from the tree
493
494
  SYNOPSIS
495
    tree_delete()
496
    key		Key that is to be deleted from tree (this)
497
498
  NOTE
499
    This also frees all sub trees that is used by the element
500
501
  RETURN
502
    root of new tree (with key deleted)
503
*/
504
optimizer::SEL_ARG *
505
optimizer::SEL_ARG::tree_delete(optimizer::SEL_ARG *key)
506
{
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;
512
513
  root= this;
514
  this->parent= 0;
515
516
  /* Unlink from list */
517
  if (key->prev)
518
    key->prev->next= key->next;
519
  if (key->next)
520
    key->next->prev= key->prev;
521
  key->increment_use_count(-1);
522
  if (! key->parent)
523
    par= &root;
524
  else
525
    par= key->parent_ptr();
526
527
  if (key->left == &optimizer::null_element)
528
  {
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;
534
  }
535
  else if (key->right == &optimizer::null_element)
536
  {
537
    *par= nod= key->left;
538
    nod->parent= fix_par= key->parent;
539
    remove_color= key->color;
540
  }
541
  else
542
  {
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;
549
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;
555
    *par= tmp;
556
    if (fix_par == key)				// key->right == key->next
557
      fix_par= tmp;				// new parent of nod
558
  }
559
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);
564
565
  root->use_count= this->use_count;		// Fix root counters
566
  root->elements= this->elements-1;
567
  root->maybe_flag= this->maybe_flag;
568
  return root;
569
}
570
571
572
optimizer::SEL_ARG *
573
optimizer::SEL_ARG::rb_insert(optimizer::SEL_ARG *leaf)
574
{
575
  optimizer::SEL_ARG *y= NULL;
576
  optimizer::SEL_ARG *par= NULL;
577
  optimizer::SEL_ARG *par2= NULL;
578
  optimizer::SEL_ARG *root= NULL;
579
1240.3.1 by Brian Aker
Merge Padraig.
580
  root= this;
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
581
  root->parent= 0;
582
583
  leaf->color= RED;
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)
587
    {
588
      y= par2->right;
589
      if (y->color == RED)
590
      {
591
        par->color= BLACK;
592
        y->color= BLACK;
593
        leaf= par2;
594
        leaf->color= RED;		/* And the loop continues */
595
      }
596
      else
597
      {
598
        if (leaf == par->right)
599
        {
600
          left_rotate(&root,leaf->parent);
601
          par= leaf; /* leaf is now parent to old leaf */
602
        }
603
        par->color= BLACK;
604
        par2->color= RED;
605
        right_rotate(&root, par2);
606
        break;
607
      }
608
    }
609
    else
610
    {
611
      y= par2->left;
612
      if (y->color == RED)
613
      {
614
        par->color= BLACK;
615
        y->color= BLACK;
616
        leaf= par2;
617
        leaf->color= RED;		/* And the loop continues */
618
      }
619
      else
620
      {
621
        if (leaf == par->left)
622
        {
623
          right_rotate(&root,par);
624
          par= leaf;
625
        }
626
        par->color= BLACK;
627
        par2->color= RED;
628
        left_rotate(&root, par2);
629
        break;
630
      }
631
    }
632
  }
633
  root->color= BLACK;
634
635
  return root;
636
}
637
638
639
optimizer::SEL_ARG *optimizer::rb_delete_fixup(optimizer::SEL_ARG *root,
640
                                               optimizer::SEL_ARG *key,
641
                                               optimizer::SEL_ARG *par)
642
{
643
  optimizer::SEL_ARG *x= NULL;
644
  optimizer::SEL_ARG *w= NULL;
645
  root->parent= 0;
646
647
  x= key;
648
  while (x != root && x->color == optimizer::SEL_ARG::BLACK)
649
  {
650
    if (x == par->left)
651
    {
652
      w= par->right;
653
      if (w->color == optimizer::SEL_ARG::RED)
654
      {
655
        w->color= optimizer::SEL_ARG::BLACK;
656
        par->color= optimizer::SEL_ARG::RED;
657
        left_rotate(&root, par);
658
        w= par->right;
659
      }
1240.3.1 by Brian Aker
Merge Padraig.
660
      if (w->left->color == optimizer::SEL_ARG::BLACK &&
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
661
          w->right->color == optimizer::SEL_ARG::BLACK)
662
      {
663
        w->color= optimizer::SEL_ARG::RED;
664
        x= par;
665
      }
666
      else
667
      {
668
        if (w->right->color == optimizer::SEL_ARG::BLACK)
669
        {
670
          w->left->color= optimizer::SEL_ARG::BLACK;
671
          w->color= optimizer::SEL_ARG::RED;
672
          right_rotate(&root, w);
673
          w= par->right;
674
        }
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);
679
        x= root;
680
        break;
681
      }
682
    }
683
    else
684
    {
685
      w= par->left;
686
      if (w->color == optimizer::SEL_ARG::RED)
687
      {
688
        w->color= optimizer::SEL_ARG::BLACK;
689
        par->color= optimizer::SEL_ARG::RED;
690
        right_rotate(&root, par);
691
        w= par->left;
692
      }
1240.3.1 by Brian Aker
Merge Padraig.
693
      if (w->right->color == optimizer::SEL_ARG::BLACK &&
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
694
          w->left->color == optimizer::SEL_ARG::BLACK)
695
      {
696
        w->color= optimizer::SEL_ARG::RED;
697
        x= par;
698
      }
699
      else
700
      {
701
        if (w->left->color == SEL_ARG::BLACK)
702
        {
703
          w->right->color= optimizer::SEL_ARG::BLACK;
704
          w->color= optimizer::SEL_ARG::RED;
705
          left_rotate(&root, w);
706
          w= par->left;
707
        }
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);
712
        x= root;
713
        break;
714
      }
715
    }
716
    par= x->parent;
717
  }
718
  x->color= optimizer::SEL_ARG::BLACK;
719
  return root;
720
}
721
722
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
723
} /* namespace drizzled */