1 /*===========================================================================
2 *
3 * PUBLIC DOMAIN NOTICE
4 * National Center for Biotechnology Information
5 *
6 * This software/database is a "United States Government Work" under the
7 * terms of the United States Copyright Act. It was written as part of
8 * the author's official duties as a United States Government employee and
9 * thus cannot be copyrighted. This software/database is freely available
10 * to the public for use. The National Library of Medicine and the U.S.
11 * Government have not placed any restriction on its use or reproduction.
12 *
13 * Although all reasonable efforts have been taken to ensure the accuracy
14 * and reliability of the software and data, the NLM and the U.S.
15 * Government do not and cannot warrant the performance or results that
16 * may be obtained by using this software or data. The NLM and the U.S.
17 * Government disclaim all warranties, express or implied, including
18 * warranties of performance, merchantability or fitness for any particular
19 * purpose.
20 *
21 * Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 */
26
27 // allow g++ to find INT64_MAX in stdint.h
28 #define __STDC_LIMIT_MACROS
29
30 #include <ktst/unit_test.hpp>
31
32 #include <klib/log.h>
33 #include <klib/out.h>
34 #include <klib/rc.h>
35 #include <kfc/ctx.h>
36 #include <kfc/except.h>
37 #include <kfc/xc.h>
38 #include <kfs/directory.h>
39 #include <kdb/manager.h>
40 #include <kdb/table.h>
41 #include <kdb/rowset.h>
42
43 #include <stdlib.h>
44 #include <time.h>
45
46 #include <vector>
47 #include <set>
48 #include <algorithm>
49 #include <string>
50
51 #define ENTRY \
52 HYBRID_FUNC_ENTRY ( rcDB, rcVector, rcValidating ); \
53 m_ctx = ctx
54
55 #define EXIT \
56 REQUIRE ( ! FAILED () ); \
57 Release()
58
59 ////// additional REQUIRE macros
60
61 #define REQUIRE_FAILED() ( REQUIRE ( FAILED () ), CLEAR() )
62
63 #define REQUIRE_EXPR(expr) \
64 (expr); \
65 REQUIRE ( !FAILED () )
66
67 #define REQUIRE_EXPR_FAILED(expr) \
68 (expr); \
69 REQUIRE_FAILED()
70
71 #define THROW_IF_FAILED(msg) \
72 if ( m_ctx -> rc != 0 ) \
73 throw std :: logic_error ( (msg) );
74
75 TEST_SUITE(KRowSetTestSuite);
76
vector_inserter(ctx_t ctx,int64_t row_id,void * data)77 void vector_inserter ( ctx_t ctx, int64_t row_id, void *data )
78 {
79 std::vector<int64_t> * rows = (std::vector<int64_t> *) data;
80 rows->push_back ( row_id );
81 }
82
83 class RowSetFixture
84 {
85 public:
86 const KCtx* m_ctx; // points into the test case's local memory
87 KDirectory* m_wd;
88 KDBManager* m_mgr;
89 KTable * m_table;
90 std::string m_tableName;
91
RowSetFixture()92 RowSetFixture()
93 : m_ctx(NULL)
94 , m_table(NULL)
95 , m_tableName("")
96 {
97 THROW_ON_RC ( KDirectoryNativeDir ( & m_wd ) );
98 THROW_ON_RC ( KDBManagerMakeUpdate ( & m_mgr, m_wd ) );
99 }
100
~RowSetFixture()101 virtual ~RowSetFixture()
102 {
103 if ( m_table != NULL && m_tableName != "" )
104 CloseRemoveTable();
105
106 KDBManagerRelease ( m_mgr );
107 KDirectoryRelease ( m_wd );
108 }
109
GetTable(const char * name)110 const KTable * GetTable ( const char * name )
111 {
112 if ( m_tableName . empty() )
113 m_tableName = name;
114
115 if ( m_tableName != name )
116 throw std :: invalid_argument ( "name does not match a name of already create table" );
117
118 if ( m_table == NULL )
119 CreateTable ();
120
121 return m_table;
122 }
123
CloseRemoveTable()124 void CloseRemoveTable ()
125 {
126 KTableRelease ( m_table );
127 m_table = NULL;
128
129 KDirectoryRemove ( m_wd, true, m_tableName . c_str () );
130 m_tableName = "";
131 }
132
GenerateId(int64_t range_start,int64_t range_count)133 int64_t GenerateId ( int64_t range_start, int64_t range_count )
134 {
135 if ( range_start == -1 )
136 range_start = 0;
137
138 if ( range_count == -1 || range_start + range_count < 0 )
139 range_count = INT64_MAX - range_start;
140
141 int64_t generated_id = ((int64_t)rand() << 32) | rand();
142 generated_id &= INT64_MAX; // make sure it is positive
143
144 generated_id = generated_id % range_count;
145 generated_id += range_start;
146
147 return generated_id;
148 }
149
150 /*
151 * "density" - can is a number between -1 and 8.
152 * -1 means that most probably each row will go to a separate leaf
153 * 0 means that rows might go to same leaves, but those leaves should still not be dense (and store data in array of ranges, not in bitmap)
154 * from 1 to 8 change density level:
155 * - 1 means that every (up to) 8k rows go to a each leaf
156 * - 8 means that every (up to) 65k rows (maximum rows per leaf) will go to each leaf
157 */
InsertRandomRows(KRowSet * rowset,int num_rows,int density)158 std::set<int64_t> InsertRandomRows ( KRowSet * rowset, int num_rows, int density )
159 {
160 int64_t range_start = 0;
161 int64_t range_count;
162 std::set<int64_t> inserted_rows_set;
163
164 assert ( num_rows > 0 );
165 assert ( density >= -1 );
166 assert ( density <= 8 );
167
168 if ( density == -1 )
169 range_count = -1;
170 else if ( density == 0 )
171 range_count = ((num_rows - 1) / 5 + 1) * 65536;
172 else
173 {
174 assert ( num_rows > 8 );
175 range_count = ((num_rows - 1) / (8192 * density) + 1) * 65536;
176 }
177
178 for ( int i = 0; i < num_rows; ++i )
179 {
180 int64_t row_id = GenerateId ( range_start, range_count );
181 if ( inserted_rows_set.find( row_id ) == inserted_rows_set.end() )
182 {
183 KRowSetAddRowId ( rowset, m_ctx, row_id );
184 THROW_IF_FAILED ( "Failed to insert a row" );
185 inserted_rows_set.insert( row_id );
186 }
187 else
188 --i;
189 }
190
191 return inserted_rows_set;
192 }
193
RunChecks(const KRowSet * rowset,std::set<int64_t> & inserted_rows_set)194 void RunChecks ( const KRowSet * rowset, std::set<int64_t> & inserted_rows_set )
195 {
196 RunChecksInt ( rowset, inserted_rows_set );
197 }
198
SetIntersection(const std::set<int64_t> & set1,const std::set<int64_t> & set2)199 std::set<int64_t> SetIntersection ( const std::set<int64_t>& set1, const std::set<int64_t>& set2 )
200 {
201 std::set<int64_t> result;
202 std::set_intersection(
203 set1.begin(), set1.end(),
204 set2.begin(), set2.end(),
205 std::inserter(result, result.begin())
206 );
207
208 return result;
209 }
210
SetUnion(const std::set<int64_t> & set1,const std::set<int64_t> & set2)211 std::set<int64_t> SetUnion ( const std::set<int64_t>& set1, const std::set<int64_t>& set2 )
212 {
213 std::set<int64_t> result;
214 std::set_union(
215 set1.begin(), set1.end(),
216 set2.begin(), set2.end(),
217 std::inserter(result, result.begin())
218 );
219
220 return result;
221 }
222
Release()223 virtual void Release()
224 {
225 if (m_ctx != 0)
226 {
227
228 m_ctx = 0; // a pointer into the caller's local memory
229 }
230 }
231 private:
RunChecksInt(const KRowSet * rowset,std::set<int64_t> & inserted_rows_set)232 void RunChecksInt ( const KRowSet * rowset, std::set<int64_t> & inserted_rows_set )
233 {
234 std::vector<int64_t> inserted_rows;
235 std::vector<int64_t> returned_rows;
236 uint64_t num_rows;
237
238 KRowSetVisit ( rowset, m_ctx, vector_inserter, (void *)&returned_rows );
239 THROW_IF_FAILED ( "Failed to iterate over rowset" );
240
241 for (std::set<int64_t>::iterator it = inserted_rows_set.begin(); it != inserted_rows_set.end(); ++it)
242 {
243 bool has_row = KRowSetHasRowId ( rowset, m_ctx, *it );
244 THROW_IF_FAILED ( "Failed to check a row in rowset" );
245 if ( ! has_row )
246 FAIL("Row is not found in rowset");
247 inserted_rows . push_back ( *it );
248 }
249
250 num_rows = KRowSetGetNumRowIds( rowset, m_ctx );
251 THROW_IF_FAILED ( "Failed to get number of row ids in rowset" );
252 /*
253 // useful in debugging
254 KOutMsg("Inserted rows: %lu, returned rows: %lu\n", inserted_rows.size(), returned_rows.size() );
255 KOutMsg("inserted:\n");
256 for ( int i = 0; i < inserted_rows.size(); ++i )
257 {
258 KOutMsg ( "%d, ", inserted_rows[i] );
259 }
260 KOutMsg("\n");
261 KOutMsg("returned:\n");
262 for ( int i = 0; i < returned_rows.size(); ++i )
263 {
264 KOutMsg ( "%d, ", returned_rows[i] );
265 }
266 KOutMsg("\n");
267 */
268
269 if ( inserted_rows.size() != returned_rows.size() )
270 FAIL("inserted_rows.size() != returned_rows.size()");
271 if ( num_rows != returned_rows.size() )
272 FAIL("num_rows != returned_rows.size()");
273 if ( inserted_rows != returned_rows )
274 FAIL("inserted_rows != returned_rows");
275 }
276
CreateTable()277 void CreateTable ()
278 {
279 THROW_ON_RC ( KDBManagerCreateTable ( m_mgr, & m_table, kcmInit + kcmMD5, m_tableName . c_str() ) );
280 }
281 };
282
283
FIXTURE_TEST_CASE(KRowSetScatteredRows,RowSetFixture)284 FIXTURE_TEST_CASE ( KRowSetScatteredRows, RowSetFixture )
285 {
286 ENTRY;
287 KRowSet * rowset;
288 std::set<int64_t> inserted_rows_set;
289 bool has_row;
290
291 REQUIRE_EXPR ( rowset = KTableMakeRowSet ( GetTable ( GetName() ), ctx ) );
292
293 REQUIRE_EXPR ( has_row = KRowSetHasRowId ( rowset, ctx, 1 ) );
294 REQUIRE ( ! has_row );
295
296 inserted_rows_set = InsertRandomRows ( rowset, 10000, -1 );
297 RunChecks ( rowset, inserted_rows_set );
298
299 REQUIRE_EXPR ( KRowSetRelease( rowset, ctx ) );
300 EXIT;
301 }
302
FIXTURE_TEST_CASE(KRowSetDenseRows,RowSetFixture)303 FIXTURE_TEST_CASE ( KRowSetDenseRows, RowSetFixture )
304 {
305 ENTRY;
306 KRowSet * rowset;
307 std::set<int64_t> inserted_rows_set;
308
309 REQUIRE_EXPR ( rowset = KTableMakeRowSet ( GetTable ( GetName() ), ctx ) );
310
311 inserted_rows_set = InsertRandomRows ( rowset, 10000, 1 );
312 RunChecks ( rowset, inserted_rows_set );
313
314 REQUIRE_EXPR ( KRowSetRelease( rowset, ctx ) );
315 EXIT;
316 }
317
FIXTURE_TEST_CASE(KRowSetSerialRows,RowSetFixture)318 FIXTURE_TEST_CASE ( KRowSetSerialRows, RowSetFixture )
319 {
320 ENTRY;
321 KRowSet * rowset;
322 std::set<int64_t> inserted_rows_set;
323
324 REQUIRE_EXPR ( rowset = KTableMakeRowSet ( GetTable ( GetName() ), ctx ) );
325
326 for ( int i = 0; i < 20000; ++i )
327 {
328 int64_t row_id = 50000 + i; // row ids will only go to first two leaves
329 REQUIRE_EXPR ( KRowSetAddRowId ( rowset, ctx, row_id) );
330 inserted_rows_set.insert( row_id );
331 }
332 RunChecks ( rowset, inserted_rows_set );
333
334 REQUIRE_EXPR ( KRowSetRelease( rowset, ctx ) );
335 EXIT;
336 }
337
FIXTURE_TEST_CASE(KRowSetRowRanges,RowSetFixture)338 FIXTURE_TEST_CASE ( KRowSetRowRanges, RowSetFixture )
339 {
340 ENTRY;
341 KRowSet * rowset;
342 std::set<int64_t> inserted_rows_set;
343
344 int64_t row_ids[] = { 0, 5, 1, 6, 20, 10, 55, 60, 65, 70, 75, 80, 85, 999, 2001 };
345 uint64_t counts[] = { 1, 1, 4, 4, 10, 10, 1, 1, 1, 1, 1, 1, 1, 1000, 1000 };
346
347 REQUIRE_EXPR ( rowset = KTableMakeRowSet ( GetTable ( GetName() ), ctx ) );
348
349 for ( size_t i = 0; i < sizeof row_ids / sizeof row_ids[0]; ++i )
350 {
351 int64_t row_id = row_ids[i];
352 uint64_t count = counts[i];
353
354 REQUIRE_EXPR ( KRowSetAddRowIdRange ( rowset, ctx, row_id, count ) );
355 for ( uint64_t j = 0; j < count; ++j )
356 inserted_rows_set.insert( row_id + j );
357 }
358 RunChecks ( rowset, inserted_rows_set );
359
360 REQUIRE_EXPR ( KRowSetRelease( rowset, ctx ) );
361 EXIT;
362 }
363
FIXTURE_TEST_CASE(KRowSetRowRangesOverlapDuplicates,RowSetFixture)364 FIXTURE_TEST_CASE ( KRowSetRowRangesOverlapDuplicates, RowSetFixture )
365 {
366 ENTRY;
367 KRowSet * rowset;
368 std::set<int64_t> inserted_rows_set;
369
370 int64_t row_ids[] = { 5, 10 };
371 uint64_t counts[] = { 1, 5 };
372
373 int64_t overlap_row_ids[] = { 0, 5, 5, 2, 9, 9, 14 };
374 uint64_t overlap_counts[] = { 6, 1, 2, 6, 2, 10, 2 };
375
376 REQUIRE_EXPR ( rowset = KTableMakeRowSet ( GetTable ( GetName() ), ctx ) );
377
378 for ( size_t i = 0; i < sizeof row_ids / sizeof row_ids[0]; ++i )
379 {
380 int64_t row_id = row_ids[i];
381 uint64_t count = counts[i];
382
383 REQUIRE_EXPR ( KRowSetAddRowIdRange ( rowset, ctx, row_id, count ) );
384 for ( uint64_t j = 0; j < count; ++j )
385 inserted_rows_set.insert( row_id + j );
386 }
387
388 for ( size_t i = 0; i < sizeof overlap_row_ids / sizeof overlap_row_ids[0]; ++i )
389 {
390 int64_t row_id = overlap_row_ids[i];
391 uint64_t count = overlap_counts[i];
392
393 REQUIRE_EXPR ( KRowSetAddRowIdRange ( rowset, ctx, row_id, count ) );
394 for ( uint64_t j = 0; j < count; ++j )
395 inserted_rows_set.insert( row_id + j );
396 }
397 RunChecks ( rowset, inserted_rows_set );
398
399 REQUIRE_EXPR ( KRowSetRelease( rowset, ctx ) );
400 EXIT;
401 }
402
FIXTURE_TEST_CASE(KRowSetRowRangesDenseOverlapDuplicates,RowSetFixture)403 FIXTURE_TEST_CASE ( KRowSetRowRangesDenseOverlapDuplicates, RowSetFixture )
404 {
405 ENTRY;
406 KRowSet * rowset;
407 std::set<int64_t> inserted_rows_set;
408
409 int64_t row_ids[] = { 0, 5, 10, 15, 20, 25, 30, 35, 40, 1000 };
410 uint64_t counts[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
411
412 int64_t overlap_row_ids[] = { 500 };
413 uint64_t overlap_counts[] = { 1000 };
414
415 REQUIRE_EXPR ( rowset = KTableMakeRowSet ( GetTable ( GetName() ), ctx ) );
416
417 for ( size_t i = 0; i < sizeof row_ids / sizeof row_ids[0]; ++i )
418 {
419 int64_t row_id = row_ids[i];
420 uint64_t count = counts[i];
421
422 REQUIRE_EXPR ( KRowSetAddRowIdRange ( rowset, ctx, row_id, count ) );
423 for ( uint64_t j = 0; j < count; ++j )
424 inserted_rows_set.insert( row_id + j );
425 }
426
427 for ( size_t i = 0; i < sizeof overlap_row_ids / sizeof overlap_row_ids[0]; ++i )
428 {
429 int64_t row_id = overlap_row_ids[i];
430 uint64_t count = overlap_counts[i];
431
432 REQUIRE_EXPR ( KRowSetAddRowIdRange ( rowset, ctx, row_id, count ) );
433 for ( uint64_t j = 0; j < count; ++j )
434 inserted_rows_set.insert( row_id + j );
435
436 }
437 RunChecks ( rowset, inserted_rows_set );
438
439 REQUIRE_EXPR ( KRowSetRelease( rowset, ctx ) );
440 EXIT;
441 }
442
FIXTURE_TEST_CASE(KRowSetIterator,RowSetFixture)443 FIXTURE_TEST_CASE ( KRowSetIterator, RowSetFixture )
444 {
445 ENTRY;
446
447 KRowSet * rowset;
448
449 int64_t row_id_inserted = 55;
450
451 REQUIRE_EXPR ( rowset = KTableMakeRowSet ( GetTable ( GetName() ), ctx ) );
452 REQUIRE_EXPR ( KRowSetAddRowIdRange ( rowset, ctx, row_id_inserted, 1 ) );
453
454 uint64_t num_rows;
455 REQUIRE_EXPR ( num_rows = KRowSetGetNumRowIds ( rowset, ctx ) );
456 REQUIRE_EQ ( num_rows, (uint64_t)1 );
457
458 int64_t row_id_retrieved;
459 KRowSetIterator * it;
460 REQUIRE_EXPR ( it = KRowSetMakeIterator ( rowset, ctx ) );
461 REQUIRE_EXPR ( KRowSetRelease( rowset, ctx ) );
462 rowset = NULL;
463
464 REQUIRE ( KRowSetIteratorIsValid ( it ) );
465 REQUIRE_EXPR ( row_id_retrieved = KRowSetIteratorGetRowId ( it, ctx ) );
466 REQUIRE_EQ ( row_id_inserted, row_id_retrieved );
467
468 bool has_row;
469 REQUIRE_EXPR ( has_row = KRowSetIteratorNext ( it, ctx ) );
470 REQUIRE ( ! has_row );
471 REQUIRE ( ! KRowSetIteratorIsValid ( it ) );
472 REQUIRE_EXPR_FAILED ( KRowSetIteratorGetRowId ( it, ctx ) );
473 REQUIRE_EXPR_FAILED ( KRowSetIteratorNext ( it, ctx ) );
474
475 // // move forward out of boundaries and then move back
476 // for ( int i = 0; i < move_out_boundaries; ++i )
477 // {
478 // REQUIRE_EXPR_FAILED ( KRowSetIteratorNext( it, ctx ) );
479 // REQUIRE ( !KRowSetIteratorIsValid ( it ) );
480 // }
481 // for ( int i = move_out_boundaries - 1; i >= 0; --i )
482 // {
483 // rc_t rc = KRowSetIteratorPrev( it );
484 // if ( i == 0 )
485 // {
486 // REQUIRE_RC ( rc );
487 // }
488 // else
489 // {
490 // REQUIRE_RC_FAIL ( rc );
491 // REQUIRE ( !KRowSetIteratorIsValid ( it ) );
492 // }
493 // }
494 // REQUIRE ( KRowSetIteratorIsValid ( it ) );
495 // REQUIRE_RC ( KRowSetIteratorRowId ( it, &row_id_retrieved ) );
496 // REQUIRE_EQ ( row_id_inserted, row_id_retrieved );
497 //
498 // // move backward out of boundaries and then move back
499 // for ( int i = 0; i < move_out_boundaries; ++i )
500 // {
501 // REQUIRE_RC_FAIL ( KRowSetIteratorPrev( it ) );
502 // REQUIRE ( !KRowSetIteratorIsValid ( it ) );
503 // }
504 // for ( int i = move_out_boundaries - 1; i >= 0; --i )
505 // {
506 // rc_t rc = KRowSetIteratorNext( it );
507 // if ( i == 0 )
508 // {
509 // REQUIRE_RC ( rc );
510 // }
511 // else
512 // {
513 // REQUIRE_RC_FAIL ( rc );
514 // REQUIRE ( !KRowSetIteratorIsValid ( it ) );
515 // }
516 // }
517 // REQUIRE ( KRowSetIteratorIsValid ( it ) );
518 // REQUIRE_RC ( KRowSetIteratorRowId ( it, &row_id_retrieved ) );
519 // REQUIRE_EQ ( row_id_inserted, row_id_retrieved );
520
521 REQUIRE_EXPR ( KRowSetIteratorRelease ( it, ctx ) );
522 EXIT;
523 }
524 //
525 //FIXTURE_TEST_CASE ( KRowSetIteratorMoveForwardAndBackward, RowSetFixture )
526 //{
527 // KRowSet * rowset;
528 //
529 // int64_t row_ids[] = { 0, 5, 10, 15, 20, 25, 30, 35, 40, 1000, 100000 };
530 //
531 // rowset = KTableMakeRowSet ( NULL, ctx );
532 // for ( int i = 0; i < sizeof row_ids / sizeof row_ids[0]; ++i )
533 // {
534 // int64_t row_id = row_ids[i];
535 // bool inserted;
536 //
537 // REQUIRE_RC ( KRowSetAddRowId ( rowset, row_id, &inserted ) );
538 // REQUIRE ( inserted );
539 // }
540 //
541 // uint64_t num_rows;
542 // REQUIRE_RC ( KRowSetGetNumRowIds ( rowset, &num_rows ) );
543 // REQUIRE_EQ ( num_rows, (uint64_t)sizeof row_ids / sizeof row_ids[0] );
544 //
545 // KRowSetIterator * it;
546 // REQUIRE_RC ( KRowSetMakeIterator ( rowset, &it ) );
547 // REQUIRE_RC ( KRowSetRelease( rowset ) );
548 // rowset = NULL;
549 //
550 // // move forward
551 // for ( int i = 0; i < sizeof row_ids / sizeof row_ids[0]; ++i )
552 // {
553 // int64_t row_id;
554 //
555 // if ( i != 0 )
556 // REQUIRE_RC ( KRowSetIteratorNext( it ) );
557 //
558 // REQUIRE ( KRowSetIteratorIsValid ( it ) );
559 // REQUIRE_RC ( KRowSetIteratorRowId ( it, &row_id ) );
560 // REQUIRE_EQ ( row_id, row_ids[i] );
561 // }
562 //
563 // // move backward
564 // for ( int i = sizeof row_ids / sizeof row_ids[0] - 1; i >= 0; --i )
565 // {
566 // int64_t row_id;
567 //
568 // if ( i != sizeof row_ids / sizeof row_ids[0] - 1 )
569 // REQUIRE_RC ( KRowSetIteratorPrev( it ) );
570 //
571 // REQUIRE ( KRowSetIteratorIsValid ( it ) );
572 // REQUIRE_RC ( KRowSetIteratorRowId ( it, &row_id ) );
573 // REQUIRE_EQ ( row_id, row_ids[i] );
574 // }
575 //
576 // REQUIRE_RC ( KRowSetIteratorRelease ( it ) );
577 //}
578
FIXTURE_TEST_CASE(KRowSetIteratorOverEmptySet,RowSetFixture)579 FIXTURE_TEST_CASE ( KRowSetIteratorOverEmptySet, RowSetFixture )
580 {
581 ENTRY;
582 KRowSet * rowset;
583 REQUIRE_EXPR ( rowset = KTableMakeRowSet ( GetTable ( GetName() ), ctx ) );
584
585 KRowSetIterator * it;
586 REQUIRE_EXPR ( it = KRowSetMakeIterator ( rowset, ctx ) );
587 REQUIRE ( !KRowSetIteratorIsValid ( it ) );
588
589 REQUIRE_EXPR ( KRowSetIteratorRelease( it, ctx ) );
590 REQUIRE_EXPR ( KRowSetRelease( rowset, ctx ) );
591 EXIT;
592 }
593
FIXTURE_TEST_CASE(KRowSetIntersectSimpleTest,RowSetFixture)594 FIXTURE_TEST_CASE ( KRowSetIntersectSimpleTest, RowSetFixture )
595 {
596 ENTRY;
597 KRowSet * rowset1;
598 KRowSet * rowset2;
599 std::set<int64_t> inserted_rows_set1;
600 std::set<int64_t> inserted_rows_set2;
601
602 REQUIRE_EXPR ( rowset1 = KTableMakeRowSet ( GetTable ( GetName() ), ctx ) );
603 REQUIRE_EXPR ( rowset2 = KTableMakeRowSet ( GetTable ( GetName() ), ctx ) );
604
605 for ( int i = 0; i < 5000; ++i )
606 {
607 int64_t row_id = GenerateId ( -1, -1 );
608 if ( inserted_rows_set1.find( row_id ) == inserted_rows_set1.end() )
609 {
610 REQUIRE_EXPR ( KRowSetAddRowId ( rowset1, ctx, row_id) );
611 inserted_rows_set1.insert( row_id );
612 // just don't insert a single row to a second rowset, but otherwise keep them equal
613 if ( i != 0 )
614 {
615 REQUIRE_EXPR ( KRowSetAddRowId ( rowset2, ctx, row_id) );
616 inserted_rows_set2.insert( row_id );
617 }
618 }
619 else
620 --i;
621 }
622
623 KRowSet * rowset_result;
624 REQUIRE_EXPR ( rowset_result = KRowSetIntersect ( ctx, rowset1, rowset2 ) );
625
626 RunChecks ( rowset1, inserted_rows_set1 );
627 RunChecks ( rowset2, inserted_rows_set2 );
628 RunChecks ( rowset_result, inserted_rows_set2 );
629
630 REQUIRE_EXPR ( KRowSetRelease( rowset1, ctx ) );
631 REQUIRE_EXPR ( KRowSetRelease( rowset2, ctx ) );
632 REQUIRE_EXPR ( KRowSetRelease( rowset_result, ctx ) );
633 EXIT;
634 }
635
FIXTURE_TEST_CASE(KRowSetIntersectNormalTest,RowSetFixture)636 FIXTURE_TEST_CASE ( KRowSetIntersectNormalTest, RowSetFixture )
637 {
638 ENTRY;
639 // check all 4 combinations of dense/scattered leaves
640 for ( int i = 0; i < 4; ++i )
641 {
642 KRowSet * rowset1;
643 KRowSet * rowset2;
644 KRowSet * rowset_result;
645 std::set<int64_t> inserted_rows_set1;
646 std::set<int64_t> inserted_rows_set2;
647 std::set<int64_t> intersection_set;
648
649 REQUIRE_EXPR ( rowset1 = KTableMakeRowSet ( GetTable ( GetName() ), ctx ) );
650 REQUIRE_EXPR ( rowset2 = KTableMakeRowSet ( GetTable ( GetName() ), ctx ) );
651
652 inserted_rows_set1 = InsertRandomRows ( rowset1, 5000, (i & 1) ? 8 : 0 );
653 inserted_rows_set2 = InsertRandomRows ( rowset2, 5000, (i & 2) ? 8 : 0 );
654
655 RunChecks ( rowset1, inserted_rows_set1 );
656 RunChecks ( rowset2, inserted_rows_set2 );
657
658 REQUIRE_EXPR ( rowset_result = KRowSetIntersect ( ctx, rowset1, rowset2 ) );
659 intersection_set = SetIntersection ( inserted_rows_set1, inserted_rows_set2 );
660
661 RunChecks ( rowset_result, intersection_set );
662 RunChecks ( rowset1, inserted_rows_set1 );
663 RunChecks ( rowset2, inserted_rows_set2 );
664 REQUIRE_EXPR ( KRowSetRelease( rowset_result, ctx ) );
665
666 REQUIRE_EXPR ( rowset_result = KRowSetIntersect ( ctx, rowset2, rowset1 ) );
667 RunChecks ( rowset_result, intersection_set );
668 RunChecks ( rowset1, inserted_rows_set1 );
669 RunChecks ( rowset2, inserted_rows_set2 );
670
671 REQUIRE_EXPR ( KRowSetRelease( rowset1, ctx ) );
672 REQUIRE_EXPR ( KRowSetRelease( rowset2, ctx ) );
673 REQUIRE_EXPR ( KRowSetRelease( rowset_result, ctx ) );
674 }
675 EXIT;
676 }
677
FIXTURE_TEST_CASE(KRowSetUnionSimpleTest,RowSetFixture)678 FIXTURE_TEST_CASE ( KRowSetUnionSimpleTest, RowSetFixture )
679 {
680 ENTRY;
681 KRowSet * rowset1;
682 KRowSet * rowset2;
683 std::set<int64_t> inserted_rows_set1;
684 std::set<int64_t> inserted_rows_set2;
685
686 REQUIRE_EXPR ( rowset1 = KTableMakeRowSet ( GetTable ( GetName() ), ctx ) );
687 REQUIRE_EXPR ( rowset2 = KTableMakeRowSet ( GetTable ( GetName() ), ctx ) );
688
689 for ( int i = 0; i < 5000; ++i )
690 {
691 int64_t row_id = GenerateId ( -1, -1 );
692 if ( inserted_rows_set1.find( row_id ) == inserted_rows_set1.end() )
693 {
694 REQUIRE_EXPR ( KRowSetAddRowId ( rowset1, ctx, row_id) );
695 inserted_rows_set1.insert( row_id );
696 // just don't insert a single row to a second rowset, but otherwise keep them equal
697 if ( i != 0 )
698 {
699 REQUIRE_EXPR ( KRowSetAddRowId ( rowset2, ctx, row_id) );
700 inserted_rows_set2.insert( row_id );
701 }
702 }
703 else
704 --i;
705 }
706
707 KRowSet * rowset_result;
708 REQUIRE_EXPR ( rowset_result = KRowSetUnion ( ctx, rowset1, rowset2 ) );
709
710 RunChecks ( rowset1, inserted_rows_set1 );
711 RunChecks ( rowset2, inserted_rows_set2 );
712 RunChecks ( rowset_result, inserted_rows_set1 );
713
714 REQUIRE_EXPR ( KRowSetRelease( rowset1, ctx ) );
715 REQUIRE_EXPR ( KRowSetRelease( rowset2, ctx ) );
716 REQUIRE_EXPR ( KRowSetRelease( rowset_result, ctx ) );
717 EXIT;
718 }
719
FIXTURE_TEST_CASE(KRowSetUnionNormalTest,RowSetFixture)720 FIXTURE_TEST_CASE ( KRowSetUnionNormalTest, RowSetFixture )
721 {
722 ENTRY;
723 // check all 4 combinations of dense/scattered leaves
724 for ( int i = 0; i < 4; ++i )
725 {
726 KRowSet * rowset1;
727 KRowSet * rowset2;
728 KRowSet * rowset_result;
729 std::set<int64_t> inserted_rows_set1;
730 std::set<int64_t> inserted_rows_set2;
731 std::set<int64_t> union_set;
732
733 REQUIRE_EXPR ( rowset1 = KTableMakeRowSet ( GetTable ( GetName() ), ctx ) );
734 REQUIRE_EXPR ( rowset2 = KTableMakeRowSet ( GetTable ( GetName() ), ctx ) );
735
736 inserted_rows_set1 = InsertRandomRows ( rowset1, 5000, (i & 1) ? 8 : 0 );
737 inserted_rows_set2 = InsertRandomRows ( rowset2, 5000, (i & 2) ? 8 : 0 );
738
739 RunChecks ( rowset1, inserted_rows_set1 );
740 RunChecks ( rowset2, inserted_rows_set2 );
741
742 REQUIRE_EXPR ( rowset_result = KRowSetUnion ( ctx, rowset1, rowset2 ) );
743 union_set = SetUnion ( inserted_rows_set1, inserted_rows_set2 );
744
745 RunChecks ( rowset_result, union_set );
746 RunChecks ( rowset1, inserted_rows_set1 );
747 RunChecks ( rowset2, inserted_rows_set2 );
748 REQUIRE_EXPR ( KRowSetRelease( rowset_result, ctx ) );
749
750 REQUIRE_EXPR ( rowset_result = KRowSetUnion ( ctx, rowset2, rowset1 ) );
751 RunChecks ( rowset_result, union_set );
752 RunChecks ( rowset1, inserted_rows_set1 );
753 RunChecks ( rowset2, inserted_rows_set2 );
754
755 REQUIRE_EXPR ( KRowSetRelease( rowset1, ctx ) );
756 REQUIRE_EXPR ( KRowSetRelease( rowset2, ctx ) );
757 REQUIRE_EXPR ( KRowSetRelease( rowset_result, ctx ) );
758 }
759 EXIT;
760 }
761
762 //////////////////////////////////////////// Main
763 extern "C"
764 {
765
766 #include <kapp/main.h>
767 #include <kapp/args.h>
768
KAppVersion(void)769 ver_t CC KAppVersion ( void )
770 {
771 return 0;
772 }
773
774
775 const char UsageDefaultName[] = "test-rowset";
776
UsageSummary(const char * progname)777 rc_t CC UsageSummary ( const char *progname )
778 {
779 return KOutMsg ( "\n"
780 "Usage:\n"
781 " %s [Options] <target>\n"
782 "\n"
783 "Summary:\n"
784 " test the rowset.\n"
785 , progname
786 );
787 }
788
Usage(const Args * args)789 rc_t CC Usage ( const Args *args )
790 {
791 const char * progname = UsageDefaultName;
792 const char * fullpath = UsageDefaultName;
793 rc_t rc;
794
795 if (args == NULL)
796 rc = RC (rcApp, rcArgv, rcAccessing, rcSelf, rcNull);
797 else
798 rc = ArgsProgram (args, &fullpath, &progname);
799 if (rc)
800 progname = fullpath = UsageDefaultName;
801
802 UsageSummary (progname);
803
804 KOutMsg ("Options:\n");
805
806 HelpOptionsStandard ();
807
808 HelpVersion (fullpath, KAppVersion());
809
810 return rc;
811 }
KMain(int argc,char * argv[])812 rc_t CC KMain ( int argc, char *argv [] )
813 {
814 srand ( time(NULL) );
815 return KRowSetTestSuite(argc, argv);
816 }
817
818 }
819
820