home *** CD-ROM | disk | FTP | other *** search
- /*
- FileList 1.4
- "Sort.c"
- */
-
- #include "Main.h"
- #include "Stack.h"
- #include "Search.h"
- #include "Utilities.h"
- #include "Sort.h"
-
- #define SHOW 0 /* 0 = Don't show sorting time */
- #define SORT 1 /* 1 = Shell sort, 2 = Quick sort */
-
- /*
- Sorting times (ticks, 60.15 ticks/second):
-
- Shell Quick
-
- 1182 files size -> name 65 57 (88 %)
- name -> name 27 1709
- name -> size 21 18 (86 %)
- size -> size 9 661
-
- 5195 files size -> name 431 354 (82 %)
- name -> name 162 27325
- name -> size 149 118 (79 %)
- size -> size 53 11170
-
- 14550 files size -> name 1625 1215 (75 %)
- name -> name 522 -
- name -> size 631 439 (70 %)
- size -> size 632 -
-
- Conclusion: Quick sort is the fastest, but degenerates dramatically
- if the data is already sorted. The Shell sort is nearly as fast as
- the Quick sort, and much faster under the conditions where Quick sort
- degenerates.
- */
-
- typedef short (*PFI)(); /* Pointer to function returning short */
-
- /* ----- Compare records ----------------------------------------------- */
- /* return <0 if Rec1 < Rec2, =0 if Rec1 == Rec2, >0 if Rec1 > Rec2 */
-
- static short CompareName ( /* By name */
- register FileInfoPtr p1,
- register FileInfoPtr p2)
- {
- return StrCompare(p1->name, p2->name);
- }
-
- static short CompareSize ( /* By size/total (name) */
- register FileInfoPtr p1,
- register FileInfoPtr p2)
- {
- register long d;
-
- d = p1->size - p2->size;
- if (d < 0)
- return -1;
- if (d > 0)
- return 1;
- return CompareName(p1, p2);
- }
-
- static short CompareType ( /* By type/free (name) */
- register FileInfoPtr p1,
- register FileInfoPtr p2)
- {
- register long d;
-
- d = p1->type - p2->type;
- if (d < 0)
- return -1;
- if (d > 0)
- return 1;
- return CompareName(p1, p2);
- }
-
- static short CompareCreator ( /* By creator/files (name) */
- register FileInfoPtr p1,
- register FileInfoPtr p2)
- {
- register long d;
-
- d = p1->creator - p2->creator;
- if (d < 0)
- return -1;
- if (d > 0)
- return 1;
- return CompareName(p1, p2);
- }
-
- static short CompareCdate ( /* By creation date (name) */
- register FileInfoPtr p1,
- register FileInfoPtr p2)
- {
- register long d;
-
- d = p1->cdate - p2->cdate;
- if (d < 0)
- return -1;
- if (d > 0)
- return 1;
- return CompareName(p1, p2);
- }
-
- static short CompareMdate ( /* By modification date (name) */
- register FileInfoPtr p1,
- register FileInfoPtr p2)
- {
- register long d;
-
- d = p1->mdate - p2->mdate;
- if (d < 0)
- return -1;
- if (d > 0)
- return 1;
- return CompareName(p1, p2);
- }
-
- static short CompareVolume ( /* By volume (name) */
- register FileInfoPtr p1,
- register FileInfoPtr p2)
- {
- register short i;
-
- if (!(i = StrCompare(GetVolume(p1), GetVolume(p2))))
- i = CompareName(p1, p2);
- return i;
- }
-
- static short ComparePath ( /* By volume (path, name) */
- register FileInfoPtr p1,
- register FileInfoPtr p2)
- {
- register unsigned char *s1, *s2;
- register short i;
- STACK stack1, stack2;
-
- InitPath(p1, &stack1);
- InitPath(p2, &stack2);
- do {
- s1 = NextPath(&stack1);
- s2 = NextPath(&stack2);
- i = StrCompare(s1 ? s1 : EmptyStr, s2 ? s2 : EmptyStr);
- } while (s1 && s2 && !i);
- if (!i)
- i = CompareName(p1, p2);
- return i;
- }
-
- #if SHOW
- /* ----- Show sort time ------------------------------------------------ */
-
- static void ShowTime (register unsigned long ticks)
- {
- register DialogPtr dialog;
- short item;
- unsigned char number[10];
-
- NumToString(ticks, number);
- ParamText(number, "\p ticks", EmptyStr, EmptyStr);
- CenterDialog('DLOG', MessageDialog);
- if (dialog = GetNewDialog(MessageDialog, 0L, -1L)) {
- ModalDialog(0L, &item);
- DisposDialog(dialog);
- }
- }
- #endif
-
- #if SORT == 1
- /* ----- Sort records (Shell sort) ------------------------------------- */
-
- static void Sort (
- register long *xp,
- register long n,
- register PFI compare)
- {
- register long i, j, gap, temp;
- register char *fp;
- #if SHOW
- unsigned long start;
- while ((start = Ticks) == Ticks)
- ;
- #endif
-
- fp = InfoBase;
- for (gap = 1; gap <= n; gap = 3*gap + 1)
- ;
- while(gap > 3) {
- gap = gap/3;
- for (i = gap; i < n; ++i) {
- temp = xp[i];
- j = i;
- while ((j >= gap) &&
- ((*compare)(
- fp + (xp[j-gap] & 0x7FFFFFFF),
- fp + (temp & 0x7FFFFFFF)) > 0)) {
- xp[j] = xp[j-gap];
- j -= gap;
- }
- xp[j] = temp;
- }
- }
- #if SHOW
- ShowTime(Ticks - start);
- #endif
- }
- #endif
-
- #if SORT == 2
- /* ----- Sort records (Quick sort) ------------------------------------- */
-
- static long *Xp;
- static PFI Compare;
-
- static void Swap (
- register long i,
- register long j)
- {
- register long t;
-
- t = Xp[i];
- Xp[i] = Xp[j];
- Xp[j] = t;
- }
-
- static void Qsort (
- register long first,
- register long last)
- {
- static long i;
- register long j;
-
- while (last - first > 1) {
- i = first;
- j = last;
- for (;;) {
- while (++i < last &&
- (*Compare)(InfoBase + Xp[i], InfoBase + Xp[first]) < 0)
- ;
- while (--j > first &&
- (*Compare)(InfoBase + Xp[j], InfoBase + Xp[first]) > 0)
- ;
- if (i >= j)
- break;
- Swap(i, j);
- }
- Swap(first, j);
- if (j - first < last - (j + 1)) {
- Qsort(first, j);
- first = j + 1;
- }
- else {
- Qsort(j + 1, last);
- last = j;
- }
- }
- }
-
- static void Sort (
- register long *xp,
- long n,
- register PFI compare)
- {
- #if SHOW
- unsigned long start;
- while ((start = Ticks) == Ticks)
- ;
- #endif
- Xp = xp;
- Compare = compare;
- Qsort (0, n);
- #if SHOW
- ShowTime(Ticks - start);
- #endif
- }
- #endif
-
- /* ----- Sort interface ------------------------------------------------ */
-
- static PFI FileCompare[] = {
- CompareName,
- CompareSize,
- CompareType,
- CompareCreator,
- CompareCdate,
- CompareMdate,
- CompareVolume,
- ComparePath };
-
- static PFI VolumeCompare[] = {
- CompareName,
- CompareType,
- CompareSize,
- CompareCreator,
- CompareCdate,
- CompareMdate };
-
- void SortFiles (register short how)
- {
- Sort(FileData.base, FileData.count, FileCompare[how]);
- }
-
- void SortVolumes(register short how)
- {
- Sort(VolumeData.base, VolumeData.count, VolumeCompare[how]);
- }
-