1
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
5
Copyright (c) 2001-2007 Octasic Inc.
9
Library used to manage a binary tree of variable max size. Library is
10
made to use one block of contiguous memory to manage the tree.
12
This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is
13
free software; you can redistribute it and/or modify it under the terms of
14
the GNU General Public License as published by the Free Software Foundation;
15
either version 2 of the License, or (at your option) any later version.
17
The OCT6100 GPL API is distributed in the hope that it will be useful, but
18
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22
You should have received a copy of the GNU General Public License
23
along with the OCT6100 GPL API; if not, write to the Free Software
24
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26
$Octasic_Release: OCT612xAPI-01.00-PR49 $
28
$Octasic_Revision: 18 $
30
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
31
#include "apilib/octapi_bt0.h"
32
#include "octapi_bt0_private.h"
36
#if !SKIP_OctApiBt0GetSize
37
UINT32 OctApiBt0GetSize(UINT32 number_of_items,UINT32 key_size, UINT32 data_size, UINT32 * b_size)
39
if ((key_size % 4) != 0) return(OCTAPI_BT0_KEY_SIZE_NOT_MUTLIPLE_OF_UINT32);
40
if ((data_size % 4) != 0) return(OCTAPI_BT0_DATA_SIZE_NOT_MUTLIPLE_OF_UINT32);
43
*b_size += sizeof(OCTAPI_BT0);
44
*b_size += sizeof(OCTAPI_BT0_NODE) * number_of_items;
45
*b_size += key_size * number_of_items;
46
*b_size += data_size * number_of_items;
52
#if !SKIP_OctApiBt0Init
53
UINT32 OctApiBt0Init(void ** b,UINT32 number_of_items,UINT32 key_size, UINT32 data_size)
58
/* Check input parameters.*/
59
if ((key_size % 4) != 0) return(OCTAPI_BT0_KEY_SIZE_NOT_MUTLIPLE_OF_UINT32);
60
if ((data_size % 4) != 0) return(OCTAPI_BT0_DATA_SIZE_NOT_MUTLIPLE_OF_UINT32);
62
/* If b is not already allocated.*/
63
if (*b == NULL) return(OCTAPI_BT0_MALLOC_FAILED);
65
bb = (OCTAPI_BT0 *)(*b);
67
/* Initialize the tree to an empty one!*/
68
bb->root_link.node_number = 0xFFFFFFFF;
69
bb->root_link.depth = 0;
71
/* Initialize tree parameters.*/
72
bb->number_of_items = number_of_items;
73
bb->key_size = key_size / 4;
74
bb->data_size = data_size / 4;
76
/* Initialize the next free node pointer.*/
77
if (number_of_items != 0)
78
bb->next_free_node = 0;
80
bb->next_free_node = 0xFFFFFFFF;
82
/* Setup the arrays.*/
83
OctApiBt0CorrectPointers(bb);
85
/* Initialize the Nodes to unused!*/
86
for(i=0;i<number_of_items;i++)
88
bb->node[i].next_free_node = i + 1;
91
/* Last empty node points to invalid node.*/
92
bb->node[number_of_items-1].next_free_node = 0xFFFFFFFF;
94
bb->invalid_value = 0xFFFFFFFF;
95
bb->no_smaller_key = OCTAPI_BT0_NO_SMALLER_KEY;
102
#if !SKIP_OctApiBt0CorrectPointers
103
void OctApiBt0CorrectPointers(OCTAPI_BT0 * bb)
105
bb->node = (OCTAPI_BT0_NODE *)(((BYTE *)bb) + sizeof(OCTAPI_BT0));
106
bb->key = (UINT32 *)(((BYTE *)bb->node) + (sizeof(OCTAPI_BT0_NODE) * bb->number_of_items));
107
bb->data = (UINT32 *)(((BYTE *)bb->key) + (sizeof(UINT32) * bb->number_of_items * bb->key_size));
112
#if !SKIP_OctApiBt0AddNode
113
UINT32 OctApiBt0AddNode(void * b,void * key,void ** data)
116
OCTAPI_BT0_NODE * new_node;
120
UINT32 new_node_number;
124
bb = (OCTAPI_BT0 *)(b);
125
OctApiBt0CorrectPointers(bb);
127
/* Check that there is at least one block left.*/
128
if (bb->next_free_node == 0xFFFFFFFF) return(OCTAPI_BT0_NO_NODES_AVAILABLE);
131
new_node_number = bb->next_free_node;
132
new_node = &(bb->node[new_node_number]);
133
bb->next_free_node = new_node->next_free_node;
135
/* Register in the key and the data.*/
136
lkey = ((UINT32 *)key);
138
/* Find the first UINT32 of the key.*/
139
nkey = &(bb->key[bb->key_size * new_node_number]);
142
for(i=0;i<bb->key_size;i++)
145
/* Attempt to place the node. Only a "multiple hit" will cause an error.*/
146
result = OctApiBt0AddNode2(bb,&(bb->root_link), lkey, new_node_number);
147
if (result != GENERIC_OK)
149
/* This attempt failed. Refree the node!*/
150
bb->next_free_node = new_node_number;
152
/* Return the error code.*/
156
/* Return the address of the data to the user.*/
157
if ( bb->data_size > 0 )
158
*data = (void *)(&(bb->data[bb->data_size * new_node_number]));
164
#if !SKIP_OctApiBt0AddNode2
165
UINT32 OctApiBt0AddNode2(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link,UINT32 * lkey,UINT32 new_node_number)
169
if (link->node_number == 0xFFFFFFFF) /* We have an empty node. Here, we shall place the new node.*/
171
bb->node[new_node_number].l[0].node_number = 0xFFFFFFFF;
172
bb->node[new_node_number].l[0].depth = 0;
173
bb->node[new_node_number].l[1].node_number = 0xFFFFFFFF;
174
bb->node[new_node_number].l[1].depth = 0;
176
/* OCTAPI_BT0_LINK to parent!*/
177
link->node_number = new_node_number;
178
link->depth = 1; /* We are a leaf, last OCTAPI_BT0_LINK depth is 1.*/
182
else /* Current node is used, check for a match and a direction.*/
184
OCTAPI_BT0_NODE * this_node;
187
/* Get a pointer to this node.*/
188
this_node = &(bb->node[link->node_number]);
190
/* Compare this node to the lkey.*/
191
compare = OctApiBt0KeyCompare(bb,link,lkey);
193
if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/
195
result = OctApiBt0AddNode2(bb,&(this_node->l[0]), lkey, new_node_number);
196
if (result != GENERIC_OK) return(result);
198
else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/
200
result = OctApiBt0AddNode2(bb,&(this_node->l[1]), lkey, new_node_number);
201
if (result != GENERIC_OK) return(result);
205
return(OCTAPI_BT0_KEY_ALREADY_IN_TREE);
208
/* Check if this node is unbalanced by 2. If so, rebalance it:*/
209
if (this_node->l[0].depth > (this_node->l[1].depth + 1) ||
210
this_node->l[1].depth > (this_node->l[0].depth + 1))
212
OctApiBt0Rebalance(bb,link);
215
/* Always update the OCTAPI_BT0_LINK depth before exiting.*/
216
OctApiBt0UpdateLinkDepth(bb,link);
224
#if !SKIP_OctApiBt0AddNode3
225
UINT32 OctApiBt0AddNode3(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link,UINT32 * lkey,UINT32 *p_new_node_number)
229
if (link->node_number == 0xFFFFFFFF) /* We have an empty node. Here, we shall place the new node.*/
231
if ( *p_new_node_number == 0xFFFFFFFF )
232
return(OCTAPI_BT0_NO_NODES_AVAILABLE);
234
bb->node[*p_new_node_number].l[0].node_number = 0xFFFFFFFF;
235
bb->node[*p_new_node_number].l[0].depth = 0;
236
bb->node[*p_new_node_number].l[1].node_number = 0xFFFFFFFF;
237
bb->node[*p_new_node_number].l[1].depth = 0;
239
/* OCTAPI_BT0_LINK to parent!*/
240
link->node_number = *p_new_node_number;
241
link->depth = 1; /* We are a leaf, last OCTAPI_BT0_LINK depth is 1.*/
245
else /* Current node is used, check for a match and a direction.*/
247
OCTAPI_BT0_NODE * this_node;
250
/* Get a pointer to this node.*/
251
this_node = &(bb->node[link->node_number]);
253
/* Compare this node to the lkey.*/
254
compare = OctApiBt0KeyCompare(bb,link,lkey);
256
if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/
258
result = OctApiBt0AddNode3(bb,&(this_node->l[0]), lkey, p_new_node_number);
259
if (result != GENERIC_OK) return(result);
261
else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/
263
result = OctApiBt0AddNode3(bb,&(this_node->l[1]), lkey, p_new_node_number);
264
if (result != GENERIC_OK) return(result);
268
*p_new_node_number = link->node_number;
269
return(OCTAPI_BT0_KEY_ALREADY_IN_TREE);
272
/* Check if this node is unbalanced by 2. If so, rebalance it:*/
273
if (this_node->l[0].depth > (this_node->l[1].depth + 1) ||
274
this_node->l[1].depth > (this_node->l[0].depth + 1))
276
OctApiBt0Rebalance(bb,link);
279
/* Always update the OCTAPI_BT0_LINK depth before exiting.*/
280
OctApiBt0UpdateLinkDepth(bb,link);
288
0 -> first call to the function.
289
1 -> recursive call.*/
290
#if !SKIP_OctApiBt0AddNode4
291
UINT32 OctApiBt0AddNode4(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link,UINT32 * lkey,UINT32 *p_new_node_number, UINT32 *p_prev_node_number, UINT32 state )
297
if (link->node_number == 0xFFFFFFFF) /* We have an empty node. Here, we shall place the new node.*/
299
bb->node[*p_new_node_number].l[0].node_number = 0xFFFFFFFF;
300
bb->node[*p_new_node_number].l[0].depth = 0;
301
bb->node[*p_new_node_number].l[1].node_number = 0xFFFFFFFF;
302
bb->node[*p_new_node_number].l[1].depth = 0;
304
/* OCTAPI_BT0_LINK to parent!*/
305
link->node_number = *p_new_node_number;
306
link->depth = 1; /* We are a leaf, last OCTAPI_BT0_LINK depth is 1.*/
309
*p_prev_node_number = 0xFFFFFFFF;
313
else /* Current node is used, check for a match and a direction.*/
315
OCTAPI_BT0_NODE * this_node;
318
/* Get a pointer to this node.*/
319
this_node = &(bb->node[link->node_number]);
321
/* Compare this node to the lkey.*/
322
compare = OctApiBt0KeyCompare(bb,link,lkey);
324
if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/
327
*p_prev_node_number = OCTAPI_BT0_NO_SMALLER_KEY;
329
if ( *p_prev_node_number != OCTAPI_BT0_NO_SMALLER_KEY )
331
/* Check if the key is the smallest one encountered yet.*/
332
okey = &(bb->key[bb->key_size * (*p_prev_node_number)]);
333
nkey = &(bb->key[bb->key_size * link->node_number]);
334
/* If the node is key smaller then the old small one, change the value.*/
338
*p_prev_node_number = link->node_number;
342
result = OctApiBt0AddNode4(bb,&(this_node->l[0]), lkey, p_new_node_number, p_prev_node_number, 1);
343
if (result != GENERIC_OK) return(result);
345
else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/
348
*p_prev_node_number = link->node_number;
351
if ( *p_prev_node_number == OCTAPI_BT0_NO_SMALLER_KEY )
352
*p_prev_node_number = link->node_number;
355
/* Check if the key is the smallest one encountered yet.*/
356
okey = &(bb->key[bb->key_size * (*p_prev_node_number)]);
357
nkey = &(bb->key[bb->key_size * link->node_number]);
358
/* If the node is key smaller then the old small one, change the value.*/
362
*p_prev_node_number = link->node_number;
367
result = OctApiBt0AddNode4(bb,&(this_node->l[1]), lkey, p_new_node_number, p_prev_node_number, 1);
368
if (result != GENERIC_OK) return(result);
372
*p_new_node_number = link->node_number;
373
return(OCTAPI_BT0_KEY_ALREADY_IN_TREE);
376
/* Check if this node is unbalanced by 2. If so, rebalance it:*/
377
if (this_node->l[0].depth > (this_node->l[1].depth + 1) ||
378
this_node->l[1].depth > (this_node->l[0].depth + 1))
380
OctApiBt0Rebalance(bb,link);
383
/* Always update the OCTAPI_BT0_LINK depth before exiting.*/
384
OctApiBt0UpdateLinkDepth(bb,link);
391
#if !SKIP_OctApiBt0KeyCompare
392
UINT32 OctApiBt0KeyCompare(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link, UINT32 * lkey)
397
/* Find the first UINT32 of the key.*/
398
nkey = &(bb->key[bb->key_size * link->node_number]);
400
for(i=0;i<bb->key_size;i++)
402
if (lkey[i] < nkey[i])
403
return(OCTAPI_BT0_LKEY_SMALLER);
404
else if (lkey[i] > nkey[i])
405
return(OCTAPI_BT0_LKEY_LARGER);
408
return(OCTAPI_BT0_LKEY_EQUAL);
413
#if !SKIP_OctApiBt0UpdateLinkDepth
414
void OctApiBt0UpdateLinkDepth(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link)
416
OCTAPI_BT0_NODE * this_node;
418
/* Get a pointer to this node.*/
419
this_node = &(bb->node[link->node_number]);
421
if (this_node->l[0].depth > this_node->l[1].depth)
422
link->depth = this_node->l[0].depth + 1;
424
link->depth = this_node->l[1].depth + 1;
428
#if !SKIP_OctApiBt0Rebalance
429
void OctApiBt0Rebalance(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * root_link)
431
if (bb->node[root_link->node_number].l[0].depth > (bb->node[root_link->node_number].l[1].depth + 1)) /* Heavy to the left.*/
433
/* Check if the right child of the heavy child node is causing a problem.*/
434
/* If so, do a left rotate in order to make the left most child the longer one.*/
436
OCTAPI_BT0_LINK * heavy_link;
437
heavy_link = &(bb->node[root_link->node_number].l[0]);
439
if (bb->node[heavy_link->node_number].l[1].depth > bb->node[heavy_link->node_number].l[0].depth)
441
OctApiBt0ExternalHeavy(bb,heavy_link);
445
/* Ready to do super rotation!*/
447
OCTAPI_BT0_LINK init_root_link;
448
OCTAPI_BT0_LINK init_heavy_link;
449
OCTAPI_BT0_LINK init_leaf_tree[3];
451
/* Save pertinent initial OCTAPI_BT0_LINK information.*/
452
init_root_link = *root_link;
453
init_heavy_link = bb->node[root_link->node_number].l[0];
454
init_leaf_tree[2] = bb->node[root_link->node_number].l[1];
455
init_leaf_tree[0] = bb->node[bb->node[root_link->node_number].l[0].node_number].l[0];
456
init_leaf_tree[1] = bb->node[bb->node[root_link->node_number].l[0].node_number].l[1];
458
/* Restructure the tree.*/
459
*root_link = init_heavy_link;
460
bb->node[init_heavy_link.node_number].l[1] = init_root_link;
461
bb->node[init_root_link.node_number].l[0] = init_leaf_tree[1];
463
/* Reconstruct the depth of the branches.*/
464
OctApiBt0UpdateLinkDepth(bb,&(bb->node[root_link->node_number].l[1]));
465
OctApiBt0UpdateLinkDepth(bb,root_link);
468
else if (bb->node[root_link->node_number].l[1].depth > (bb->node[root_link->node_number].l[0].depth + 1)) /* Heavy to the right.*/
470
/* Check if the right child of the heavy child node is causing a problem.*/
471
/* If so, do a left rotate in order to make the left most child the longer one.*/
473
OCTAPI_BT0_LINK * heavy_link;
474
heavy_link = &(bb->node[root_link->node_number].l[1]);
476
if (bb->node[heavy_link->node_number].l[0].depth > bb->node[heavy_link->node_number].l[1].depth)
478
OctApiBt0ExternalHeavy(bb,heavy_link);
482
/* Ready to do super rotation!*/
484
OCTAPI_BT0_LINK init_root_link;
485
OCTAPI_BT0_LINK init_heavy_link;
486
OCTAPI_BT0_LINK init_leaf_tree[3];
488
/* Save pertinent initial OCTAPI_BT0_LINK information.*/
489
init_root_link = *root_link;
490
init_heavy_link = bb->node[root_link->node_number].l[1];
491
init_leaf_tree[2] = bb->node[root_link->node_number].l[0];
492
init_leaf_tree[0] = bb->node[bb->node[root_link->node_number].l[1].node_number].l[1];
493
init_leaf_tree[1] = bb->node[bb->node[root_link->node_number].l[1].node_number].l[0];
495
/* Restructure the tree.*/
496
*root_link = init_heavy_link;
497
bb->node[init_heavy_link.node_number].l[0] = init_root_link;
498
bb->node[init_root_link.node_number].l[1] = init_leaf_tree[1];
500
/* Reconstruct the depth of the branches.*/
501
OctApiBt0UpdateLinkDepth(bb,&(bb->node[root_link->node_number].l[0]));
502
OctApiBt0UpdateLinkDepth(bb,root_link);
508
/* This function does a rotation towards the outside of the tree*/
509
/* in order to keep the heavy branches towards the outside.*/
510
#if !SKIP_OctApiBt0ExternalHeavy
511
void OctApiBt0ExternalHeavy(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * root_link)
513
if (bb->node[root_link->node_number].l[1].depth > bb->node[root_link->node_number].l[0].depth) /* Exterior of tree is towards the left.*/
515
OCTAPI_BT0_LINK init_root_link;
516
OCTAPI_BT0_LINK init_heavy_link;
517
OCTAPI_BT0_LINK init_leaf_tree[3];
519
/* Save pertinent initial OCTAPI_BT0_LINK information.*/
520
init_root_link = *root_link;
521
init_leaf_tree[0] = bb->node[root_link->node_number].l[0];
522
init_heavy_link = bb->node[root_link->node_number].l[1];
523
init_leaf_tree[1] = bb->node[bb->node[root_link->node_number].l[1].node_number].l[0];
524
init_leaf_tree[2] = bb->node[bb->node[root_link->node_number].l[1].node_number].l[1];
526
/* Restructure the tree.*/
527
*root_link = init_heavy_link;
528
bb->node[init_heavy_link.node_number].l[0] = init_root_link;
529
bb->node[init_root_link.node_number].l[1] = init_leaf_tree[1];
531
/* Reconstruct the depth of the branches.*/
532
OctApiBt0UpdateLinkDepth(bb,&(bb->node[root_link->node_number].l[0]));
533
OctApiBt0UpdateLinkDepth(bb,root_link);
535
else if (bb->node[root_link->node_number].l[0].depth > bb->node[root_link->node_number].l[1].depth) /* Exterior of tree is towards the right.*/
537
OCTAPI_BT0_LINK init_root_link;
538
OCTAPI_BT0_LINK init_heavy_link;
539
OCTAPI_BT0_LINK init_leaf_tree[3];
541
/* Save pertinent initial OCTAPI_BT0_LINK information.*/
542
init_root_link = *root_link;
543
init_leaf_tree[0] = bb->node[root_link->node_number].l[1];
544
init_heavy_link = bb->node[root_link->node_number].l[0];
545
init_leaf_tree[1] = bb->node[bb->node[root_link->node_number].l[0].node_number].l[1];
546
init_leaf_tree[2] = bb->node[bb->node[root_link->node_number].l[0].node_number].l[0];
548
/* Restructure the tree.*/
549
*root_link = init_heavy_link;
550
bb->node[init_heavy_link.node_number].l[1] = init_root_link;
551
bb->node[init_root_link.node_number].l[0] = init_leaf_tree[1];
553
/* Reconstruct the depth of the branches.*/
554
OctApiBt0UpdateLinkDepth(bb,&(bb->node[root_link->node_number].l[1]));
555
OctApiBt0UpdateLinkDepth(bb,root_link);
562
/* 0 = seeking node to be removed.*/
563
/* 1 = node found, left branch taken.*/
564
/* 2 = node found, right branch taken.*/
565
#if !SKIP_OctApiBt0RemoveNode2
566
UINT32 OctApiBt0RemoveNode2(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link, UINT32 * lkey, OCTAPI_BT0_LINK * link_to_removed_node, UINT32 state, OCTAPI_BT0_LINK * volatile_grandparent_link)
569
OCTAPI_BT0_NODE * this_node;
571
/* Get a pointer to this node.*/
572
this_node = &(bb->node[link->node_number]);
576
if (link->node_number == 0xFFFFFFFF) /* We have an empty node. The node we were looking for does not exist.*/
578
return(OCTAPI_BT0_KEY_NOT_IN_TREE);
580
else /* Current node is used, check for a match and a direction.*/
584
/* Compare this node to the lkey.*/
585
compare = OctApiBt0KeyCompare(bb,link,lkey);
587
if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/
589
result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[0]), lkey, link_to_removed_node, 0, NULL);
590
if (result != GENERIC_OK) return(result);
592
else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/
594
result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[1]), lkey, link_to_removed_node, 0, NULL);
595
if (result != GENERIC_OK) return(result);
599
link_to_removed_node = link;
601
/* Keep on going down to find a replacement node.*/
602
if (bb->node[link->node_number].l[0].node_number == 0xFFFFFFFF && bb->node[link->node_number].l[1].node_number == 0xFFFFFFFF)
604
/* Doe! No tree left! WHAT TO DO? */
605
/* Just delete the current node. That's it.*/
607
/* Release the current node (restore free node link-list)*/
608
bb->node[link->node_number].next_free_node = bb->next_free_node;
609
bb->next_free_node = link->node_number;
611
link->node_number = 0xFFFFFFFF;
616
else if (bb->node[link->node_number].l[0].node_number != 0xFFFFFFFF) /* Left node is present. Go left, then permanently right.*/
618
OCTAPI_BT0_NODE * removed_node_pnt;
619
removed_node_pnt = &(bb->node[link->node_number]);
621
result = OctApiBt0RemoveNode2(bb,&(removed_node_pnt->l[0]), lkey, link_to_removed_node, 1, link);
622
if (result != GENERIC_OK) return(result);
624
/* Caution! Once we are here, the link->node_pnt->l[0] has been modified,*/
625
/* but is about to be discarded! Save it quickly!*/
626
/* bb->node[link->node_number].l[0] = removed_node_pnt->l[0];*/
628
else /* Right node is present. Go right, then permanently left.*/
630
OCTAPI_BT0_NODE * removed_node_pnt;
631
removed_node_pnt = &(bb->node[link->node_number]);
633
result = OctApiBt0RemoveNode2(bb,&(removed_node_pnt->l[1]), lkey, link_to_removed_node, 2, link);
634
if (result != GENERIC_OK) return(result);
636
/* Caution! Once we are here, the link->node_pnt->l[0] has been modified,*/
637
/* but is about to be discarded! Save it quickly!*/
638
/* bb->node[link->node_number].l[1] = removed_node_pnt->l[1];*/
645
/* Left side, Right-most node found! OR*/
646
/* Right side, Left-most node found!*/
647
if ((state == 1 && bb->node[link->node_number].l[1].node_number == 0xFFFFFFFF) ||
648
(state == 2 && bb->node[link->node_number].l[0].node_number == 0xFFFFFFFF))
650
OCTAPI_BT0_LINK init_chosen_link;
652
/* Release the current node (restore free node link-list)*/
653
bb->node[link_to_removed_node->node_number].next_free_node = bb->next_free_node;
654
bb->next_free_node = link_to_removed_node->node_number;
656
/* Save the link to the chosen node, because it is about to be deleted.*/
657
init_chosen_link = *link;
659
/* Remove this node, and allow the tree to go on:*/
661
OCTAPI_BT0_LINK init_child_link[2];
663
init_child_link[0] = bb->node[link->node_number].l[0];
664
init_child_link[1] = bb->node[link->node_number].l[1];
667
*link = init_child_link[0];
669
*link = init_child_link[1];
672
/* Replace the removed node by this node.*/
674
OCTAPI_BT0_LINK init_removed_child_link[2];
676
init_removed_child_link[0] = bb->node[link_to_removed_node->node_number].l[0];
677
init_removed_child_link[1] = bb->node[link_to_removed_node->node_number].l[1];
679
*link_to_removed_node = init_chosen_link;
680
bb->node[init_chosen_link.node_number].l[0] = init_removed_child_link[0];
681
bb->node[init_chosen_link.node_number].l[1] = init_removed_child_link[1];
688
/* Keep on going, we have not found the center most node yet!*/
691
result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[1]), lkey, link_to_removed_node, state, NULL);
692
if (result != GENERIC_OK) return(result);
694
/* Refresh the link if our link is volatile.*/
695
if (volatile_grandparent_link != NULL)
697
link = &(bb->node[volatile_grandparent_link->node_number].l[0]);
702
result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[0]), lkey, link_to_removed_node, state, NULL);
703
if (result != GENERIC_OK) return(result);
705
/* Refresh the link if our link is volatile.*/
706
if (volatile_grandparent_link != NULL)
708
link = &(bb->node[volatile_grandparent_link->node_number].l[1]);
714
/* We may have messed up the tree. So patch it!*/
715
/* Check if this node is unbalanced by 2. If so, rebalance it:*/
716
if (this_node->l[0].depth > (this_node->l[1].depth + 1) ||
717
this_node->l[1].depth > (this_node->l[0].depth + 1))
719
OctApiBt0Rebalance(bb,link);
722
/* Always update the OCTAPI_BT0_LINK depth before exiting.*/
723
OctApiBt0UpdateLinkDepth(bb,link);
731
/* 0 = seeking node to be removed.*/
732
/* 1 = node found, left branch taken.*/
733
/* 2 = node found, right branch taken.*/
734
#if !SKIP_OctApiBt0RemoveNode3
735
UINT32 OctApiBt0RemoveNode3(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link, UINT32 * lkey, OCTAPI_BT0_LINK * link_to_removed_node, UINT32 state, OCTAPI_BT0_LINK * volatile_grandparent_link, UINT32 *p_prev_node_number )
740
OCTAPI_BT0_NODE * this_node;
742
/* Get a pointer to this node.*/
743
this_node = &(bb->node[link->node_number]);
747
if (link->node_number == 0xFFFFFFFF) /* We have an empty node. The node we were looking for does not exist.*/
749
return(OCTAPI_BT0_KEY_NOT_IN_TREE);
751
else /* Current node is used, check for a match and a direction.*/
755
/* Compare this node to the lkey.*/
756
compare = OctApiBt0KeyCompare(bb,link,lkey);
758
if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/
760
/* Check if the key is the biggest one encountered yet.*/
761
okey = &(bb->key[bb->key_size * (*p_prev_node_number)]);
762
nkey = &(bb->key[bb->key_size * link->node_number]);
763
/* If the node is key bigger then the old one, change the value.*/
767
*p_prev_node_number = link->node_number;
770
result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[0]), lkey, link_to_removed_node, 0, NULL);
771
if (result != GENERIC_OK) return(result);
773
else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/
775
/* Check if the key is the biggest one encountered yet.*/
776
okey = &(bb->key[bb->key_size * (*p_prev_node_number)]);
777
nkey = &(bb->key[bb->key_size * link->node_number]);
778
/* If the node is key bigger then the old one, change the value.*/
782
*p_prev_node_number = link->node_number;
785
result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[1]), lkey, link_to_removed_node, 0, NULL);
786
if (result != GENERIC_OK) return(result);
790
link_to_removed_node = link;
792
/* Keep on going down to find a replacement node.*/
793
if (bb->node[link->node_number].l[0].node_number == 0xFFFFFFFF && bb->node[link->node_number].l[1].node_number == 0xFFFFFFFF)
795
/* Doe! No tree left! WHAT TO DO? */
796
/* Just delete the current node. That's it.*/
798
/* Release the current node (restore free node link-list)*/
799
bb->node[link->node_number].next_free_node = bb->next_free_node;
800
bb->next_free_node = link->node_number;
802
link->node_number = 0xFFFFFFFF;
807
else if (bb->node[link->node_number].l[0].node_number != 0xFFFFFFFF) /* Left node is present. Go left, then permanently right.*/
809
OCTAPI_BT0_NODE * removed_node_pnt;
810
removed_node_pnt = &(bb->node[link->node_number]);
812
result = OctApiBt0RemoveNode2(bb,&(removed_node_pnt->l[0]), lkey, link_to_removed_node, 1, link);
813
if (result != GENERIC_OK) return(result);
815
/* Caution! Once we are here, the link->node_pnt->l[0] has been modified,*/
816
/* but is about to be discarded! Save it quickly!*/
817
/* bb->node[link->node_number].l[0] = removed_node_pnt->l[0];*/
819
else /* Right node is present. Go right, then permanently left.*/
821
OCTAPI_BT0_NODE * removed_node_pnt;
822
removed_node_pnt = &(bb->node[link->node_number]);
824
result = OctApiBt0RemoveNode2(bb,&(removed_node_pnt->l[1]), lkey, link_to_removed_node, 2, link);
825
if (result != GENERIC_OK) return(result);
827
/* Caution! Once we are here, the link->node_pnt->l[0] has been modified,*/
828
/* but is about to be discarded! Save it quickly!*/
829
/* bb->node[link->node_number].l[1] = removed_node_pnt->l[1];*/
836
/* Check if the key is the biggest one encountered yet.*/
837
okey = &(bb->key[bb->key_size * (*p_prev_node_number)]);
838
nkey = &(bb->key[bb->key_size * link->node_number]);
839
/* If the node is key bigger then the old one, change the value.*/
843
*p_prev_node_number = link->node_number;
846
/* Left side, Right-most node found! OR*/
847
/* Right side, Left-most node found!*/
848
if ((state == 1 && bb->node[link->node_number].l[1].node_number == 0xFFFFFFFF) ||
849
(state == 2 && bb->node[link->node_number].l[0].node_number == 0xFFFFFFFF))
851
OCTAPI_BT0_LINK init_chosen_link;
853
/* Release the current node (restore free node link-list)*/
854
bb->node[link_to_removed_node->node_number].next_free_node = bb->next_free_node;
855
bb->next_free_node = link_to_removed_node->node_number;
857
/* Save the link to the chosen node, because it is about to be deleted.*/
858
init_chosen_link = *link;
860
/* Remove this node, and allow the tree to go on:*/
862
OCTAPI_BT0_LINK init_child_link[2];
864
init_child_link[0] = bb->node[link->node_number].l[0];
865
init_child_link[1] = bb->node[link->node_number].l[1];
868
*link = init_child_link[0];
870
*link = init_child_link[1];
873
/* Replace the removed node by this node.*/
875
OCTAPI_BT0_LINK init_removed_child_link[2];
877
init_removed_child_link[0] = bb->node[link_to_removed_node->node_number].l[0];
878
init_removed_child_link[1] = bb->node[link_to_removed_node->node_number].l[1];
880
*link_to_removed_node = init_chosen_link;
881
bb->node[init_chosen_link.node_number].l[0] = init_removed_child_link[0];
882
bb->node[init_chosen_link.node_number].l[1] = init_removed_child_link[1];
889
/* Keep on going, we have not found the center most node yet!*/
892
result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[1]), lkey, link_to_removed_node, state, NULL);
893
if (result != GENERIC_OK) return(result);
895
/* Refresh the link if our link is volatile.*/
896
if (volatile_grandparent_link != NULL)
898
link = &(bb->node[volatile_grandparent_link->node_number].l[0]);
903
result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[0]), lkey, link_to_removed_node, state, NULL);
904
if (result != GENERIC_OK) return(result);
906
/* Refresh the link if our link is volatile.*/
907
if (volatile_grandparent_link != NULL)
909
link = &(bb->node[volatile_grandparent_link->node_number].l[1]);
915
/* We may have messed up the tree. So patch it!*/
916
/* Check if this node is unbalanced by 2. If so, rebalance it:*/
917
if (this_node->l[0].depth > (this_node->l[1].depth + 1) ||
918
this_node->l[1].depth > (this_node->l[0].depth + 1))
920
OctApiBt0Rebalance(bb,link);
923
/* Always update the OCTAPI_BT0_LINK depth before exiting.*/
924
OctApiBt0UpdateLinkDepth(bb,link);
930
#if !SKIP_OctApiBt0RemoveNode
931
UINT32 OctApiBt0RemoveNode(void * b,void * key)
938
bb = (OCTAPI_BT0 *)(b);
939
OctApiBt0CorrectPointers(bb);
941
/* Register in the key and the data.*/
942
lkey = ((UINT32 *)key);
944
/* Attempt to remove the node. Only a "no hit" will cause an error.*/
945
result = OctApiBt0RemoveNode2(bb,&(bb->root_link), lkey, NULL, 0, NULL);
946
if (result != GENERIC_OK) return(result);
952
#if !SKIP_OctApiBt0QueryNode2
953
UINT32 OctApiBt0QueryNode2(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link,UINT32 * lkey,UINT32 * node_number)
957
if (link->node_number == 0xFFFFFFFF) /* We have an empty node. The node we were looking for does not exist.*/
959
return(OCTAPI_BT0_KEY_NOT_IN_TREE);
961
else /* Current node is used, check for a match and a direction.*/
965
/* Compare this node to the lkey.*/
966
compare = OctApiBt0KeyCompare(bb,link,lkey);
968
if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/
970
result = OctApiBt0QueryNode2(bb,&(bb->node[link->node_number].l[0]), lkey, node_number);
971
if (result != GENERIC_OK) return(result);
973
else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/
975
result = OctApiBt0QueryNode2(bb,&(bb->node[link->node_number].l[1]), lkey, node_number);
976
if (result != GENERIC_OK) return(result);
981
*node_number = link->node_number;
990
#if !SKIP_OctApiBt0QueryNode
991
UINT32 OctApiBt0QueryNode(void * b,void * key,void ** data)
999
bb = (OCTAPI_BT0 *)(b);
1000
OctApiBt0CorrectPointers(bb);
1002
/* Register in the key and the data.*/
1003
lkey = ((UINT32 *)key);
1005
/* Get the node number.*/
1006
result = OctApiBt0QueryNode2(bb,&(bb->root_link),lkey,&node_number);
1007
if (result != GENERIC_OK) return(result);
1009
/* Return the address of the data to the user.*/
1010
if ( bb->data_size > 0 )
1011
*data = (void *)(&(bb->data[bb->data_size * node_number]));
1017
#if !SKIP_OctApiBt0GetFirstNode
1018
UINT32 OctApiBt0GetFirstNode(void * b,void ** key, void ** data)
1021
OCTAPI_BT0_NODE * node;
1026
bb = (OCTAPI_BT0 *)(b);
1027
OctApiBt0CorrectPointers(bb);
1029
/* Register in the key and the data.*/
1030
lkey = ((UINT32 *)key);
1032
/* Check if there are any keys present in the tree. */
1033
if (bb->root_link.node_number == 0xFFFFFFFF) return OCTAPI_BT0_NO_NODES_AVAILABLE;
1035
node_number = bb->root_link.node_number;
1036
node = &bb->node[node_number];
1038
/* Make our way down to the left-most node. */
1039
while (node->l[0].node_number != 0xFFFFFFFF)
1041
node_number = node->l[0].node_number;
1042
node = &bb->node[node_number];
1045
/* Return the address of the data to the user.*/
1046
if ( bb->key_size > 0 )
1047
*key = (void *)(&(bb->key[bb->key_size * node_number]));
1049
if ( bb->data_size > 0 )
1050
*data = (void *)(&(bb->data[bb->data_size * node_number]));
1056
#if !SKIP_OctApiBt0FindOrAddNode
1057
UINT32 OctApiBt0FindOrAddNode(void * b,void * key,void ** data, UINT32 *fnct_result)
1060
OCTAPI_BT0_NODE * new_node;
1064
UINT32 new_node_number;
1065
UINT32 temp_node_number = 0;
1067
UINT32 tree_already_full = FALSE;
1070
bb = (OCTAPI_BT0 *)(b);
1071
OctApiBt0CorrectPointers(bb);
1073
/* Seize the node!*/
1074
new_node_number = bb->next_free_node;
1075
/* Register in the key and the data.*/
1076
lkey = ((UINT32 *)key);
1078
/* Check that there is at least one block left.*/
1079
if (bb->next_free_node != 0xFFFFFFFF)
1082
temp_node_number = new_node_number;
1083
new_node = &(bb->node[new_node_number]);
1084
bb->next_free_node = new_node->next_free_node;
1086
/* Find the first UINT32 of the key.*/
1087
nkey = &(bb->key[bb->key_size * new_node_number]);
1090
for(i=0;i<bb->key_size;i++)
1094
tree_already_full = TRUE; /* Signal that the tree was already full when the function was called.*/
1096
/* Attempt to place the node. Only a "multiple hit" will cause an error.*/
1097
result = OctApiBt0AddNode3(bb,&(bb->root_link), lkey, &new_node_number);
1101
*fnct_result = OCTAPI0_BT0_NODE_ADDDED;
1103
case OCTAPI_BT0_KEY_ALREADY_IN_TREE:
1104
*fnct_result = OCTAPI0_BT0_NODE_FOUND;
1105
/* This attempt did not add a new node. Refree the node!*/
1106
if ( tree_already_full == FALSE )
1107
bb->next_free_node = temp_node_number;
1108
result = GENERIC_OK;
1114
if (result != GENERIC_OK)
1116
/* This attempt failed. Refree the node!*/
1117
if ( tree_already_full == FALSE )
1118
bb->next_free_node = new_node_number;
1120
/* Return the error code.*/
1124
/* Return the address of the data to the user.*/
1125
if ( bb->data_size > 0 )
1126
*data = (void *)(&(bb->data[bb->data_size * new_node_number]));
1133
#if !SKIP_OctApiBt0AddNodeReportPrevNodeData
1134
UINT32 OctApiBt0AddNodeReportPrevNodeData(void * b,void * key,void ** data, void ** prev_data, PUINT32 fnct_result )
1137
OCTAPI_BT0_NODE * new_node;
1141
UINT32 new_node_number;
1142
UINT32 temp_node_number;
1143
UINT32 prev_node_number;
1147
bb = (OCTAPI_BT0 *)(b);
1148
OctApiBt0CorrectPointers(bb);
1150
/* Check that there is at least one block left.*/
1151
if (bb->next_free_node == 0xFFFFFFFF) return(OCTAPI_BT0_NO_NODES_AVAILABLE);
1153
/* Seize the node!*/
1154
new_node_number = bb->next_free_node;
1155
temp_node_number = new_node_number;
1156
new_node = &(bb->node[new_node_number]);
1157
bb->next_free_node = new_node->next_free_node;
1159
/* Set the previous node value */
1160
prev_node_number = 0xFFFFFFFF;
1162
/* Register in the key and the data.*/
1163
lkey = ((UINT32 *)key);
1165
/* Find the first UINT32 of the key.*/
1166
nkey = &(bb->key[bb->key_size * new_node_number]);
1169
for(i=0;i<bb->key_size;i++)
1172
/* Attempt to place the node. Only a "multiple hit" will cause an error.*/
1173
result = OctApiBt0AddNode4(bb,&(bb->root_link), lkey, &new_node_number, &prev_node_number, 0);
1177
*fnct_result = OCTAPI0_BT0_NODE_ADDDED;
1179
case OCTAPI_BT0_KEY_ALREADY_IN_TREE:
1180
*fnct_result = OCTAPI0_BT0_NODE_FOUND;
1181
/* This attempt did not add a new node. Refree the node!*/
1182
bb->next_free_node = temp_node_number;
1183
result = GENERIC_OK;
1189
if (result != GENERIC_OK)
1191
/* This attempt failed. Refree the node!*/
1192
bb->next_free_node = new_node_number;
1194
/* Return the error code.*/
1198
/* Return the address of the data to the user.*/
1199
if ( bb->data_size > 0 )
1200
*data = (void *)(&(bb->data[bb->data_size * new_node_number]));
1202
if ( bb->data_size > 0 )
1204
if ( (prev_node_number != 0xFFFFFFFF) &&
1205
(prev_node_number != OCTAPI_BT0_NO_SMALLER_KEY) &&
1206
(*fnct_result == OCTAPI0_BT0_NODE_ADDDED))
1207
*prev_data = ( void* )(&(bb->data[bb->data_size * prev_node_number]));
1208
else if ( prev_node_number == 0xFFFFFFFF )
1209
*prev_data = ( void* )(&bb->invalid_value);
1210
else if ( prev_node_number == OCTAPI_BT0_NO_SMALLER_KEY )
1211
*prev_data = ( void* )(&bb->no_smaller_key);