ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libeio/eio.c
(Generate patch)

Comparing libeio/eio.c (file contents):
Revision 1.38 by root, Fri Jun 12 20:01:42 2009 UTC vs.
Revision 1.39 by root, Sat Jun 13 03:59:04 2009 UTC

993} 993}
994 994
995static signed char 995static signed char
996eio_dent_cmp (const eio_dirent *a, const eio_dirent *b) 996eio_dent_cmp (const eio_dirent *a, const eio_dirent *b)
997{ 997{
998 return b->score - a->score ? b->score - a->score /* works because our signed char is always 0..100 */ 998 return b->score - a->score ? b->score - a->score /* works because our signed char is always 0..100 */
999 : a->inode < b->inode ? -1 : a->inode > b->inode ? 1 : 0; 999 : a->inode < b->inode ? -1 : a->inode > b->inode ? 1 : 0;
1000} 1000}
1001 1001
1002#define EIO_DENT_CMP(i,op,j) eio_dent_cmp (&i, &j) op 0
1003
1002#define EIO_QSORT_CUTOFF 20 /* quite high, but performs well on many filesystems */ 1004#define EIO_QSORT_CUTOFF 30 /* quite high, but performs well on many filesystems */
1005#define EIO_QSORT_SKIP 60 /* when to skip qsort completely */
1003 1006
1004static void 1007static void
1005eio_dent_sort (eio_dirent *dents, int size) 1008eio_dent_sort (eio_dirent *dents, int size)
1006{ 1009{
1007 int i, j; 1010 int i, j;
1008 1011
1012 if (size <= 1)
1013 return; /* our insertion sort relies on size > 0 */
1014
1009 if (size > EIO_QSORT_CUTOFF * 3) /* skip quicksort for small directories */ 1015 if (size > EIO_QSORT_SKIP) /* skip quicksort for small directories */
1010 { 1016 {
1011 /* first, use quicksort */ 1017 /* first, use quicksort */
1012 /* should be good for 2**31 entries */ 1018 /* should be good for 2**31 entries */
1013 struct rng { int l, r; } rng [32]; 1019 struct rng { int l, r; } rng [32];
1014 1020
1025 { 1031 {
1026 eio_dirent piv = dents [L]; 1032 eio_dirent piv = dents [L];
1027 1033
1028 while (L < R) 1034 while (L < R)
1029 { 1035 {
1030 while (eio_dent_cmp (&dents [R], &piv) >= 0 && L < R) 1036 while (EIO_DENT_CMP (dents [R], >=, piv) && L < R)
1031 --R; 1037 --R;
1032 1038
1033 if (L < R) 1039 if (L < R)
1034 dents [L++] = dents [R]; 1040 dents [L++] = dents [R];
1035 1041
1036 while (eio_dent_cmp (&dents [L], &piv) <= 0 && L < R) 1042 while (EIO_DENT_CMP (dents [L], <=, piv) && L < R)
1037 ++L; 1043 ++L;
1038 1044
1039 if (L < R) 1045 if (L < R)
1040 dents [R--] = dents [L]; 1046 dents [R--] = dents [L];
1041 } 1047 }
1057 else 1063 else
1058 --i; 1064 --i;
1059 } 1065 }
1060 } 1066 }
1061 1067
1062 /* use a simple insertion sort at the end */ 1068 /* use an insertion sort after qsort, or for small arrays */
1069 /* first move the smallest element to the front, to act as a sentinel */
1070 {
1071 int min = 0;
1072
1073 for (i = size > EIO_QSORT_SKIP ? EIO_QSORT_CUTOFF : size; --i; )
1074 if (EIO_DENT_CMP (dents [i], <, dents [min]))
1075 min = i;
1076
1077 /* swap elements 0 and j (minimum) */
1078 {
1079 eio_dirent tmp = dents [0]; dents [0] = dents [min]; dents [min] = tmp;
1080 }
1081 }
1082
1083 /* then do standard insertion sort */
1063 for (i = 1; i < size; ++i) 1084 for (i = 1; i < size; ++i)
1064 { 1085 {
1065 eio_dirent value = dents [i]; 1086 eio_dirent value = dents [i];
1066 1087
1067 for (j = i - 1; j >= 0 && eio_dent_cmp (&dents [j], &value) > 0; --j) 1088 for (j = i - 1; EIO_DENT_CMP (dents [j], >, value); --j)
1068 dents [j + 1] = dents [j]; 1089 dents [j + 1] = dents [j];
1069 1090
1070 dents [j + 1] = value; 1091 dents [j + 1] = value;
1071 } 1092 }
1072} 1093}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines