Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#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;
        }
}