exsort.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. int ulcmp(const void*, const void*);
  12. void swapem(uint32_t*, int32_t);
  13. enum
  14. {
  15. Wormsize = 157933,
  16. };
  17. int wflag;
  18. void
  19. main(int argc, char *argv[])
  20. {
  21. int32_t i, l, x, lobits, hibits, tot;
  22. int f, j;
  23. char *file;
  24. uint32_t *b, a, lo, hi;
  25. ARGBEGIN {
  26. default:
  27. print("usage: disk/exsort [-w] [file]\n");
  28. exits("usage");
  29. case 'w':
  30. wflag++;
  31. break;
  32. } ARGEND;
  33. file = "/adm/cache";
  34. if(argc > 0)
  35. file = argv[0];
  36. if(wflag)
  37. f = open(file, ORDWR);
  38. else
  39. f = open(file, OREAD);
  40. if(f < 0) {
  41. print("cant open %s: %r\n", file);
  42. exits("open");
  43. }
  44. l = seek(f, 0, 2) / sizeof(int32_t);
  45. b = malloc(l*sizeof(int32_t));
  46. if(b == 0) {
  47. print("cant malloc %s: %r\n", file);
  48. exits("malloc");
  49. }
  50. seek(f, 0, 0);
  51. if(read(f, b, l*sizeof(int32_t)) != l*sizeof(int32_t)) {
  52. print("short read %s: %r\n", file);
  53. exits("read");
  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. print("lobits = %6ld\n", lobits);
  65. print("hibits = %6ld\n", hibits);
  66. if(hibits > lobits) {
  67. print("swapping\n");
  68. swapem(b, l);
  69. }
  70. qsort(b, l, sizeof(uint32_t), ulcmp);
  71. tot = 0;
  72. for(j=0; j<100; j++) {
  73. lo = j*Wormsize;
  74. hi = lo + Wormsize;
  75. x = 0;
  76. for(i=0; i<l; i++) {
  77. a = b[i];
  78. if(a >= lo && a < hi)
  79. x++;
  80. }
  81. if(x) {
  82. print("disk %2d %6ld blocks\n", j, x);
  83. tot += x;
  84. }
  85. }
  86. print("total %6ld blocks\n", tot);
  87. if(wflag) {
  88. if(hibits > lobits)
  89. swapem(b, l);
  90. seek(f, 0, 0);
  91. if(write(f, b, l*sizeof(int32_t)) != l*sizeof(int32_t)) {
  92. print("short write %s\n", file);
  93. exits("write");
  94. }
  95. }
  96. exits(0);
  97. }
  98. int
  99. ulcmp(const void *va, const void *vb)
  100. {
  101. uint32_t *a, *b;
  102. a = va;
  103. b = vb;
  104. if(*a > *b)
  105. return 1;
  106. if(*a < *b)
  107. return -1;
  108. return 0;
  109. }
  110. void
  111. swapem(uint32_t *b, int32_t l)
  112. {
  113. int32_t i;
  114. uint32_t x, a;
  115. for(i=0; i<l; i++, b++) {
  116. a = *b;
  117. x = (((a>>0) & 0xff) << 24) |
  118. (((a>>8) & 0xff) << 16) |
  119. (((a>>16) & 0xff) << 8) |
  120. (((a>>24) & 0xff) << 0);
  121. *b = x;
  122. }
  123. }