1515import java .nio .file .Files ;
1616import java .nio .file .Path ;
1717import java .util .Comparator ;
18+ import java .util .Optional ;
19+ import java .util .concurrent .TimeUnit ;
1820import java .util .concurrent .locks .ReentrantLock ;
1921import java .util .function .Supplier ;
2022import java .util .stream .Stream ;
2729import org .eclipse .rdf4j .common .transaction .IsolationLevel ;
2830import org .eclipse .rdf4j .common .transaction .IsolationLevels ;
2931import org .eclipse .rdf4j .model .ValueFactory ;
32+ import org .eclipse .rdf4j .query .Dataset ;
3033import org .eclipse .rdf4j .query .algebra .evaluation .EvaluationStrategy ;
3134import org .eclipse .rdf4j .query .algebra .evaluation .EvaluationStrategyFactory ;
35+ import org .eclipse .rdf4j .query .algebra .evaluation .QueryOptimizerPipeline ;
36+ import org .eclipse .rdf4j .query .algebra .evaluation .TripleSource ;
3237import org .eclipse .rdf4j .query .algebra .evaluation .federation .FederatedServiceResolver ;
3338import org .eclipse .rdf4j .query .algebra .evaluation .federation .FederatedServiceResolverClient ;
3439import org .eclipse .rdf4j .query .algebra .evaluation .impl .DefaultEvaluationStrategyFactory ;
40+ import org .eclipse .rdf4j .query .algebra .evaluation .impl .EvaluationStatistics ;
3541import org .eclipse .rdf4j .repository .sparql .federation .SPARQLServiceResolver ;
3642import org .eclipse .rdf4j .sail .InterruptedSailException ;
3743import org .eclipse .rdf4j .sail .NotifyingSailConnection ;
3844import org .eclipse .rdf4j .sail .SailException ;
3945import org .eclipse .rdf4j .sail .base .SailSource ;
4046import org .eclipse .rdf4j .sail .base .SailStore ;
47+ import org .eclipse .rdf4j .sail .base .SketchBasedJoinEstimator ;
4148import org .eclipse .rdf4j .sail .base .SnapshotSailStore ;
4249import org .eclipse .rdf4j .sail .helpers .AbstractNotifyingSail ;
4350import org .eclipse .rdf4j .sail .helpers .DirectoryLockManager ;
@@ -84,7 +91,15 @@ public class LmdbStore extends AbstractNotifyingSail implements FederatedService
8491 */
8592 private volatile Lock dirLock ;
8693
87- private EvaluationStrategyFactory evalStratFactory ;
94+ private EvaluationStrategyFactory explicitEvalStratFactory ;
95+
96+ private DefaultEvaluationStrategyFactory defaultEvalStratFactory ;
97+
98+ private LmdbEvaluationStrategyFactory lmdbEvalStratFactory ;
99+
100+ private EvaluationStrategyFactory connectionEvalStratFactory ;
101+
102+ private QueryOptimizerPipeline automaticOptimizerPipeline ;
88103
89104 /**
90105 * independent life cycle
@@ -167,13 +182,16 @@ public void setDataDir(File dataDir) {
167182 * @return Returns the {@link EvaluationStrategy}.
168183 */
169184 public synchronized EvaluationStrategyFactory getEvaluationStrategyFactory () {
170- if (evalStratFactory == null ) {
171- evalStratFactory = new LmdbEvaluationStrategyFactory (getFederatedServiceResolver ());
185+ EvaluationStrategyFactory factory ;
186+ if (explicitEvalStratFactory != null ) {
187+ factory = explicitEvalStratFactory ;
188+ } else if (isSketchEstimatorReadyNonBlocking ()) {
189+ factory = getAutomaticLmdbEvaluationStrategyFactory ();
190+ } else {
191+ factory = getAutomaticDefaultEvaluationStrategyFactory ();
172192 }
173- evalStratFactory .setQuerySolutionCacheThreshold (getIterationCacheSyncThreshold ());
174- evalStratFactory .setTrackResultSize (isTrackResultSize ());
175- evalStratFactory .setCollectionFactory (getCollectionFactory ());
176- return evalStratFactory ;
193+ configureEvaluationStrategyFactory (factory );
194+ return factory ;
177195 }
178196
179197 public boolean getPageCardinalityEstimator () {
@@ -184,7 +202,10 @@ public boolean getPageCardinalityEstimator() {
184202 * Sets the {@link EvaluationStrategy} to use.
185203 */
186204 public synchronized void setEvaluationStrategyFactory (EvaluationStrategyFactory factory ) {
187- evalStratFactory = factory ;
205+ explicitEvalStratFactory = factory ;
206+ if (factory != null ) {
207+ configureEvaluationStrategyFactory (factory );
208+ }
188209 }
189210
190211 /**
@@ -209,8 +230,14 @@ public synchronized FederatedServiceResolver getFederatedServiceResolver() {
209230 @ Override
210231 public synchronized void setFederatedServiceResolver (FederatedServiceResolver resolver ) {
211232 this .serviceResolver = resolver ;
212- if (resolver != null && evalStratFactory instanceof FederatedServiceResolverClient ) {
213- ((FederatedServiceResolverClient ) evalStratFactory ).setFederatedServiceResolver (resolver );
233+ if (resolver != null && explicitEvalStratFactory instanceof FederatedServiceResolverClient ) {
234+ ((FederatedServiceResolverClient ) explicitEvalStratFactory ).setFederatedServiceResolver (resolver );
235+ }
236+ if (resolver != null && defaultEvalStratFactory != null ) {
237+ defaultEvalStratFactory .setFederatedServiceResolver (resolver );
238+ }
239+ if (resolver != null && lmdbEvalStratFactory != null ) {
240+ lmdbEvalStratFactory .setFederatedServiceResolver (resolver );
214241 }
215242 }
216243
@@ -265,7 +292,7 @@ protected void initializeInternal() throws SailException {
265292 properties .setVersion (String .valueOf (VERSION ));
266293 }
267294
268- boolean useSketchBasedJoinEstimator = usesLmdbEvaluationStrategyFactory ();
295+ boolean useSketchBasedJoinEstimator = usesAutomaticEvaluationStrategyFactory ();
269296 backingStore = new LmdbSailStore (dataDir , properties , config , useSketchBasedJoinEstimator );
270297
271298 // update version afer loading and potential internal migration within value and triple store
@@ -423,8 +450,126 @@ LmdbSailStore getBackingStore() {
423450 return backingStore ;
424451 }
425452
426- private boolean usesLmdbEvaluationStrategyFactory () {
427- return getEvaluationStrategyFactory () instanceof LmdbEvaluationStrategyFactory ;
453+ EvaluationStrategyFactory getConnectionEvaluationStrategyFactory () {
454+ EvaluationStrategyFactory factory = connectionEvalStratFactory ;
455+ if (factory == null ) {
456+ synchronized (this ) {
457+ factory = connectionEvalStratFactory ;
458+ if (factory == null ) {
459+ factory = new AdaptiveEvaluationStrategyFactory ();
460+ connectionEvalStratFactory = factory ;
461+ }
462+ }
463+ }
464+ return factory ;
465+ }
466+
467+ public boolean awaitSketchesReady (long timeout , TimeUnit unit ) throws InterruptedException {
468+ SketchBasedJoinEstimator estimator = getSketchBasedJoinEstimator ();
469+ return estimator != null && estimator .awaitReady (timeout , unit );
470+ }
471+
472+ private boolean usesAutomaticEvaluationStrategyFactory () {
473+ return explicitEvalStratFactory == null ;
474+ }
475+
476+ private boolean isSketchEstimatorReadyNonBlocking () {
477+ SketchBasedJoinEstimator estimator = getSketchBasedJoinEstimator ();
478+ return estimator != null && estimator .isReadyNonBlocking ();
479+ }
480+
481+ private SketchBasedJoinEstimator getSketchBasedJoinEstimator () {
482+ LmdbSailStore backingStore = this .backingStore ;
483+ return backingStore == null ? null : backingStore .getSketchBasedJoinEstimator ();
484+ }
485+
486+ private DefaultEvaluationStrategyFactory getAutomaticDefaultEvaluationStrategyFactory () {
487+ if (defaultEvalStratFactory == null ) {
488+ defaultEvalStratFactory = new DefaultEvaluationStrategyFactory (getFederatedServiceResolver ());
489+ defaultEvalStratFactory .setOptimizerPipeline (automaticOptimizerPipeline );
490+ }
491+ return defaultEvalStratFactory ;
492+ }
493+
494+ private LmdbEvaluationStrategyFactory getAutomaticLmdbEvaluationStrategyFactory () {
495+ if (lmdbEvalStratFactory == null ) {
496+ lmdbEvalStratFactory = new LmdbEvaluationStrategyFactory (getFederatedServiceResolver ());
497+ lmdbEvalStratFactory .setOptimizerPipeline (automaticOptimizerPipeline );
498+ }
499+ return lmdbEvalStratFactory ;
500+ }
501+
502+ private void configureEvaluationStrategyFactory (EvaluationStrategyFactory factory ) {
503+ factory .setQuerySolutionCacheThreshold (getIterationCacheSyncThreshold ());
504+ factory .setTrackResultSize (isTrackResultSize ());
505+ factory .setCollectionFactory (getCollectionFactory ());
506+ if (factory instanceof FederatedServiceResolverClient ) {
507+ ((FederatedServiceResolverClient ) factory ).setFederatedServiceResolver (getFederatedServiceResolver ());
508+ }
509+ }
510+
511+ private final class AdaptiveEvaluationStrategyFactory
512+ implements EvaluationStrategyFactory , FederatedServiceResolverClient {
513+
514+ @ Override
515+ public void setQuerySolutionCacheThreshold (long threshold ) {
516+ getEvaluationStrategyFactory ().setQuerySolutionCacheThreshold (threshold );
517+ }
518+
519+ @ Override
520+ public long getQuerySolutionCacheThreshold () {
521+ return getEvaluationStrategyFactory ().getQuerySolutionCacheThreshold ();
522+ }
523+
524+ @ Override
525+ public void setOptimizerPipeline (QueryOptimizerPipeline pipeline ) {
526+ automaticOptimizerPipeline = pipeline ;
527+ if (explicitEvalStratFactory != null ) {
528+ explicitEvalStratFactory .setOptimizerPipeline (pipeline );
529+ }
530+ if (defaultEvalStratFactory != null ) {
531+ defaultEvalStratFactory .setOptimizerPipeline (pipeline );
532+ }
533+ if (lmdbEvalStratFactory != null ) {
534+ lmdbEvalStratFactory .setOptimizerPipeline (pipeline );
535+ }
536+ }
537+
538+ @ Override
539+ public Optional <QueryOptimizerPipeline > getOptimizerPipeline () {
540+ return getEvaluationStrategyFactory ().getOptimizerPipeline ();
541+ }
542+
543+ @ Override
544+ public EvaluationStrategy createEvaluationStrategy (Dataset dataset , TripleSource tripleSource ,
545+ EvaluationStatistics evaluationStatistics ) {
546+ return getEvaluationStrategyFactory ().createEvaluationStrategy (dataset , tripleSource , evaluationStatistics );
547+ }
548+
549+ @ Override
550+ public boolean isTrackResultSize () {
551+ return getEvaluationStrategyFactory ().isTrackResultSize ();
552+ }
553+
554+ @ Override
555+ public void setTrackResultSize (boolean trackResultSize ) {
556+ getEvaluationStrategyFactory ().setTrackResultSize (trackResultSize );
557+ }
558+
559+ @ Override
560+ public void setCollectionFactory (Supplier <CollectionFactory > collectionFactory ) {
561+ getEvaluationStrategyFactory ().setCollectionFactory (collectionFactory );
562+ }
563+
564+ @ Override
565+ public void setFederatedServiceResolver (FederatedServiceResolver resolver ) {
566+ LmdbStore .this .setFederatedServiceResolver (resolver );
567+ }
568+
569+ @ Override
570+ public FederatedServiceResolver getFederatedServiceResolver () {
571+ return LmdbStore .this .getFederatedServiceResolver ();
572+ }
428573 }
429574
430575 private boolean upgradeStore (File dataDir , String version ) throws SailException {
0 commit comments