… | |
… | |
1060 | } |
1060 | } |
1061 | |
1061 | |
1062 | static signed char |
1062 | static signed char |
1063 | eio_dent_cmp (const eio_dirent *a, const eio_dirent *b) |
1063 | eio_dent_cmp (const eio_dirent *a, const eio_dirent *b) |
1064 | { |
1064 | { |
1065 | return a->score - b->score ? a->score - b->score /* works because our signed char is always 0..100 */ |
1065 | return a->score - b->score ? a->score - b->score /* works because our signed char is always 0..100 */ |
1066 | : a->inode < b->inode ? -1 : a->inode > b->inode ? 1 : 0; |
1066 | : a->inode < b->inode ? -1 |
|
|
1067 | : a->inode > b->inode ? 1 |
|
|
1068 | : 0; |
1067 | } |
1069 | } |
1068 | |
1070 | |
1069 | #define EIO_DENT_CMP(i,op,j) eio_dent_cmp (&i, &j) op 0 |
1071 | #define EIO_DENT_CMP(i,op,j) eio_dent_cmp (&i, &j) op 0 |
1070 | |
1072 | |
1071 | #define EIO_SORT_CUTOFF 30 /* quite high, but performs well on many filesystems */ |
1073 | #define EIO_SORT_CUTOFF 30 /* quite high, but performs well on many filesystems */ |
… | |
… | |
1077 | unsigned char bits [9 + sizeof (ino_t) * 8]; |
1079 | unsigned char bits [9 + sizeof (ino_t) * 8]; |
1078 | unsigned char *bit = bits; |
1080 | unsigned char *bit = bits; |
1079 | |
1081 | |
1080 | assert (CHAR_BIT == 8); |
1082 | assert (CHAR_BIT == 8); |
1081 | assert (sizeof (eio_dirent) * 8 < 256); |
1083 | assert (sizeof (eio_dirent) * 8 < 256); |
1082 | assert (offsetof (eio_dirent, inode)); /* we use 0 as sentinel */ |
1084 | assert (offsetof (eio_dirent, inode)); /* we use bit #0 as sentinel */ |
1083 | assert (offsetof (eio_dirent, score)); /* we use 0 as sentinel */ |
1085 | assert (offsetof (eio_dirent, score)); /* we use bit #0 as sentinel */ |
1084 | |
1086 | |
1085 | if (size <= EIO_SORT_FAST) |
1087 | if (size <= EIO_SORT_FAST) |
1086 | return; |
1088 | return; |
1087 | |
1089 | |
1088 | /* first prepare an array of bits to test in our radix sort */ |
1090 | /* first prepare an array of bits to test in our radix sort */ |
… | |
… | |
1243 | flags &= ~(EIO_READDIR_DIRS_FIRST | EIO_READDIR_STAT_ORDER); |
1245 | flags &= ~(EIO_READDIR_DIRS_FIRST | EIO_READDIR_STAT_ORDER); |
1244 | |
1246 | |
1245 | X_LOCK (wrklock); |
1247 | X_LOCK (wrklock); |
1246 | /* the corresponding closedir is in ETP_WORKER_CLEAR */ |
1248 | /* the corresponding closedir is in ETP_WORKER_CLEAR */ |
1247 | self->dirp = dirp = opendir (req->ptr1); |
1249 | self->dirp = dirp = opendir (req->ptr1); |
|
|
1250 | |
1248 | req->flags |= EIO_FLAG_PTR1_FREE | EIO_FLAG_PTR2_FREE; |
1251 | req->flags |= EIO_FLAG_PTR1_FREE | EIO_FLAG_PTR2_FREE; |
1249 | req->ptr1 = dents = flags ? malloc (dentalloc * sizeof (eio_dirent)) : 0; |
1252 | req->ptr1 = dents = flags ? malloc (dentalloc * sizeof (eio_dirent)) : 0; |
1250 | req->ptr2 = names = malloc (namesalloc); |
1253 | req->ptr2 = names = malloc (namesalloc); |
1251 | X_UNLOCK (wrklock); |
1254 | X_UNLOCK (wrklock); |
1252 | |
1255 | |
… | |
… | |
1264 | /* sort etc. */ |
1267 | /* sort etc. */ |
1265 | req->int1 = flags; |
1268 | req->int1 = flags; |
1266 | req->result = dentoffs; |
1269 | req->result = dentoffs; |
1267 | |
1270 | |
1268 | if (flags & EIO_READDIR_STAT_ORDER) |
1271 | if (flags & EIO_READDIR_STAT_ORDER) |
1269 | eio_dent_sort (dents, dentoffs, 0, inode_bits); /* sort by inode exclusively */ |
1272 | eio_dent_sort (dents, dentoffs, flags & EIO_READDIR_DIRS_FIRST ? 7 : 0, inode_bits); |
1270 | else if (flags & EIO_READDIR_DIRS_FIRST) |
1273 | else if (flags & EIO_READDIR_DIRS_FIRST) |
1271 | if (flags & EIO_READDIR_FOUND_UNKNOWN) |
1274 | if (flags & EIO_READDIR_FOUND_UNKNOWN) |
1272 | eio_dent_sort (dents, dentoffs, 7, inode_bits); /* sort by score and inode */ |
1275 | eio_dent_sort (dents, dentoffs, 7, inode_bits); /* sort by score and inode */ |
1273 | else |
1276 | else |
1274 | { |
1277 | { |