Lumiera  0.pre.03
»edit your freedom«
test-psplay.c
Go to the documentation of this file.
1 /*
2  TEST-PSPLAY - test the probabilistic splay tree
3 
4  Copyright (C) Lumiera.org
5  2008, Christian Thaeter <ct@pipapo.org>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
31 #include <time.h>
32 #include <stdlib.h>
33 #include <nobug.h>
34 
35 #include "lib/psplay.h"
36 #include "lib/test/test.h"
37 
38 struct testitem
39 {
40  psplaynode node;
41  char* key;
42 };
43 typedef struct testitem* TestItem;
44 
45 TestItem
46 testitem_new (const char* str)
47 {
48  TestItem self = malloc (sizeof *self);
49  psplaynode_init (&self->node);
50  self->key = strdup (str);
51  return self;
52 }
53 
54 void
55 testitem_delete (TestItem self)
56 {
57  free (self->key);
58  free (self);
59 }
60 
61 
62 
63 static int
64 cmp_fn (const void*, const void*);
65 
66 static const void*
67 key_fn (const PSplaynode);
68 
69 static void
70 delete_fn (PSplaynode);
71 
72 //static psplay_delete_fn
73 //action_fn (PSplaynode node, const enum psplay_order_e which, int level, void* data);
74 
75 static int
76 fcmp_fn (const void*, const void*);
77 
78 static const void*
79 fkey_fn (const PSplaynode);
80 
81 static void
82 fdelete_fn (PSplaynode);
83 
84 //static psplay_delete_fn
85 //action_fn (PSplaynode node, const enum psplay_order_e which, int level, void* data);
86 
87 
89 testitem_print_node (PSplaynode node, const enum psplay_order_enum which, int level, void* data)
90 {
91  FILE* fh = data;
92  static char* sp = " ";
93  if (level>40)
94  {
95  if (which == PSPLAY_PREORDER)
96  fprintf (fh, "%s ...\n", sp);
97  return PSPLAY_CONT;
98  }
99 
100  switch (which)
101  {
102  case PSPLAY_PREORDER:
103  fprintf (fh, "%s%p '%s'\n", sp+40-level, node, ((TestItem)node)->key);
104  if (node->left) fprintf (fh, "%sleft %p '%s'\n", sp+40-level, node->left, ((TestItem)node->left)->key);
105  break;
106  case PSPLAY_INORDER:
107  if (node->right) fprintf (fh, "%sright %p '%s'\n", sp+40-level, node->right, ((TestItem)node->right)->key);
108  break;
109  case PSPLAY_POSTORDER:
110  break;
111  }
112 
113  return PSPLAY_CONT;
114 }
115 
116 void
117 testitem_dump (PSplay self, FILE* dest)
118 {
119  fprintf (dest, "root %p '%s'\n", self->tree, self->tree?((TestItem)self->tree)->key:"EMPTY");
120  psplay_walk (self, NULL, testitem_print_node, 0, dest);
121  fprintf (dest, "\n");
122 }
123 
125 testitem_graphvizprint_node (PSplaynode node, const enum psplay_order_enum which, int level, void* data)
126 {
127  FILE* fh = data;
128 
129  switch (which)
130  {
131  case PSPLAY_PREORDER:
132  if (node->left)
133  fprintf (fh, "\t\"%p:%s\":sw -> \"%p:%s\":ne;\n",
134  node,
135  ((TestItem)node)->key,
136  node->left,
137  ((TestItem)node->left)->key);
138  break;
139  case PSPLAY_INORDER:
140  if (node->right)
141  fprintf (fh, "\t\"%p:%s\":se -> \"%p:%s\":nw;\n",
142  node,
143  ((TestItem)node)->key,
144  node->right,
145  ((TestItem)node->right)->key);
146  break;
147  case PSPLAY_POSTORDER:
148  break;
149  }
150 
151  return PSPLAY_CONT;
152 }
153 
154 
155 
156 void
157 testitem_graphvizdump (PSplay self, FILE* dest)
158 {
159  static int cnt = 0;
160  if (!cnt) cnt = (time(NULL) % 1000) * 100;
161  char cmd[256];
162 
163  sprintf(cmd,"dot -Tps >/var/tmp/dbg%d.ps; gv /var/tmp/dbg%d.ps",cnt,cnt);
164  FILE * graph = popen(cmd, "w");
165 
166  fprintf(graph, "digraph \"%s\" { center=true; size=\"6,6\"; node [color=lightblue2, style=filled];", "psplay");
167  ++cnt;
168 
169  fprintf(graph, "\t\"root\":s -> \"%p:%s\":n;\n",
170  self->tree, self->tree?((TestItem)self->tree)->key:"EMPTY");
171 
172  psplay_walk (self, NULL, testitem_graphvizprint_node, 0, graph);
173 
174  fprintf(graph, "}");
175 
176  pclose(graph);
177 }
178 
179 
180 
181 TESTS_BEGIN
182 
183 TEST ("basic")
184 {
185  psplay splay_tree;
186  psplay_init (&splay_tree, cmp_fn, key_fn, delete_fn);
187 
188  psplay_dump (&splay_tree, stdout);
189 
190  psplay_destroy (&splay_tree);
191 }
192 
193 
194 TEST ("basic_insert_dump")
195 {
196  CHECK (argv[2]);
197 
198  psplay splay_tree;
199  psplay_init (&splay_tree, cmp_fn, key_fn, delete_fn);
200 
201  int end = atoi (argv[2]);
202 
203  char key[1024];
204 
205  for (int i = 1; i <= end; ++i)
206  {
207  sprintf (key, "%d", i);
208  ECHO ("insert %s", key);
209  psplay_insert (&splay_tree, (PSplaynode)testitem_new (key), 100);
210  }
211 
212  psplay_dump (&splay_tree, stderr);
213 
214 #if 0
215  for (int i = 1; i <= end; ++i)
216  {
217  sprintf (key, "%d", i);
218  ECHO ("insert %s", key);
219  psplay_remove_key (&splay_tree, key);
220  psplay_dump (&splay_tree, stderr);
221  }
222  for (int i = end; i; --i)
223  {
224  sprintf (key, "%d", i);
225  ECHO ("insert %s", key);
226  psplay_remove_key (&splay_tree, key);
227  psplay_dump (&splay_tree, stderr);
228  }
229 #endif
230 
231  psplay_destroy (&splay_tree);
232  printf ("done\n");
233 }
234 
235 
236 TEST ("insert_find")
237 {
238  psplay splay_tree;
239  psplay_init (&splay_tree, cmp_fn, key_fn, delete_fn);
240 
241  psplay_insert (&splay_tree, (PSplaynode)testitem_new ("foo"), 100);
242  psplay_insert (&splay_tree, (PSplaynode)testitem_new ("bar"), 100);
243  psplay_insert (&splay_tree, (PSplaynode)testitem_new ("baz"), 100);
244  psplay_insert (&splay_tree, (PSplaynode)testitem_new ("test"), 100);
245  psplay_insert (&splay_tree, (PSplaynode)testitem_new ("pap"), 100);
246  psplay_insert (&splay_tree, (PSplaynode)testitem_new ("qux"), 100);
247 
248  testitem_graphvizdump (&splay_tree, stdout);
249  psplay_dump (&splay_tree, stdout);
250 
251  //TestItem f = (TestItem) psplay_find (&splay_tree, "baz", 100);
252  TestItem f = (TestItem) psplay_find (&splay_tree, "baz", 100);
253  CHECK (f);
254  printf ("found %p (%.4s)\n", &f->node, f->key);
255  psplay_dump (&splay_tree, stdout);
256 
257  f = (TestItem) psplay_find (&splay_tree, "test", 100);
258  CHECK (f);
259  printf ("found %p (%.4s)\n", &f->node, f->key);
260  psplay_dump (&splay_tree, stdout);
261 
262  f = (TestItem) psplay_find (&splay_tree, "test", 100);
263  CHECK (f);
264  printf ("found %p (%.4s)\n", &f->node, f->key);
265  psplay_dump (&splay_tree, stdout);
266 
267  f = (TestItem) psplay_find (&splay_tree, "foo", 100);
268  CHECK (f);
269  printf ("found %p (%.4s)\n", &f->node, f->key);
270  psplay_dump (&splay_tree, stdout);
271 
272 #if 0
273  psplay_delete (psplay_remove (&splay_tree, root.tree));
274  psplay_dump (&splay_tree, stdout);
275 
276  psplay_delete (psplay_remove (&splay_tree, root.tree));
277  psplay_dump (&splay_tree, stdout);
278 
279  psplay_delete (psplay_remove (&splay_tree, root.tree));
280  psplay_dump (&splay_tree, stdout);
281 #endif
282  printf ("destroying\n");
283  psplay_destroy (&splay_tree);
284  psplay_dump (&splay_tree, stdout);
285 #if 0
286  psplay_delete (psplay_remove (&splay_tree, root.tree));
287  psplay_dump (&splay_tree, stdout);
288 
289  psplay_delete (psplay_remove (&splay_tree, root.tree));
290  psplay_dump (&splay_tree, stdout);
291 
292  psplay_delete (psplay_remove (&splay_tree, root.tree));
293  psplay_dump (&splay_tree, stdout);
294 #endif
295  return 0;
296 }
297 
298 TEST ("basic_insert_splay")
299 {
300  CHECK (argv[2]);
301 
302  psplay splay_tree;
303  psplay_init (&splay_tree, cmp_fn, key_fn, delete_fn);
304 
305  int end = atoi (argv[2]);
306 
307  char key[1024];
308 
309  for (int i = 1; i <= end; ++i)
310  {
311  sprintf (key, "%d", i);
312  ECHO ("insert %s", key);
313  psplay_insert (&splay_tree, (PSplaynode)testitem_new (key), 100);
314  }
315 
316  for (int i = end/2; i <= end; ++i)
317  {
318  psplay_dump (&splay_tree, stderr);
319  sprintf (key, "%d", i);
320  psplay_find (&splay_tree, key, 100);
321  }
322  psplay_destroy (&splay_tree);
323  printf ("done\n");
324 }
325 
326 
327 TEST ("basic_rand_insert_dump")
328 {
329  CHECK (argv[2]);
330 
331  psplay splay_tree;
332  psplay_init (&splay_tree, cmp_fn, key_fn, delete_fn);
333 
334  int end = atoi (argv[2]);
335 
336  char key[1024];
337 
338  for (int i = 1; i <= end; ++i)
339  {
340  sprintf (key, "%d", i /*rand()*/);
341  psplay_insert (&splay_tree, (PSplaynode)testitem_new (key), 100);
342  }
343 
344  testitem_graphvizdump (&splay_tree, stdout);
345  //testitem_dump (&splay_tree, stdout);
346 
347  psplay_destroy (&splay_tree);
348  printf ("done\n");
349 }
350 
351 
352 TEST ("fast_insert")
353 {
354  CHECK (argv[2]);
355 
356  psplay splay_tree;
357  psplay_init (&splay_tree, fcmp_fn, fkey_fn, fdelete_fn);
358 
359  int end = atoi (argv[2]);
360 
361  char key[1024];
362 
363  for (int i = 1; i <= end; ++i)
364  {
365  sprintf (key, "%d", i);
366  psplay_insert (&splay_tree, (PSplaynode)testitem_new (key), 100);
367  }
368 
369  psplay_destroy (&splay_tree);
370  printf ("done\n");
371 }
372 
373 
374 
375 
376 TEST ("nonexistant")
377 {
378  CHECK (argv[2]);
379 
380 }
381 
382 
383 TEST ("insert")
384 {
385  CHECK (argv[2]);
386 
387 }
388 
389 
390 
391 TEST ("insert_rand")
392 {
393  CHECK (argv[2]);
394 
395 }
396 
397 
398 
399 TEST ("insert_fastcheck")
400 {
401  CHECK (argv[2]);
402 
403 }
404 
405 
406 
407 TESTS_END
408 
409 
410 
411 
412 /* === PSplay support functions === */
413 
414 static int
415 cmp_fn (const void* a, const void* b)
416 {
417  CHECK (a);
418  CHECK (b);
419  return strcmp (a, b);
420 }
421 
422 static const void*
423 key_fn (const PSplaynode node)
424 {
425  CHECK (node);
426  CHECK (((TestItem)node)->key);
427 
428  return ((TestItem)node)->key;
429 }
430 
431 static void
432 delete_fn (PSplaynode node)
433 {
434  CHECK (node);
435  testitem_delete ((TestItem) node);
436 }
437 
438 
439 
440 
441 static int
442 fcmp_fn (const void* a, const void* b)
443 {
444  return strcmp (a, b);
445 }
446 
447 static const void*
448 fkey_fn (const PSplaynode node)
449 {
450  return ((TestItem)node)->key;
451 }
452 
453 static void
454 fdelete_fn (PSplaynode node)
455 {
456  testitem_delete ((TestItem) node);
457 }
458 
459 
460 
461 
462 
463 
464 
465 /*
466 // Local Variables:
467 // mode: C
468 // c-file-style: "gnu"
469 // indent-tabs-mode: nil
470 // End:
471 */
PSplay psplay_destroy(PSplay self)
Destroy a splay tree Frees all elements and associated resources of a splay tree. ...
Definition: psplay.c:110
Common functions for handling of time values.
Helpers and support macros for defining test executables in C.
PSplay psplay_init(PSplay self, psplay_cmp_fn cmp, psplay_key_fn key, psplay_delete_fn del)
Initialize a splay tree.
Definition: psplay.c:75
PSplaynode psplay_find(PSplay self, const void *key, int splayfactor)
Find a element in a splay tree.
Definition: psplay.c:309
PSplaynode psplay_insert(PSplay self, PSplaynode node, int splayfactor)
Insert a element into a splay tree.
Definition: psplay.c:255
void psplay_delete(PSplay self)
Delete a splay tree Frees all elements and associated resources of a splay tree and then itseld...
Definition: psplay.c:124
Probabilistic splay tree.
PSplaynode psplay_remove(PSplay self, PSplaynode node)
Remove a node from a splay tree.
Definition: psplay.c:349
int psplay_walk(PSplay self, PSplaynode node, psplay_action_fn action, int level, void *data)
Start a tree traversal.
Definition: psplay.c:451
PSplaynode psplay_remove_key(PSplay self, void *key)
Remove a node by key from a splay tree.
Definition: psplay.c:400
PSplaynode psplaynode_init(PSplaynode self)
Initialise a splay tree node The user has to place this nodes within his datastructure and must Initi...
Definition: psplay.c:131
void(* psplay_delete_fn)(PSplaynode node)
Destructor for user defined data Called when an element got removed from a splay tree.
Definition: psplay.h:74