source: rtems/testsuites/sptests/sprbtree01/init.c @ b2f66e6

4.115
Last change on this file since b2f66e6 was b2f66e6, checked in by Joel Sherrill <joel.sherrill@…>, on 08/02/11 at 19:26:05

2011-08-02 Joel Sherrill <joel.sherrill@…>

PR 1877/cpukit

  • sprbtree01/init.c: Add comparison function for RBTrees.
  • Property mode set to 100644
File size: 16.1 KB
Line 
1/*
2 * Copyright (c) 2010 Gedare Bloom.
3 *
4 *  The license and distribution terms for this file may be
5 *  found in the file LICENSE in this distribution or at
6 *  http://www.rtems.com/license/LICENSE.
7 *
8 *  $Id$
9 */
10
11#include <tmacros.h>
12#include <rtems/rbtree.h>
13
14int numbers[20] = {
1552, 99, 0, 85, 43, 44, 10, 60, 50, 19, 8, 68, 48, 57, 17, 67, 90, 12, 77, 71};
16
17int numbers_sorted[20] = {
18  0, 8, 10, 12, 17, 19, 43, 44, 48, 50, 52, 57, 60, 67, 68, 71, 77, 85, 90, 99};
19
20typedef struct {
21  int              id;
22  int              key;
23  rtems_rbtree_node Node;
24} test_node;
25
26int test_compare_function (
27  rtems_rbtree_node* n1,
28  rtems_rbtree_node* n2
29)
30{
31  int key1 = rtems_rbtree_container_of( n1, test_node, Node )->key;
32  int key2 = rtems_rbtree_container_of( n2, test_node, Node )->key;
33
34  if (key1 > key2) return 1;
35  else if (key1 < key2) return -1;
36  else return 0;
37}
38
39/*
40 * recursively checks tree. if the tree is built properly it should only
41 * be a depth of 7 function calls for 100 entries in the tree.
42 */
43int rb_assert ( rtems_rbtree_node *root )
44{
45  int lh, rh;
46
47  if ( root == NULL )
48    return 1;
49  else {
50    rtems_rbtree_node *ln = rtems_rbtree_left(root);
51    rtems_rbtree_node *rn = rtems_rbtree_right(root);
52
53    /* Consecutive red links */
54    if ( root->color == RBT_RED ) {
55      if ((ln && ln->color == RBT_RED)  || (rn && rn->color == RBT_RED)) {
56        puts ( "Red violation" );
57        return -1;
58      }
59    }
60
61      lh = rb_assert ( ln );
62      rh = rb_assert ( rn );
63
64    /* Invalid binary search tree */
65    if ( ( ln != NULL && test_compare_function(ln, root) > 0 )
66        || ( rn != NULL && test_compare_function(rn, root) < 0 ) )
67    {
68      puts ( "Binary tree violation" );
69      return -1;
70    }
71
72    /* Black height mismatch */
73    if ( lh != -1 && rh != -1 && lh != rh ) {
74      puts ( "Black violation" );
75      return -1;
76    }
77
78    /* Only count black links */
79    if ( lh != -1 && rh != -1 )
80      return ( root->color == RBT_RED ) ? lh : lh + 1;
81    else
82      return -1;
83  }
84}
85
86
87
88rtems_task Init(
89    rtems_task_argument ignored
90    )
91{
92  rtems_rbtree_control  rbtree1;
93  rtems_rbtree_node    *p;
94  test_node            node1, node2;
95  test_node            node_array[100];
96  test_node            search_node;
97  int                  id;
98  int i;
99
100  puts( "\n\n*** TEST OF RTEMS RBTREE API ***" );
101
102  puts( "Init - Initialize rbtree empty" );
103  rtems_rbtree_initialize_empty( &rbtree1, &test_compare_function );
104 
105  /* verify that the rbtree insert work */
106  puts( "INIT - Verify rtems_rbtree_insert with two nodes" );
107  node1.id = 1;
108  node1.key = 1;
109  node2.id = 2;
110  node2.key = 2;
111  rtems_rbtree_insert( &rbtree1, &node1.Node );
112  rtems_rbtree_insert( &rbtree1, &node2.Node );
113
114  p = _RBTree_Insert_unprotected( &rbtree1, NULL );
115  if (p != (void *)(-1))
116    puts( "INIT - FAILED NULL NODE INSERT" );
117
118  _RBTree_Rotate(NULL, RBT_LEFT);
119  i = (node1.Node.parent == &node2.Node);
120  _RBTree_Rotate( &node1.Node,
121                  !node1.Node.child[RBT_LEFT] ? RBT_RIGHT : RBT_LEFT
122                );
123  if ( (node1.Node.parent == &node2.Node) != i )
124    puts( "INIT - FAILED FALSE ROTATION" );
125
126  if (!rb_assert(rbtree1.root) )
127    puts( "INIT - FAILED TREE CHECK" );
128
129  for ( p = rtems_rbtree_get_min(&rbtree1), id = 1 ; p ;
130      p = rtems_rbtree_get_min(&rbtree1) , id++ ) {
131    test_node *t = rtems_rbtree_container_of(p,test_node,Node);
132    if ( id > 2 ) {
133      puts( "INIT - TOO MANY NODES ON RBTREE" );
134      rtems_test_exit(0);
135    }
136    if ( t->id != id ) {
137      puts( "INIT - ERROR ON RBTREE ID MISMATCH" );
138      rtems_test_exit(0);
139    }
140
141    if (!rb_assert(rbtree1.root) )
142      puts( "INIT - FAILED TREE CHECK" );
143  }
144  if (id < 2) {
145    puts("INIT - NOT ENOUGH NODES ON RBTREE");
146    rtems_test_exit(0);
147  }
148
149  puts("INIT - Verify rtems_rbtree_insert with the same value twice");
150  node2.key = node1.key;
151  rtems_rbtree_insert(&rbtree1, &node1.Node);
152  rtems_rbtree_insert(&rbtree1, &node2.Node);
153  for ( p = rtems_rbtree_get_min(&rbtree1), id = 1 ; p ;
154      p = rtems_rbtree_get_min(&rbtree1) , id++ ) {
155    test_node *t = rtems_rbtree_container_of(p,test_node,Node);
156    if ( id > 1 ) {
157      puts( "INIT - TOO MANY NODES ON RBTREE" );
158      rtems_test_exit(0);
159    }
160    if ( t->id != id ) {
161      puts( "INIT - ERROR ON RBTREE ID MISMATCH" );
162      rtems_test_exit(0);
163    }
164
165    if (!rb_assert(rbtree1.root) )
166      puts( "INIT - FAILED TREE CHECK" );
167  }
168  if (id < 1) {
169    puts("INIT - NOT ENOUGH NODES ON RBTREE");
170    rtems_test_exit(0);
171  }
172  node2.key = 2;
173
174  /* verify that the rbtree is empty */
175  puts( "INIT - Verify rtems_rbtree_is_empty" );
176  if(!rtems_rbtree_is_empty(&rbtree1)) {
177    puts( "INIT - TREE NOT EMPTY" );
178    rtems_test_exit(0);
179  }
180
181  puts( "INIT - Verify rtems_XXX on an empty tree" );
182  if(rtems_rbtree_get_min(&rbtree1)) {
183    puts("INIT - get_min on empty returned non-NULL");
184    rtems_test_exit(0);
185  }
186  if(rtems_rbtree_get_max(&rbtree1)) {
187    puts("INIT - get_max on empty returned non-NULL");
188    rtems_test_exit(0);
189  }
190  if(rtems_rbtree_peek_min(&rbtree1)) {
191    puts("INIT - peek_min on empty returned non-NULL");
192    rtems_test_exit(0);
193  }
194  if(rtems_rbtree_peek_max(&rbtree1)) {
195    puts("INIT - peek_max on empty returned non-NULL");
196    rtems_test_exit(0);
197  }
198
199
200  /* verify that the rbtree insert works after a tree is emptied */
201  puts( "INIT - Verify rtems_rbtree_insert after empty tree" );
202  node1.id = 2;
203  node1.key = 2;
204  node2.id = 1;
205  node2.key = 1;
206  rtems_rbtree_insert( &rbtree1, &node1.Node );
207  rtems_rbtree_insert( &rbtree1, &node2.Node );
208
209  puts( "INIT - Verify rtems_rbtree_peek_max/min, rtems_rbtree_extract" );
210  test_node *t1 = rtems_rbtree_container_of(rtems_rbtree_peek_max(&rbtree1),
211         test_node,Node);
212  test_node *t2 = rtems_rbtree_container_of(rtems_rbtree_peek_min(&rbtree1),
213         test_node,Node);
214  if (t1->key - t2->key != 1) {
215    puts( "INIT - Peek Min - Max failed" );
216    rtems_test_exit(0);
217  }
218  p = rtems_rbtree_peek_max(&rbtree1);
219  rtems_rbtree_extract(&rbtree1, p);
220  t1 = rtems_rbtree_container_of(p,test_node,Node);
221  if (t1->key != 2) {
222    puts( "INIT - rtems_rbtree_extract failed");
223    rtems_test_exit(0);
224  }
225  rtems_rbtree_insert(&rbtree1, p);
226
227  for ( p = rtems_rbtree_get_min(&rbtree1), id = 1 ; p ;
228      p = rtems_rbtree_get_min(&rbtree1) , id++ ) {
229    test_node *t = rtems_rbtree_container_of(p,test_node,Node);
230    if ( id > 2 ) {
231      puts( "INIT - TOO MANY NODES ON RBTREE" );
232      rtems_test_exit(0);
233    }
234    if ( t->id != id ) {
235      puts( "INIT - ERROR ON RBTREE ID MISMATCH" );
236      rtems_test_exit(0);
237    }
238  }
239 
240  puts( "INIT - Verify rtems_rbtree_insert with 100 nodes value [0,99]" );
241  for (i = 0; i < 100; i++) {
242    node_array[i].id = i;
243    node_array[i].key = i;
244    rtems_rbtree_insert( &rbtree1, &node_array[i].Node );
245
246    if (!rb_assert(rbtree1.root) )
247      puts( "INIT - FAILED TREE CHECK" );
248  }
249
250  puts( "INIT - Removing 100 nodes" );
251
252  for ( p = rtems_rbtree_get_min(&rbtree1), id = 0 ; p ;
253      p = rtems_rbtree_get_min(&rbtree1) , id++ ) {
254    test_node *t = rtems_rbtree_container_of(p,test_node,Node);
255    if ( id > 99 ) {
256      puts( "INIT - TOO MANY NODES ON RBTREE" );
257      rtems_test_exit(0);
258    }
259    if ( t->id != id ) {
260      puts( "INIT - ERROR ON RBTREE ID MISMATCH" );
261      rtems_test_exit(0);
262    }
263
264    if (!rb_assert(rbtree1.root) )
265      puts( "INIT - FAILED TREE CHECK" );
266  }
267 
268  if(!rtems_rbtree_is_empty(&rbtree1)) {
269    puts( "INIT - TREE NOT EMPTY" );
270    rtems_test_exit(0);
271  }
272
273  puts( "INIT - Verify rtems_rbtree_insert with 100 nodes value [99,0]" );
274  for (i = 0; i < 100; i++) {
275    node_array[i].id = 99-i;
276    node_array[i].key = 99-i;
277    rtems_rbtree_insert( &rbtree1, &node_array[i].Node );
278
279    if (!rb_assert(rbtree1.root) )
280      puts( "INIT - FAILED TREE CHECK" );
281  }
282
283  puts( "INIT - Removing 100 nodes" );
284
285  for ( p = rtems_rbtree_get_min(&rbtree1), id = 0 ; p ;
286      p = rtems_rbtree_get_min(&rbtree1) , id++ ) {
287    test_node *t = rtems_rbtree_container_of(p,test_node,Node);
288    if ( id > 99 ) {
289      puts( "INIT - TOO MANY NODES ON RBTREE" );
290      rtems_test_exit(0);
291    }
292    if ( t->id != id ) {
293      puts( "INIT - ERROR ON RBTREE ID MISMATCH" );
294      rtems_test_exit(0);
295    }
296
297    if (!rb_assert(rbtree1.root) )
298      puts( "INIT - FAILED TREE CHECK" );
299  }
300
301  if(!rtems_rbtree_is_empty(&rbtree1)) {
302    puts( "INIT - TREE NOT EMPTY" );
303    rtems_test_exit(0);
304  }
305
306  /* testing rbtree_extract by adding 100 nodes then removing the 20 with
307   * keys specified by the numbers array, then removing the rest */
308  puts( "INIT - Verify rtems_rbtree_extract with 100 nodes value [0,99]" );
309  for (i = 0; i < 100; i++) {
310    node_array[i].id = i;
311    node_array[i].key = i;
312    rtems_rbtree_insert( &rbtree1, &node_array[i].Node );
313
314    if (!rb_assert(rbtree1.root) )
315      puts( "INIT - FAILED TREE CHECK" );
316  }
317
318  puts( "INIT - Extracting 20 random nodes" );
319
320  for (i = 0; i < 20; i++) {
321    id = numbers[i];
322    rtems_rbtree_extract( &rbtree1, &node_array[id].Node );
323    if (!rb_assert(rbtree1.root) )
324      puts( "INIT - FAILED TREE CHECK" );
325  }
326
327  puts( "INIT - Removing 80 nodes" );
328
329  for ( p = rtems_rbtree_get_min(&rbtree1), id = 0, i = 0 ; p ;
330      p = rtems_rbtree_get_min(&rbtree1) , id++ ) {
331    test_node *t = rtems_rbtree_container_of(p, test_node, Node);
332
333    while ( id == numbers_sorted[i] ) {
334      /* skip if expected minimum (id) is in the set of extracted numbers */
335      id++;
336      i++;
337    }
338
339    if ( id > 99 ) {
340      puts( "INIT - TOO MANY NODES ON RBTREE" );
341      rtems_test_exit(0);
342    }
343
344    if ( t->id != id ) {
345      puts( "INIT - ERROR ON RBTREE ID MISMATCH" );
346      rtems_test_exit(0);
347    }
348
349    if (!rb_assert(rbtree1.root) )
350      puts( "INIT - FAILED TREE CHECK" );
351  }
352
353  if(!rtems_rbtree_is_empty(&rbtree1)) {
354    puts( "INIT - TREE NOT EMPTY" );
355    rtems_test_exit(0);
356  }
357
358  /* Additional rtems_rbtree_extract test which removes a node
359   * with two children while target node has a left child only. */
360  for ( i = 0; i < 7; i++ ) {
361    node_array[i].id = i;
362    node_array[i].key = i;
363  }
364  rtems_rbtree_insert( &rbtree1, &node_array[3].Node );
365  rtems_rbtree_insert( &rbtree1, &node_array[1].Node );
366  rtems_rbtree_insert( &rbtree1, &node_array[5].Node );
367  rtems_rbtree_insert( &rbtree1, &node_array[0].Node );
368  rtems_rbtree_insert( &rbtree1, &node_array[2].Node );
369  rtems_rbtree_insert( &rbtree1, &node_array[4].Node );
370  rtems_rbtree_insert( &rbtree1, &node_array[6].Node );
371  rtems_rbtree_extract( &rbtree1, &node_array[2].Node );
372  /* node_array[1] has now only a left child. */
373  if ( !node_array[1].Node.child[RBT_LEFT] ||
374        node_array[1].Node.child[RBT_RIGHT] )
375     puts( "INIT - LEFT CHILD ONLY NOT FOUND" );
376  rtems_rbtree_extract( &rbtree1, &node_array[3].Node );
377  while( (p = rtems_rbtree_get_max(&rbtree1)) );
378
379  puts( "INIT - Verify rtems_rbtree_get_max with 100 nodes value [99,0]" );
380  for (i = 0; i < 100; i++) {
381    node_array[i].id = 99-i;
382    node_array[i].key = 99-i;
383    rtems_rbtree_insert( &rbtree1, &node_array[i].Node );
384
385    if (!rb_assert(rbtree1.root) )
386      puts( "INIT - FAILED TREE CHECK" );
387  }
388
389  puts( "INIT - Removing 100 nodes" );
390
391  for ( p = rtems_rbtree_get_max(&rbtree1), id = 0 ; p ;
392      p = rtems_rbtree_get_max(&rbtree1) , id++ ) {
393    test_node *t = rtems_rbtree_container_of(p,test_node,Node);
394    if ( id > 99 ) {
395      puts( "INIT - TOO MANY NODES ON RBTREE" );
396      rtems_test_exit(0);
397    }
398    if ( t->id != 99-id ) {
399      puts( "INIT - ERROR ON RBTREE ID MISMATCH" );
400      rtems_test_exit(0);
401    }
402
403    if (!rb_assert(rbtree1.root) )
404      puts( "INIT - FAILED TREE CHECK" );
405  }
406
407  if(!rtems_rbtree_is_empty(&rbtree1)) {
408    puts( "INIT - TREE NOT EMPTY" );
409    rtems_test_exit(0);
410  }
411
412  puts( "INIT - Verify rtems_rbtree_get_max with 100 nodes value [0,99]" );
413  for (i = 0; i < 100; i++) {
414    node_array[i].id = i;
415    node_array[i].key = i;
416    rtems_rbtree_insert( &rbtree1, &node_array[i].Node );
417
418    if (!rb_assert(rbtree1.root) )
419      puts( "INIT - FAILED TREE CHECK" );
420  }
421
422  puts( "INIT - Verify rtems_rbtree_find" );
423  search_node.key = 30;
424  p = rtems_rbtree_find(&rbtree1, &search_node.Node);
425  if(rtems_rbtree_container_of(p,test_node,Node)->id != 30) {
426    puts ("INIT - ERROR ON RBTREE ID MISMATCH");
427    rtems_test_exit(0);
428  }
429
430  puts( "INIT - Verify rtems_rbtree_predecessor/successor");
431  p = rtems_rbtree_predecessor(p);
432  if(p && rtems_rbtree_container_of(p,test_node,Node)->id > 30) {
433    puts ("INIT - ERROR ON RBTREE ID MISMATCH");
434    rtems_test_exit(0);
435  }
436  p = rtems_rbtree_find(&rbtree1, &search_node.Node);
437  p = rtems_rbtree_successor(p);
438  if(p && rtems_rbtree_container_of(p,test_node,Node)->id < 30) {
439    puts ("INIT - ERROR ON RBTREE ID MISMATCH");
440    rtems_test_exit(0);
441  }
442
443  p = rtems_rbtree_find(&rbtree1, &search_node.Node);
444  puts( "INIT - Verify rtems_rbtree_find_header" );
445  if (rtems_rbtree_find_header(p) != &rbtree1) {
446    puts ("INIT - ERROR ON RBTREE HEADER MISMATCH");
447    rtems_test_exit(0);
448  }
449
450  if ( _RBTree_Sibling( NULL ) != NULL )
451    puts ( "INIT - ERROR ON RBTREE NULL SIBLING MISMATCH" );
452  if ( _RBTree_Sibling( rbtree1.root ) != NULL )
453    puts ( "INIT - ERROR ON RBTREE NULL SIBLING MISMATCH" );
454  if ( _RBTree_Grandparent( NULL ) != NULL )
455    puts ( "INIT - ERROR ON RBTREE NULL GRANDPARENT MISMATCH" );
456
457  puts( "INIT - Removing 100 nodes" );
458
459  for ( p = rtems_rbtree_get_max(&rbtree1), id = 99 ; p ;
460      p = rtems_rbtree_get_max(&rbtree1) , id-- ) {
461    test_node *t = rtems_rbtree_container_of(p,test_node,Node);
462    if ( id < 0 ) {
463      puts( "INIT - TOO MANY NODES ON RBTREE" );
464      rtems_test_exit(0);
465    }
466    if ( t->id != id ) {
467      puts( "INIT - ERROR ON RBTREE ID MISMATCH" );
468      rtems_test_exit(0);
469    }
470
471    if (!rb_assert(rbtree1.root) )
472      puts( "INIT - FAILED TREE CHECK" );
473  }
474
475  if(!rtems_rbtree_is_empty(&rbtree1)) {
476    puts( "INIT - TREE NOT EMPTY" );
477    rtems_test_exit(0);
478  }
479
480  if (rtems_rbtree_find_header(p) != NULL) {
481    puts ("INIT - ERROR ON RBTREE HEADER MISMATCH");
482    rtems_test_exit(0);
483  }
484  if (rtems_rbtree_find_header(NULL) != NULL) {
485    puts ("INIT - ERROR ON RBTREE HEADER MISMATCH");
486    rtems_test_exit(0);
487  }
488
489  puts("INIT - Insert 20 random numbers");
490  for (i = 0; i < 20; i++) {
491    node_array[i].id = numbers[i];
492    node_array[i].key = numbers[i];
493    rtems_rbtree_insert( &rbtree1, &node_array[i].Node );
494
495    if (!rb_assert(rbtree1.root) )
496      puts( "INIT - FAILED TREE CHECK" );
497  }
498
499  puts( "INIT - Removing 20 nodes" );
500
501  for ( p = rtems_rbtree_get_min(&rbtree1), id = 0 ; p ;
502      p = rtems_rbtree_get_min(&rbtree1) , id++ ) {
503    test_node *t = rtems_rbtree_container_of(p,test_node,Node);
504    if ( id > 19 ) {
505      puts( "INIT - TOO MANY NODES ON RBTREE" );
506      rtems_test_exit(0);
507    }
508    if ( t->id != numbers_sorted[id] ) {
509      puts( "INIT - ERROR ON RBTREE ID MISMATCH" );
510      rtems_test_exit(0);
511    }
512
513    if (!rb_assert(rbtree1.root) )
514      puts( "INIT - FAILED TREE CHECK" );
515  }
516
517  if(!rtems_rbtree_is_empty(&rbtree1)) {
518    puts( "INIT - TREE NOT EMPTY" );
519    rtems_test_exit(0);
520  }
521
522  puts( "INIT - Verify rtems_rbtree_initialize with 100 nodes value [0,99]" );
523  for (i = 0; i < 100; i++) {
524    node_array[i].id = i;
525    node_array[i].key = i;
526  }
527  rtems_rbtree_initialize( &rbtree1, &test_compare_function,
528                           &node_array[0].Node, 100, sizeof(test_node));
529
530  puts( "INIT - Removing 100 nodes" );
531
532  for ( p = rtems_rbtree_get_min(&rbtree1), id = 0 ; p ;
533      p = rtems_rbtree_get_min(&rbtree1) , id++ ) {
534    test_node *t = rtems_rbtree_container_of(p,test_node,Node);
535    if ( id > 99 ) {
536      puts( "INIT - TOO MANY NODES ON RBTREE" );
537      rtems_test_exit(0);
538    }
539
540    if ( t->id != id ) {
541      puts( "INIT - ERROR ON RBTREE ID MISMATCH" );
542      rtems_test_exit(0);
543    }
544
545    if (!rb_assert(rbtree1.root) )
546      puts( "INIT - FAILED TREE CHECK" );
547  }
548
549  if(!rtems_rbtree_is_empty(&rbtree1)) {
550    puts( "INIT - TREE NOT EMPTY" );
551    rtems_test_exit(0);
552  }
553
554  puts( "*** END OF RTEMS RBTREE API TEST ***" );
555  rtems_test_exit(0);
556}
557
558/* configuration information */
559
560#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
561#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
562
563#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
564#define CONFIGURE_MAXIMUM_TASKS 1
565
566#define CONFIGURE_INIT
567#include <rtems/confdefs.h>
568
569/* global variables */
Note: See TracBrowser for help on using the repository browser.