Skip to content

Commit f89069e

Browse files
committed
MCIndexSegmentSetMutualIntersector: Allow usage from multiple threads
1 parent 3cfed69 commit f89069e

18 files changed

+85
-108
lines changed

benchmarks/index/chain/MonotoneChainBuilderPerfTest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ static void BM_MonotoneChainBuilder(benchmark::State& state) {
6060

6161
for (auto _ : state) {
6262
std::vector<MonotoneChain> chains;
63-
MonotoneChainBuilder::getChains(&cs, nullptr, chains);
63+
MonotoneChainBuilder::getChains(&cs, nullptr, 0, chains);
6464
}
6565
}
6666

benchmarks/index/chain/MonotoneChainPerfTest.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ static void BM_MonotoneChainOverlaps(benchmark::State& state) {
4848
prev = c;
4949
}
5050

51-
MonotoneChain mc1(cs1, 0, cs1.size(), nullptr);
52-
MonotoneChain mc2(cs2, 0, cs1.size(), nullptr);
51+
MonotoneChain mc1(cs1, 0, cs1.size(), nullptr, 0.0);
52+
MonotoneChain mc2(cs2, 0, cs1.size(), nullptr, 0.0);
5353

5454
struct EmptyOverlapAction : public MonotoneChainOverlapAction {
5555
virtual void

include/geos/index/chain/MonotoneChain.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,12 @@ class GEOS_DLL MonotoneChain {
9696
/// Ownership left to caller, this class holds a reference.
9797
///
9898
MonotoneChain(const geom::CoordinateSequence& pts,
99-
std::size_t start, std::size_t end, void* context);
99+
std::size_t start, std::size_t end, void* context, double expansionDistance);
100100

101101
~MonotoneChain() = default;
102102

103103
/// Returned envelope is owned by this class
104104
const geom::Envelope& getEnvelope() const;
105-
const geom::Envelope& getEnvelope(double expansionDistance) const;
106105

107106
size_t
108107
getStartIndex() const

include/geos/index/chain/MonotoneChainBuilder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class GEOS_DLL MonotoneChainBuilder {
5858
*/
5959
static void getChains(const geom::CoordinateSequence* pts,
6060
void* context,
61+
double expansionDistance,
6162
std::vector<MonotoneChain>& mcList);
6263

6364
/**

include/geos/noding/FastSegmentSetIntersectionFinder.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ namespace noding { // geos::noding
4949
*/
5050
class FastSegmentSetIntersectionFinder {
5151
private:
52-
std::unique_ptr<MCIndexSegmentSetMutualIntersector> segSetMutInt;
53-
std::unique_ptr<geos::algorithm::LineIntersector> lineIntersector;
52+
MCIndexSegmentSetMutualIntersector segSetMutInt;
5453

5554
protected:
5655
public:
@@ -67,7 +66,7 @@ class FastSegmentSetIntersectionFinder {
6766
const SegmentSetMutualIntersector*
6867
getSegmentSetIntersector() const
6968
{
70-
return segSetMutInt.get();
69+
return &segSetMutInt;
7170
}
7271

7372
bool intersects(SegmentString::ConstVect* segStrings);

include/geos/noding/MCIndexSegmentSetMutualIntersector.h

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ class SegmentIntersector;
2929
}
3030
}
3131

32-
//using namespace geos::index::strtree;
33-
3432
namespace geos {
3533
namespace noding { // geos::noding
3634

@@ -45,12 +43,7 @@ class MCIndexSegmentSetMutualIntersector : public SegmentSetMutualIntersector {
4543
public:
4644

4745
MCIndexSegmentSetMutualIntersector(double p_tolerance)
48-
: monoChains()
49-
, indexCounter(0)
50-
, processCounter(0)
51-
, nOverlaps(0)
52-
, overlapTolerance(p_tolerance)
53-
, indexBuilt(false)
46+
: overlapTolerance(p_tolerance)
5447
{}
5548

5649
MCIndexSegmentSetMutualIntersector()
@@ -68,9 +61,10 @@ class MCIndexSegmentSetMutualIntersector : public SegmentSetMutualIntersector {
6861

6962
void setBaseSegments(SegmentString::ConstVect* segStrings) override;
7063

71-
// NOTE: re-populates the MonotoneChain vector with newly created chains
7264
void process(SegmentString::ConstVect* segStrings) override;
7365

66+
void process(SegmentString::ConstVect* segStrings, SegmentIntersector* si);
67+
7468
class SegmentOverlapAction : public index::chain::MonotoneChainOverlapAction {
7569
private:
7670
SegmentIntersector& si;
@@ -98,31 +92,25 @@ class MCIndexSegmentSetMutualIntersector : public SegmentSetMutualIntersector {
9892
private:
9993

10094
typedef std::vector<index::chain::MonotoneChain> MonoChains;
101-
MonoChains monoChains;
10295

10396
/*
10497
* The index::SpatialIndex used should be something that supports
10598
* envelope (range) queries efficiently (such as a index::quadtree::Quadtree
10699
* or index::strtree::STRtree).
107100
*/
108101
index::strtree::TemplateSTRtree<const index::chain::MonotoneChain*> index;
109-
int indexCounter;
110-
int processCounter;
111-
// statistics
112-
int nOverlaps;
113-
double overlapTolerance;
102+
103+
const double overlapTolerance;
114104

115105
/* memory management helper, holds MonotoneChain objects used
116106
* in the SpatialIndex. It's cleared when the SpatialIndex is
117107
*/
118-
bool indexBuilt;
108+
std::once_flag indexBuilt;
119109
MonoChains indexChains;
120110

121-
void addToIndex(SegmentString* segStr);
122-
123-
void intersectChains();
111+
void intersectChains(const MonoChains& chains, SegmentIntersector& segmentIntersector);
124112

125-
void addToMonoChains(SegmentString* segStr);
113+
void addChains(const SegmentString* segStr, MonoChains& chains) const;
126114

127115
};
128116

include/geos/noding/SegmentIntersectionDetector.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ namespace noding { // geos::noding
4040
*/
4141
class SegmentIntersectionDetector : public SegmentIntersector {
4242
private:
43-
algorithm::LineIntersector* li;
43+
algorithm::LineIntersector li;
4444

4545
bool findProper;
4646
bool findAllTypes;
@@ -54,9 +54,8 @@ class SegmentIntersectionDetector : public SegmentIntersector {
5454

5555
protected:
5656
public:
57-
SegmentIntersectionDetector(algorithm::LineIntersector* p_li)
57+
SegmentIntersectionDetector()
5858
:
59-
li(p_li),
6059
findProper(false),
6160
findAllTypes(false),
6261
_hasIntersection(false),
@@ -68,7 +67,6 @@ class SegmentIntersectionDetector : public SegmentIntersector {
6867

6968
~SegmentIntersectionDetector() override
7069
{
71-
//delete intPt;
7270
delete intSegments;
7371
}
7472

src/geom/prep/AbstractPreparedPolygonContains.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,7 @@ AbstractPreparedPolygonContains::findAndClassifyIntersections(const geom::Geomet
8383
noding::SegmentString::ConstVect lineSegStr;
8484
noding::SegmentStringUtil::extractSegmentStrings(geom, lineSegStr);
8585

86-
algorithm::LineIntersector li;
87-
88-
noding::SegmentIntersectionDetector intDetector(&li);
86+
noding::SegmentIntersectionDetector intDetector;
8987

9088
intDetector.setFindAllIntersectionTypes(true);
9189
prepPoly->getIntersectionFinder()->intersects(&lineSegStr, &intDetector);

src/index/chain/MonotoneChain.cpp

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,29 +32,22 @@ namespace index { // geos.index
3232
namespace chain { // geos.index.chain
3333

3434
MonotoneChain::MonotoneChain(const geom::CoordinateSequence& newPts,
35-
std::size_t nstart, std::size_t nend, void* nContext)
35+
std::size_t nstart, std::size_t nend, void* nContext,
36+
double expansionDistance)
3637
: pts(&newPts)
3738
, context(nContext)
3839
, start(nstart)
3940
, end(nend)
40-
, env()
41-
{}
42-
43-
const Envelope&
44-
MonotoneChain::getEnvelope() const
41+
, env(pts->getAt<CoordinateXY>(start), pts->getAt<CoordinateXY>(end))
4542
{
46-
return getEnvelope(0.0);
43+
if (expansionDistance > 0.0) {
44+
env.expandBy(expansionDistance);
45+
}
4746
}
4847

4948
const Envelope&
50-
MonotoneChain::getEnvelope(double expansionDistance) const
49+
MonotoneChain::getEnvelope() const
5150
{
52-
if (env.isNull()) {
53-
env.init(pts->getAt<CoordinateXY>(start), pts->getAt<CoordinateXY>(end));
54-
if (expansionDistance > 0.0) {
55-
env.expandBy(expansionDistance);
56-
}
57-
}
5851
return env;
5952
}
6053

src/index/chain/MonotoneChainBuilder.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,14 @@ namespace chain { // geos.index.chain
4848
*/
4949
class ChainBuilder : public CoordinateFilter {
5050
public:
51-
ChainBuilder(const CoordinateSequence* pts, void* context, std::vector<MonotoneChain> & list) :
51+
ChainBuilder(const CoordinateSequence* pts, void* context, double expansionDistance, std::vector<MonotoneChain> & list) :
5252
m_prev(nullptr),
5353
m_i(0),
5454
m_quadrant(-1),
5555
m_start(0),
5656
m_seq(pts),
5757
m_context(context),
58+
m_distance(expansionDistance),
5859
m_list(list) {}
5960

6061
void filter_ro(const CoordinateXY* c) override {
@@ -72,7 +73,7 @@ class ChainBuilder : public CoordinateFilter {
7273
void finishChain() {
7374
if ( m_i == 0 ) return;
7475
std::size_t chainEnd = m_i - 1;
75-
m_list.emplace_back(*m_seq, m_start, chainEnd, m_context);
76+
m_list.emplace_back(*m_seq, m_start, chainEnd, m_context, m_distance);
7677
m_start = chainEnd;
7778
}
7879

@@ -99,15 +100,17 @@ class ChainBuilder : public CoordinateFilter {
99100
std::size_t m_start;
100101
const CoordinateSequence* m_seq;
101102
void* m_context;
103+
double m_distance;
102104
std::vector<MonotoneChain>& m_list;
103105
};
104106

105107

106108
/* static public */
107109
void
108110
MonotoneChainBuilder::getChains(const CoordinateSequence* pts, void* context,
111+
double expansionDistance,
109112
std::vector<MonotoneChain>& mcList) {
110-
ChainBuilder builder(pts, context, mcList);
113+
ChainBuilder builder(pts, context, expansionDistance, mcList);
111114
pts->apply_ro(&builder);
112115
builder.finish();
113116
}

src/noding/FastSegmentSetIntersectionFinder.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,15 @@ namespace noding { // geos::noding
3939
*/
4040
FastSegmentSetIntersectionFinder::
4141
FastSegmentSetIntersectionFinder(noding::SegmentString::ConstVect* baseSegStrings)
42-
: segSetMutInt(new MCIndexSegmentSetMutualIntersector()),
43-
lineIntersector(new algorithm::LineIntersector())
4442
{
45-
segSetMutInt->setBaseSegments(baseSegStrings);
43+
segSetMutInt.setBaseSegments(baseSegStrings);
4644
}
4745

4846
bool
4947
FastSegmentSetIntersectionFinder::
5048
intersects(noding::SegmentString::ConstVect* segStrings)
5149
{
52-
SegmentIntersectionDetector intFinder(lineIntersector.get());
50+
SegmentIntersectionDetector intFinder;
5351

5452
return this->intersects(segStrings, &intFinder);
5553
}
@@ -59,8 +57,7 @@ FastSegmentSetIntersectionFinder::
5957
intersects(noding::SegmentString::ConstVect* segStrings,
6058
SegmentIntersectionDetector* intDetector)
6159
{
62-
segSetMutInt->setSegmentIntersector(intDetector);
63-
segSetMutInt->process(segStrings);
60+
segSetMutInt.process(segStrings, intDetector);
6461

6562
return intDetector->hasIntersection();
6663
}

src/noding/MCIndexNoder.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ MCIndexNoder::computeNodes(SegmentString::NonConstVect* inputSegStrings)
5151

5252
if (!indexBuilt) {
5353
for(const auto& mc : monoChains) {
54-
index.insert(mc.getEnvelope(overlapTolerance), &mc);
54+
index.insert(mc.getEnvelope(), &mc);
5555
}
5656
indexBuilt = true;
5757
}
@@ -84,7 +84,7 @@ MCIndexNoder::add(SegmentString* segStr)
8484

8585
// segChains will contain newly allocated MonotoneChain objects
8686
MonotoneChainBuilder::getChains(segStr->getCoordinates(),
87-
segStr, monoChains);
87+
segStr, overlapTolerance, monoChains);
8888

8989
}
9090

0 commit comments

Comments
 (0)