77
77
void init_tree(TREE *tree, uint32_t default_alloc_size, uint32_t memory_limit,
78
int size, qsort_cmp2 compare, bool with_delete,
78
uint32_t size, qsort_cmp2 compare, bool with_delete,
79
79
tree_element_free free_element, void *custom_arg)
81
81
if (default_alloc_size < DEFAULT_ALLOC_SIZE)
83
83
default_alloc_size= MY_ALIGN(default_alloc_size, DEFAULT_ALIGN_SIZE);
84
84
memset(&tree->null_element, 0, sizeof(tree->null_element));
85
85
tree->root= &tree->null_element;
86
tree->compare=compare;
87
tree->size_of_element=size > 0 ? (uint) size : 0;
88
tree->memory_limit=memory_limit;
89
tree->free=free_element;
91
tree->elements_in_tree=0;
86
tree->compare= compare;
87
tree->size_of_element= size > 0 ? (uint32_t) size : 0;
88
tree->memory_limit= memory_limit;
89
tree->free= free_element;
91
tree->elements_in_tree= 0;
92
92
tree->custom_arg = custom_arg;
93
tree->null_element.colour=BLACK;
94
tree->null_element.left=tree->null_element.right=0;
93
tree->null_element.colour= BLACK;
94
tree->null_element.left=tree->null_element.right= 0;
96
if (!free_element && size >= 0 &&
97
((uint) size <= sizeof(void*) || ((uint) size & (sizeof(void*)-1))))
97
(size <= sizeof(void*) || ((uint32_t) size & (sizeof(void*)-1))))
100
100
We know that the data doesn't have to be aligned (like if the key
101
101
contains a double), so we can store the data combined with the
104
tree->offset_to_key=sizeof(TREE_ELEMENT); /* Put key after element */
104
tree->offset_to_key= sizeof(TREE_ELEMENT); /* Put key after element */
105
105
/* Fix allocation size so that we don't lose any memory */
106
default_alloc_size/=(sizeof(TREE_ELEMENT)+size);
106
default_alloc_size/= (sizeof(TREE_ELEMENT)+size);
107
107
if (!default_alloc_size)
108
default_alloc_size=1;
109
default_alloc_size*=(sizeof(TREE_ELEMENT)+size);
108
default_alloc_size= 1;
109
default_alloc_size*= (sizeof(TREE_ELEMENT)+size);
113
tree->offset_to_key=0; /* use key through pointer */
114
tree->size_of_element+=sizeof(void*);
113
tree->offset_to_key= 0; /* use key through pointer */
114
tree->size_of_element+= sizeof(void*);
116
if (!(tree->with_delete=with_delete))
116
if (! (tree->with_delete= with_delete))
118
init_alloc_root(&tree->mem_root, (uint) default_alloc_size, 0);
119
tree->mem_root.min_malloc=(sizeof(TREE_ELEMENT)+tree->size_of_element);
118
init_alloc_root(&tree->mem_root, (uint32_t) default_alloc_size, 0);
119
tree->mem_root.min_malloc= (sizeof(TREE_ELEMENT)+tree->size_of_element);
124
123
static void free_tree(TREE *tree, myf free_flags)
207
204
if (element == &tree->null_element)
209
uint32_t alloc_size=sizeof(TREE_ELEMENT)+key_size+tree->size_of_element;
210
tree->allocated+=alloc_size;
206
size_t alloc_size= sizeof(TREE_ELEMENT)+key_size+tree->size_of_element;
207
tree->allocated+= alloc_size;
212
209
if (tree->memory_limit && tree->elements_in_tree
213
210
&& tree->allocated > tree->memory_limit)
216
213
return tree_insert(tree, key, key_size, custom_arg);
219
key_size+=tree->size_of_element;
216
key_size+= tree->size_of_element;
220
217
if (tree->with_delete)
221
element=(TREE_ELEMENT *) malloc(alloc_size);
218
element= (TREE_ELEMENT *) malloc(alloc_size);
223
element=(TREE_ELEMENT *) alloc_root(&tree->mem_root,alloc_size);
220
element= (TREE_ELEMENT *) alloc_root(&tree->mem_root,alloc_size);
227
element->left=element->right= &tree->null_element;
224
element->left= element->right= &tree->null_element;
228
225
if (!tree->offset_to_key)
230
227
if (key_size == sizeof(void*)) /* no length, save pointer */
231
*((void**) (element+1))=key;
228
*((void**) (element+1))= key;
234
231
*((void**) (element+1))= (void*) ((void **) (element+1)+1);
239
236
memcpy((unsigned char*) element + tree->offset_to_key, key, key_size);
240
element->count=1; /* May give warning in purify */
237
element->count= 1; /* May give warning in purify */
241
238
tree->elements_in_tree++;
242
239
rb_insert(tree,parent,element); /* rebalance tree */
250
247
if (! element->count)
251
248
element->count--;
256
254
int tree_delete(TREE *tree, void *key, uint32_t key_size, void *custom_arg)
258
int cmp,remove_colour;
259
257
TREE_ELEMENT *element,***parent, ***org_parent, *nod;
260
258
if (!tree->with_delete)
261
259
return 1; /* not allowed */
264
262
*parent= &tree->root; element= tree->root;
267
267
if (element == &tree->null_element)
268
268
return 1; /* Was not in tree */
269
269
if ((cmp = (*tree->compare)(custom_arg, ELEMENT_KEY(tree,element),
281
281
if (element->left == &tree->null_element)
283
(**parent)=element->right;
283
(**parent)= element->right;
284
284
remove_colour= element->colour;
286
286
else if (element->right == &tree->null_element)
288
(**parent)=element->left;
288
(**parent)= element->left;
289
289
remove_colour= element->colour;
297
297
*++parent= &nod->left; nod= nod->left;
299
(**parent)=nod->right; /* unlink nod from tree */
299
(**parent)= nod->right; /* unlink nod from tree */
300
300
remove_colour= nod->colour;
301
org_parent[0][0]=nod; /* put y in place of element */
301
org_parent[0][0]= nod; /* put y in place of element */
302
302
org_parent[1]= &nod->right;
303
nod->left=element->left;
304
nod->right=element->right;
305
nod->colour=element->colour;
303
nod->left= element->left;
304
nod->right= element->right;
305
nod->colour= element->colour;
307
307
if (remove_colour == BLACK)
308
308
rb_delete_fixup(tree,parent);
311
311
tree->allocated-= sizeof(TREE_ELEMENT) + tree->size_of_element + key_size;
312
312
free((unsigned char*) element);
313
313
tree->elements_in_tree--;
318
void *tree_search(TREE *tree, void *key, void *custom_arg)
321
TREE_ELEMENT *element=tree->root;
325
if (element == &tree->null_element)
327
if ((cmp = (*tree->compare)(custom_arg, ELEMENT_KEY(tree,element),
329
return ELEMENT_KEY(tree,element);
331
element=element->right;
333
element=element->left;
337
318
void *tree_search_key(TREE *tree, const void *key,
338
319
TREE_ELEMENT **parents, TREE_ELEMENT ***last_pos,
339
320
enum ha_rkey_function flag, void *custom_arg)
342
322
TREE_ELEMENT *element= tree->root;
343
323
TREE_ELEMENT **last_left_step_parent= NULL, **last_right_step_parent= NULL;
344
324
TREE_ELEMENT **last_equal_element= NULL;
461
445
ha_rows tree_record_pos(TREE *tree, const void *key,
462
446
enum ha_rkey_function flag, void *custom_arg)
465
448
TREE_ELEMENT *element= tree->root;
467
450
double right= tree->elements_in_tree;
469
452
while (element != &tree->null_element)
471
456
if ((cmp= (*tree->compare)(custom_arg, ELEMENT_KEY(tree, element),
545
533
error=tree_walk_right_root_left(tree,element->left,action,argument);
552
/* Functions to fix up the tree after insert and delete */
541
/* Functions to fix up the tree after insert and delete */
554
543
static void left_rotate(TREE_ELEMENT **parent, TREE_ELEMENT *leaf)
548
leaf->right= y->left;
564
553
static void right_rotate(TREE_ELEMENT **parent, TREE_ELEMENT *leaf)
558
leaf->left= x->right;
574
563
static void rb_insert(TREE *tree, TREE_ELEMENT ***parent, TREE_ELEMENT *leaf)
584
573
if (y->colour == RED)
590
leaf->colour=RED; /* And the loop continues */
579
leaf->colour= RED; /* And the loop continues */
594
583
if (leaf == par->right)
596
585
left_rotate(parent[-1],par);
597
par=leaf; /* leaf is now parent to old leaf */
586
par= leaf; /* leaf is now parent to old leaf */
601
590
right_rotate(parent[-2],par2);
640
629
if (x == (par=parent[-1][0])->left)
643
632
if (w->colour == RED)
647
636
left_rotate(parent[-1],par);
648
637
parent[0]= &w->left;
649
638
*++parent= &par->left;
652
641
if (w->left->colour == BLACK && w->right->colour == BLACK)
660
649
if (w->right->colour == BLACK)
662
w->left->colour=BLACK;
651
w->left->colour= BLACK;
664
653
right_rotate(&par->right,w);
667
w->colour=par->colour;
669
w->right->colour=BLACK;
656
w->colour= par->colour;
658
w->right->colour= BLACK;
670
659
left_rotate(parent[-1],par);
678
667
if (w->colour == RED)
682
671
right_rotate(parent[-1],par);
683
672
parent[0]= &w->right;
684
673
*++parent= &par->right;
687
676
if (w->right->colour == BLACK && w->left->colour == BLACK)
695
684
if (w->left->colour == BLACK)
697
w->right->colour=BLACK;
686
w->right->colour= BLACK;
699
688
left_rotate(&par->left,w);
702
w->colour=par->colour;
704
w->left->colour=BLACK;
691
w->colour= par->colour;
693
w->left->colour= BLACK;
705
694
right_rotate(parent[-1],par);