1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *          Copyright (c) 1999-2013 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 <glenn.s.fowler@gmail.com>                *
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 
objcmp(Dt_t * dt,Void_t * arg1,Void_t * arg2,Dtdisc_t * disc)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 
objhash(Dt_t * dt,Void_t * arg,Dtdisc_t * disc)35 static unsigned int objhash(Dt_t* dt, Void_t* arg, Dtdisc_t* disc)
36 {
37 	Obj_t	*o = (Obj_t*)arg;
38 	return dtstrhash(0, (char*)(&o->key), sizeof(long));
39 }
40 
objprint(Void_t * arg)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	100000	/* total number of elements	*/
53 #define	N_PATH	100	/* need N_OBJ%NPATH == 0	*/
54 static Obj_t	Obj[N_OBJ];
55 static Obj_t	*Ord[N_OBJ];
56 
tmain()57 tmain()
58 {
59 	int		i, k, p, meth;
60 	char		*name;
61 	Obj_t		*o, *obj;
62 	Void_t		*walk, *path[N_PATH];
63 	Dt_t		*dt;
64 	Dtstat_t	stat;
65 
66 	/* construct objects */
67 	for(i = 0; i < N_OBJ; ++i)
68 	{	Obj[i].key = i;
69 		Obj[i].ord = i;
70 	}
71 
72 	for(meth = 0; meth < 4; ++meth)
73 	{	switch(meth)
74 		{ case 0:
75 			name = "Dtoset";
76 			if(!(dt = dtopen(&Disc, Dtoset)) )
77 				terror("%s: Can't open dictionary", name);
78 			break;
79 		  case 1:
80 			name = "Dtset";
81 			if(!(dt = dtopen(&Disc, Dtset)) )
82 				terror("%s: Can't open dictionary", name);
83 			break;
84 		  case 2:
85 			name = "Dtlist";
86 			if(!(dt = dtopen(&Disc, Dtlist)) )
87 				terror("%s: Can't open dictionary", name);
88 			break;
89 		  case 3:
90 			name = "Dtrhset";
91 			if(!(dt = dtopen(&Disc, Dtrhset)) )
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(i = 0; i < N_OBJ; ++i)
102 		{	obj = Obj + i;
103 			o = (meth == 2 /* Dtlist */) ? dtappend(dt,obj) : dtinsert(dt,obj);
104 			if(o != obj)
105 				terror("%s: Inserting (key=%d,ord=%d) failed", name, obj->key, obj->ord);
106 		}
107 
108 		/* construct the list of objects in walk order */
109 		tresource(-1,0);
110 		if(!(walk = dtstart(dt, NIL(Void_t*))) )
111 			terror("%s: Can't open walk", name);
112 		for(k = 0, o = dtstep(dt,walk); o; )
113 		{	Ord[k++] = o;
114 			o = dtstep(dt,walk);
115 		}
116 		if(k != N_OBJ)
117 			terror("%s: walk count is %d != expected %d", k, N_OBJ);
118 		tinfo("%s: Timing for walk of all %d objects in dictionary:", name, N_OBJ);
119 		tresource(0,0);
120 
121 		/* now walk different parts of the list */
122 		tresource(-1,0);
123 		for(p = 0; p < N_PATH; ++p)
124 			if(!(path[p] = dtstart(dt, Ord[p*(N_OBJ/N_PATH)])) )
125 				terror("%s: Can't create a path at pos=%d", name, p*(N_OBJ/N_PATH) );
126 		for(k = 0; k < N_OBJ/N_PATH; ++k)
127 		{	for(p = 0;  p < N_PATH; ++p)
128 			{	if(!(o = dtstep(dt, path[p])) )
129 					terror("%s: missing an object", name);
130 				if(o != Ord[p*(N_OBJ/N_PATH) + k] )
131 					terror("%s: object=%d != expected %d", name,
132 						o->key, Ord[p*(N_OBJ/N_PATH) + k]->key);
133 			}
134 		}
135 		for(p = 0; p < N_PATH; ++p)
136 			dtstop(dt, path[p]);
137 		tinfo("%s: Timing for walk of %d paths:", name, N_PATH);
138 		tresource(0,0);
139 
140 		dtstop(dt, walk);
141 
142 		dtclose(dt);
143 	}
144 
145 	texit(0);
146 }
147