39 BOOST_CHECK( tree.
empty() );
42 int searchMin[2] = { 0, 0 };
43 int searchMax[2] = { 100, 100 };
45 auto visitor = []( intptr_t ) {
return true; };
48 BOOST_CHECK( tree.
begin() == tree.
end() );
56 int min[2] = { 10, 20 };
57 int max[2] = { 30, 40 };
58 tree.
Insert( min, max, 42 );
61 BOOST_CHECK( !tree.
empty() );
64 int sMin[2] = { 0, 0 };
65 int sMax[2] = { 15, 25 };
66 std::vector<intptr_t> results;
68 auto collect = [&results]( intptr_t val )
70 results.push_back( val );
79 int sMin2[2] = { 100, 100 };
80 int sMax2[2] = { 200, 200 };
89 for(
int i = 0; i < 1000; ++i )
91 int min[2] = { i * 10, i * 10 };
92 int max[2] = { i * 10 + 9, i * 10 + 9 };
93 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
99 int sMin[2] = { 500 * 10, 500 * 10 };
100 int sMax[2] = { 500 * 10 + 9, 500 * 10 + 9 };
101 std::vector<intptr_t> results;
103 auto collect = [&results]( intptr_t val )
105 results.push_back( val );
109 tree.
Search( sMin, sMax, collect );
110 BOOST_CHECK( std::find( results.begin(), results.end(), 500 ) != results.end() );
118 int min1[2] = { 0, 0 };
119 int max1[2] = { 10, 10 };
120 tree.
Insert( min1, max1, 1 );
122 int min2[2] = { 20, 20 };
123 int max2[2] = { 30, 30 };
124 tree.
Insert( min2, max2, 2 );
129 BOOST_CHECK( tree.
Remove( min1, max1, 1 ) );
133 std::vector<intptr_t> results;
135 auto collect = [&results]( intptr_t val )
137 results.push_back( val );
141 int fullMin[2] = { -100, -100 };
142 int fullMax[2] = { 100, 100 };
143 tree.
Search( fullMin, fullMax, collect );
154 int min[2] = { 0, 0 };
155 int max[2] = { 10, 10 };
156 tree.
Insert( min, max, 1 );
158 int fakeMin[2] = { 100, 100 };
159 int fakeMax[2] = { 200, 200 };
160 BOOST_CHECK( !tree.
Remove( fakeMin, fakeMax, 999 ) );
170 int min1[2] = { 0, 0 };
171 int max1[2] = { 10, 10 };
172 tree.
Insert( min1, max1, 1 );
174 int min2[2] = { 100, 0 };
175 int max2[2] = { 110, 10 };
176 tree.
Insert( min2, max2, 2 );
178 int min3[2] = { 0, 100 };
179 int max3[2] = { 10, 110 };
180 tree.
Insert( min3, max3, 3 );
182 int min4[2] = { 100, 100 };
183 int max4[2] = { 110, 110 };
184 tree.
Insert( min4, max4, 4 );
187 std::set<intptr_t> results;
189 auto collect = [&results]( intptr_t val )
191 results.insert( val );
195 int sMin[2] = { -10, -10 };
196 int sMax[2] = { 50, 200 };
197 tree.
Search( sMin, sMax, collect );
199 BOOST_CHECK( results.count( 1 ) );
200 BOOST_CHECK( results.count( 3 ) );
204 int dMin[2] = { 50, 50 };
205 int dMax[2] = { 90, 90 };
206 tree.
Search( dMin, dMax, collect );
207 BOOST_CHECK( results.empty() );
211 int aMin[2] = { -1000, -1000 };
212 int aMax[2] = { 1000, 1000 };
213 tree.
Search( aMin, aMax, collect );
221 std::mt19937
rng( 67890 );
222 std::uniform_int_distribution<int> coordDist( -500000, 500000 );
223 std::uniform_int_distribution<int> sizeDist( 1, 5000 );
232 std::vector<ITEM> items(
N );
235 for(
int i = 0; i <
N; ++i )
237 int x = coordDist(
rng );
238 int y = coordDist(
rng );
239 int w = sizeDist(
rng );
240 int h = sizeDist(
rng );
244 items[i].max[0] = x + w;
245 items[i].max[1] = y + h;
246 items[i].id =
static_cast<intptr_t
>( i );
248 tree.
Insert( items[i].min, items[i].max, items[i].
id );
254 for(
int q = 0; q < 50; ++q )
256 int qx = coordDist(
rng );
257 int qy = coordDist(
rng );
258 int qw = sizeDist(
rng ) * 10;
259 int qh = sizeDist(
rng ) * 10;
261 int qMin[2] = { qx, qy };
262 int qMax[2] = { qx + qw, qy + qh };
266 for(
const ITEM& item : items )
268 if( item.min[0] <= qMax[0] && item.max[0] >= qMin[0]
269 && item.min[1] <= qMax[1] && item.max[1] >= qMin[1] )
275 std::set<intptr_t>
actual;
277 auto collect = [&
actual]( intptr_t val )
283 tree.
Search( qMin, qMax, collect );
302 std::vector<ITEM> items(
N );
304 for(
int i = 0; i <
N; ++i )
306 items[i].min[0] = i * 5;
307 items[i].min[1] = i * 5;
308 items[i].max[0] = i * 5 + 4;
309 items[i].max[1] = i * 5 + 4;
310 items[i].id =
static_cast<intptr_t
>( i );
312 tree.
Insert( items[i].min, items[i].max, items[i].
id );
316 for(
int i = 0; i <
N; i += 2 )
317 BOOST_CHECK( tree.
Remove( items[i].min, items[i].max, items[i].id ) );
322 std::set<intptr_t> remaining;
324 auto collect = [&remaining]( intptr_t val )
326 remaining.insert( val );
330 int fullMin[2] = { -10000, -10000 };
331 int fullMax[2] = { 10000, 10000 };
332 tree.
Search( fullMin, fullMax, collect );
336 for(
int i = 1; i <
N; i += 2 )
337 BOOST_CHECK( remaining.count( i ) );
345 for(
int i = 0; i < 50; ++i )
347 int min[2] = { i, i };
348 int max[2] = { i + 5, i + 5 };
349 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
361 tree3 = std::move( tree2 );
366 int sMin[2] = { 0, 0 };
367 int sMax[2] = { 100, 100 };
370 auto counter = [&count]( intptr_t )
376 tree3.
Search( sMin, sMax, counter );
385 for(
int i = 0; i < 100; ++i )
387 int min[2] = { i, i };
388 int max[2] = { i + 1, i + 1 };
389 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
396 BOOST_CHECK( tree.
empty() );
399 int min[2] = { 0, 0 };
400 int max[2] = { 10, 10 };
401 tree.
Insert( min, max, 999 );
410 for(
int i = 0; i < 100; ++i )
412 int min[3] = { i, i, i };
413 int max[3] = { i + 5, i + 5, i + 5 };
414 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
419 int sMin[3] = { 10, 10, 10 };
420 int sMax[3] = { 20, 20, 20 };
423 auto counter = [&count]( intptr_t )
429 tree.
Search( sMin, sMax, counter );
430 BOOST_CHECK_GT( count, 0 );
439 for(
int i = 0; i < 20; ++i )
441 int min[2] = { i * 100, 0 };
442 int max[2] = { i * 100 + 10, 10 };
443 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
447 int point[2] = { 0, 0 };
448 std::vector<std::pair<int64_t, intptr_t>> results;
457 for(
size_t i = 1; i < results.size(); ++i )
458 BOOST_CHECK_GE( results[i].first, results[i - 1].first );
466 for(
int i = 0; i < 200; ++i )
468 int min[2] = { i * 3, i * 7 };
469 int max[2] = { i * 3 + 2, i * 7 + 6 };
470 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
473 std::set<intptr_t> iterated;
475 for(
const auto& val : tree )
476 iterated.insert( val );
480 for(
int i = 0; i < 200; ++i )
481 BOOST_CHECK( iterated.count( i ) );
489 for(
int i = 0; i < 100; ++i )
491 int min[2] = { 0, 0 };
492 int max[2] = { 100, 100 };
493 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
498 auto stopAfter5 = [&count]( intptr_t )
504 int sMin[2] = { 0, 0 };
505 int sMax[2] = { 100, 100 };
506 tree.
Search( sMin, sMax, stopAfter5 );
519 int origMin[2] = { 100, 100 };
520 int origMax[2] = { 200, 200 };
521 tree.
Insert( origMin, origMax, 42 );
523 int otherMin[2] = { 500, 500 };
524 int otherMax[2] = { 600, 600 };
525 tree.
Insert( otherMin, otherMax, 99 );
531 int movedMin[2] = { 300, 300 };
532 int movedMax[2] = { 400, 400 };
533 BOOST_CHECK( tree.
Remove( movedMin, movedMax, 42 ) );
537 std::vector<intptr_t> results;
539 auto collect = [&results]( intptr_t val )
541 results.push_back( val );
545 int fullMin[2] = { -1000, -1000 };
546 int fullMax[2] = { 1000, 1000 };
547 tree.
Search( fullMin, fullMax, collect );
557 std::mt19937
rng( 11111 );
558 std::uniform_int_distribution<int> coordDist( 0, 100000 );
559 std::uniform_int_distribution<int> sizeDist( 100, 5000 );
560 std::uniform_int_distribution<int> opDist( 0, 9 );
571 std::vector<ITEM> liveItems;
573 for(
int op = 0; op <
N; ++op )
575 int which = opDist(
rng );
577 if( which < 5 || liveItems.empty() )
581 item.min[0] = coordDist(
rng );
582 item.min[1] = coordDist(
rng );
583 item.max[0] = item.min[0] + sizeDist(
rng );
584 item.max[1] = item.min[1] + sizeDist(
rng );
585 item.id =
static_cast<intptr_t
>( op );
587 tree.
Insert( item.min, item.max, item.id );
588 liveItems.push_back( item );
593 std::uniform_int_distribution<int> idxDist( 0, liveItems.size() - 1 );
594 int idx = idxDist(
rng );
595 ITEM& item = liveItems[idx];
597 BOOST_CHECK( tree.
Remove( item.min, item.max, item.id ) );
599 liveItems.erase( liveItems.begin() + idx );
604 int qMin[2] = { coordDist(
rng ), coordDist(
rng ) };
605 int qMax[2] = { qMin[0] + sizeDist(
rng ) * 5, qMin[1] + sizeDist(
rng ) * 5 };
609 for(
const ITEM& item : liveItems )
611 if( item.min[0] <= qMax[0] && item.max[0] >= qMin[0]
612 && item.min[1] <= qMax[1] && item.max[1] >= qMin[1] )
618 std::set<intptr_t>
actual;
620 auto collect = [&
actual]( intptr_t val )
626 tree.
Search( qMin, qMax, collect );
638 std::vector<DYNAMIC_RTREE<int, int, 2>::BULK_ENTRY> entries;
642 BOOST_CHECK( tree.
empty() );
649 std::vector<DYNAMIC_RTREE<int, int, 2>::BULK_ENTRY> entries;
650 entries.push_back( { { 10, 20 }, { 30, 40 }, 42 } );
655 std::vector<int> results;
656 auto collect = [&results](
int val ) { results.push_back( val );
return true; };
657 int qMin[2] = { 0, 0 };
658 int qMax[2] = { 100, 100 };
659 tree.
Search( qMin, qMax, collect );
669 std::mt19937
rng( 99999 );
670 std::uniform_int_distribution<int> coordDist( 0, 100000 );
671 std::uniform_int_distribution<int> sizeDist( 100, 5000 );
680 std::vector<ITEM> items(
N );
682 for(
int i = 0; i <
N; ++i )
684 items[i].min[0] = coordDist(
rng );
685 items[i].min[1] = coordDist(
rng );
686 items[i].max[0] = items[i].min[0] + sizeDist(
rng );
687 items[i].max[1] = items[i].min[1] + sizeDist(
rng );
693 std::vector<DYNAMIC_RTREE<int, int, 2>::BULK_ENTRY> entries;
694 entries.reserve(
N );
696 for(
const auto& item : items )
697 entries.push_back( { { item.min[0], item.min[1] }, { item.max[0], item.max[1] }, item.id } );
704 const int QUERIES = 200;
706 for(
int q = 0; q < QUERIES; ++q )
708 int qMin[2] = { coordDist(
rng ), coordDist(
rng ) };
709 int qMax[2] = { qMin[0] + sizeDist(
rng ) * 5, qMin[1] + sizeDist(
rng ) * 5 };
713 for(
const auto& item : items )
715 if( item.min[0] <= qMax[0] && item.max[0] >= qMin[0]
716 && item.min[1] <= qMax[1] && item.max[1] >= qMin[1] )
723 auto collect = [&
actual](
int val ) {
actual.insert( val );
return true; };
724 tree.
Search( qMin, qMax, collect );
731 std::set<int> allViaIter;
733 for(
int val : tree )
734 allViaIter.insert( val );
743 std::mt19937
rng( 77777 );
744 std::uniform_int_distribution<int> coordDist( 0, 100000 );
745 std::uniform_int_distribution<int> sizeDist( 100, 5000 );
749 std::vector<DYNAMIC_RTREE<int, int, 2>::BULK_ENTRY> entries;
758 std::vector<ITEM> liveItems;
760 for(
int i = 0; i <
N; ++i )
763 item.min[0] = coordDist(
rng );
764 item.min[1] = coordDist(
rng );
765 item.max[0] = item.min[0] + sizeDist(
rng );
766 item.max[1] = item.min[1] + sizeDist(
rng );
768 entries.push_back( { { item.min[0], item.min[1] }, { item.max[0], item.max[1] }, item.id } );
769 liveItems.push_back( item );
776 for(
int i =
N; i <
N + 100; ++i )
779 item.min[0] = coordDist(
rng );
780 item.min[1] = coordDist(
rng );
781 item.max[0] = item.min[0] + sizeDist(
rng );
782 item.max[1] = item.min[1] + sizeDist(
rng );
784 tree.
Insert( item.min, item.max, item.id );
785 liveItems.push_back( item );
791 for(
int i = 0; i < 50; ++i )
793 std::uniform_int_distribution<int> idxDist( 0, liveItems.size() - 1 );
794 int idx = idxDist(
rng );
795 ITEM& item = liveItems[idx];
797 BOOST_CHECK( tree.
Remove( item.min, item.max, item.id ) );
798 liveItems.erase( liveItems.begin() + idx );
804 int qMin[2] = { 0, 0 };
805 int qMax[2] = { 200000, 200000 };
809 for(
const auto& item : liveItems )
811 if( item.min[0] <= qMax[0] && item.max[0] >= qMin[0]
812 && item.min[1] <= qMax[1] && item.max[1] >= qMin[1] )
819 auto collect = [&
actual](
int val ) {
actual.insert( val );
return true; };
820 tree.
Search( qMin, qMax, collect );
838 for(
int i = 0; i < 100; ++i )
840 int min[2] = { i * 10, i * 10 };
841 int max[2] = { i * 10 + 9, i * 10 + 9 };
842 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
848 auto clone = tree.
Clone();
852 int sMin[2] = { 0, 0 };
853 int sMax[2] = { 50, 50 };
855 std::set<intptr_t> origResults;
856 std::set<intptr_t> cloneResults;
858 auto collectOrig = [&origResults]( intptr_t val )
860 origResults.insert( val );
864 auto collectClone = [&cloneResults]( intptr_t val )
866 cloneResults.insert( val );
870 tree.
Search( sMin, sMax, collectOrig );
871 clone.Search( sMin, sMax, collectClone );
873 BOOST_CHECK( origResults == cloneResults );
881 for(
int i = 0; i < 50; ++i )
883 int min[2] = { i * 10, 0 };
884 int max[2] = { i * 10 + 9, 9 };
885 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
888 auto clone = tree.
Clone();
891 int newMin[2] = { 1000, 1000 };
892 int newMax[2] = { 1010, 1010 };
893 clone.
Insert( newMin, newMax, 999 );
899 std::vector<intptr_t> origResults;
901 auto collectOrig = [&origResults]( intptr_t val )
903 origResults.push_back( val );
907 tree.
Search( newMin, newMax, collectOrig );
908 BOOST_CHECK( origResults.empty() );
911 std::vector<intptr_t> cloneResults;
913 auto collectClone = [&cloneResults]( intptr_t val )
915 cloneResults.push_back( val );
919 clone.Search( newMin, newMax, collectClone );
929 for(
int i = 0; i < 50; ++i )
931 int min[2] = { i * 10, 0 };
932 int max[2] = { i * 10 + 9, 9 };
933 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
936 auto clone = tree.
Clone();
939 int rmMin[2] = { 0, 0 };
940 int rmMax[2] = { 9, 9 };
941 BOOST_CHECK( clone.Remove( rmMin, rmMax, 0 ) );
947 std::vector<intptr_t> origResults;
949 auto collectOrig = [&origResults]( intptr_t val )
951 origResults.push_back( val );
955 tree.
Search( rmMin, rmMax, collectOrig );
956 BOOST_CHECK( std::find( origResults.begin(), origResults.end(), 0 )
957 != origResults.end() );
965 for(
int i = 0; i < 30; ++i )
967 int min[2] = { i * 10, 0 };
968 int max[2] = { i * 10 + 9, 9 };
969 root.
Insert( min, max,
static_cast<intptr_t
>( i ) );
972 auto child1 = root.
Clone();
974 int newMin1[2] = { 500, 500 };
975 int newMax1[2] = { 510, 510 };
976 child1.
Insert( newMin1, newMax1, 100 );
978 auto grandchild = child1.Clone();
980 int newMin2[2] = { 600, 600 };
981 int newMax2[2] = { 610, 610 };
982 grandchild.Insert( newMin2, newMax2, 200 );
989 std::vector<intptr_t> rootResults;
991 auto collectRoot = [&rootResults]( intptr_t val )
993 rootResults.push_back( val );
997 root.
Search( newMin1, newMax1, collectRoot );
998 BOOST_CHECK( rootResults.empty() );
1000 root.
Search( newMin2, newMax2, collectRoot );
1001 BOOST_CHECK( rootResults.empty() );
1009 for(
int i = 0; i < 50; ++i )
1011 int min[2] = { i, i };
1012 int max[2] = { i + 1, i + 1 };
1013 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
1016 auto clone = tree.
Clone();
1018 std::set<intptr_t> cloneItems;
1020 for(
const auto& val : clone )
1021 cloneItems.insert( val );
1031 for(
int i = 0; i < 30; ++i )
1033 int min[2] = { i, i };
1034 int max[2] = { i + 1, i + 1 };
1035 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
1038 auto clone = tree.
Clone();
Copy-on-Write wrapper for DYNAMIC_RTREE.
int Search(const ELEMTYPE aMin[NUMDIMS], const ELEMTYPE aMax[NUMDIMS], VISITOR &aVisitor) const
Search for items whose bounding boxes overlap the query rectangle.
void Insert(const ELEMTYPE aMin[NUMDIMS], const ELEMTYPE aMax[NUMDIMS], const DATATYPE &aData)
Insert an item.
COW_RTREE Clone() const
Create a clone that shares the tree structure with this tree.
Dynamic R*-tree with SoA node layout and stored insertion bounding boxes.
void NearestNeighbors(const ELEMTYPE aPoint[NUMDIMS], int aK, std::vector< std::pair< int64_t, DATATYPE > > &aResults) const
Nearest-neighbor search using Hjaltason & Samet's algorithm.
int Search(const ELEMTYPE aMin[NUMDIMS], const ELEMTYPE aMax[NUMDIMS], VISITOR &aVisitor) const
Search for items whose bounding boxes overlap the query rectangle.
bool Remove(const ELEMTYPE aMin[NUMDIMS], const ELEMTYPE aMax[NUMDIMS], const DATATYPE &aData)
Remove an item using its stored insertion bounding box.
void Insert(const ELEMTYPE aMin[NUMDIMS], const ELEMTYPE aMax[NUMDIMS], const DATATYPE &aData)
Insert an item with the given bounding box.
void BulkLoad(std::vector< BULK_ENTRY > &aEntries)
Build the tree from a batch of entries using Hilbert-curve packed bulk loading.
void RemoveAll()
Remove all items from the tree.
static thread_local boost::mt19937 rng
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_CASE(EmptyTree)
BOOST_AUTO_TEST_SUITE_END()
VECTOR3I expected(15, 30, 45)
BOOST_CHECK_EQUAL(result, "25.4")