Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Annotation of /trunk/src/sorting.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 871 - (hide annotations) (download) (as text)
Sat Oct 15 13:45:34 2011 UTC (13 years, 5 months ago) by amb
File MIME type: text/x-csrc
File size: 20132 byte(s)
Bug fixes for the previous change.

1 amb 269 /***************************************
2     Merge sort functions.
3    
4     Part of the Routino routing software.
5     ******************/ /******************
6 amb 680 This file Copyright 2009-2011 Andrew M. Bishop
7 amb 269
8     This program is free software: you can redistribute it and/or modify
9     it under the terms of the GNU Affero General Public License as published by
10     the Free Software Foundation, either version 3 of the License, or
11     (at your option) any later version.
12    
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     GNU Affero General Public License for more details.
17    
18     You should have received a copy of the GNU Affero General Public License
19     along with this program. If not, see <http://www.gnu.org/licenses/>.
20     ***************************************/
21    
22    
23     #include <stdio.h>
24     #include <stdlib.h>
25     #include <string.h>
26     #include <assert.h>
27    
28 amb 532 #include "types.h"
29    
30 amb 449 #include "files.h"
31 amb 532 #include "sorting.h"
32 amb 269
33    
34 amb 680 /* Global variables */
35 amb 269
36 amb 289 /*+ The command line '--tmpdir' option or its default value. +*/
37 amb 284 extern char *option_tmpdirname;
38 amb 269
39 amb 358 /*+ The amount of RAM to use for filesorting. +*/
40     extern size_t option_filesort_ramsize;
41 amb 269
42 amb 358
43 amb 269 /*++++++++++++++++++++++++++++++++++++++
44 amb 310 A function to sort the contents of a file of fixed length objects using a
45     limited amount of RAM.
46 amb 269
47     The data is sorted using a "Merge sort" http://en.wikipedia.org/wiki/Merge_sort
48     and in particular an "external sort" http://en.wikipedia.org/wiki/External_sorting.
49     The individual sort steps and the merge step both use a "Heap sort"
50     http://en.wikipedia.org/wiki/Heapsort. The combination of the two should work well
51     if the data is already partially sorted.
52    
53     int fd_in The file descriptor of the input file (opened for reading and at the beginning).
54    
55     int fd_out The file descriptor of the output file (opened for writing and empty).
56    
57     size_t itemsize The size of each item in the file that needs sorting.
58    
59     int (*compare)(const void*, const void*) The comparison function (identical to qsort if the
60     data to be sorted is an array of things not pointers).
61    
62 amb 274 int (*buildindex)(void *,index_t) If non-NULL then this function is called for each item, if it
63     returns 1 then it is written to the output file.
64 amb 269 ++++++++++++++++++++++++++++++++++++++*/
65    
66 amb 311 void filesort_fixed(int fd_in,int fd_out,size_t itemsize,int (*compare)(const void*,const void*),int (*buildindex)(void*,index_t))
67 amb 269 {
68     int *fds=NULL,*heap=NULL;
69     int nfiles=0,ndata=0;
70     index_t count=0,total=0;
71 amb 358 size_t nitems=option_filesort_ramsize/(itemsize+sizeof(void*));
72 amb 283 void *data=NULL,**datap=NULL;
73 amb 269 char *filename;
74     int i,more=1;
75    
76     /* Allocate the RAM buffer and other bits */
77    
78     data=malloc(nitems*itemsize);
79     datap=malloc(nitems*sizeof(void*));
80    
81 amb 284 filename=(char*)malloc(strlen(option_tmpdirname)+24);
82 amb 269
83     /* Loop around, fill the buffer, sort the data and write a temporary file */
84    
85     do
86     {
87     int fd,n=0;
88    
89     /* Read in the data and create pointers */
90    
91     for(i=0;i<nitems;i++)
92     {
93     datap[i]=data+i*itemsize;
94    
95     if(ReadFile(fd_in,datap[i],itemsize))
96     {
97     more=0;
98     break;
99     }
100    
101     total++;
102     }
103    
104     n=i;
105    
106 amb 546 /* Shortcut if there is no data and no previous files (i.e. no data at all) */
107    
108     if(nfiles==0 && n==0)
109     goto tidy_and_exit;
110    
111 amb 543 /* No new data read in this time round */
112    
113 amb 269 if(n==0)
114     break;
115    
116     /* Sort the data pointers using a heap sort */
117    
118 amb 503 filesort_heapsort(datap,n,compare);
119 amb 269
120     /* Shortcut if all read in and sorted at once */
121    
122 amb 310 if(nfiles==0 && !more)
123 amb 269 {
124     for(i=0;i<n;i++)
125     {
126 amb 274 if(!buildindex || buildindex(datap[i],count))
127     {
128     WriteFile(fd_out,datap[i],itemsize);
129     count++;
130     }
131 amb 269 }
132    
133 amb 283 goto tidy_and_exit;
134 amb 269 }
135    
136     /* Create a temporary file and write the result */
137    
138 amb 284 sprintf(filename,"%s/filesort.%d.tmp",option_tmpdirname,nfiles);
139 amb 269
140 amb 502 fd=OpenFileNew(filename);
141 amb 269
142     for(i=0;i<n;i++)
143     WriteFile(fd,datap[i],itemsize);
144    
145     CloseFile(fd);
146    
147     nfiles++;
148     }
149     while(more);
150    
151     /* Shortcut if only one file (unlucky for us there must have been exactly
152     nitems, lucky for us we still have the data in RAM) */
153    
154     if(nfiles==1)
155     {
156     for(i=0;i<nitems;i++)
157     {
158 amb 274 if(!buildindex || buildindex(datap[i],count))
159     {
160     WriteFile(fd_out,datap[i],itemsize);
161     count++;
162     }
163 amb 269 }
164    
165     DeleteFile(filename);
166    
167 amb 283 goto tidy_and_exit;
168 amb 269 }
169    
170     /* Check that number of files is less than file size */
171    
172     assert(nfiles<nitems);
173    
174     /* Open all of the temporary files */
175    
176     fds=(int*)malloc(nfiles*sizeof(int));
177    
178     for(i=0;i<nfiles;i++)
179     {
180 amb 284 sprintf(filename,"%s/filesort.%d.tmp",option_tmpdirname,i);
181 amb 269
182     fds[i]=ReOpenFile(filename);
183    
184     DeleteFile(filename);
185     }
186    
187     /* Perform an n-way merge using a binary heap */
188    
189 amb 870 heap=(int*)malloc(nfiles*sizeof(int));
190 amb 269
191     /* Fill the heap to start with */
192    
193     for(i=0;i<nfiles;i++)
194     {
195     int index;
196    
197     datap[i]=data+i*itemsize;
198    
199     ReadFile(fds[i],datap[i],itemsize);
200    
201 amb 870 index=i;
202 amb 269
203 amb 867 heap[index]=i;
204 amb 269
205     /* Bubble up the new value */
206    
207 amb 870 while(index>0)
208 amb 269 {
209     int newindex;
210     int temp;
211    
212 amb 870 newindex=(index-1)/4;
213 amb 269
214 amb 869 if(compare(datap[heap[index]],datap[heap[newindex]])>=0)
215     break;
216    
217 amb 269 temp=heap[index];
218     heap[index]=heap[newindex];
219     heap[newindex]=temp;
220    
221     index=newindex;
222     }
223     }
224    
225     /* Repeatedly pull out the root of the heap and refill from the same file */
226    
227     ndata=nfiles;
228    
229     do
230     {
231 amb 870 int index=0;
232 amb 269
233 amb 867 if(!buildindex || buildindex(datap[heap[index]],count))
234 amb 274 {
235 amb 867 WriteFile(fd_out,datap[heap[index]],itemsize);
236 amb 274 count++;
237     }
238 amb 269
239 amb 867 if(ReadFile(fds[heap[index]],datap[heap[index]],itemsize))
240 amb 269 {
241 amb 870 ndata--;
242 amb 867 heap[index]=heap[ndata];
243 amb 269 }
244    
245     /* Bubble down the new value */
246    
247 amb 870 while((4*index+4)<ndata)
248 amb 269 {
249 amb 870 int childindex,newindex;
250 amb 269 int temp;
251    
252 amb 870 childindex=newindex=4*index+1;
253 amb 269
254 amb 870 if(compare(datap[heap[newindex]],datap[heap[++childindex]])>0)
255 amb 871 newindex=childindex;
256 amb 870 if(compare(datap[heap[newindex]],datap[heap[++childindex]])>0)
257 amb 871 newindex=childindex;
258 amb 870 if(compare(datap[heap[newindex]],datap[heap[++childindex]])>0)
259 amb 871 newindex=childindex;
260 amb 869
261     if(compare(datap[heap[index]],datap[heap[newindex]])<=0)
262     break;
263    
264 amb 269 temp=heap[newindex];
265     heap[newindex]=heap[index];
266     heap[index]=temp;
267    
268     index=newindex;
269     }
270    
271 amb 870 if((4*index+4)==ndata)
272 amb 269 {
273 amb 870 int childindex,newindex;
274     int temp;
275    
276     childindex=newindex=4*index+1;
277    
278     if(compare(datap[heap[newindex]],datap[heap[++childindex]])>0)
279 amb 871 newindex=childindex;
280 amb 870 if(compare(datap[heap[newindex]],datap[heap[++childindex]])>0)
281 amb 871 newindex=childindex;
282 amb 870
283     if(compare(datap[heap[index]],datap[heap[newindex]])<=0)
284     ; /* break */
285     else
286     {
287     temp=heap[newindex];
288     heap[newindex]=heap[index];
289     heap[index]=temp;
290     }
291     }
292    
293 amb 871 else if((4*index+3)==ndata)
294 amb 870 {
295     int childindex,newindex;
296     int temp;
297    
298     childindex=newindex=4*index+1;
299    
300     if(compare(datap[heap[newindex]],datap[heap[++childindex]])>0)
301 amb 871 newindex=childindex;
302 amb 870
303     if(compare(datap[heap[index]],datap[heap[newindex]])<=0)
304     ; /* break */
305     else
306     {
307     temp=heap[newindex];
308     heap[newindex]=heap[index];
309     heap[index]=temp;
310     }
311     }
312    
313 amb 871 else if((4*index+2)==ndata)
314 amb 870 {
315 amb 269 int newindex;
316     int temp;
317    
318 amb 870 newindex=4*index+1;
319 amb 269
320 amb 869 if(compare(datap[heap[index]],datap[heap[newindex]])<=0)
321     ; /* break */
322     else
323     {
324     temp=heap[newindex];
325     heap[newindex]=heap[index];
326     heap[index]=temp;
327     }
328 amb 269 }
329     }
330     while(ndata>0);
331    
332     /* Tidy up */
333    
334 amb 283 tidy_and_exit:
335 amb 269
336 amb 283 if(fds)
337     {
338     for(i=0;i<nfiles;i++)
339     CloseFile(fds[i]);
340     free(fds);
341     }
342    
343     if(heap)
344     free(heap);
345    
346 amb 269 free(data);
347     free(datap);
348     free(filename);
349     }
350    
351    
352     /*++++++++++++++++++++++++++++++++++++++
353 amb 310 A function to sort the contents of a file of variable length objects (each
354 amb 867 preceded by its length in FILESORT_VARSIZE bytes) using a limited amount of RAM.
355 amb 310
356     The data is sorted using a "Merge sort" http://en.wikipedia.org/wiki/Merge_sort
357     and in particular an "external sort" http://en.wikipedia.org/wiki/External_sorting.
358     The individual sort steps and the merge step both use a "Heap sort"
359     http://en.wikipedia.org/wiki/Heapsort. The combination of the two should work well
360     if the data is already partially sorted.
361    
362     int fd_in The file descriptor of the input file (opened for reading and at the beginning).
363    
364     int fd_out The file descriptor of the output file (opened for writing and empty).
365    
366     int (*compare)(const void*, const void*) The comparison function (identical to qsort if the
367     data to be sorted is an array of things not pointers).
368    
369     int (*buildindex)(void *,index_t) If non-NULL then this function is called for each item, if it
370     returns 1 then it is written to the output file.
371     ++++++++++++++++++++++++++++++++++++++*/
372    
373 amb 311 void filesort_vary(int fd_in,int fd_out,int (*compare)(const void*,const void*),int (*buildindex)(void*,index_t))
374 amb 310 {
375     int *fds=NULL,*heap=NULL;
376     int nfiles=0,ndata=0;
377     index_t count=0,total=0;
378 amb 311 FILESORT_VARINT nextitemsize,largestitemsize=0;
379 amb 310 void *data=NULL,**datap=NULL;
380     char *filename;
381     int i,more=1;
382    
383     /* Allocate the RAM buffer and other bits */
384    
385 amb 358 data=malloc(option_filesort_ramsize);
386 amb 310
387     filename=(char*)malloc(strlen(option_tmpdirname)+24);
388    
389     /* Loop around, fill the buffer, sort the data and write a temporary file */
390    
391 amb 311 if(ReadFile(fd_in,&nextitemsize,FILESORT_VARSIZE)) /* Always have the next item size known in advance */
392 amb 310 goto tidy_and_exit;
393    
394     do
395     {
396     int fd,n=0;
397 amb 311 size_t ramused=FILESORT_VARALIGN-FILESORT_VARSIZE;
398 amb 310
399 amb 358 datap=data+option_filesort_ramsize;
400 amb 310
401     /* Read in the data and create pointers */
402    
403 amb 311 while((ramused+FILESORT_VARSIZE+nextitemsize)<=((void*)datap-sizeof(void*)-data))
404 amb 310 {
405 amb 311 FILESORT_VARINT itemsize=nextitemsize;
406 amb 310
407     if(itemsize>largestitemsize)
408     largestitemsize=itemsize;
409    
410 amb 311 *(FILESORT_VARINT*)(data+ramused)=itemsize;
411 amb 310
412 amb 311 ramused+=FILESORT_VARSIZE;
413 amb 310
414 amb 311 ReadFile(fd_in,data+ramused,itemsize);
415 amb 310
416 amb 311 *--datap=data+ramused; /* points to real data */
417 amb 310
418 amb 311 ramused+=itemsize;
419    
420     ramused =FILESORT_VARALIGN*((ramused+FILESORT_VARSIZE-1)/FILESORT_VARALIGN);
421     ramused+=FILESORT_VARALIGN-FILESORT_VARSIZE;
422    
423 amb 310 total++;
424     n++;
425    
426 amb 311 if(ReadFile(fd_in,&nextitemsize,FILESORT_VARSIZE))
427 amb 310 {
428     more=0;
429     break;
430     }
431     }
432    
433 amb 543 /* No new data read in this time round */
434    
435 amb 310 if(n==0)
436     break;
437    
438     /* Sort the data pointers using a heap sort */
439    
440 amb 503 filesort_heapsort(datap,n,compare);
441 amb 310
442     /* Shortcut if all read in and sorted at once */
443    
444     if(nfiles==0 && !more)
445     {
446     for(i=0;i<n;i++)
447     {
448     if(!buildindex || buildindex(datap[i],count))
449     {
450 amb 311 FILESORT_VARINT itemsize=*(FILESORT_VARINT*)(datap[i]-FILESORT_VARSIZE);
451 amb 310
452 amb 311 WriteFile(fd_out,datap[i]-FILESORT_VARSIZE,itemsize+FILESORT_VARSIZE);
453 amb 310 count++;
454     }
455     }
456    
457     goto tidy_and_exit;
458     }
459    
460     /* Create a temporary file and write the result */
461    
462     sprintf(filename,"%s/filesort.%d.tmp",option_tmpdirname,nfiles);
463    
464 amb 502 fd=OpenFileNew(filename);
465 amb 310
466     for(i=0;i<n;i++)
467     {
468 amb 311 FILESORT_VARINT itemsize=*(FILESORT_VARINT*)(datap[i]-FILESORT_VARSIZE);
469 amb 310
470 amb 311 WriteFile(fd,datap[i]-FILESORT_VARSIZE,itemsize+FILESORT_VARSIZE);
471 amb 310 }
472    
473     CloseFile(fd);
474    
475     nfiles++;
476     }
477     while(more);
478    
479     /* Check that number of files is less than file size */
480    
481 amb 311 largestitemsize=FILESORT_VARALIGN*(1+(largestitemsize+FILESORT_VARALIGN-FILESORT_VARSIZE)/FILESORT_VARALIGN);
482 amb 310
483 amb 358 assert(nfiles<((option_filesort_ramsize-nfiles*sizeof(void*))/largestitemsize));
484 amb 310
485     /* Open all of the temporary files */
486    
487     fds=(int*)malloc(nfiles*sizeof(int));
488    
489     for(i=0;i<nfiles;i++)
490     {
491     sprintf(filename,"%s/filesort.%d.tmp",option_tmpdirname,i);
492    
493     fds[i]=ReOpenFile(filename);
494    
495     DeleteFile(filename);
496     }
497    
498     /* Perform an n-way merge using a binary heap */
499    
500 amb 870 heap=(int*)malloc(nfiles*sizeof(int));
501 amb 310
502 amb 358 datap=data+option_filesort_ramsize-nfiles*sizeof(void*);
503 amb 310
504     /* Fill the heap to start with */
505    
506     for(i=0;i<nfiles;i++)
507     {
508     int index;
509 amb 311 FILESORT_VARINT itemsize;
510 amb 310
511 amb 311 datap[i]=data+FILESORT_VARALIGN-FILESORT_VARSIZE+i*largestitemsize;
512 amb 310
513 amb 311 ReadFile(fds[i],&itemsize,FILESORT_VARSIZE);
514 amb 310
515 amb 311 *(FILESORT_VARINT*)(datap[i]-FILESORT_VARSIZE)=itemsize;
516 amb 310
517     ReadFile(fds[i],datap[i],itemsize);
518    
519 amb 870 index=i;
520 amb 310
521 amb 867 heap[index]=i;
522 amb 310
523     /* Bubble up the new value */
524    
525 amb 870 while(index>0)
526 amb 310 {
527     int newindex;
528     int temp;
529    
530 amb 870 newindex=(index-1)/4;
531 amb 310
532 amb 869 if(compare(datap[heap[index]],datap[heap[newindex]])>=0)
533     break;
534    
535 amb 310 temp=heap[index];
536     heap[index]=heap[newindex];
537     heap[newindex]=temp;
538    
539     index=newindex;
540     }
541     }
542    
543     /* Repeatedly pull out the root of the heap and refill from the same file */
544    
545     ndata=nfiles;
546    
547     do
548     {
549 amb 870 int index=0;
550 amb 311 FILESORT_VARINT itemsize;
551 amb 310
552 amb 867 if(!buildindex || buildindex(datap[heap[index]],count))
553 amb 310 {
554 amb 867 itemsize=*(FILESORT_VARINT*)(datap[heap[index]]-FILESORT_VARSIZE);
555 amb 310
556 amb 867 WriteFile(fd_out,datap[heap[index]]-FILESORT_VARSIZE,itemsize+FILESORT_VARSIZE);
557 amb 310 count++;
558     }
559    
560 amb 867 if(ReadFile(fds[heap[index]],&itemsize,FILESORT_VARSIZE))
561 amb 310 {
562 amb 870 ndata--;
563 amb 867 heap[index]=heap[ndata];
564 amb 310 }
565     else
566     {
567 amb 867 *(FILESORT_VARINT*)(datap[heap[index]]-FILESORT_VARSIZE)=itemsize;
568 amb 310
569 amb 867 ReadFile(fds[heap[index]],datap[heap[index]],itemsize);
570 amb 310 }
571    
572     /* Bubble down the new value */
573    
574 amb 870 while((4*index+4)<ndata)
575 amb 310 {
576 amb 870 int childindex,newindex;
577 amb 310 int temp;
578    
579 amb 870 childindex=newindex=4*index+1;
580 amb 310
581 amb 870 if(compare(datap[heap[newindex]],datap[heap[++childindex]])>0)
582 amb 871 newindex=childindex;
583 amb 870 if(compare(datap[heap[newindex]],datap[heap[++childindex]])>0)
584 amb 871 newindex=childindex;
585 amb 870 if(compare(datap[heap[newindex]],datap[heap[++childindex]])>0)
586 amb 871 newindex=childindex;
587 amb 869
588     if(compare(datap[heap[index]],datap[heap[newindex]])<=0)
589     break;
590    
591 amb 310 temp=heap[newindex];
592     heap[newindex]=heap[index];
593     heap[index]=temp;
594    
595     index=newindex;
596     }
597    
598 amb 870 if((4*index+4)==ndata)
599 amb 310 {
600 amb 870 int childindex,newindex;
601     int temp;
602    
603     childindex=newindex=4*index+1;
604    
605     if(compare(datap[heap[newindex]],datap[heap[++childindex]])>0)
606 amb 871 newindex=childindex;
607 amb 870 if(compare(datap[heap[newindex]],datap[heap[++childindex]])>0)
608 amb 871 newindex=childindex;
609 amb 870
610     if(compare(datap[heap[index]],datap[heap[newindex]])<=0)
611     ; /* break */
612     else
613     {
614     temp=heap[newindex];
615     heap[newindex]=heap[index];
616     heap[index]=temp;
617     }
618     }
619    
620 amb 871 else if((4*index+3)==ndata)
621 amb 870 {
622     int childindex,newindex;
623     int temp;
624    
625     childindex=newindex=4*index+1;
626    
627     if(compare(datap[heap[newindex]],datap[heap[++childindex]])>0)
628 amb 871 newindex=childindex;
629 amb 870
630     if(compare(datap[heap[index]],datap[heap[newindex]])<=0)
631     ; /* break */
632     else
633     {
634     temp=heap[newindex];
635     heap[newindex]=heap[index];
636     heap[index]=temp;
637     }
638     }
639    
640 amb 871 else if((4*index+2)==ndata)
641 amb 870 {
642 amb 310 int newindex;
643     int temp;
644    
645 amb 870 newindex=4*index+1;
646 amb 310
647 amb 869 if(compare(datap[heap[index]],datap[heap[newindex]])<=0)
648     ; /* break */
649     else
650     {
651     temp=heap[newindex];
652     heap[newindex]=heap[index];
653     heap[index]=temp;
654     }
655 amb 310 }
656     }
657     while(ndata>0);
658    
659     /* Tidy up */
660    
661     tidy_and_exit:
662    
663     if(fds)
664     {
665     for(i=0;i<nfiles;i++)
666     CloseFile(fds[i]);
667     free(fds);
668     }
669    
670     if(heap)
671     free(heap);
672    
673     free(data);
674     free(filename);
675     }
676    
677    
678     /*++++++++++++++++++++++++++++++++++++++
679 amb 269 A function to sort an array of pointers efficiently.
680    
681     The data is sorted using a "Heap sort" http://en.wikipedia.org/wiki/Heapsort,
682     in particular an this good because it can operate in-place and doesn't
683     allocate more memory like using qsort() does.
684    
685     void **datap A pointer to the array of pointers to sort.
686    
687     size_t nitems The number of items of data to sort.
688    
689     int(*compare)(const void *, const void *) The comparison function (identical to qsort if the
690     data to be sorted was an array of things not pointers).
691     ++++++++++++++++++++++++++++++++++++++*/
692    
693 amb 503 void filesort_heapsort(void **datap,size_t nitems,int(*compare)(const void*, const void*))
694 amb 269 {
695     int i;
696    
697     /* Fill the heap by pretending to insert the data that is already there */
698    
699 amb 870 for(i=1;i<nitems;i++)
700 amb 269 {
701     int index=i;
702    
703     /* Bubble up the new value (upside-down, put largest at top) */
704    
705 amb 870 while(index>0)
706 amb 269 {
707     int newindex;
708     void *temp;
709    
710 amb 871 newindex=(index-1)/4;
711 amb 269
712 amb 870 if(compare(datap[index],datap[newindex])<=0) /* reversed compared to filesort_fixed() above */
713 amb 869 break;
714    
715 amb 870 temp=datap[index];
716     datap[index]=datap[newindex];
717     datap[newindex]=temp;
718 amb 269
719     index=newindex;
720     }
721     }
722    
723     /* Repeatedly pull out the root of the heap and swap with the bottom item */
724    
725 amb 870 for(i=nitems-1;i>0;i--)
726 amb 269 {
727 amb 870 int index=0;
728 amb 269 void *temp;
729    
730 amb 870 temp=datap[index];
731     datap[index]=datap[i];
732     datap[i]=temp;
733 amb 269
734     /* Bubble down the new value (upside-down, put largest at top) */
735    
736 amb 870 while((4*index+4)<i)
737 amb 269 {
738 amb 870 int childindex,newindex;
739 amb 269 void *temp;
740    
741 amb 870 childindex=newindex=4*index+1;
742 amb 269
743 amb 870 if(compare(datap[newindex],datap[++childindex])<0) /* reversed compared to filesort_fixed() above */
744     newindex=childindex;
745     if(compare(datap[newindex],datap[++childindex])<0) /* reversed compared to filesort_fixed() above */
746     newindex=childindex;
747     if(compare(datap[newindex],datap[++childindex])<0) /* reversed compared to filesort_fixed() above */
748     newindex=childindex;
749 amb 869
750 amb 870 if(compare(datap[index],datap[newindex])>=0) /* reversed compared to filesort_fixed() above */
751 amb 869 break;
752    
753 amb 870 temp=datap[newindex];
754     datap[newindex]=datap[index];
755     datap[index]=temp;
756 amb 269
757     index=newindex;
758     }
759    
760 amb 870 if((4*index+4)==i)
761 amb 269 {
762 amb 870 int childindex,newindex;
763     void *temp;
764    
765     childindex=newindex=4*index+1;
766    
767     if(compare(datap[newindex],datap[++childindex])<0) /* reversed compared to filesort_fixed() above */
768     newindex=childindex;
769     if(compare(datap[newindex],datap[++childindex])<0) /* reversed compared to filesort_fixed() above */
770     newindex=childindex;
771    
772     if(compare(datap[index],datap[newindex])>=0) /* reversed compared to filesort_fixed() above */
773     ; /* break */
774     else
775     {
776     temp=datap[newindex];
777     datap[newindex]=datap[index];
778     datap[index]=temp;
779     }
780     }
781    
782 amb 871 else if((4*index+3)==i)
783 amb 870 {
784     int childindex,newindex;
785     void *temp;
786    
787     childindex=newindex=4*index+1;
788    
789     if(compare(datap[newindex],datap[++childindex])<0) /* reversed compared to filesort_fixed() above */
790     newindex=childindex;
791    
792     if(compare(datap[index],datap[newindex])>=0) /* reversed compared to filesort_fixed() above */
793     ; /* break */
794     else
795     {
796     temp=datap[newindex];
797     datap[newindex]=datap[index];
798     datap[index]=temp;
799     }
800     }
801    
802 amb 871 else if((4*index+2)==i)
803 amb 870 {
804 amb 269 int newindex;
805     void *temp;
806    
807 amb 870 newindex=4*index+1;
808 amb 269
809 amb 870 if(compare(datap[index],datap[newindex])>=0) /* reversed compared to filesort_fixed() above */
810 amb 869 ; /* break */
811     else
812     {
813 amb 870 temp=datap[newindex];
814     datap[newindex]=datap[index];
815     datap[index]=temp;
816 amb 869 }
817 amb 269 }
818     }
819     }

Properties

Name Value
cvs:description Functions to perform sorting.