Skip to content

Commit 6679db0

Browse files
committed
[optimisation] Lazy initialisation of Modules Dependency Graph
1 parent 15e62ea commit 6679db0

File tree

2 files changed

+30
-25
lines changed

2 files changed

+30
-25
lines changed

exist-core/src/main/java/org/exist/xquery/ModuleContext.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,7 @@ public ModuleContext(final XQueryContext parentContext, final String moduleNames
6666
super(parentContext != null ? parentContext.db : null,
6767
parentContext != null ? parentContext.getConfiguration() : null,
6868
null,
69-
false,
70-
null);
69+
false);
7170
this.moduleNamespace = moduleNamespace;
7271
this.modulePrefix = modulePrefix;
7372
this.location = location;

exist-core/src/main/java/org/exist/xquery/XQueryContext.java

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
import org.exist.xquery.update.Modification;
9696
import org.exist.xquery.util.SerializerUtils;
9797
import org.exist.xquery.value.*;
98+
import org.jgrapht.Graph;
9899
import org.jgrapht.alg.interfaces.ShortestPathAlgorithm;
99100
import org.jgrapht.alg.shortestpath.TransitNodeRoutingShortestPath;
100101
import org.jgrapht.graph.DefaultEdge;
@@ -235,7 +236,8 @@ public class XQueryContext implements BinaryValueManager, Context {
235236
/**
236237
* Describes a graph of all the modules and how they import each other.
237238
*/
238-
private @Nullable final FastutilMapGraph<ModuleVertex, DefaultEdge> modulesDependencyGraph;
239+
private @Nullable Graph<ModuleVertex, DefaultEdge> modulesDependencyGraph;
240+
private @Nullable ThreadPoolExecutor modulesDependencyGraphSPExecutor;
239241

240242
/**
241243
* Used to save current state when modules are imported dynamically
@@ -467,10 +469,6 @@ public XQueryContext(@Nullable final Database db, @Nullable final Configuration
467469
}
468470

469471
protected XQueryContext(@Nullable final Database db, @Nullable final Configuration configuration, @Nullable final Profiler profiler, final boolean loadDefaults) {
470-
this(db, configuration, profiler, loadDefaults, new FastutilMapGraph<>(null, SupplierUtil.createDefaultEdgeSupplier(), DefaultGraphType.directedPseudograph().asUnweighted()));
471-
}
472-
473-
protected XQueryContext(@Nullable final Database db, @Nullable final Configuration configuration, @Nullable final Profiler profiler, final boolean loadDefaults, final @Nullable FastutilMapGraph<ModuleVertex, DefaultEdge> modulesDependencyGraph) {
474472
this.db = db;
475473

476474
// if needed, fallback to db.getConfiguration
@@ -491,8 +489,6 @@ protected XQueryContext(@Nullable final Database db, @Nullable final Configurati
491489
this.profiler = new Profiler(null);
492490
}
493491

494-
this.modulesDependencyGraph = modulesDependencyGraph;
495-
496492
this.watchdog = new XQueryWatchDog(this);
497493

498494
// load configuration defaults
@@ -1459,6 +1455,15 @@ public void reset(final boolean keepGlobals) {
14591455
httpContext = null;
14601456
}
14611457

1458+
if (modulesDependencyGraphSPExecutor != null) {
1459+
try {
1460+
ConcurrencyUtil.shutdownExecutionService(modulesDependencyGraphSPExecutor);
1461+
} catch (final InterruptedException e) {
1462+
Thread.currentThread().interrupt();
1463+
}
1464+
modulesDependencyGraphSPExecutor = null;
1465+
}
1466+
14621467
analyzed = false;
14631468
}
14641469

@@ -1548,13 +1553,21 @@ public void addModule(final String namespaceURI, final Module module) {
15481553
addRootModule(namespaceURI, module);
15491554
}
15501555

1556+
private Graph<ModuleVertex, DefaultEdge> getModulesDependencyGraph() {
1557+
// NOTE(AR) intentionally lazily initialised!
1558+
if (modulesDependencyGraph == null) {
1559+
this.modulesDependencyGraph = new FastutilMapGraph<>(null, SupplierUtil.createDefaultEdgeSupplier(), DefaultGraphType.directedPseudograph().asUnweighted());
1560+
}
1561+
return modulesDependencyGraph;
1562+
}
1563+
15511564
/**
15521565
* Add a vertex to the Modules Dependency Graph.
15531566
*
15541567
* @param moduleVertex the module vertex
15551568
*/
15561569
protected void addModuleVertex(final ModuleVertex moduleVertex) {
1557-
modulesDependencyGraph.addVertex(moduleVertex);
1570+
getModulesDependencyGraph().addVertex(moduleVertex);
15581571
}
15591572

15601573
/**
@@ -1565,7 +1578,7 @@ protected void addModuleVertex(final ModuleVertex moduleVertex) {
15651578
* @return true if the module vertex exists, false otherwise
15661579
*/
15671580
protected boolean hasModuleVertex(final ModuleVertex moduleVertex) {
1568-
return modulesDependencyGraph.containsVertex(moduleVertex);
1581+
return getModulesDependencyGraph().containsVertex(moduleVertex);
15691582
}
15701583

15711584
/**
@@ -1575,7 +1588,7 @@ protected boolean hasModuleVertex(final ModuleVertex moduleVertex) {
15751588
* @param sink the imported module
15761589
*/
15771590
protected void addModuleEdge(final ModuleVertex source, final ModuleVertex sink) {
1578-
modulesDependencyGraph.addEdge(source, sink);
1591+
getModulesDependencyGraph().addEdge(source, sink);
15791592
}
15801593

15811594
/**
@@ -1591,20 +1604,13 @@ protected boolean hasModulePath(final ModuleVertex source, final ModuleVertex si
15911604
return false;
15921605
}
15931606

1594-
ThreadPoolExecutor executor = null;
1595-
try {
1596-
executor = ConcurrencyUtil.createThreadPoolExecutor(2);
1597-
final ShortestPathAlgorithm<ModuleVertex, DefaultEdge> spa = new TransitNodeRoutingShortestPath<>(modulesDependencyGraph, executor);
1598-
return spa.getPath(source, sink) != null;
1599-
} finally {
1600-
if (executor != null) {
1601-
try {
1602-
ConcurrencyUtil.shutdownExecutionService(executor);
1603-
} catch (final InterruptedException e) {
1604-
Thread.currentThread().interrupt();
1605-
}
1606-
}
1607+
// NOTE(AR) intentionally lazily initialised!
1608+
if (modulesDependencyGraphSPExecutor == null) {
1609+
modulesDependencyGraphSPExecutor = ConcurrencyUtil.createThreadPoolExecutor(2);
16071610
}
1611+
1612+
final ShortestPathAlgorithm<ModuleVertex, DefaultEdge> spa = new TransitNodeRoutingShortestPath<>(getModulesDependencyGraph(), modulesDependencyGraphSPExecutor);
1613+
return spa.getPath(source, sink) != null;
16081614
}
16091615

16101616
protected void setRootModules(final String namespaceURI, @Nullable final Module[] modules) {

0 commit comments

Comments
 (0)