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