Initial revision 6759
[qball-mpd.git] / src / tree.c
blob87028d744b785d5317b82f63969dc5d509231a3a
1 /* the Music Player Daemon (MPD)
2 * Copyright (C) 2006-2007 by Warren Dukes (warren.dukes@gmail.com)
3 * This project's homepage is: http://www.musicpd.org
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
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 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "tree.h"
20 #include "utils.h"
22 #include <assert.h>
23 #include <stdlib.h>
24 #include <string.h>
26 #ifndef CHILDREN_PER_NODE
27 #define CHILDREN_PER_NODE 25
28 #endif
30 #define DATA_PER_NODE (CHILDREN_PER_NODE-1)
32 #if CHILDREN_PER_NODE > 7
33 #define USE_BINARY_SEARCH 1
34 #endif
37 /************************* DATA STRUCTURES **********************************/
39 struct _TreeNode
41 TreeKeyData keyData[DATA_PER_NODE];
42 struct _TreeNode * parent;
43 short parentPos;
44 struct _TreeNode * children[CHILDREN_PER_NODE];
45 short count;
48 struct _Tree
50 TreeCompareKeyFunction compareKey;
51 TreeFreeFunction freeKey;
52 TreeFreeFunction freeData;
53 TreeNode * rootNode;
54 int size;
57 /************************* STATIC METHODS ***********************************/
59 static
60 TreeNode *
61 _MakeNode(void)
63 TreeNode * ret = xmalloc(sizeof(TreeNode));
64 memset(ret, 0, sizeof(TreeNode));
65 return ret;
68 static
69 void
70 _ClearKeyData(TreeKeyData * keyData)
72 memset(keyData, 0, sizeof(TreeKeyData));
75 static
76 int
77 _FindPosition(Tree * tree, TreeNode * node, void * key, int * pos)
79 #ifdef USE_BINARY_SEARCH
80 int low = 0;
81 int high = node->count;
82 int cmp = -1;
84 while (high > low)
86 int cur = (high + low) >> 1;
87 cmp = tree->compareKey(key, node->keyData[cur].key);
88 if (cmp > 0)
90 low = cur+1;
92 else if (cmp < 0)
94 high = cur;
96 else
98 low = cur;
99 break;
103 *pos = low;
104 return (cmp == 0);
105 #else
106 int i = 0;
107 int cmp = -1;
108 for (;
109 i < node->count &&
110 (cmp = tree->compareKey(key, node->keyData[i].key)) > 0;
111 i++);
112 *pos = i;
113 return (cmp == 0);
114 #endif
117 static
119 _Find(TreeIterator * iter, void * key)
121 while (1)
123 if (_FindPosition(iter->tree, iter->node, key, &iter->which))
125 iter->which++;
126 return 1;
129 if (iter->node->children[iter->which])
131 iter->node = iter->node->children[iter->which];
133 else
135 return 0;
140 static void _SetIteratorToRoot(Tree * tree, TreeIterator * iter)
142 iter->tree = tree;
143 iter->node = tree->rootNode;
144 iter->which = 0;
147 static
148 TreeNode *
149 _SplitNode(TreeNode * node)
151 TreeNode *newNode = _MakeNode();
152 int i = DATA_PER_NODE/2;
153 int j = 0;
155 assert(node->count == DATA_PER_NODE);
157 for (; i < DATA_PER_NODE; i++, j++)
159 newNode->keyData[j] = node->keyData[i];
160 newNode->children[j+1] = node->children[i+1];
161 if (newNode->children[j+1])
163 newNode->children[j+1]->parent = newNode;
164 newNode->children[j+1]->parentPos = j+1;
166 _ClearKeyData(&(node->keyData[i]));
167 node->children[i+1] = NULL;
169 newNode->count = (DATA_PER_NODE-DATA_PER_NODE/2);
170 node->count -= (DATA_PER_NODE-DATA_PER_NODE/2);
172 return newNode;
175 static
176 void
177 _InsertNodeAndData(Tree * tree,
178 TreeNode * node,
179 int pos,
180 TreeNode * newNode,
181 TreeKeyData keyData)
183 int j = node->count;
185 assert(node->count < DATA_PER_NODE);
187 for (; j > pos; j--)
189 node->keyData[j] = node->keyData[j-1];
190 node->children[j+1] = node->children[j];
191 if (node->children[j+1])
193 node->children[j+1]->parentPos = j+1;
197 node->keyData[pos] = keyData;
198 node->count++;
200 node->children[pos+1] = newNode;
201 if (newNode)
203 newNode->parent = node;
204 newNode->parentPos = pos+1;
208 static
209 TreeKeyData
210 _AddDataToSplitNodes(Tree * tree,
211 TreeNode * lessNode,
212 TreeNode * moreNode,
213 int pos,
214 TreeNode * newNode,
215 TreeKeyData keyData)
217 TreeKeyData retKeyData;
219 assert(moreNode->children[0] == NULL);
221 if (pos <= lessNode->count)
223 _InsertNodeAndData(tree, lessNode, pos, newNode, keyData);
224 lessNode->count--;
225 retKeyData = lessNode->keyData[lessNode->count];
226 _ClearKeyData(&(lessNode->keyData[lessNode->count]));
227 moreNode->children[0] =
228 lessNode->children[lessNode->count+1];
229 if (moreNode->children[0])
231 moreNode->children[0]->parent = moreNode;
232 moreNode->children[0]->parentPos = 0;
234 lessNode->children[lessNode->count+1] = NULL;
236 else
238 int j;
240 pos -= lessNode->count;
241 retKeyData = moreNode->keyData[0];
242 assert(!moreNode->children[0]);
244 for (j = 0; j < pos; j++)
246 moreNode->keyData[j] = moreNode->keyData[j+1];
247 moreNode->children[j] = moreNode->children[j+1];
248 if (moreNode->children[j])
250 moreNode->children[j]->parentPos = j;
254 moreNode->keyData[pos-1] = keyData;
255 moreNode->children[pos] = newNode;
256 if (newNode)
258 newNode->parent = moreNode;
259 newNode->parentPos = pos;
263 return retKeyData;
266 static
267 void
268 _InsertAt(TreeIterator * iter, TreeKeyData keyData)
270 TreeNode * node = iter->node;
271 TreeNode * insertNode = NULL;
272 int pos = iter->which;
274 while (node != NULL)
276 /* see if there's any NULL data in the current node */
277 if (node->count == DATA_PER_NODE)
279 /* no open data slots, split this node! */
280 TreeNode * newNode = _SplitNode(node);
282 /* insert data in split nodes */
283 keyData = _AddDataToSplitNodes(iter->tree,
284 node,
285 newNode,
286 pos,
287 insertNode,
288 keyData);
290 if (node->parent == NULL)
292 assert(node == iter->tree->rootNode);
293 iter->tree->rootNode = _MakeNode();
294 iter->tree->rootNode->children[0] = node;
295 node->parent = iter->tree->rootNode;
296 node->parentPos = 0;
297 iter->tree->rootNode->children[1] = newNode;
298 newNode->parent = iter->tree->rootNode;
299 newNode->parentPos = 1;
300 iter->tree->rootNode->keyData[0] = keyData;
301 iter->tree->rootNode->count = 1;
302 return;
305 pos = node->parentPos;
306 node = node->parent;
307 insertNode = newNode;
309 else
311 /* insert the data and newNode */
312 _InsertNodeAndData(iter->tree,
313 node,
314 pos,
315 insertNode,
316 keyData);
317 return;
322 static
323 void
324 _MergeNodes(TreeNode * lessNode, TreeNode * moreNode)
326 int i = 0;
327 int j = lessNode->count;
329 assert((lessNode->count + moreNode->count) <= DATA_PER_NODE);
330 assert(lessNode->children[j] == NULL);
332 for(; i < moreNode->count; i++,j++)
334 assert(!lessNode->children[j]);
335 lessNode->keyData[j] = moreNode->keyData[i];
336 lessNode->children[j] = moreNode->children[i];
337 if (lessNode->children[j])
339 lessNode->children[j]->parent = lessNode;
340 lessNode->children[j]->parentPos = j;
343 lessNode->children[j] = moreNode->children[i];
344 if (lessNode->children[j])
346 lessNode->children[j]->parent = lessNode;
347 lessNode->children[j]->parentPos = j;
349 lessNode->count += i;
351 free(moreNode);
354 static void _DeleteAt(TreeIterator * iter)
356 TreeNode * node = iter->node;
357 int pos = iter->which - 1;
358 TreeKeyData * keyData = &(node->keyData[pos]);
359 TreeKeyData keyDataToFree = *keyData;
360 int i;
363 /* find the least greater than data to fill the whole! */
364 if (node->children[pos+1])
366 TreeNode * child = node->children[++pos];
367 while (child->children[0])
369 pos = 0;
370 child = child->children[0];
373 *keyData = child->keyData[0];
374 keyData = &(child->keyData[0]);
375 node = child;
377 /* or the greatest lesser than data to fill the whole! */
378 else if (node->children[pos])
380 TreeNode * child = node->children[pos];
381 while (child->children[child->count])
383 pos = child->count;
384 child = child->children[child->count];
387 *keyData = child->keyData[child->count-1];
388 keyData = &(child->keyData[child->count-1]);
389 node = child;
391 else
393 pos = node->parentPos;
397 /* move data nodes over, we're at a leaf node, so we can ignore
398 children */
399 i = keyData - node->keyData;
400 for (; i < node->count-1; i++)
402 node->keyData[i] = node->keyData[i+1];
404 _ClearKeyData(&(node->keyData[--node->count]));
406 /* merge the nodes from the bottom up which have too few data */
407 while (node->count < (DATA_PER_NODE/2))
409 /* if we're not the root */
410 if (node->parent)
412 TreeNode ** child = &(node->parent->children[pos]);
413 assert(node->parent->children[pos] == node);
415 /* check siblings for extra data */
416 if (pos < node->parent->count &&
417 (*(child+1))->count > (DATA_PER_NODE/2))
419 child++;
420 node->keyData[node->count++] =
421 node->parent->keyData[pos];
422 node->children[node->count] =
423 (*child)->children[0];
424 if (node->children[node->count])
426 node->children[node->count]->
427 parent = node;
428 node->children[node->count]->
429 parentPos = node->count;
431 node->parent->keyData[pos] =
432 (*child)->keyData[0];
433 i = 0;
434 for(; i < (*child)->count-1; i++)
436 (*child)->keyData[i] =
437 (*child)->keyData[i+1];
438 (*child)->children[i] =
439 (*child)->children[i+1];
440 if ((*child)->children[i])
442 (*child)->children[i]->
443 parentPos = i;
446 (*child)->children[i] = (*child)->children[i+1];
447 if ((*child)->children[i])
449 (*child)->children[i]->parentPos = i;
451 (*child)->children[i+1] =NULL;
452 _ClearKeyData(&((*child)->keyData[i]));
453 (*child)->count--;
455 else if (pos > 0 &&
456 (*(child-1))->count>(DATA_PER_NODE/2))
458 child--;
459 i = node->count++;
460 for(; i > 0; i--)
462 node->keyData[i] = node->keyData[i-1];
463 node->children[i+1] = node->children[i];
464 if (node->children[i+1])
466 node->children[i+1]->parentPos =
467 i+1;
470 node->children[1] = node->children[0];
471 if (node->children[1])
473 node->children[1]->parentPos = 1;
475 node->keyData[0] = node->parent->keyData[pos-1];
476 node->children[0] =
477 (*child)->children[(*child)->count];
478 if (node->children[0])
480 node->children[0]->parent = node;
481 node->children[0]->parentPos = 0;
483 node->parent->keyData[pos-1] =
484 (*child)->keyData[(*child)->count-1];
485 (*child)->children[(*child)->count--] =
486 NULL;
487 _ClearKeyData(
488 &((*child)->keyData[(*child)->count]));
490 /* merge with one of our siblings */
491 else
493 if (pos < node->parent->count)
495 child++;
496 assert(*child);
498 node->keyData[node->count++] =
499 node->parent->keyData[pos];
501 _MergeNodes(node, *child);
503 else
505 assert(pos > 0);
506 child--;
507 assert(*child);
508 pos--;
510 (*child)->keyData[(*child)->count++] =
511 node->parent->keyData[pos];
513 _MergeNodes(*child, node);
514 node = *child;
517 i = pos;
518 for(; i < node->parent->count-1; i++)
520 node->parent->keyData[i] =
521 node->parent->keyData[i+1];
522 node->parent->children[i+1] =
523 node->parent->children[i+2];
524 if (node->parent->children[i+1])
526 node->parent->children[i+1]->
527 parentPos = i+1;
530 _ClearKeyData(&(node->parent->keyData[i]));
531 node->parent->children[i+1] = NULL;
532 node->parent->count--;
534 node = node->parent;
535 pos = node->parentPos;
538 /* this is a root node */
539 else
541 if (node->count == 0)
543 if (node->children[0])
545 node->children[0]->parent = NULL;
546 node->children[0]->parentPos = 0;
549 iter->tree->rootNode = node->children[0];
551 free(node);
554 break;
558 if (iter->tree->freeKey)
560 iter->tree->freeData(keyDataToFree.key);
562 if (iter->tree->freeData)
564 iter->tree->freeData(keyDataToFree.data);
568 /************************* PUBLIC METHODS ***********************************/
570 Tree *
571 MakeTree(TreeCompareKeyFunction compareKey,
572 TreeFreeFunction freeKey,
573 TreeFreeFunction freeData)
575 Tree * ret = xmalloc(sizeof(Tree));
576 ret->compareKey = compareKey;
577 ret->freeKey = freeKey;
578 ret->freeData = freeData;
579 ret->rootNode = _MakeNode();
580 ret->size = 0;
581 return ret;
584 void
585 FreeTree(Tree * tree)
587 assert(tree->rootNode == NULL);
588 free(tree);
592 GetTreeSize(Tree * tree)
594 return tree->size;
597 void SetTreeIteratorToBegin(Tree * tree, TreeIterator * iter)
599 _SetIteratorToRoot(tree, iter);
600 IncrementTreeIterator(iter);
603 int IsTreeIteratorAtEnd(const TreeIterator * iter)
605 return (iter->node == NULL);
608 void IncrementTreeIterator(TreeIterator * iter)
610 while(iter->node)
612 if (iter->node->children[iter->which])
614 iter->node = iter->node->children[iter->which];
615 iter->which = 0;
617 else
619 iter->which++;
622 while (iter->node && iter->which > iter->node->count)
624 iter->which = iter->node->parentPos + 1;
625 iter->node = iter->node->parent;
628 if (iter->node &&
629 iter->which > 0 && iter->which <= iter->node->count)
631 return;
636 TreeKeyData
637 GetTreeKeyData(TreeIterator * iter)
639 assert(iter->node &&
640 iter->which > 0 &&
641 iter->which <= iter->node->count);
642 return iter->node->keyData[iter->which-1];
646 InsertInTree(Tree * tree, void * key, void * data)
648 TreeKeyData keyData;
649 TreeIterator iter;
651 _SetIteratorToRoot(tree, &iter);
653 if (_Find(&iter, key))
655 return 0;
658 keyData.key = key;
659 keyData.data = data;
660 _InsertAt(&iter, keyData);
661 tree->size++;
663 return 1;
667 RemoveFromTreeByKey(Tree * tree, void * key)
669 TreeIterator iter;
670 _SetIteratorToRoot(tree, &iter);
672 if (_Find(&iter, key))
674 _DeleteAt(&iter);
675 tree->size--;
676 return 1;
679 return 0;
682 void
683 RemoveFromTreeByIterator(Tree * tree, TreeIterator * iter)
685 _DeleteAt(iter);
686 tree->size--;
690 FindInTree(Tree * tree, void * key, TreeIterator * iter)
692 TreeIterator i;
694 if (iter == NULL)
696 iter = &i;
699 _SetIteratorToRoot(tree, iter);
700 if (_Find(iter, key))
702 return 1;
705 return 0;