ref: 0b9c6fa117c3fe571aed497579b3340b2f8a1164
dir: /sys/src/cmd/disk/exsort.c/
#include <u.h> #include <libc.h> int ulcmp(void*, void*); void swapem(ulong*, long); enum { Wormsize = 157933, }; int wflag; void main(int argc, char *argv[]) { long i, l, x, lobits, hibits, tot; int f, j; char *file; ulong *b, a, lo, hi; ARGBEGIN { default: print("usage: disk/exsort [-w] [file]\n"); exits("usage"); case 'w': wflag++; break; } ARGEND; file = "/adm/cache"; if(argc > 0) file = argv[0]; if(wflag) f = open(file, ORDWR); else f = open(file, OREAD); if(f < 0) { print("cant open %s: %r\n", file); exits("open"); } l = seek(f, 0, 2) / sizeof(long); b = malloc(l*sizeof(long)); if(b == 0) { print("cant malloc %s: %r\n", file); exits("malloc"); } seek(f, 0, 0); if(read(f, b, l*sizeof(long)) != l*sizeof(long)) { print("short read %s: %r\n", file); exits("read"); } lobits = 0; hibits = 0; for(i=0; i<l; i++) { a = b[i]; if(a & (1L<<7)) lobits++; if(a & (1L<<31)) hibits++; } print("lobits = %6ld\n", lobits); print("hibits = %6ld\n", hibits); if(hibits > lobits) { print("swapping\n"); swapem(b, l); } qsort(b, l, sizeof(ulong), ulcmp); tot = 0; for(j=0; j<100; j++) { lo = j*Wormsize; hi = lo + Wormsize; x = 0; for(i=0; i<l; i++) { a = b[i]; if(a >= lo && a < hi) x++; } if(x) { print("disk %2d %6ld blocks\n", j, x); tot += x; } } print("total %6ld blocks\n", tot); if(wflag) { if(hibits > lobits) swapem(b, l); seek(f, 0, 0); if(write(f, b, l*sizeof(long)) != l*sizeof(long)) { print("short write %s\n", file); exits("write"); } } exits(0); } int ulcmp(void *va, void *vb) { ulong *a, *b; a = va; b = vb; if(*a > *b) return 1; if(*a < *b) return -1; return 0; } void swapem(ulong *b, long l) { long i; ulong x, a; for(i=0; i<l; i++, b++) { a = *b; x = (((a>>0) & 0xff) << 24) | (((a>>8) & 0xff) << 16) | (((a>>16) & 0xff) << 8) | (((a>>24) & 0xff) << 0); *b = x; } }