xref: /plan9/sys/src/cmd/disk/exsort.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1 #include	<u.h>
2 #include	<libc.h>
3 
4 int	ulcmp(void*, void*);
5 void	swapem(ulong*, long);
6 
7 enum
8 {
9 	Wormsize	= 157933,
10 };
11 int	wflag;
12 
13 void
main(int argc,char * argv[])14 main(int argc, char *argv[])
15 {
16 	long i, l, x, lobits, hibits, tot;
17 	int f, j;
18 	char *file;
19 	ulong *b, a, lo, hi;
20 
21 	ARGBEGIN {
22 	default:
23 		print("usage: disk/exsort [-w] [file]\n");
24 		exits("usage");
25 	case 'w':
26 		wflag++;
27 		break;
28 	} ARGEND;
29 
30 	file = "/adm/cache";
31 	if(argc > 0)
32 		file = argv[0];
33 
34 	if(wflag)
35 		f = open(file, ORDWR);
36 	else
37 		f = open(file, OREAD);
38 	if(f < 0) {
39 		print("cant open %s: %r\n", file);
40 		exits("open");
41 	}
42 	l = seek(f, 0, 2) / sizeof(long);
43 
44 	b = malloc(l*sizeof(long));
45 	if(b == 0) {
46 		print("cant malloc %s: %r\n", file);
47 		exits("malloc");
48 	}
49 	seek(f, 0, 0);
50 	if(read(f, b, l*sizeof(long)) != l*sizeof(long)) {
51 		print("short read %s: %r\n", file);
52 		exits("read");
53 	}
54 
55 	lobits = 0;
56 	hibits = 0;
57 	for(i=0; i<l; i++) {
58 		a = b[i];
59 		if(a & (1L<<7))
60 			lobits++;
61 		if(a & (1L<<31))
62 			hibits++;
63 	}
64 
65 	print("lobits = %6ld\n", lobits);
66 	print("hibits = %6ld\n", hibits);
67 
68 	if(hibits > lobits) {
69 		print("swapping\n");
70 		swapem(b, l);
71 	}
72 
73 	qsort(b, l, sizeof(ulong), ulcmp);
74 
75 	tot = 0;
76 	for(j=0; j<100; j++) {
77 		lo = j*Wormsize;
78 		hi = lo + Wormsize;
79 
80 		x = 0;
81 		for(i=0; i<l; i++) {
82 			a = b[i];
83 			if(a >= lo && a < hi)
84 				x++;
85 		}
86 		if(x) {
87 			print("disk %2d %6ld blocks\n", j, x);
88 			tot += x;
89 		}
90 	}
91 	print("total   %6ld blocks\n", tot);
92 
93 
94 	if(wflag) {
95 		if(hibits > lobits)
96 			swapem(b, l);
97 		seek(f, 0, 0);
98 		if(write(f, b, l*sizeof(long)) != l*sizeof(long)) {
99 			print("short write %s\n", file);
100 			exits("write");
101 		}
102 	}
103 
104 	exits(0);
105 }
106 
107 int
ulcmp(void * va,void * vb)108 ulcmp(void *va, void *vb)
109 {
110 	ulong *a, *b;
111 
112 	a = va;
113 	b = vb;
114 
115 	if(*a > *b)
116 		return 1;
117 	if(*a < *b)
118 		return -1;
119 	return 0;
120 }
121 
122 void
swapem(ulong * b,long l)123 swapem(ulong *b, long l)
124 {
125 	long i;
126 	ulong x, a;
127 
128 	for(i=0; i<l; i++, b++) {
129 		a = *b;
130 		x = (((a>>0) & 0xff) << 24) |
131 			(((a>>8) & 0xff) << 16) |
132 			(((a>>16) & 0xff) << 8) |
133 			(((a>>24) & 0xff) << 0);
134 		*b = x;
135 	}
136 }
137