1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <assert.h>
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h>
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdlib.h>
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <string.h>
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_basics.h"
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcbase.h"
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcassert.h"
10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcprint.h"
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// I need this to avoid some signedness warnings, not sure why
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// #define Char char
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// jrs 19 Aug 2005: m_oset.c relies on Char being a signed char.
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// It appears that plain 'char' on ppc32 is unsigned and so the
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// above #define screws up the AVL tree balancing logic and
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// leads to segfaults.  Commenting it out and using the standard
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// definition of Char from pub_core_basics.h seems a good solution
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// as that has the same signedness on all platforms.
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Crudely redirect various VG_(foo)() functions to their libc equivalents.
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef vg_assert
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define vg_assert(e)                   assert(e)
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef vg_assert2
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define vg_assert2(e, fmt, args...)    assert(e)
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define vgPlain_printf                 printf
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define vgPlain_memset                 memset
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define vgPlain_memcpy                 memcpy
30663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define vgPlain_memmove                memmove
31663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
32663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// Crudely replace some functions (in m_xarray.c, but not needed for
33663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// this unit test) by (hopefully) failing asserts.
34663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define vgPlain_ssort(a,b,c,d) assert(a)
35663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define vgPlain_vcbprintf(a,b,...) assert(a == b)
36663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "coregrind/m_xarray.c"
37663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#undef vgPlain_ssort
38663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#undef vgPlain_vcbprintf
39663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "coregrind/m_poolalloc.c"
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "coregrind/m_oset.c"
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define NN  1000       // Size of OSets being created
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Consistent random number generator, so it produces the
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   same results on all platforms. */
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define random error_do_not_use_libc_random
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt seed = 0;
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt myrandom( void )
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  seed = (1103515245 * seed + 12345);
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return seed;
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
57436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void* allocate_node(const HChar* cc, SizeT szB)
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ return malloc(szB); }
59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void free_node(void* p)
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ return free(p); }
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//---------------------------------------------------------------------------
65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Word example
66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//---------------------------------------------------------------------------
67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// This example shows that an element can be a single value (in this
69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// case a Word), in which case the element is also the key.
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((unused))
72436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic HChar *wordToStr(void *p)
73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
74436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   static HChar buf[32];
75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sprintf(buf, "%ld", *(Word*)p);
76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return buf;
77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((unused))
80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Word wordCmp(void* vkey, void* velem)
81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return *(Word*)vkey - *(Word*)velem;
83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
85663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid example1singleset(OSet* oset, char *descr)
86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int  i, n;
88436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UWord v, prev;
89436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UWord* vs[NN];
90436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UWord *pv;
91436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UWord  sorted_elts[NN]; // Used to test VG_(OSetGen_ResetIterAt)
92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Try some operations on an empty OSet to ensure they don't screw up.
94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetGen_Contains)(oset, &v) );
95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetGen_Lookup)(oset, &v) );
96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetGen_Remove)(oset, &v) );
97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetGen_Next)(oset) );
98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( 0 == VG_(OSetGen_Size)(oset) );
99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Create some elements, with gaps (they're all even) but no dups,
101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // and shuffle them randomly.
102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i++) {
103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vs[i] = VG_(OSetGen_AllocNode)(oset, sizeof(Word));
104436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      *(vs[i]) = 2*(i+1);
105436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      sorted_elts[i] = *(vs[i]);
106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   seed = 0;
108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i++) {
109436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      UWord r1  = myrandom() % NN;
110436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      UWord r2  = myrandom() % NN;
111436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      UWord* tmp= vs[r1];
112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vs[r1]   = vs[r2];
113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vs[r2]   = tmp;
114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Insert the elements
117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i++) {
118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(OSetGen_Insert)(oset, vs[i]);
119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check the size
122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( NN == VG_(OSetGen_Size)(oset) );
123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check we can find all the elements we inserted
125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i++) {
126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assert( VG_(OSetGen_Contains)(oset, vs[i]) );
127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
129436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define FULLCHECKEVERY 20
130436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // Check VG_(OSetGen_ResetIterAt) works before, at, and after each element.
131436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // For some elements, we check all the successive elements.
132436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   for (i = 0; i < NN; i++) {
133436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      UWord k;
134436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      UWord *pval;
135436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Int j;
136436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
137436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      // check ResetIterAt just before an elt gives this elt.
138436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      k = sorted_elts[i] - 1;
139436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      VG_(OSetGen_ResetIterAt) (oset, &k);
140436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      // Check all elts till the end
141436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      for (j = i; j < NN; j++) {
142436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         pval = VG_(OSetGen_Next)(oset);
143436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         assert (*pval == sorted_elts[j]);
144436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         if (i % FULLCHECKEVERY != 0) break;
145436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
146436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
147436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      // check ResetIterAt at an elt gives this elt.
148436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      k = sorted_elts[i];
149436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      VG_(OSetGen_ResetIterAt) (oset, &k);
150436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      // Check all elts till the end
151436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      for (j = i; j < NN; j++) {
152436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         pval = VG_(OSetGen_Next)(oset);
153436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         assert (*pval == sorted_elts[j]);
154436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         if (i % FULLCHECKEVERY != 0) break;
155436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
156436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
157436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      // check ResetIterAt after an elt gives the next elt or nothing
158436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      // when we reset after the last elt.
159436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      k = sorted_elts[i] + 1;
160436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      VG_(OSetGen_ResetIterAt) (oset, &k);
161436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      if (i < NN - 1) {
162436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         for (j = i+1; j < NN; j++) {
163436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            pval = VG_(OSetGen_Next)(oset);
164436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            assert (*pval == sorted_elts[j]);
165436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            if (i % FULLCHECKEVERY != 0) break;
166436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         }
167436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      } else {
168436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         pval = VG_(OSetGen_Next)(oset);
169436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         assert (pval == NULL);
170436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
171436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
172436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
173436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check we cannot find elements we did not insert, below, within (odd
175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // numbers), and above the inserted elements.
176436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   v = 0;
177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   assert( ! VG_(OSetGen_Contains)(oset, &v) );
178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i++) {
179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      v = *(vs[i]) + 1;
180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assert( ! VG_(OSetGen_Contains)(oset, &v) );
181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
182436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   v = 2*(NN+1);
183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   assert( ! VG_(OSetGen_Contains)(oset, &v) );
184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check we can find all the elements we inserted, and the right values
186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // are returned.
187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i++) {
188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assert( vs[i] == VG_(OSetGen_Lookup)(oset, vs[i]) );
189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check that we can iterate over the OSet elements in sorted order, and
192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // there is the right number of them.
193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   n = 0;
194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pv = NULL;
195436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   prev = 0;
196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(OSetGen_ResetIter)(oset);
197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while ( (pv = VG_(OSetGen_Next)(oset)) ) {
198436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      UWord curr = *pv;
199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assert(prev < curr);
200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      prev = curr;
201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      n++;
202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   assert(NN == n);
204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetGen_Next)(oset) );
205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetGen_Next)(oset) );
206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check that we can remove half of the elements, and that their values
208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // are as expected.
209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i += 2) {
210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assert( pv = VG_(OSetGen_Remove)(oset, vs[i]) );
211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assert( pv == vs[i] );
212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check the size
215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( NN/2 == VG_(OSetGen_Size)(oset) );
216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check we can find the remaining elements (with the right values).
218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 1; i < NN; i += 2) {
219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assert( pv = VG_(OSetGen_LookupWithCmp)(oset, vs[i], NULL) );
220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assert( pv == vs[i] );
221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check we cannot find any of the elements we removed.
224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i += 2) {
225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assert( ! VG_(OSetGen_Contains)(oset, vs[i]) );
226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check that we can remove the remaining half of the elements, and that
229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // their values are as expected.
230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 1; i < NN; i += 2) {
231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assert( pv = VG_(OSetGen_Remove)(oset, vs[i]) );
232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assert( pv == vs[i] );
233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Try some more operations on the empty OSet to ensure they don't screw up.
236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetGen_Contains)(oset, &v) );
237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetGen_Lookup)(oset, &v) );
238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetGen_Remove)(oset, &v) );
239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetGen_Next)(oset) );
240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( 0 == VG_(OSetGen_Size)(oset) );
241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Free a few elements
243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(OSetGen_FreeNode)(oset, vs[0]);
244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(OSetGen_FreeNode)(oset, vs[1]);
245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(OSetGen_FreeNode)(oset, vs[2]);
246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Re-insert remaining elements, to give OSetGen_Destroy something to
248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // work with.
249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 3; i < NN; i++) {
250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(OSetGen_Insert)(oset, vs[i]);
251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Print the list
254663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   OSet_Print(oset, descr, wordToStr);
255663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
256663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
257663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
258663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid example1(void)
259663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
260663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   OSet *oset, *oset_empty_clone;
261663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
262436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // Create a static OSet of UWords.  This one uses fast (built-in)
263663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   // comparisons.
264663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
265663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   // First a single oset, no pool allocator.
266663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   oset = VG_(OSetGen_Create)(0,
267663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                              NULL,
268663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                              allocate_node, "oset_test.1", free_node);
269663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   example1singleset(oset, "single oset, no pool allocator");
270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Destroy the OSet
272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(OSetGen_Destroy)(oset);
273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
274663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   // Then same, but with a group allocator
275663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   oset = VG_(OSetGen_Create_With_Pool)(0,
276663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                        NULL,
277663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                        allocate_node, "oset_test.1",
278663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                        free_node,
279663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                        101, sizeof(Word));
280663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   example1singleset(oset, "single oset, pool allocator");
281663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
282663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   // Destroy the OSet
283663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   VG_(OSetGen_Destroy)(oset);
284663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
285663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
286663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   // Then two sets, sharing a group allocator.
287663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   oset = VG_(OSetGen_Create_With_Pool)
288663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      (0,
289663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       NULL,
290663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       allocate_node, "oset_test.1", free_node,
291663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       101, sizeof(Word));
292663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   oset_empty_clone = VG_(OSetGen_EmptyClone) (oset);
293663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   example1singleset(oset, "oset, shared pool");
294663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   example1singleset(oset_empty_clone, "cloned oset, shared pool");
295663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   // Destroy both OSet
296663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
297663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   VG_(OSetGen_Destroy)(oset_empty_clone);
298663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   VG_(OSetGen_Destroy)(oset);
299663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
300663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid example1b(void)
303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int  i, n;
305436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UWord v = 0, prev;
306436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UWord vs[NN];
307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
308436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // Create a static OSet of UWords.  This one uses fast (built-in)
309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // comparisons.
310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OSet* oset = VG_(OSetWord_Create)(allocate_node, "oset_test.2", free_node);
311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Try some operations on an empty OSet to ensure they don't screw up.
313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetWord_Contains)(oset, v) );
314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetWord_Remove)(oset, v) );
315436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vg_assert( ! VG_(OSetWord_Next)(oset, (UWord *)&v) );
316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( 0 == VG_(OSetWord_Size)(oset) );
317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Create some elements, with gaps (they're all even) but no dups,
319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // and shuffle them randomly.
320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i++) {
321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vs[i] = 2*i;
322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   seed = 0;
324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i++) {
325436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      UWord r1  = myrandom() % NN;
326436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      UWord r2  = myrandom() % NN;
327436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      UWord tmp = vs[r1];
328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vs[r1]   = vs[r2];
329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vs[r2]   = tmp;
330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Insert the elements
333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i++) {
334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(OSetWord_Insert)(oset, vs[i]);
335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check the size
338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( NN == VG_(OSetWord_Size)(oset) );
339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check we can find all the elements we inserted
341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i++) {
342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assert( VG_(OSetWord_Contains)(oset, vs[i]) );
343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check we cannot find elements we did not insert, below, within (odd
346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // numbers), and above the inserted elements.
347436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   v = 0xffffffff;
348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   assert( ! VG_(OSetWord_Contains)(oset, v) );
349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i++) {
350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      v = vs[i] + 1;
351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assert( ! VG_(OSetWord_Contains)(oset, v) );
352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   v = NN*2;
354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   assert( ! VG_(OSetWord_Contains)(oset, v) );
355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check we can find all the elements we inserted.
357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i++) {
358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assert( VG_(OSetWord_Contains)(oset, vs[i]) );
359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check that we can iterate over the OSet elements in sorted order, and
362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // there is the right number of them.
363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   n = 0;
364436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   prev = 0;
365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(OSetWord_ResetIter)(oset);
366436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   while ( VG_(OSetWord_Next)(oset, (UWord *)&v) ) {
367436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      UWord curr = v;
368436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      if (n == 0)
369436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         assert(prev == curr);
370436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      else
371436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         assert(prev < curr);
372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      prev = curr;
373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      n++;
374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   assert(NN == n);
376436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vg_assert( ! VG_(OSetWord_Next)(oset, (UWord *)&v) );
377436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vg_assert( ! VG_(OSetWord_Next)(oset, (UWord *)&v) );
378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check that we can remove half of the elements.
380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i += 2) {
381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assert( VG_(OSetWord_Remove)(oset, vs[i]) );
382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check the size
385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( NN/2 == VG_(OSetWord_Size)(oset) );
386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check we can find the remaining elements (with the right values).
388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 1; i < NN; i += 2) {
389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assert( VG_(OSetWord_Contains)(oset, vs[i]) );
390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check we cannot find any of the elements we removed.
393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i += 2) {
394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assert( ! VG_(OSetWord_Contains)(oset, vs[i]) );
395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check that we can remove the remaining half of the elements.
398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 1; i < NN; i += 2) {
399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assert( VG_(OSetWord_Remove)(oset, vs[i]) );
400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Try some more operations on the empty OSet to ensure they don't screw up.
403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetWord_Contains)(oset, v) );
404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetWord_Remove)(oset, v) );
405436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vg_assert( ! VG_(OSetWord_Next)(oset, (UWord *)&v) );
406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( 0 == VG_(OSetWord_Size)(oset) );
407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Re-insert remaining elements, to give OSetWord_Destroy something to
409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // work with.
410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 3; i < NN; i++) {
411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(OSetWord_Insert)(oset, vs[i]);
412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Print the list
415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OSet_Print(oset, "oset1b", wordToStr);
416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Destroy the OSet
418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(OSetWord_Destroy)(oset);
419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//---------------------------------------------------------------------------
423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Struct example
424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//---------------------------------------------------------------------------
425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// This element shows that a key can be in the middle of the element, and
427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// be of arbitrary size and even span multiple (contiguous) fields.  It
428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// also demonstrates how an OSet can be used to implement a list of
429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// non-overlapping intervals.
430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct {
432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int   b1;
433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr  first;
434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr  last;
435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int   b2;
436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBlock;
438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((unused))
440436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic HChar *blockToStr(void *p)
441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
442436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   static HChar buf[32];
443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Block* b = (Block*)p;
444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sprintf(buf, "<(%d) %lu..%lu (%d)>", b->b1, b->first, b->last, b->b2);
445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return buf;
446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Word blockCmp(const void* vkey, const void* velem)
449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr   key  = *(const Addr*)vkey;
451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   const Block* elem = (const Block*)velem;
452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   assert(elem->first <= elem->last);
454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (key < elem->first) return -1;
455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (key > elem->last)  return  1;
456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return 0;
457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid example2(void)
460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int i, n;
462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr a;
463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Block* vs[NN];
464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Block v, prev;
465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Block *pv;
466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Create a dynamic OSet of Blocks.  This one uses slow (custom)
468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // comparisons.
469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OSet* oset = VG_(OSetGen_Create)(offsetof(Block, first),
470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    blockCmp,
471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    allocate_node, "oset_test.3", free_node);
472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Try some operations on an empty OSet to ensure they don't screw up.
474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetGen_Contains)(oset, &v) );
475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetGen_Lookup)(oset, &v) );
476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetGen_Remove)(oset, &v) );
477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetGen_Next)(oset) );
478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( 0 == VG_(OSetGen_Size)(oset) );
479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Create some inputs, with gaps -- intervals are 1..3, 11..13, ... -- but
481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // no dups, and shuffle them randomly.
482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i++) {
483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vs[i] = VG_(OSetGen_AllocNode)(oset, sizeof(Block));
484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vs[i]->b1    = i;
485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vs[i]->first = i*10 + 1;
486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vs[i]->last  = vs[i]->first + 2;
487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vs[i]->b2    = i+1;
488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   seed = 0;
490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i++) {
491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int r1  = myrandom() % NN;
492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int r2  = myrandom() % NN;
493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Block* tmp = vs[r1];
494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vs[r1]  = vs[r2];
495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vs[r2]  = tmp;
496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Insert the elements
499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i++) {
500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(OSetGen_Insert)(oset, vs[i]);
501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check the size
504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( NN == VG_(OSetGen_Size)(oset) );
505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check we can find all the elements we inserted, within the full range
507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // of each Block.
508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i++) {
509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a = vs[i]->first + 0;    assert( VG_(OSetGen_Contains)(oset, &a) );
510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a = vs[i]->first + 1;    assert( VG_(OSetGen_Contains)(oset, &a) );
511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a = vs[i]->first + 2;    assert( VG_(OSetGen_Contains)(oset, &a) );
512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check we cannot find elements we did not insert, below and above the
515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // ranges of the inserted elements.
516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   a = 0;
517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   assert( ! VG_(OSetGen_Contains)(oset, &a) );
518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i++) {
519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a = vs[i]->first - 1;    assert( ! VG_(OSetGen_Contains)(oset, &a) );
520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a = vs[i]->first + 3;    assert( ! VG_(OSetGen_Contains)(oset, &a) );
521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check we can find all the elements we inserted, and the right values
524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // are returned.
525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i++) {
526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a = vs[i]->first + 0;    assert( vs[i] == VG_(OSetGen_Lookup)(oset, &a) );
527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a = vs[i]->first + 1;    assert( vs[i] == VG_(OSetGen_Lookup)(oset, &a) );
528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a = vs[i]->first + 2;    assert( vs[i] == VG_(OSetGen_Lookup)(oset, &a) );
529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assert( vs[i] == VG_(OSetGen_LookupWithCmp)(oset, &a, blockCmp) );
530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check that we can iterate over the OSet elements in sorted order, and
533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // there is the right number of them.
534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   n = 0;
535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pv = NULL;
536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   prev.last = 0;
537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(OSetGen_ResetIter)(oset);
538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while ( (pv = VG_(OSetGen_Next)(oset)) ) {
539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Block curr = *pv;
540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assert(prev.last < curr.first);
541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      prev = curr;
542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      n++;
543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   assert(NN == n);
545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetGen_Next)(oset) );
546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetGen_Next)(oset) );
547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check that we can remove half of the elements, and that their values
549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // are as expected.
550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i += 2) {
551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a = vs[i]->first;    assert( vs[i] == VG_(OSetGen_Remove)(oset, &a) );
552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check the size
555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( NN/2 == VG_(OSetGen_Size)(oset) );
556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check we can find the remaining elements (with the right values).
558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 1; i < NN; i += 2) {
559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a = vs[i]->first + 0;    assert( vs[i] == VG_(OSetGen_Lookup)(oset, &a) );
560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a = vs[i]->first + 1;    assert( vs[i] == VG_(OSetGen_Lookup)(oset, &a) );
561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a = vs[i]->first + 2;    assert( vs[i] == VG_(OSetGen_Lookup)(oset, &a) );
562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check we cannot find any of the elements we removed.
565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i += 2) {
566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a = vs[i]->first + 0;    assert( ! VG_(OSetGen_Contains)(oset, &a) );
567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a = vs[i]->first + 1;    assert( ! VG_(OSetGen_Contains)(oset, &a) );
568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a = vs[i]->first + 2;    assert( ! VG_(OSetGen_Contains)(oset, &a) );
569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check that we can remove the remaining half of the elements, and that
572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // their values are as expected.
573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 1; i < NN; i += 2) {
574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a = vs[i]->first;    assert( vs[i] == VG_(OSetGen_Remove)(oset, &a) );
575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Try some more operations on the empty OSet to ensure they don't screw up.
578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetGen_Contains)(oset, &v) );
579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetGen_Lookup)(oset, &v) );
580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetGen_Remove)(oset, &v) );
581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( ! VG_(OSetGen_Next)(oset) );
582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( 0 == VG_(OSetGen_Size)(oset) );
583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Re-insert all elements, to give OSetGen_Destroy something to work with.
585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < NN; i++) {
586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(OSetGen_Insert)(oset, vs[i]);
587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Destroy the OSet
590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(OSetGen_Destroy)(oset);
591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//-----------------------------------------------------------------------
594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// main()
595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//-----------------------------------------------------------------------
596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main(void)
598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   example1();
600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   example1b();
601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   example2();
602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return 0;
603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
604