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
26 #ifndef CHILDREN_PER_NODE
27 #define CHILDREN_PER_NODE 25
30 #define DATA_PER_NODE (CHILDREN_PER_NODE-1)
32 #if CHILDREN_PER_NODE > 7
33 #define USE_BINARY_SEARCH 1
37 /************************* DATA STRUCTURES **********************************/
41 TreeKeyData keyData[DATA_PER_NODE];
42 struct _TreeNode * parent;
44 struct _TreeNode * children[CHILDREN_PER_NODE];
50 TreeCompareKeyFunction compareKey;
51 TreeFreeFunction freeKey;
52 TreeFreeFunction freeData;
57 /************************* STATIC METHODS ***********************************/
63 TreeNode * ret = xmalloc(sizeof(TreeNode));
64 memset(ret, 0, sizeof(TreeNode));
70 _ClearKeyData(TreeKeyData * keyData)
72 memset(keyData, 0, sizeof(TreeKeyData));
77 _FindPosition(Tree * tree, TreeNode * node, void * key, int * pos)
79 #ifdef USE_BINARY_SEARCH
81 int high = node->count;
86 int cur = (high + low) >> 1;
87 cmp = tree->compareKey(key, node->keyData[cur].key);
110 (cmp = tree->compareKey(key, node->keyData[i].key)) > 0;
119 _Find(TreeIterator * iter, void * key)
123 if (_FindPosition(iter->tree, iter->node, key, &iter->which))
129 if (iter->node->children[iter->which])
131 iter->node = iter->node->children[iter->which];
140 static void _SetIteratorToRoot(Tree * tree, TreeIterator * iter)
143 iter->node = tree->rootNode;
149 _SplitNode(TreeNode * node)
151 TreeNode *newNode = _MakeNode();
152 int i = DATA_PER_NODE/2;
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);
177 _InsertNodeAndData(Tree * tree,
185 assert(node->count < DATA_PER_NODE);
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;
200 node->children[pos+1] = newNode;
203 newNode->parent = node;
204 newNode->parentPos = pos+1;
210 _AddDataToSplitNodes(Tree * tree,
217 TreeKeyData retKeyData;
219 assert(moreNode->children[0] == NULL);
221 if (pos <= lessNode->count)
223 _InsertNodeAndData(tree, lessNode, pos, newNode, keyData);
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;
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;
258 newNode->parent = moreNode;
259 newNode->parentPos = pos;
268 _InsertAt(TreeIterator * iter, TreeKeyData keyData)
270 TreeNode * node = iter->node;
271 TreeNode * insertNode = NULL;
272 int pos = iter->which;
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,
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;
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;
305 pos = node->parentPos;
307 insertNode = newNode;
311 /* insert the data and newNode */
312 _InsertNodeAndData(iter->tree,
324 _MergeNodes(TreeNode * lessNode, TreeNode * moreNode)
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;
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;
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])
370 child = child->children[0];
373 *keyData = child->keyData[0];
374 keyData = &(child->keyData[0]);
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])
384 child = child->children[child->count];
387 *keyData = child->keyData[child->count-1];
388 keyData = &(child->keyData[child->count-1]);
393 pos = node->parentPos;
397 /* move data nodes over, we're at a leaf node, so we can ignore
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 */
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))
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]->
428 node->children[node->count]->
429 parentPos = node->count;
431 node->parent->keyData[pos] =
432 (*child)->keyData[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]->
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]));
456 (*(child-1))->count>(DATA_PER_NODE/2))
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 =
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];
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--] =
488 &((*child)->keyData[(*child)->count]));
490 /* merge with one of our siblings */
493 if (pos < node->parent->count)
498 node->keyData[node->count++] =
499 node->parent->keyData[pos];
501 _MergeNodes(node, *child);
510 (*child)->keyData[(*child)->count++] =
511 node->parent->keyData[pos];
513 _MergeNodes(*child, node);
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]->
530 _ClearKeyData(&(node->parent->keyData[i]));
531 node->parent->children[i+1] = NULL;
532 node->parent->count--;
535 pos = node->parentPos;
538 /* this is a root node */
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];
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 ***********************************/
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();
585 FreeTree(Tree * tree)
587 assert(tree->rootNode == NULL);
592 GetTreeSize(Tree * tree)
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)
612 if (iter->node->children[iter->which])
614 iter->node = iter->node->children[iter->which];
622 while (iter->node && iter->which > iter->node->count)
624 iter->which = iter->node->parentPos + 1;
625 iter->node = iter->node->parent;
629 iter->which > 0 && iter->which <= iter->node->count)
637 GetTreeKeyData(TreeIterator * iter)
641 iter->which <= iter->node->count);
642 return iter->node->keyData[iter->which-1];
646 InsertInTree(Tree * tree, void * key, void * data)
651 _SetIteratorToRoot(tree, &iter);
653 if (_Find(&iter, key))
660 _InsertAt(&iter, keyData);
667 RemoveFromTreeByKey(Tree * tree, void * key)
670 _SetIteratorToRoot(tree, &iter);
672 if (_Find(&iter, key))
683 RemoveFromTreeByIterator(Tree * tree, TreeIterator * iter)
690 FindInTree(Tree * tree, void * key, TreeIterator * iter)
699 _SetIteratorToRoot(tree, iter);
700 if (_Find(iter, key))