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
))