summaryrefslogtreecommitdiff
path: root/apps/plugins/pdbox/dbestfit-3.3/bysize.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/pdbox/dbestfit-3.3/bysize.c')
-rw-r--r--apps/plugins/pdbox/dbestfit-3.3/bysize.c848
1 files changed, 848 insertions, 0 deletions
diff --git a/apps/plugins/pdbox/dbestfit-3.3/bysize.c b/apps/plugins/pdbox/dbestfit-3.3/bysize.c
new file mode 100644
index 0000000000..6808406dbc
--- /dev/null
+++ b/apps/plugins/pdbox/dbestfit-3.3/bysize.c
@@ -0,0 +1,848 @@
1/*****************************************************************************
2 *
3 * Size-sorted list/tree functions.
4 *
5 * Author: Daniel Stenberg
6 * Date: March 7, 1997
7 * Version: 2.0
8 * Email: Daniel.Stenberg@sth.frontec.se
9 *
10 *
11 * v2.0
12 * - Added SPLAY TREE functionality.
13 *
14 * Adds and removes CHUNKS from a list or tree.
15 *
16 ****************************************************************************/
17
18#include <stdio.h>
19#include <stdlib.h>
20
21#define SPLAY /* we use the splay version as that is much faster */
22
23#ifndef TRUE
24#define TRUE 1
25#endif
26#ifndef FALSE
27#define FALSE 0
28#endif
29
30#ifndef SPLAY /* these routines are for the non-splay version */
31
32struct ChunkInfo {
33 struct ChunkInfo *larger;
34 struct ChunkInfo *smaller;
35 size_t size;
36};
37
38/* the CHUNK list anchor */
39struct ChunkInfo *chunkHead=NULL;
40
41/***********************************************************************
42
43 findchunkbysize()
44
45 Find the chunk that is smaller than the input size. Returns
46 NULL if none is.
47
48 **********************************************************************/
49
50static struct ChunkInfo *findchunkbysize(size_t size)
51{
52 struct ChunkInfo *test = chunkHead;
53 struct ChunkInfo *smaller = NULL;
54 while(test && (test->size < size)) {
55 smaller = test;
56 test = test->larger;
57 }
58 return smaller;
59}
60
61/***********************************************************************
62
63 remove_chunksize()
64
65 Remove the chunk from the size-sorted list.
66 ***********************************************************************/
67
68void remove_chunksize(void *data)
69{
70 struct ChunkInfo *chunk = (struct ChunkInfo *)data;
71 if(chunk->smaller)
72 chunk->smaller->larger = chunk->larger;
73 else {
74 /* if this has no smaller, this is the head */
75 chunkHead = chunk->larger; /* new head */
76 }
77 if(chunk->larger)
78 chunk->larger->smaller = chunk->smaller;
79}
80
81void insert_bysize(char *data, size_t size)
82{
83 struct ChunkInfo *newchunk = (struct ChunkInfo *)data;
84 struct ChunkInfo *chunk = findchunkbysize ( size );
85
86 newchunk->size = size;
87
88 if(chunk) {
89 /* 'chunk' is smaller than size, append the new chunk ahead of this */
90 newchunk->smaller = chunk;
91 newchunk->larger = chunk->larger;
92 if(chunk->larger)
93 chunk->larger->smaller = newchunk;
94 chunk->larger = newchunk;
95 }
96 else {
97 /* smallest CHUNK around, append first in the list */
98 newchunk->larger = chunkHead;
99 newchunk->smaller = NULL;
100
101 if(chunkHead)
102 chunkHead->smaller = newchunk;
103 chunkHead = newchunk;
104 }
105}
106
107char *obtainbysize( size_t size)
108{
109 struct ChunkInfo *chunk = findchunkbysize( size );
110
111 if(!chunk) {
112 if(size <= (chunkHead->size))
113 /* there is no smaller CHUNK, use the first one (if we fit within that)
114 */
115 chunk = chunkHead;
116 }
117 else
118 /* we're on the last CHUNK that is smaller than requested, step onto
119 the bigger one */
120 chunk = chunk->larger;
121
122 if(chunk) {
123 remove_chunksize( chunk ); /* unlink size-wise */
124 return (char *)chunk;
125 }
126 else
127 return NULL;
128}
129
130void print_sizes(void)
131{
132 struct ChunkInfo *chunk = chunkHead;
133 printf("List of CHUNKS (in size order):\n");
134#if 1
135 while(chunk) {
136 printf(" START %p END %p SIZE %d\n",
137 chunk, (char *)chunk+chunk->size, chunk->size);
138 chunk = chunk->larger;
139 }
140#endif
141 printf("End of CHUNKS:\n");
142}
143
144#else /* Here follows all routines dealing with the SPLAY TREES */
145
146typedef struct tree_node Tree;
147struct tree_node {
148 Tree *smaller; /* smaller node */
149 Tree *larger; /* larger node */
150 Tree *same; /* points to a node with identical key */
151 int key; /* the "sort" key */
152};
153
154Tree *chunkHead = NULL; /* the root */
155
156#define compare(i,j) ((i)-(j))
157
158/* Set this to a key value that will *NEVER* appear otherwise */
159#define KEY_NOTUSED -1
160
161/*
162 * Splay using the key i (which may or may not be in the tree.) The starting
163 * root is t. Weight fields are maintained.
164 */
165Tree * splay (int i, Tree *t)
166{
167 Tree N, *l, *r, *y;
168 int comp;
169
170 if (t == NULL)
171 return t;
172 N.smaller = N.larger = NULL;
173 l = r = &N;
174
175 for (;;) {
176 comp = compare(i, t->key);
177 if (comp < 0) {
178 if (t->smaller == NULL)
179 break;
180 if (compare(i, t->smaller->key) < 0) {
181 y = t->smaller; /* rotate smaller */
182 t->smaller = y->larger;
183 y->larger = t;
184
185 t = y;
186 if (t->smaller == NULL)
187 break;
188 }
189 r->smaller = t; /* link smaller */
190 r = t;
191 t = t->smaller;
192 }
193 else if (comp > 0) {
194 if (t->larger == NULL)
195 break;
196 if (compare(i, t->larger->key) > 0) {
197 y = t->larger; /* rotate larger */
198 t->larger = y->smaller;
199 y->smaller = t;
200 t = y;
201 if (t->larger == NULL)
202 break;
203 }
204 l->larger = t; /* link larger */
205 l = t;
206 t = t->larger;
207 }
208 else {
209 break;
210 }
211 }
212
213 l->larger = r->smaller = NULL;
214
215 l->larger = t->smaller; /* assemble */
216 r->smaller = t->larger;
217 t->smaller = N.larger;
218 t->larger = N.smaller;
219
220 return t;
221}
222
223/* Insert key i into the tree t. Return a pointer to the resulting tree or
224 NULL if something went wrong. */
225Tree *insert(int i, Tree *t, Tree *new)
226{
227 if (new == NULL) {
228 return t;
229 }
230
231 if (t != NULL) {
232 t = splay(i,t);
233 if (compare(i, t->key)==0) {
234 /* it already exists one of this size */
235
236 new->same = t;
237 new->key = i;
238 new->smaller = t->smaller;
239 new->larger = t->larger;
240
241 t->smaller = new;
242 t->key = KEY_NOTUSED;
243
244 return new; /* new root node */
245 }
246 }
247
248 if (t == NULL) {
249 new->smaller = new->larger = NULL;
250 }
251 else if (compare(i, t->key) < 0) {
252 new->smaller = t->smaller;
253 new->larger = t;
254 t->smaller = NULL;
255 }
256 else {
257 new->larger = t->larger;
258 new->smaller = t;
259 t->larger = NULL;
260 }
261 new->key = i;
262
263 new->same = NULL; /* no identical node (yet) */
264
265 return new;
266}
267
268/* Finds and deletes the best-fit node from the tree. Return a pointer to the
269 resulting tree. best-fit means the smallest node that fits the requested
270 size. */
271Tree *removebestfit(int i, Tree *t, Tree **removed)
272{
273 Tree *x;
274
275 if (t==NULL)
276 return NULL;
277 t = splay(i,t);
278 if(compare(i, t->key) > 0) {
279 /* too small node, try the larger chain */
280 if(t->larger)
281 t=splay(t->larger->key, t);
282 else {
283 /* fail */
284 *removed = NULL;
285 return t;
286 }
287 }
288
289 if (compare(i, t->key) <= 0) { /* found it */
290
291 /* FIRST! Check if there is a list with identical sizes */
292 x = t->same;
293 if(x) {
294 /* there is, pick one from the list */
295
296 /* 'x' is the new root node */
297
298 x->key = t->key;
299 x->larger = t->larger;
300 x->smaller = t->smaller;
301 *removed = t;
302 return x; /* new root */
303 }
304
305 if (t->smaller == NULL) {
306 x = t->larger;
307 }
308 else {
309 x = splay(i, t->smaller);
310 x->larger = t->larger;
311 }
312 *removed = t;
313
314 return x;
315 }
316 else {
317 *removed = NULL; /* no match */
318 return t; /* It wasn't there */
319 }
320}
321
322
323/* Deletes the node we point out from the tree if it's there. Return a pointer
324 to the resulting tree. */
325Tree *removebyaddr(Tree *t, Tree *remove)
326{
327 Tree *x;
328
329 if (!t || !remove)
330 return NULL;
331
332 if(KEY_NOTUSED == remove->key) {
333 /* just unlink ourselves nice and quickly: */
334 remove->smaller->same = remove->same;
335 if(remove->same)
336 remove->same->smaller = remove->smaller;
337 /* voila, we're done! */
338 return t;
339 }
340
341 t = splay(remove->key,t);
342
343 /* Check if there is a list with identical sizes */
344
345 x = t->same;
346 if(x) {
347 /* 'x' is the new root node */
348
349 x->key = t->key;
350 x->larger = t->larger;
351 x->smaller = t->smaller;
352
353 return x; /* new root */
354 }
355
356 /* Remove the actualy root node: */
357
358 if (t->smaller == NULL) {
359 x = t->larger;
360 }
361 else {
362 x = splay(remove->key, t->smaller);
363 x->larger = t->larger;
364 }
365
366 return x;
367}
368
369int printtree(Tree * t, int d, char output)
370{
371 int distance=0;
372 Tree *node;
373 int i;
374 if (t == NULL)
375 return 0;
376 distance += printtree(t->larger, d+1, output);
377 for (i=0; i<d; i++)
378 if(output)
379 printf(" ");
380
381 if(output) {
382 printf("%d[%d]", t->key, i);
383 }
384
385 for(node = t->same; node; node = node->same) {
386 distance += i; /* this has the same "virtual" distance */
387
388 if(output)
389 printf(" [+]");
390 }
391 if(output)
392 puts("");
393
394 distance += i;
395 distance += printtree(t->smaller, d+1, output);
396 return distance;
397}
398
399/* Here follow the look-alike interface so that the tree-function names are
400 the same as the list-ones to enable easy interchange */
401
402void remove_chunksize(void *data)
403{
404 chunkHead = removebyaddr(chunkHead, data);
405}
406
407void insert_bysize(char *data, size_t size)
408{
409 chunkHead = insert(size, chunkHead, (Tree *)data);
410}
411
412char *obtainbysize( size_t size)
413{
414 Tree *receive;
415 chunkHead = removebestfit(size, chunkHead, &receive);
416 return (char *)receive;
417}
418
419void print_sizes(void)
420{
421 printtree(chunkHead, 0, 1);
422}
423
424#endif
425/*****************************************************************************
426 *
427 * Size-sorted list/tree functions.
428 *
429 * Author: Daniel Stenberg
430 * Date: March 7, 1997
431 * Version: 2.0
432 * Email: Daniel.Stenberg@sth.frontec.se
433 *
434 *
435 * v2.0
436 * - Added SPLAY TREE functionality.
437 *
438 * Adds and removes CHUNKS from a list or tree.
439 *
440 ****************************************************************************/
441
442#include <stdio.h>
443#include <stdlib.h>
444
445#define SPLAY /* we use the splay version as that is much faster */
446
447#ifndef TRUE
448#define TRUE 1
449#endif
450#ifndef FALSE
451#define FALSE 0
452#endif
453
454#ifndef SPLAY /* these routines are for the non-splay version */
455
456struct ChunkInfo {
457 struct ChunkInfo *larger;
458 struct ChunkInfo *smaller;
459 size_t size;
460};
461
462/* the CHUNK list anchor */
463struct ChunkInfo *chunkHead=NULL;
464
465/***********************************************************************
466
467 findchunkbysize()
468
469 Find the chunk that is smaller than the input size. Returns
470 NULL if none is.
471
472 **********************************************************************/
473
474static struct ChunkInfo *findchunkbysize(size_t size)
475{
476 struct ChunkInfo *test = chunkHead;
477 struct ChunkInfo *smaller = NULL;
478 while(test && (test->size < size)) {
479 smaller = test;
480 test = test->larger;
481 }
482 return smaller;
483}
484
485/***********************************************************************
486
487 remove_chunksize()
488
489 Remove the chunk from the size-sorted list.
490 ***********************************************************************/
491
492void remove_chunksize(void *data)
493{
494 struct ChunkInfo *chunk = (struct ChunkInfo *)data;
495 if(chunk->smaller)
496 chunk->smaller->larger = chunk->larger;
497 else {
498 /* if this has no smaller, this is the head */
499 chunkHead = chunk->larger; /* new head */
500 }
501 if(chunk->larger)
502 chunk->larger->smaller = chunk->smaller;
503}
504
505void insert_bysize(char *data, size_t size)
506{
507 struct ChunkInfo *newchunk = (struct ChunkInfo *)data;
508 struct ChunkInfo *chunk = findchunkbysize ( size );
509
510 newchunk->size = size;
511
512 if(chunk) {
513 /* 'chunk' is smaller than size, append the new chunk ahead of this */
514 newchunk->smaller = chunk;
515 newchunk->larger = chunk->larger;
516 if(chunk->larger)
517 chunk->larger->smaller = newchunk;
518 chunk->larger = newchunk;
519 }
520 else {
521 /* smallest CHUNK around, append first in the list */
522 newchunk->larger = chunkHead;
523 newchunk->smaller = NULL;
524
525 if(chunkHead)
526 chunkHead->smaller = newchunk;
527 chunkHead = newchunk;
528 }
529}
530
531char *obtainbysize( size_t size)
532{
533 struct ChunkInfo *chunk = findchunkbysize( size );
534
535 if(!chunk) {
536 if(size <= (chunkHead->size))
537 /* there is no smaller CHUNK, use the first one (if we fit within that)
538 */
539 chunk = chunkHead;
540 }
541 else
542 /* we're on the last CHUNK that is smaller than requested, step onto
543 the bigger one */
544 chunk = chunk->larger;
545
546 if(chunk) {
547 remove_chunksize( chunk ); /* unlink size-wise */
548 return (char *)chunk;
549 }
550 else
551 return NULL;
552}
553
554void print_sizes(void)
555{
556 struct ChunkInfo *chunk = chunkHead;
557 printf("List of CHUNKS (in size order):\n");
558#if 1
559 while(chunk) {
560 printf(" START %p END %p SIZE %d\n",
561 chunk, (char *)chunk+chunk->size, chunk->size);
562 chunk = chunk->larger;
563 }
564#endif
565 printf("End of CHUNKS:\n");
566}
567
568#else /* Here follows all routines dealing with the SPLAY TREES */
569
570typedef struct tree_node Tree;
571struct tree_node {
572 Tree *smaller; /* smaller node */
573 Tree *larger; /* larger node */
574 Tree *same; /* points to a node with identical key */
575 int key; /* the "sort" key */
576};
577
578Tree *chunkHead = NULL; /* the root */
579
580#define compare(i,j) ((i)-(j))
581
582/* Set this to a key value that will *NEVER* appear otherwise */
583#define KEY_NOTUSED -1
584
585/*
586 * Splay using the key i (which may or may not be in the tree.) The starting
587 * root is t. Weight fields are maintained.
588 */
589Tree * splay (int i, Tree *t)
590{
591 Tree N, *l, *r, *y;
592 int comp;
593
594 if (t == NULL)
595 return t;
596 N.smaller = N.larger = NULL;
597 l = r = &N;
598
599 for (;;) {
600 comp = compare(i, t->key);
601 if (comp < 0) {
602 if (t->smaller == NULL)
603 break;
604 if (compare(i, t->smaller->key) < 0) {
605 y = t->smaller; /* rotate smaller */
606 t->smaller = y->larger;
607 y->larger = t;
608
609 t = y;
610 if (t->smaller == NULL)
611 break;
612 }
613 r->smaller = t; /* link smaller */
614 r = t;
615 t = t->smaller;
616 }
617 else if (comp > 0) {
618 if (t->larger == NULL)
619 break;
620 if (compare(i, t->larger->key) > 0) {
621 y = t->larger; /* rotate larger */
622 t->larger = y->smaller;
623 y->smaller = t;
624 t = y;
625 if (t->larger == NULL)
626 break;
627 }
628 l->larger = t; /* link larger */
629 l = t;
630 t = t->larger;
631 }
632 else {
633 break;
634 }
635 }
636
637 l->larger = r->smaller = NULL;
638
639 l->larger = t->smaller; /* assemble */
640 r->smaller = t->larger;
641 t->smaller = N.larger;
642 t->larger = N.smaller;
643
644 return t;
645}
646
647/* Insert key i into the tree t. Return a pointer to the resulting tree or
648 NULL if something went wrong. */
649Tree *insert(int i, Tree *t, Tree *new)
650{
651 if (new == NULL) {
652 return t;
653 }
654
655 if (t != NULL) {
656 t = splay(i,t);
657 if (compare(i, t->key)==0) {
658 /* it already exists one of this size */
659
660 new->same = t;
661 new->key = i;
662 new->smaller = t->smaller;
663 new->larger = t->larger;
664
665 t->smaller = new;
666 t->key = KEY_NOTUSED;
667
668 return new; /* new root node */
669 }
670 }
671
672 if (t == NULL) {
673 new->smaller = new->larger = NULL;
674 }
675 else if (compare(i, t->key) < 0) {
676 new->smaller = t->smaller;
677 new->larger = t;
678 t->smaller = NULL;
679 }
680 else {
681 new->larger = t->larger;
682 new->smaller = t;
683 t->larger = NULL;
684 }
685 new->key = i;
686
687 new->same = NULL; /* no identical node (yet) */
688
689 return new;
690}
691
692/* Finds and deletes the best-fit node from the tree. Return a pointer to the
693 resulting tree. best-fit means the smallest node that fits the requested
694 size. */
695Tree *removebestfit(int i, Tree *t, Tree **removed)
696{
697 Tree *x;
698
699 if (t==NULL)
700 return NULL;
701 t = splay(i,t);
702 if(compare(i, t->key) > 0) {
703 /* too small node, try the larger chain */
704 if(t->larger)
705 t=splay(t->larger->key, t);
706 else {
707 /* fail */
708 *removed = NULL;
709 return t;
710 }
711 }
712
713 if (compare(i, t->key) <= 0) { /* found it */
714
715 /* FIRST! Check if there is a list with identical sizes */
716 x = t->same;
717 if(x) {
718 /* there is, pick one from the list */
719
720 /* 'x' is the new root node */
721
722 x->key = t->key;
723 x->larger = t->larger;
724 x->smaller = t->smaller;
725 *removed = t;
726 return x; /* new root */
727 }
728
729 if (t->smaller == NULL) {
730 x = t->larger;
731 }
732 else {
733 x = splay(i, t->smaller);
734 x->larger = t->larger;
735 }
736 *removed = t;
737
738 return x;
739 }
740 else {
741 *removed = NULL; /* no match */
742 return t; /* It wasn't there */
743 }
744}
745
746
747/* Deletes the node we point out from the tree if it's there. Return a pointer
748 to the resulting tree. */
749Tree *removebyaddr(Tree *t, Tree *remove)
750{
751 Tree *x;
752
753 if (!t || !remove)
754 return NULL;
755
756 if(KEY_NOTUSED == remove->key) {
757 /* just unlink ourselves nice and quickly: */
758 remove->smaller->same = remove->same;
759 if(remove->same)
760 remove->same->smaller = remove->smaller;
761 /* voila, we're done! */
762 return t;
763 }
764
765 t = splay(remove->key,t);
766
767 /* Check if there is a list with identical sizes */
768
769 x = t->same;
770 if(x) {
771 /* 'x' is the new root node */
772
773 x->key = t->key;
774 x->larger = t->larger;
775 x->smaller = t->smaller;
776
777 return x; /* new root */
778 }
779
780 /* Remove the actualy root node: */
781
782 if (t->smaller == NULL) {
783 x = t->larger;
784 }
785 else {
786 x = splay(remove->key, t->smaller);
787 x->larger = t->larger;
788 }
789
790 return x;
791}
792
793int printtree(Tree * t, int d, char output)
794{
795 int distance=0;
796 Tree *node;
797 int i;
798 if (t == NULL)
799 return 0;
800 distance += printtree(t->larger, d+1, output);
801 for (i=0; i<d; i++)
802 if(output)
803 printf(" ");
804
805 if(output) {
806 printf("%d[%d]", t->key, i);
807 }
808
809 for(node = t->same; node; node = node->same) {
810 distance += i; /* this has the same "virtual" distance */
811
812 if(output)
813 printf(" [+]");
814 }
815 if(output)
816 puts("");
817
818 distance += i;
819 distance += printtree(t->smaller, d+1, output);
820 return distance;
821}
822
823/* Here follow the look-alike interface so that the tree-function names are
824 the same as the list-ones to enable easy interchange */
825
826void remove_chunksize(void *data)
827{
828 chunkHead = removebyaddr(chunkHead, data);
829}
830
831void insert_bysize(char *data, size_t size)
832{
833 chunkHead = insert(size, chunkHead, (Tree *)data);
834}
835
836char *obtainbysize( size_t size)
837{
838 Tree *receive;
839 chunkHead = removebestfit(size, chunkHead, &receive);
840 return (char *)receive;
841}
842
843void print_sizes(void)
844{
845 printtree(chunkHead, 0, 1);
846}
847
848#endif