Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/librecsort/rs-radix.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1996-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Phong Vo <[email protected]> *
18
* Glenn Fowler <[email protected]> *
19
* *
20
***********************************************************************/
21
/* Radix sort.
22
** Strategy:
23
** 1. All records are kept on a linked list.
24
** 2. In each phase, portions of the linked list are sorted using
25
** bucketing based on the byte at the position for that phase.
26
**
27
** Written by Kiem-Phong Vo (07/08/96).
28
*/
29
30
#include "rshdr.h"
31
32
typedef struct rsradix_s
33
{ Rsobj_t* list;
34
} Rsradix_t;
35
36
#if __STD_C
37
static int radixinsert(Rs_t* rs, reg Rsobj_t* obj)
38
#else
39
static int radixinsert(rs, obj)
40
Rs_t* rs;
41
reg Rsobj_t* obj;
42
#endif
43
{
44
reg Rsobj_t* r;
45
reg Rsradix_t* radix = (Rsradix_t*)rs->methdata;
46
47
obj->equal = NIL(Rsobj_t*);
48
if((r = radix->list) )
49
r->left->right = obj;
50
else radix->list = (r = obj);
51
r->left = obj;
52
return 0;
53
}
54
55
#if __STD_C
56
static Rsobj_t* radixlist(Rs_t* rs)
57
#else
58
static Rsobj_t* radixlist(rs)
59
Rs_t* rs;
60
#endif
61
{
62
reg Rsobj_t *work, *r;
63
reg ssize_t ph;
64
reg Rsobj_t **bin, *t, *empty, *list, *endl, *next, **lo, **maxpart;
65
reg ssize_t n, maxph;
66
Rsobj_t *part[UCHAR_MAX+1];
67
reg Rsradix_t* radix = (Rsradix_t*)rs->methdata;
68
69
if (!radix->list)
70
return NIL(Rsobj_t*);
71
for(lo = part, maxpart = part + UCHAR_MAX+1; lo < maxpart; ++lo)
72
*lo = NIL(Rsobj_t*);
73
74
work = radix->list; radix->list = NIL(Rsobj_t*);
75
work->left->right = NIL(Rsobj_t*);
76
list = NIL(Rsobj_t*);
77
78
if(rs->type&RS_KSAMELEN)
79
{ maxph = work->keylen-1;
80
for(work->order = 0; work; )
81
{ next = work->left->right; work->left->right = NIL(Rsobj_t*);
82
83
lo = maxpart; n = 0;
84
if((ph = (ssize_t)work->order) == maxph)
85
{ for(; work; work = work->right)
86
{ bin = part + work->key[ph];
87
if(!(r = *bin) )
88
{ *bin = work;
89
if(lo > bin)
90
lo = bin;
91
n += 1;
92
}
93
else EQUAL(r,work,t);
94
}
95
96
endl = list ? (endl->right = *lo) : (list = *lo);
97
*lo = NIL(Rsobj_t*);
98
for(bin = lo+1, n -= 1; n > 0; ++bin)
99
{ if(!(r = *bin) )
100
continue;
101
n -= 1;
102
endl = (endl->right = r);
103
*bin = NIL(Rsobj_t*);
104
}
105
106
work = next;
107
}
108
else
109
{ for(; work; work = work->right)
110
{ bin = part + work->key[ph];
111
if((r = *bin) )
112
r->left->right = work;
113
else
114
{ r = *bin = work;
115
if(lo > bin)
116
lo = bin;
117
n += 1;
118
}
119
r->left = work;
120
}
121
122
ph += 1;
123
work = *lo; t = work->left; *lo = NIL(Rsobj_t*);
124
work->order = ph;
125
for(bin = lo+1, n -= 1; n > 0; ++bin)
126
{ if((r = *bin) )
127
{ n -= 1;
128
r->order = ph;
129
t->right = r;
130
t = r->left;
131
132
*bin = NIL(Rsobj_t*);
133
}
134
}
135
136
t->right = next;
137
}
138
139
if(work && work->left == work)
140
{ endl = list ? (endl->right = work) : (list = work);
141
for(work = work->right; work; work = work->right)
142
{ if(work->left != work)
143
break;
144
endl = endl->right = work;
145
}
146
}
147
}
148
}
149
else
150
{ for(work->order = 0; work; )
151
{ next = work->left->right; work->left->right = NIL(Rsobj_t*);
152
empty = NIL(Rsobj_t*);
153
lo = maxpart; n = 0;
154
ph = (ssize_t)work->order;
155
for(; work; work = work->right)
156
{ if(ph >= work->keylen)
157
{ if(!empty)
158
empty = work;
159
else EQUAL(empty,work,t);
160
}
161
else
162
{ bin = part + work->key[ph];
163
if((r = *bin) )
164
r->left->right = work;
165
else
166
{ r = *bin = work;
167
if(lo > bin)
168
lo = bin;
169
n += 1;
170
}
171
r->left = work;
172
}
173
}
174
175
if(empty)
176
{ if(list)
177
endl->right = empty;
178
else list = empty;
179
endl = empty;
180
}
181
182
if(n <= 0)
183
work = next;
184
else
185
{ ph += 1;
186
work = *lo; *lo = NIL(Rsobj_t*);
187
t = work->left;
188
work->order = ph;
189
190
for(bin = lo+1, n -= 1; n > 0; ++bin)
191
{ if((r = *bin) )
192
{ n -= 1;
193
194
r->order = ph;
195
t->right = r;
196
t = r->left;
197
198
*bin = NIL(Rsobj_t*);
199
}
200
}
201
202
t->right = next;
203
}
204
205
if(work && work->left == work)
206
{ endl = list ? (endl->right = work) : (list = work);
207
for(work = work->right; work; work = work->right)
208
{ if(work->left != work)
209
break;
210
endl = endl->right = work;
211
}
212
}
213
}
214
}
215
216
if(list)
217
{ list->left = endl;
218
endl->right = NIL(Rsobj_t*);
219
}
220
221
return list;
222
}
223
224
/* public method */
225
static Rsmethod_t _Rsradix =
226
{ radixinsert,
227
radixlist,
228
sizeof(Rsradix_t),
229
RS_MTRADIX,
230
"radix",
231
"Radix sort."
232
};
233
234
__DEFINE__(Rsmethod_t*, Rsradix, &_Rsradix);
235
236
#ifdef NoF
237
NoF(rsradix)
238
#endif
239
240