|
|
1.1 root 1: /* Copyright 1990, AT&T Bell Labs */
2: #include "fsort.h"
3:
4: /* Radix sort by bytes. Records are chained in a list.
5: There are up to 257 bins at each recursion level.
6: The "null bin" is for short strings that have run out;
7: the rest are for byte values 0-255 */
8:
9: int aflag = 0;
10: int uflag = 0;
11: int rflag = 0;
12: int sflag = 0;
13:
14: /* Sort the list s by distributing according to
15: digit d into an array of bins, sorting the bins
16: recursively, and re-collecting them back into the list.
17: If uflag is nonzero return only 1 representative of
18: each equivalence class. The squeeze step noted
19: below determines what bins are in use, and squeezes
20: those into a stack frame, which is contiguous to s.
21: The null bin is handled separately to cut the span
22: of the squeeze loop.
23: Precondition: length(s) > 1 */
24:
25: #define tiebreak(t) \
26: if(uflag) { \
27: t->tail = !aflag? t->head: \
28: listaccum(t->head, t->tail); \
29: t->tail->next = 0; \
30: } else if(keyed && !sflag && t->head->next) { \
31: rflag = fields[0].rflag; \
32: keyed = 0; \
33: sort(t, 0); \
34: keyed = 1; \
35: rflag = 0; \
36: } else
37:
38: void
39: sort(struct list *s, int d)
40: {
41: extern int uflag;
42: struct list *t;
43: struct rec *r, *q;
44: struct list *frame = s + 1; /* stack frame */
45: static struct list bins[257];
46: # define nullbin (bins+256)
47: int nbin; /* number of filled bins */
48: struct list *low; /* lowest unsorted nonnull bin */
49: loop:
50: r = s->head;
51: low = bins + 256;
52: nbin = 0;
53: while(r) {
54: if(keyed)
55: if(r->klen > (len_t)d)
56: t = bins + key(r)[d];
57: else
58: t = nullbin;
59: else
60: if(r->dlen > (len_t)d)
61: t = bins + data(r)[d];
62: else
63: t = nullbin;
64: if(t->head == 0) {
65: if(low > t)
66: low = t;
67: t->head = r;
68: nbin++;
69: } else
70: t->tail->next = r; /* stable sort */
71: t->tail = r;
72: r = r->next;
73: }
74: t = frame; /* t is stack top */
75: if(t+nbin > stackmax)
76: fatal("stack overflow", "", 0);
77: # define push(b) /* onto stack */ \
78: *t = *b, \
79: t->tail->next = 0, \
80: t++, \
81: b->head = 0, \
82: nbin--
83: if(nullbin->head)
84: push(nullbin);
85: for( ; nbin>0; low++)
86: if(low->head)
87: push(low);
88: if(t == frame+1) { /* tail recursion */
89: /* debug(frame, t, d);*/
90: r = frame->head;
91: if(r->len[keyed] <= d) {
92: tiebreak(frame);
93: *s = *frame;
94: return; /* string ran out */
95: }
96: d++;
97: goto loop;
98: }
99: /* debug(frame, t, d);*/
100: t--;
101: if(t->head->next) /* skip 1-item list */
102: sort(t, d+1);
103: if(!rflag) { /* forward order */
104: r = t->tail;
105: while(t > frame) {
106: q = t->head;
107: if((--t>frame || t->head->len[keyed]>d)
108: && t->head->next)
109: sort(t, d+1);
110: else if(t==frame)
111: tiebreak(t);
112: t->tail->next = q; /* concatenate */
113: }
114: s->head = frame->head;
115: s->tail = r;
116: } else { /* reverse order */
117: r = t->head;
118: while(t > frame) {
119: q = t->tail;
120: if((--t>frame || t->head->len[keyed]>d)
121: && t->head->next)
122: sort(t, d+1);
123: else if(t==frame)
124: tiebreak(t);
125: q->next = t->head; /* concatenate */
126: }
127: s->head = r;
128: s->tail = frame->tail;
129: }
130: /* printf("return\n"); debug(s,s+1,d);*/
131: }
132:
133: /*
134: debug(struct list *stack, struct list *top, int d)
135: {
136: printf("----------------------level %d\n", d);
137: while(stack<top) {
138: printout(stack->head, stdout, "stdout");
139: printf("----------------------\n");
140: stack++;
141: }
142: }
143: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.