Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/librecsort/rswrite.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
#include "rshdr.h"
22
23
/* Writing sorted objects.
24
**
25
** Written by Kiem-Phong Vo (07/08/96).
26
*/
27
28
#define NOTIFY(rs,r,rsrv,endrsrv,cur,out,n) \
29
do { \
30
tmp.data = r->data; \
31
tmp.datalen = r->datalen; \
32
for (;;) \
33
{ for (;;) \
34
{ out.data = cur; \
35
out.datalen = n = endrsrv - cur; \
36
if ((c = rsnotify(rs, RS_WRITE, r, &out, rs->disc)) < 0) \
37
return -1; \
38
if (c == RS_DELETE) \
39
{ out.datalen = 0; \
40
break; \
41
} \
42
if (n >= out.datalen) \
43
break; \
44
RESERVE(rs,f,rsrv,endrsrv,cur,out.datalen); \
45
} \
46
cur += out.datalen; \
47
if (c != RS_INSERT) \
48
break; \
49
r->data = tmp.data; \
50
r->datalen = tmp.datalen; \
51
} \
52
} while (0)
53
54
#define RESERVE(rs,f,rsrv,endrsrv,cur,w) \
55
{ reg ssize_t rw; \
56
if((endrsrv-cur) < w) \
57
{ if(rsrv && sfwrite(f,rsrv,cur-rsrv) != cur-rsrv) return -1; \
58
rw = w < RS_RESERVE ? RS_RESERVE : ((w/1024)+1)*1024; \
59
if(!(rsrv = (uchar*)sfreserve(f,rw,SF_LOCKR)) ) \
60
{ if((rw = sfvalue(f)) < w) rw = w; \
61
if(!(rsrv = (uchar*)sfreserve(f,rw,SF_LOCKR)) ) return -1; \
62
} \
63
endrsrv = (cur = rsrv) + rw; \
64
} \
65
}
66
67
#define WRITE(rs,to,fr,len,t) { \
68
t = (fr); \
69
MEMCPY(to,t,len); \
70
}
71
72
#if __STD_C
73
int rswrite(Rs_t* rs, Sfio_t* f, int type)
74
#else
75
int rswrite(rs, f, type)
76
Rs_t* rs; /* sorting context */
77
Sfio_t* f; /* stream to write to */
78
int type; /* RS_TEXT */
79
#endif
80
{
81
reg Rsobj_t *r, *e, *o;
82
reg uchar *d, *cur, *endrsrv, *rsrv;
83
ssize_t w, head, n;
84
int local, flags, u, c;
85
Rsobj_t out;
86
Rsobj_t tmp;
87
Rsobj_t usr;
88
89
#if 0
90
if(type == RS_OTEXT && (rs->events & RS_READ))
91
{ usr.data = 0;
92
usr.datalen = 0;
93
if((n = rsnotify(rs,RS_READ,&usr,(Void_t*)0,rs->disc))<0)
94
return -1;
95
if(n == RS_INSERT && rsprocess(rs, usr.data, usr.datalen) < 0)
96
return -1;
97
}
98
#endif
99
if(GETLOCAL(rs,local))
100
{ rsrv = rs->rsrv; endrsrv = rs->endrsrv; cur = rs->cur;
101
r = rs->sorted;
102
}
103
else /* external call */
104
{ rsrv = cur = endrsrv = NIL(uchar*);
105
if(!(r = rslist(rs)) )
106
return 0;
107
108
flags = sfset(f,0,1);
109
if(!(flags&SF_WRITE))
110
return -1;
111
sfset(f,(SF_READ|SF_SHARE|SF_PUBLIC),0);
112
}
113
114
#if _PACKAGE_ast
115
head = (rs->type&RS_DSAMELEN) ? -1 : (rs->disc->data & ~0xff) ? 0 : sizeof(ssize_t);
116
#else
117
head = (rs->type&RS_DSAMELEN) ? -1 : sizeof(ssize_t);
118
#endif
119
120
if(type&RS_OTEXT) /* write in plain text */
121
{ u = (rs->events & RS_WRITE) != 0;
122
if((rs->type&RS_UNIQ) && (rs->events & RS_SUMMARY))
123
{ for(; r; r = r->right)
124
{ if(r->equal)
125
{ tmp.data = r->data;
126
tmp.datalen = r->datalen;
127
if((c = RSNOTIFY(rs,RS_SUMMARY,r,0,rs->disc)) < 0)
128
return -1;
129
if(c == RS_DELETE)
130
continue;
131
if(c == RS_INSERT)
132
{ usr = *r;
133
usr.data = tmp.data;
134
usr.datalen = tmp.datalen;
135
usr.right = r;
136
r = &usr;
137
}
138
}
139
w = r->datalen;
140
RESERVE(rs,f,rsrv,endrsrv,cur,w);
141
if (u)
142
NOTIFY(rs,r,rsrv,endrsrv,cur,out,n);
143
else
144
WRITE(rs,cur,r->data,w,d);
145
}
146
}
147
else if(local || (rs->type&RS_UNIQ) )
148
{ if(head>=0)
149
{ for(; r; r = r->right)
150
{ w = r->datalen;
151
RESERVE(rs,f,rsrv,endrsrv,cur,w);
152
if (u)
153
NOTIFY(rs,r,rsrv,endrsrv,cur,out,n);
154
else
155
WRITE(rs,cur,r->data,w,d);
156
}
157
}
158
else
159
{ w = r->datalen;
160
for(; r; r = r->right)
161
{ RESERVE(rs,f,rsrv,endrsrv,cur,w);
162
if (u)
163
NOTIFY(rs,r,rsrv,endrsrv,cur,out,n);
164
else
165
WRITE(rs,cur,r->data,w,d);
166
}
167
}
168
}
169
else
170
{ if(head>=0)
171
{ for(; r; r = r->right)
172
{ w = r->datalen;
173
RESERVE(rs,f,rsrv,endrsrv,cur,w);
174
if (u)
175
NOTIFY(rs,r,rsrv,endrsrv,cur,out,n);
176
else
177
WRITE(rs,cur,r->data,w,d);
178
for(e = r->equal; e; e = e->right)
179
{ w = e->datalen;
180
RESERVE(rs,f,rsrv,endrsrv,cur,w);
181
if (u)
182
NOTIFY(rs,e,rsrv,endrsrv,cur,out,n);
183
else
184
WRITE(rs,cur,e->data,w,d);
185
}
186
}
187
}
188
else
189
{ w = r->datalen;
190
for(; r; r = r->right)
191
{ RESERVE(rs,f,rsrv,endrsrv,cur,w);
192
if (u)
193
NOTIFY(rs,r,rsrv,endrsrv,cur,out,n);
194
else
195
WRITE(rs,cur,r->data,w,d);
196
for(e = r->equal; e; e = e->right)
197
{ RESERVE(rs,f,rsrv,endrsrv,cur,w);
198
if (u)
199
NOTIFY(rs,e,rsrv,endrsrv,cur,out,n);
200
else
201
WRITE(rs,cur,e->data,w,d);
202
}
203
}
204
}
205
}
206
}
207
else if(local)
208
{ n = (ssize_t)r->order; /* chain size already calculated */
209
if(n > 0 && (rs->type&RS_DATA) )
210
n = -n;
211
goto write_size;
212
}
213
else if(rs->type&RS_UNIQ)
214
{ /* count and write chain size */
215
for(n = 0, e = r; e; e = e->right)
216
n += 1;
217
n = -n;
218
write_size:
219
if(n != 0)
220
{ RESERVE(rs,f,rsrv,endrsrv,cur,sizeof(ssize_t));
221
WRITE(rs,cur,(uchar*)(&n),sizeof(ssize_t),d);
222
}
223
224
if((rs->type&RS_UNIQ) && (rs->events & RS_SUMMARY))
225
{ for(; r; r = r->right)
226
{ if(r->equal)
227
{ tmp.data = r->data;
228
tmp.datalen = r->datalen;
229
if((c = RSNOTIFY(rs,RS_SUMMARY,r,0,rs->disc)) < 0)
230
return -1;
231
if(c == RS_DELETE)
232
continue;
233
if(c == RS_INSERT)
234
{ usr = *r;
235
usr.data = tmp.data;
236
usr.datalen = tmp.datalen;
237
usr.right = r;
238
r = &usr;
239
}
240
}
241
w = (n = r->datalen) + (head>0?head:0);
242
RESERVE(rs,f,rsrv,endrsrv,cur,w);
243
if(head>0)
244
WRITE(rs,cur,(uchar*)(&n),sizeof(ssize_t),d);
245
WRITE(rs,cur,r->data,n,d);
246
}
247
}
248
else if(head>=0)
249
{ for(; r; r = r->right)
250
{ w = (n = r->datalen) + head;
251
RESERVE(rs,f,rsrv,endrsrv,cur,w);
252
if(head)
253
WRITE(rs,cur,(uchar*)(&n),sizeof(ssize_t),d);
254
WRITE(rs,cur,r->data,n,d);
255
}
256
}
257
else
258
{ w = r->datalen;
259
for(; r; r = r->right)
260
{ RESERVE(rs,f,rsrv,endrsrv,cur,w);
261
WRITE(rs,cur,r->data,w,d);
262
}
263
}
264
}
265
else
266
{ while(r)
267
{ if((e = r->equal) )
268
{ for(w = 2, e = e->right; e; e = e->right)
269
w += 1;
270
n = (rs->type&RS_DATA) ? -w : w;
271
}
272
else
273
{ for(w = 1, e = r->right; e && !e->equal; e = e->right)
274
w += 1;
275
n = -w;
276
}
277
278
w = r->datalen + (head>0?head:0) + sizeof(ssize_t);
279
RESERVE(rs,f,rsrv,endrsrv,cur,w);
280
WRITE(rs,cur,(uchar*)(&n),sizeof(ssize_t),d);
281
if(head>0)
282
WRITE(rs,cur,(uchar*)(&r->datalen),sizeof(ssize_t),d);
283
WRITE(rs,cur,r->data,r->datalen,d);
284
285
if((o = r->equal) )
286
r = r->right;
287
else if(!(o = r->right) )
288
break;
289
else r = e;
290
291
if(head>=0)
292
{ for(; o != e; o = o->right)
293
{ w = (n = o->datalen) + head;
294
RESERVE(rs,f,rsrv,endrsrv,cur,w);
295
if(head)
296
WRITE(rs,cur,(uchar*)(&n),sizeof(ssize_t),d);
297
WRITE(rs,cur,o->data,n,d);
298
}
299
}
300
else
301
{ w = o->datalen;
302
for(; o != e; o = o->right)
303
{ RESERVE(rs,f,rsrv,endrsrv,cur,w);
304
WRITE(rs,cur,o->data,w,d);
305
}
306
}
307
}
308
}
309
310
if(local)
311
{ rs->rsrv = rsrv; rs->endrsrv = endrsrv; rs->cur = cur;
312
}
313
else
314
{ if(rsrv)
315
sfwrite(f,rsrv,cur-rsrv);
316
rsclear(rs);
317
sfset(f,(flags&(SF_READ|SF_SHARE|SF_PUBLIC)),1);
318
}
319
320
return 0;
321
}
322
323