plan9fox/sys/src/cmd/disk/exsort.c
2011-03-30 19:35:09 +03:00

137 lines
1.9 KiB
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;
}
}