Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/tests/cdt/tbags.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1999-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
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#include "dttest.h"
21
22
typedef struct _obj_s
23
{ Dtlink_t link;
24
long key;
25
long ord;
26
} Obj_t;
27
28
static int objcmp(Dt_t* dt, Void_t* arg1, Void_t* arg2, Dtdisc_t* disc)
29
{
30
Obj_t *o1 = (Obj_t*)arg1, *o2 = (Obj_t*)arg2;
31
32
return (int)(o1->key - o2->key);
33
}
34
35
static unsigned int objhash(Dt_t* dt, Void_t* arg, Dtdisc_t* disc)
36
{
37
Obj_t *o = (Obj_t*)arg;
38
return (unsigned int)(o->key/8); /* cause hash collisions */
39
}
40
41
static char* objprint(Void_t* arg)
42
{
43
Obj_t *obj = (Obj_t*)arg;
44
static char buf[1024];
45
46
sprintf(buf,"%ld,%ld", obj->key, obj->ord);
47
return buf;
48
}
49
50
Dtdisc_t Disc = { 0, 0, 0, 0, 0, objcmp, objhash, 0, 0 };
51
52
#define N_OBJ 10000 /* total number of elements */
53
#define R_OBJ 10 /* repetition: N_OBJ%R_OBJ == 0 */
54
static Obj_t Obj[N_OBJ];
55
56
tmain()
57
{
58
Dt_t *dt;
59
Dtstat_t stat;
60
Obj_t *p, *o, *obj, proto;
61
char *name;
62
long i, k, mid, n_mid, n_obj, meth;
63
64
/* construct repetitive objects */
65
for(i = 0; i < N_OBJ; i += R_OBJ)
66
{ for(k = 0; k < R_OBJ; ++k)
67
{ Obj[i+k].key = i;
68
Obj[i+k].ord = k;
69
}
70
}
71
72
for(meth = 0; meth < 4; ++meth)
73
{ switch(meth)
74
{ case 0:
75
name = "Dtobag";
76
if(!(dt = dtopen(&Disc, Dtobag)) )
77
terror("%s: Can't open dictionary", name);
78
break;
79
case 1:
80
name = "Dtbag";
81
if(!(dt = dtopen(&Disc, Dtbag)) )
82
terror("%s: Can't open dictionary", name);
83
break;
84
case 2:
85
name = "Dtrhbag";
86
if(!(dt = dtopen(&Disc, Dtrhbag)) )
87
terror("%s: Can't open dictionary", name);
88
break;
89
case 3:
90
name = "Dtlist";
91
if(!(dt = dtopen(&Disc, Dtlist)) )
92
terror("%s: Can't open dictionary", name);
93
break;
94
default: terror("Unknown storage method");
95
break;
96
}
97
tinfo("Testing method %s:", name);
98
dtcustomize(dt, DT_SHARE, 1); /* make it more interesting */
99
100
/* add all objects into dictionary */
101
for(k = 0; k < R_OBJ; ++k)
102
for(i = 0; i < N_OBJ/R_OBJ; ++i)
103
{ obj = Obj + i*R_OBJ + k;
104
o = (meth == 3 || i%2 == 0) ? dtappend(dt,obj) : dtinsert(dt,obj);
105
if(o != obj)
106
terror("%s: dtappend (key=%d,ord=%d) failed", name, obj->key, obj->ord);
107
}
108
109
mid = ((N_OBJ/R_OBJ)/2) * R_OBJ; /* key for middle group */
110
proto.key = mid;
111
proto.ord = -1;
112
113
if(meth == 3) /* testing ATMOST/ATLEAST for Dtlist */
114
{ /* note that dtappend() was used to keep objects in order of insertion */
115
if(!(o = dtatmost(dt, &proto)) )
116
terror("%s: dtatmost (key=%d) failed", name, mid);
117
if(o->ord != 0)
118
terror("%s: dtatmost (key=%d) but ord=%d > 0", name, o->key, o->ord);
119
120
if(!(o = dtatleast(dt, &proto)) )
121
terror("%s: dtatleast (key=%d) failed", name, mid);
122
if(o->ord != R_OBJ-1)
123
terror("%s: dtatleast (key=%d) but ord=%d > 0", name, o->key, o->ord);
124
125
n_obj = 0; /* test ordering */
126
for(p = NIL(Obj_t*), o = dtfirst(dt); o; p = o, o = dtnext(dt,o) )
127
{ n_obj += 1;
128
if(p && p->ord > o->ord)
129
terror("%s: objects not ordered correctly p=%d > o=%d",
130
name, p->ord, o->ord);
131
}
132
if(n_obj != N_OBJ)
133
terror("%s: Bad object count %d != %d", n_obj, N_OBJ);
134
}
135
136
if(meth == 0) /* testing ordering properties of Dtobag */
137
{
138
n_obj = 0; /* test atmost/next */
139
for(o = dtatmost(dt, &proto); o; o = dtnext(dt,o) )
140
{ if(o->key == mid)
141
n_obj += 1;
142
else break;
143
}
144
if(n_obj != R_OBJ)
145
terror("%s: dtatmost/dtnext count n_obj=%d != %d", name, n_obj, R_OBJ);
146
147
n_obj = 0; /* test atleast/prev */
148
for(o = dtatleast(dt, &proto); o; o = dtprev(dt,o) )
149
{ if(o->key == mid)
150
n_obj += 1;
151
else break;
152
}
153
if(n_obj != R_OBJ)
154
terror("%s: dtatleast/dtprev count n_obj=%d != %d", name, n_obj, R_OBJ);
155
156
n_obj = 0; /* test linear order */
157
for(p = NIL(Obj_t*), o = dtfirst(dt); o; p = o, o = dtnext(dt,o) )
158
{ n_obj += 1;
159
if(p && p->key > o->key)
160
terror("%s: objects not ordered correctly p=%d > o=%d",
161
name, p->key, o->key);
162
}
163
if(n_obj != N_OBJ)
164
terror("%s: Bad object count %d != %d", n_obj, N_OBJ);
165
}
166
167
n_mid = n_obj = 0; /* walk forward and count objects */
168
for(o = dtfirst(dt); o; o = dtnext(dt,o))
169
{ n_obj += 1;
170
if(o->key == mid)
171
n_mid += 1;
172
}
173
if(n_obj != N_OBJ)
174
terror("%s: Walk forward n_obj=%d != %d", name, n_obj, N_OBJ);
175
if(n_mid != R_OBJ)
176
terror("%s: Walk forward n_mid=%d != %d", name, n_mid, R_OBJ);
177
178
n_mid = n_obj = 0; /* walk backward and count objects */
179
for(o = dtlast(dt); o; o = dtprev(dt,o))
180
{ n_obj += 1;
181
if(o->key == mid)
182
n_mid += 1;
183
}
184
if(n_obj != N_OBJ)
185
terror("%s: Walk backward n_obj=%d != %d", name, n_obj, N_OBJ);
186
if(n_mid != R_OBJ)
187
terror("%s: Walk backward n_mid=%d != %d", name, n_mid, R_OBJ);
188
189
n_mid = n_obj = 0; /* walk flattened list and count objects */
190
for(o = (Obj_t*)dtflatten(dt); o; o = (Obj_t*)dtlink(dt,o) )
191
{ n_obj += 1;
192
if(o->key == mid)
193
n_mid += 1;
194
}
195
if(n_obj != N_OBJ)
196
terror("%s: Walk flattened list n_obj=%d != %d", name, n_obj, N_OBJ);
197
if(n_mid != R_OBJ)
198
terror("%s: Walk flattened list n_mid=%d != %d", name, n_mid, R_OBJ);
199
200
n_mid = 0; /* delete a bunch of objects */
201
for(i = 0; i < N_OBJ-1; i += R_OBJ)
202
{ obj = Obj + i + R_OBJ/2; /* use the one in the middle of group */
203
204
if((o = dtremove(dt, obj)) == obj )
205
n_mid += 1;
206
else terror("%s: dtremove (key=%d,ord=%d) wrongly yielded (key=%d,ord=%d)",
207
name, obj->key, obj->ord, o->key, o->ord);
208
209
if((o = dtremove(dt, obj)) != NIL(Obj_t*) )
210
terror("%s: dtremove (key=%d,ord=%d) wrongly yielded (key=%d,ord=%d)",
211
name, obj->key, obj->ord, o->key, o->ord);
212
213
if((o = dtdelete(dt, obj)) != NIL(Obj_t*) )
214
n_mid += 1;
215
else terror("%s: dtdelete matching object to (key=%d,ord=%d) failed",
216
name, obj->key, obj->ord);
217
}
218
219
n_obj = 0; /* count the left over */
220
for(o = (Obj_t*)dtflatten(dt); o; o = (Obj_t*)dtlink(dt,o))
221
n_obj += 1;
222
if((n_obj+n_mid) != N_OBJ)
223
terror("%s: wrong count (n_obj=%d + n_del=%d) != %d", name, n_obj, n_mid, N_OBJ);
224
225
dtcustomize(dt, DT_OPTIMIZE, 1); /* balance the tree in Dtobag to reduce depth */
226
if(dtstat(dt, &stat) < 0 )
227
terror("%s: Couldn't get statistics", name);
228
if(stat.size != n_obj)
229
terror("%s: stat.size=%d != %d (actual size)", name, stat.size, n_obj);
230
231
dtclose(dt);
232
}
233
234
texit(0);
235
}
236
237