Line data Source code
1 : #include "multiset_test_impl.hpp"
2 :
3 : #include <vset/allocators/mmap_allocator.hpp>
4 : #include <vset/allocators/inmem_allocator.hpp>
5 : #include <vset/multiset.hpp>
6 : #include <vset/memory/manager.hpp>
7 : #include <vset/memory/fsb/aspect.hpp>
8 :
9 : #ifdef NDEBUG
10 : #define TEST_COUNT 10000
11 : #else
12 : #define TEST_COUNT 5
13 : #endif
14 :
15 :
16 : namespace {
17 :
18 : struct data
19 : {
20 : int data1;
21 : int data2;
22 : int data3;
23 : };
24 :
25 : typedef vset::memory::strategy::fsb_mmap<data, ::vset::memory::fsb::aspect_offset > mmap_data_aspect;
26 : typedef vset::memory::manager<mmap_data_aspect> data_buffer;
27 : typedef data_buffer::const_pointer data_const_pointer;
28 : typedef data_buffer::pointer data_pointer;
29 :
30 : typedef unsigned int offset_t;
31 :
32 : struct cmp123
33 : {
34 : mutable data_const_pointer left;
35 : mutable data_const_pointer right;
36 :
37 1 : cmp123(): left(), right() {}
38 :
39 204 : explicit cmp123(const data_buffer& b)
40 : : left(b.end())
41 204 : , right(b.end())
42 204 : {}
43 :
44 360621 : bool operator()(offset_t l, offset_t r) const
45 : {
46 360621 : left.set_offset(l);
47 360621 : right.set_offset(r);
48 :
49 572488 : return left->data1 < right->data1 ||
50 847782 : ( ! ( right->data1 < left->data1 ) && left->data2 < right->data2 ) ||
51 691017 : ( ! ( right->data1 < left->data1 ) && ! ( right->data2 < left->data2 ) && left->data3 < right->data3 );
52 : }
53 : };
54 :
55 : typedef vset::multiset< offset_t, cmp123, vset::inmem_allocator<9> > index123_type;
56 :
57 10010 : data generate()
58 : {
59 : data d;
60 10010 : d.data1 = std::rand()%(TEST_COUNT*10);
61 10010 : d.data2 = std::rand()%(TEST_COUNT*10);
62 10010 : d.data3 = std::rand()%(TEST_COUNT*10);
63 10010 : return d;
64 : }
65 :
66 10010 : bool create(data_buffer& buffer, index123_type& index123)
67 : {
68 10010 : data_pointer ptr = buffer.allocate(1);
69 10010 : *ptr = generate();
70 10010 : index123_type::iterator itr = index123.find( static_cast<offset_t>( ptr.get_offset() ) );
71 10010 : if (itr == index123.end())
72 : {
73 10010 : index123.insert( static_cast<offset_t>( ptr.get_offset() ) );
74 : }
75 : else
76 : {
77 0 : buffer.deallocate(ptr, 1);
78 : }
79 10010 : return itr == index123.end();
80 : }
81 :
82 10000 : void create_one(data_buffer& buffer, index123_type& index123)
83 : {
84 10000 : while(!create(buffer,index123));
85 10000 : }
86 :
87 203 : bool check(data_buffer& buffer, index123_type& index123)
88 : {
89 203 : std::ptrdiff_t buffer_size = std::distance(buffer.begin(), buffer.end());
90 203 : std::ptrdiff_t buffer2_size = std::ptrdiff_t(buffer.count());
91 203 : std::ptrdiff_t index_size = std::ptrdiff_t(index123.size());
92 203 : std::ptrdiff_t index2_size = std::distance(index123.begin(), index123.end());
93 203 : bool size_check_fail = (buffer_size != index_size || buffer2_size != index2_size || buffer2_size != index_size);
94 203 : if ( size_check_fail )
95 : {
96 0 : std::cout << std::endl << "buffer/index size check failed!" << std::endl;
97 0 : std::cout << "buffer_size " << buffer_size << std::endl;
98 0 : std::cout << "index_size " << index_size << std::endl;
99 0 : return false;
100 : }
101 :
102 203 : if ( index123.size() < 2 )
103 : {
104 0 : return true;
105 : }
106 :
107 203 : cmp123 cmp(buffer);
108 203 : index123_type::iterator itr1 = index123.begin();
109 203 : index123_type::iterator itr2 = itr1 + 1;
110 914 : for ( ;itr2!=index123.end(); ++itr1, ++itr2)
111 : {
112 711 : if ( cmp(*itr1, *itr2) )
113 : {
114 711 : continue;
115 : }
116 0 : if ( !cmp(*itr2, *itr1) )
117 : {
118 0 : continue;
119 : }
120 :
121 0 : std::cout << std::endl << "comparator failed!" << std::endl;
122 0 : return false;
123 : }
124 203 : return true;
125 : }
126 :
127 2 : bool init(data_buffer& buffer, index123_type& index123)
128 : {
129 14 : for (int i = 0; i < TEST_COUNT; )
130 : {
131 10 : if ( create(buffer, index123) )
132 : {
133 10 : ++i;
134 10 : if (i % 1000 == 0)
135 : {
136 0 : buffer.buffer().reserve( buffer.buffer().size() + 100);
137 0 : if( !check(buffer, index123) )
138 : {
139 0 : return false;
140 : }
141 : }
142 : }
143 : }
144 2 : return true;
145 : }
146 :
147 : static const volatile int negate_optfix = -1;
148 10005 : bool erase_one(data_buffer& buffer, index123_type& index123)
149 : {
150 10005 : std::ptrdiff_t buffer_size = std::distance(buffer.begin(), buffer.end());
151 10005 : data_pointer ptr = buffer.begin() /* + buffer_size > 0 ? std::rand()%buffer_size : 0*/;
152 10005 : if ( buffer_size > 0 )
153 : {
154 10005 : ptr -= negate_optfix;
155 10005 : ptr += negate_optfix;
156 10005 : ptr += std::rand()%buffer_size;
157 : }
158 :
159 10005 : offset_t offset = static_cast<offset_t>( ptr.get_offset() );
160 :
161 10005 : index123_type::iterator lower = index123.lower_bound(offset);
162 10005 : index123_type::iterator upper = index123.upper_bound(offset);
163 10005 : if (std::distance(lower,upper)!=1 )
164 : {
165 0 : std::cout << ptr->data1 << "," << ptr->data2 << ", " << ptr->data3 << std::endl;
166 0 : std::cout << "std::distance(lower,upper): " << std::distance(lower,upper) << std::endl;
167 0 : return false;
168 : }
169 :
170 10005 : index123.erase( offset );
171 10005 : buffer.deallocate(ptr, 1);
172 10005 : std::ptrdiff_t buffer_size2 = std::distance(buffer.begin(), buffer.end());
173 10005 : if ( (buffer_size - buffer_size2) != 1)
174 : {
175 0 : std::cout << "Buffer size check failed - " << (buffer_size-1) << "!=" << buffer_size2 << std::endl;
176 0 : return false;
177 : }
178 :
179 10005 : return true;
180 : }
181 :
182 1 : bool erase_begin(data_buffer& buffer, index123_type& index123)
183 : {
184 1 : data_pointer ptr = buffer.begin();
185 1 : index123_type::iterator itr = index123.find( static_cast<offset_t>( ptr.get_offset() ) );
186 1 : index123.erase(itr);
187 1 : buffer.deallocate(ptr, 1);
188 1 : return true;
189 : }
190 :
191 1 : bool clear(data_buffer& buffer, index123_type& index123)
192 : {
193 7 : for (int i = 0; i < TEST_COUNT; )
194 : {
195 5 : if ( erase_one(buffer, index123) )
196 : {
197 5 : ++i;
198 5 : if (i%1000 == 0)
199 : {
200 0 : if( !check(buffer, index123) )
201 : {
202 0 : return false;
203 : }
204 : }
205 : }
206 : }
207 :
208 1 : return true;
209 : }
210 :
211 1 : bool stress(data_buffer& buffer, index123_type& index123, int count)
212 : {
213 10001 : for(int i =0 ; i < count && index123.size() > 1; i++)
214 : {
215 10000 : erase_one(buffer, index123);
216 10000 : if (i % 100 == 0)
217 : {
218 100 : if( !check(buffer, index123) )
219 : {
220 0 : return false;
221 : }
222 : }
223 10000 : create_one(buffer, index123);
224 10000 : if (i % 100 == 0)
225 : {
226 100 : if( !check(buffer, index123) )
227 : {
228 0 : return false;
229 : }
230 : }
231 : }
232 :
233 1 : return true;
234 : }
235 : }
236 :
237 1 : bool multiset_test()
238 : {
239 : #if ( ! (__GNUC__==4 && __GNUC_MINOR__==6) )
240 1 : data_buffer buffer;
241 1 : buffer.buffer().open("./test2_.bin");
242 1 : buffer.buffer().reserve(TEST_COUNT*sizeof(data)+TEST_COUNT);
243 1 : buffer.buffer().clear();
244 :
245 2 : index123_type index123( (cmp123(buffer)) );
246 1 : index123.clear();
247 :
248 : return
249 1 : init(buffer, index123)
250 :
251 1 : && check(buffer, index123)
252 1 : && stress(buffer, index123, 10000)
253 1 : && check(buffer, index123)
254 1 : && clear(buffer, index123)
255 1 : && init(buffer, index123)
256 1 : && erase_begin(buffer, index123)
257 3 : && check(buffer, index123);
258 : #else
259 : return true;
260 : #endif
261 :
262 3 : }
|