43 BOOST_CHECK( tree.
empty() );
46 int searchMin[2] = { 0, 0 };
47 int searchMax[2] = { 100, 100 };
49 auto visitor = []( intptr_t ) {
return true; };
52 BOOST_CHECK( tree.
begin() == tree.
end() );
60 int min[2] = { 10, 20 };
61 int max[2] = { 30, 40 };
62 tree.
Insert( min, max, 42 );
65 BOOST_CHECK( !tree.
empty() );
68 int sMin[2] = { 0, 0 };
69 int sMax[2] = { 15, 25 };
70 std::vector<intptr_t> results;
72 auto collect = [&results]( intptr_t val )
74 results.push_back( val );
83 int sMin2[2] = { 100, 100 };
84 int sMax2[2] = { 200, 200 };
93 for(
int i = 0; i < 1000; ++i )
95 int min[2] = { i * 10, i * 10 };
96 int max[2] = { i * 10 + 9, i * 10 + 9 };
97 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
103 int sMin[2] = { 500 * 10, 500 * 10 };
104 int sMax[2] = { 500 * 10 + 9, 500 * 10 + 9 };
105 std::vector<intptr_t> results;
107 auto collect = [&results]( intptr_t val )
109 results.push_back( val );
113 tree.
Search( sMin, sMax, collect );
114 BOOST_CHECK( std::find( results.begin(), results.end(), 500 ) != results.end() );
122 int min1[2] = { 0, 0 };
123 int max1[2] = { 10, 10 };
124 tree.
Insert( min1, max1, 1 );
126 int min2[2] = { 20, 20 };
127 int max2[2] = { 30, 30 };
128 tree.
Insert( min2, max2, 2 );
133 BOOST_CHECK( tree.
Remove( min1, max1, 1 ) );
137 std::vector<intptr_t> results;
139 auto collect = [&results]( intptr_t val )
141 results.push_back( val );
145 int fullMin[2] = { -100, -100 };
146 int fullMax[2] = { 100, 100 };
147 tree.
Search( fullMin, fullMax, collect );
158 int min[2] = { 0, 0 };
159 int max[2] = { 10, 10 };
160 tree.
Insert( min, max, 1 );
162 int fakeMin[2] = { 100, 100 };
163 int fakeMax[2] = { 200, 200 };
164 BOOST_CHECK( !tree.
Remove( fakeMin, fakeMax, 999 ) );
174 int min1[2] = { 0, 0 };
175 int max1[2] = { 10, 10 };
176 tree.
Insert( min1, max1, 1 );
178 int min2[2] = { 100, 0 };
179 int max2[2] = { 110, 10 };
180 tree.
Insert( min2, max2, 2 );
182 int min3[2] = { 0, 100 };
183 int max3[2] = { 10, 110 };
184 tree.
Insert( min3, max3, 3 );
186 int min4[2] = { 100, 100 };
187 int max4[2] = { 110, 110 };
188 tree.
Insert( min4, max4, 4 );
191 std::set<intptr_t> results;
193 auto collect = [&results]( intptr_t val )
195 results.insert( val );
199 int sMin[2] = { -10, -10 };
200 int sMax[2] = { 50, 200 };
201 tree.
Search( sMin, sMax, collect );
203 BOOST_CHECK( results.count( 1 ) );
204 BOOST_CHECK( results.count( 3 ) );
208 int dMin[2] = { 50, 50 };
209 int dMax[2] = { 90, 90 };
210 tree.
Search( dMin, dMax, collect );
211 BOOST_CHECK( results.empty() );
215 int aMin[2] = { -1000, -1000 };
216 int aMax[2] = { 1000, 1000 };
217 tree.
Search( aMin, aMax, collect );
225 std::mt19937
rng( 67890 );
226 std::uniform_int_distribution<int> coordDist( -500000, 500000 );
227 std::uniform_int_distribution<int> sizeDist( 1, 5000 );
236 std::vector<ITEM> items(
N );
239 for(
int i = 0; i <
N; ++i )
241 int x = coordDist(
rng );
242 int y = coordDist(
rng );
243 int w = sizeDist(
rng );
244 int h = sizeDist(
rng );
248 items[i].max[0] = x + w;
249 items[i].max[1] = y + h;
250 items[i].id =
static_cast<intptr_t
>( i );
252 tree.
Insert( items[i].min, items[i].max, items[i].
id );
258 for(
int q = 0; q < 50; ++q )
260 int qx = coordDist(
rng );
261 int qy = coordDist(
rng );
262 int qw = sizeDist(
rng ) * 10;
263 int qh = sizeDist(
rng ) * 10;
265 int qMin[2] = { qx, qy };
266 int qMax[2] = { qx + qw, qy + qh };
270 for(
const ITEM& item : items )
272 if( item.min[0] <= qMax[0] && item.max[0] >= qMin[0]
273 && item.min[1] <= qMax[1] && item.max[1] >= qMin[1] )
279 std::set<intptr_t>
actual;
281 auto collect = [&
actual]( intptr_t val )
287 tree.
Search( qMin, qMax, collect );
306 std::vector<ITEM> items(
N );
308 for(
int i = 0; i <
N; ++i )
310 items[i].min[0] = i * 5;
311 items[i].min[1] = i * 5;
312 items[i].max[0] = i * 5 + 4;
313 items[i].max[1] = i * 5 + 4;
314 items[i].id =
static_cast<intptr_t
>( i );
316 tree.
Insert( items[i].min, items[i].max, items[i].
id );
320 for(
int i = 0; i <
N; i += 2 )
321 BOOST_CHECK( tree.
Remove( items[i].min, items[i].max, items[i].id ) );
326 std::set<intptr_t> remaining;
328 auto collect = [&remaining]( intptr_t val )
330 remaining.insert( val );
334 int fullMin[2] = { -10000, -10000 };
335 int fullMax[2] = { 10000, 10000 };
336 tree.
Search( fullMin, fullMax, collect );
340 for(
int i = 1; i <
N; i += 2 )
341 BOOST_CHECK( remaining.count( i ) );
349 for(
int i = 0; i < 50; ++i )
351 int min[2] = { i, i };
352 int max[2] = { i + 5, i + 5 };
353 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
365 tree3 = std::move( tree2 );
370 int sMin[2] = { 0, 0 };
371 int sMax[2] = { 100, 100 };
374 auto counter = [&count]( intptr_t )
380 tree3.
Search( sMin, sMax, counter );
389 for(
int i = 0; i < 100; ++i )
391 int min[2] = { i, i };
392 int max[2] = { i + 1, i + 1 };
393 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
400 BOOST_CHECK( tree.
empty() );
403 int min[2] = { 0, 0 };
404 int max[2] = { 10, 10 };
405 tree.
Insert( min, max, 999 );
414 for(
int i = 0; i < 100; ++i )
416 int min[3] = { i, i, i };
417 int max[3] = { i + 5, i + 5, i + 5 };
418 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
423 int sMin[3] = { 10, 10, 10 };
424 int sMax[3] = { 20, 20, 20 };
427 auto counter = [&count]( intptr_t )
433 tree.
Search( sMin, sMax, counter );
434 BOOST_CHECK_GT( count, 0 );
443 for(
int i = 0; i < 20; ++i )
445 int min[2] = { i * 100, 0 };
446 int max[2] = { i * 100 + 10, 10 };
447 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
451 int point[2] = { 0, 0 };
452 std::vector<std::pair<int64_t, intptr_t>> results;
461 for(
size_t i = 1; i < results.size(); ++i )
462 BOOST_CHECK_GE( results[i].first, results[i - 1].first );
470 for(
int i = 0; i < 200; ++i )
472 int min[2] = { i * 3, i * 7 };
473 int max[2] = { i * 3 + 2, i * 7 + 6 };
474 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
477 std::set<intptr_t> iterated;
479 for(
const auto& val : tree )
480 iterated.insert( val );
484 for(
int i = 0; i < 200; ++i )
485 BOOST_CHECK( iterated.count( i ) );
493 for(
int i = 0; i < 100; ++i )
495 int min[2] = { 0, 0 };
496 int max[2] = { 100, 100 };
497 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
502 auto stopAfter5 = [&count]( intptr_t )
508 int sMin[2] = { 0, 0 };
509 int sMax[2] = { 100, 100 };
510 tree.
Search( sMin, sMax, stopAfter5 );
523 int origMin[2] = { 100, 100 };
524 int origMax[2] = { 200, 200 };
525 tree.
Insert( origMin, origMax, 42 );
527 int otherMin[2] = { 500, 500 };
528 int otherMax[2] = { 600, 600 };
529 tree.
Insert( otherMin, otherMax, 99 );
535 int movedMin[2] = { 300, 300 };
536 int movedMax[2] = { 400, 400 };
537 BOOST_CHECK( tree.
Remove( movedMin, movedMax, 42 ) );
541 std::vector<intptr_t> results;
543 auto collect = [&results]( intptr_t val )
545 results.push_back( val );
549 int fullMin[2] = { -1000, -1000 };
550 int fullMax[2] = { 1000, 1000 };
551 tree.
Search( fullMin, fullMax, collect );
561 std::mt19937
rng( 11111 );
562 std::uniform_int_distribution<int> coordDist( 0, 100000 );
563 std::uniform_int_distribution<int> sizeDist( 100, 5000 );
564 std::uniform_int_distribution<int> opDist( 0, 9 );
575 std::vector<ITEM> liveItems;
577 for(
int op = 0; op <
N; ++op )
579 int which = opDist(
rng );
581 if( which < 5 || liveItems.empty() )
585 item.min[0] = coordDist(
rng );
586 item.min[1] = coordDist(
rng );
587 item.max[0] = item.min[0] + sizeDist(
rng );
588 item.max[1] = item.min[1] + sizeDist(
rng );
589 item.id =
static_cast<intptr_t
>( op );
591 tree.
Insert( item.min, item.max, item.id );
592 liveItems.push_back( item );
597 std::uniform_int_distribution<int> idxDist( 0, liveItems.size() - 1 );
598 int idx = idxDist(
rng );
599 ITEM& item = liveItems[idx];
601 BOOST_CHECK( tree.
Remove( item.min, item.max, item.id ) );
603 liveItems.erase( liveItems.begin() + idx );
608 int qMin[2] = { coordDist(
rng ), coordDist(
rng ) };
609 int qMax[2] = { qMin[0] + sizeDist(
rng ) * 5, qMin[1] + sizeDist(
rng ) * 5 };
613 for(
const ITEM& item : liveItems )
615 if( item.min[0] <= qMax[0] && item.max[0] >= qMin[0]
616 && item.min[1] <= qMax[1] && item.max[1] >= qMin[1] )
622 std::set<intptr_t>
actual;
624 auto collect = [&
actual]( intptr_t val )
630 tree.
Search( qMin, qMax, collect );
642 std::vector<DYNAMIC_RTREE<int, int, 2>::BULK_ENTRY> entries;
646 BOOST_CHECK( tree.
empty() );
653 std::vector<DYNAMIC_RTREE<int, int, 2>::BULK_ENTRY> entries;
654 entries.push_back( { { 10, 20 }, { 30, 40 }, 42 } );
659 std::vector<int> results;
660 auto collect = [&results](
int val ) { results.push_back( val );
return true; };
661 int qMin[2] = { 0, 0 };
662 int qMax[2] = { 100, 100 };
663 tree.
Search( qMin, qMax, collect );
673 std::mt19937
rng( 99999 );
674 std::uniform_int_distribution<int> coordDist( 0, 100000 );
675 std::uniform_int_distribution<int> sizeDist( 100, 5000 );
684 std::vector<ITEM> items(
N );
686 for(
int i = 0; i <
N; ++i )
688 items[i].min[0] = coordDist(
rng );
689 items[i].min[1] = coordDist(
rng );
690 items[i].max[0] = items[i].min[0] + sizeDist(
rng );
691 items[i].max[1] = items[i].min[1] + sizeDist(
rng );
697 std::vector<DYNAMIC_RTREE<int, int, 2>::BULK_ENTRY> entries;
698 entries.reserve(
N );
700 for(
const auto& item : items )
701 entries.push_back( { { item.min[0], item.min[1] }, { item.max[0], item.max[1] }, item.id } );
708 const int QUERIES = 200;
710 for(
int q = 0; q < QUERIES; ++q )
712 int qMin[2] = { coordDist(
rng ), coordDist(
rng ) };
713 int qMax[2] = { qMin[0] + sizeDist(
rng ) * 5, qMin[1] + sizeDist(
rng ) * 5 };
717 for(
const auto& item : items )
719 if( item.min[0] <= qMax[0] && item.max[0] >= qMin[0]
720 && item.min[1] <= qMax[1] && item.max[1] >= qMin[1] )
727 auto collect = [&
actual](
int val ) {
actual.insert( val );
return true; };
728 tree.
Search( qMin, qMax, collect );
735 std::set<int> allViaIter;
737 for(
int val : tree )
738 allViaIter.insert( val );
747 std::mt19937
rng( 77777 );
748 std::uniform_int_distribution<int> coordDist( 0, 100000 );
749 std::uniform_int_distribution<int> sizeDist( 100, 5000 );
753 std::vector<DYNAMIC_RTREE<int, int, 2>::BULK_ENTRY> entries;
762 std::vector<ITEM> liveItems;
764 for(
int i = 0; i <
N; ++i )
767 item.min[0] = coordDist(
rng );
768 item.min[1] = coordDist(
rng );
769 item.max[0] = item.min[0] + sizeDist(
rng );
770 item.max[1] = item.min[1] + sizeDist(
rng );
772 entries.push_back( { { item.min[0], item.min[1] }, { item.max[0], item.max[1] }, item.id } );
773 liveItems.push_back( item );
780 for(
int i =
N; i <
N + 100; ++i )
783 item.min[0] = coordDist(
rng );
784 item.min[1] = coordDist(
rng );
785 item.max[0] = item.min[0] + sizeDist(
rng );
786 item.max[1] = item.min[1] + sizeDist(
rng );
788 tree.
Insert( item.min, item.max, item.id );
789 liveItems.push_back( item );
795 for(
int i = 0; i < 50; ++i )
797 std::uniform_int_distribution<int> idxDist( 0, liveItems.size() - 1 );
798 int idx = idxDist(
rng );
799 ITEM& item = liveItems[idx];
801 BOOST_CHECK( tree.
Remove( item.min, item.max, item.id ) );
802 liveItems.erase( liveItems.begin() + idx );
808 int qMin[2] = { 0, 0 };
809 int qMax[2] = { 200000, 200000 };
813 for(
const auto& item : liveItems )
815 if( item.min[0] <= qMax[0] && item.max[0] >= qMin[0]
816 && item.min[1] <= qMax[1] && item.max[1] >= qMin[1] )
823 auto collect = [&
actual](
int val ) {
actual.insert( val );
return true; };
824 tree.
Search( qMin, qMax, collect );
842 for(
int i = 0; i < 100; ++i )
844 int min[2] = { i * 10, i * 10 };
845 int max[2] = { i * 10 + 9, i * 10 + 9 };
846 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
852 auto clone = tree.
Clone();
856 int sMin[2] = { 0, 0 };
857 int sMax[2] = { 50, 50 };
859 std::set<intptr_t> origResults;
860 std::set<intptr_t> cloneResults;
862 auto collectOrig = [&origResults]( intptr_t val )
864 origResults.insert( val );
868 auto collectClone = [&cloneResults]( intptr_t val )
870 cloneResults.insert( val );
874 tree.
Search( sMin, sMax, collectOrig );
875 clone.Search( sMin, sMax, collectClone );
877 BOOST_CHECK( origResults == cloneResults );
885 for(
int i = 0; i < 50; ++i )
887 int min[2] = { i * 10, 0 };
888 int max[2] = { i * 10 + 9, 9 };
889 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
892 auto clone = tree.
Clone();
895 int newMin[2] = { 1000, 1000 };
896 int newMax[2] = { 1010, 1010 };
897 clone.
Insert( newMin, newMax, 999 );
903 std::vector<intptr_t> origResults;
905 auto collectOrig = [&origResults]( intptr_t val )
907 origResults.push_back( val );
911 tree.
Search( newMin, newMax, collectOrig );
912 BOOST_CHECK( origResults.empty() );
915 std::vector<intptr_t> cloneResults;
917 auto collectClone = [&cloneResults]( intptr_t val )
919 cloneResults.push_back( val );
923 clone.Search( newMin, newMax, collectClone );
933 for(
int i = 0; i < 50; ++i )
935 int min[2] = { i * 10, 0 };
936 int max[2] = { i * 10 + 9, 9 };
937 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
940 auto clone = tree.
Clone();
943 int rmMin[2] = { 0, 0 };
944 int rmMax[2] = { 9, 9 };
945 BOOST_CHECK( clone.Remove( rmMin, rmMax, 0 ) );
951 std::vector<intptr_t> origResults;
953 auto collectOrig = [&origResults]( intptr_t val )
955 origResults.push_back( val );
959 tree.
Search( rmMin, rmMax, collectOrig );
960 BOOST_CHECK( std::find( origResults.begin(), origResults.end(), 0 )
961 != origResults.end() );
969 for(
int i = 0; i < 30; ++i )
971 int min[2] = { i * 10, 0 };
972 int max[2] = { i * 10 + 9, 9 };
973 root.
Insert( min, max,
static_cast<intptr_t
>( i ) );
976 auto child1 = root.
Clone();
978 int newMin1[2] = { 500, 500 };
979 int newMax1[2] = { 510, 510 };
980 child1.
Insert( newMin1, newMax1, 100 );
982 auto grandchild = child1.Clone();
984 int newMin2[2] = { 600, 600 };
985 int newMax2[2] = { 610, 610 };
986 grandchild.Insert( newMin2, newMax2, 200 );
993 std::vector<intptr_t> rootResults;
995 auto collectRoot = [&rootResults]( intptr_t val )
997 rootResults.push_back( val );
1001 root.
Search( newMin1, newMax1, collectRoot );
1002 BOOST_CHECK( rootResults.empty() );
1004 root.
Search( newMin2, newMax2, collectRoot );
1005 BOOST_CHECK( rootResults.empty() );
1013 for(
int i = 0; i < 50; ++i )
1015 int min[2] = { i, i };
1016 int max[2] = { i + 1, i + 1 };
1017 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
1020 auto clone = tree.
Clone();
1022 std::set<intptr_t> cloneItems;
1024 for(
const auto& val : clone )
1025 cloneItems.insert( val );
1035 for(
int i = 0; i < 30; ++i )
1037 int min[2] = { i, i };
1038 int max[2] = { i + 1, i + 1 };
1039 tree.
Insert( min, max,
static_cast<intptr_t
>( i ) );
1042 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")