@@ -53,7 +53,8 @@ public class StatementPatternQueryEvaluationStep implements QueryEvaluationStep
5353 private final TripleSource tripleSource ;
5454 private final boolean emptyGraph ;
5555 private final Function <Value , Resource []> contextSup ;
56- private final BiConsumer <MutableBindingSet , Statement > converter ;
56+ private BiConsumer <MutableBindingSet , Statement > converter ;
57+ private BiConsumer <MutableBindingSet , Statement > convertStatementConverter ;
5758 private final QueryEvaluationContext context ;
5859 private final StatementOrder order ;
5960
@@ -64,6 +65,11 @@ public class StatementPatternQueryEvaluationStep implements QueryEvaluationStep
6465 private final Function <BindingSet , Value > getPredicateVar ;
6566 private final Function <BindingSet , Value > getObjectVar ;
6667
68+ private final Var normalizedSubjectVar ;
69+ private final Var normalizedPredicateVar ;
70+ private final Var normalizedObjectVar ;
71+ private final Var normalizedContextVar ;
72+
6773 // We try to do as much work as possible in the constructor.
6874 // With the aim of making the evaluate method as cheap as possible.
6975 public StatementPatternQueryEvaluationStep (StatementPattern statementPattern , QueryEvaluationContext context ,
@@ -137,9 +143,13 @@ public StatementPatternQueryEvaluationStep(StatementPattern statementPattern, Qu
137143 }
138144 }
139145
140- converter = makeConverter (context , subjVar , predVar , objVar , conVar );
146+ normalizedSubjectVar = subjVar ;
147+ normalizedPredicateVar = predVar ;
148+ normalizedObjectVar = objVar ;
149+ normalizedContextVar = conVar ;
141150
142- unboundTest = getUnboundTest (context , subjVar , predVar , objVar , conVar );
151+ unboundTest = getUnboundTest (context , normalizedSubjectVar , normalizedPredicateVar , normalizedObjectVar ,
152+ normalizedContextVar );
143153
144154 }
145155
@@ -276,7 +286,7 @@ private JoinStatementWithBindingSetIterator getIteration(BindingSet bindings) {
276286 iteration = handleFilter (contexts , (Resource ) subject , (IRI ) predicate , object , iteration );
277287
278288 // Return an iterator that converts the statements to var bindings
279- return new JoinStatementWithBindingSetIterator (iteration , converter , bindings , context );
289+ return new JoinStatementWithBindingSetIterator (iteration , getConverter () , bindings , context );
280290 } catch (Throwable t ) {
281291 if (iteration != null ) {
282292 iteration .close ();
@@ -328,7 +338,7 @@ private ConvertStatementToBindingSetIterator getIteration() {
328338 iteration = handleFilter (contexts , (Resource ) subject , (IRI ) predicate , object , iteration );
329339
330340 // Return an iterator that converts the statements to var bindings
331- return new ConvertStatementToBindingSetIterator (iteration , converter , context );
341+ return new ConvertStatementToBindingSetIterator (iteration , getConvertStatementConverter () , context );
332342 } catch (Throwable t ) {
333343 if (iteration != null ) {
334344 iteration .close ();
@@ -340,6 +350,36 @@ private ConvertStatementToBindingSetIterator getIteration() {
340350 }
341351 }
342352
353+ private BiConsumer <MutableBindingSet , Statement > getConverter () {
354+ BiConsumer <MutableBindingSet , Statement > localConverter = converter ;
355+ if (localConverter == null ) {
356+ synchronized (this ) {
357+ localConverter = converter ;
358+ if (localConverter == null ) {
359+ localConverter = makeConverter (context , normalizedSubjectVar , normalizedPredicateVar ,
360+ normalizedObjectVar , normalizedContextVar );
361+ converter = localConverter ;
362+ }
363+ }
364+ }
365+ return localConverter ;
366+ }
367+
368+ private BiConsumer <MutableBindingSet , Statement > getConvertStatementConverter () {
369+ BiConsumer <MutableBindingSet , Statement > localConverter = convertStatementConverter ;
370+ if (localConverter == null ) {
371+ synchronized (this ) {
372+ localConverter = convertStatementConverter ;
373+ if (localConverter == null ) {
374+ localConverter = makeConvertStatementConverter (context , normalizedSubjectVar ,
375+ normalizedPredicateVar , normalizedObjectVar , normalizedContextVar );
376+ convertStatementConverter = localConverter ;
377+ }
378+ }
379+ }
380+ return localConverter ;
381+ }
382+
343383 private CloseableIteration <? extends Statement > handleFilter (Resource [] contexts ,
344384 Resource subject , IRI predicate , Value object ,
345385 CloseableIteration <? extends Statement > iteration ) {
@@ -526,23 +566,23 @@ private static Resource[] fillContextsFromDatasSetGraphs(Set<IRI> graphs) {
526566 private static final class ConvertStatementToBindingSetIterator
527567 implements CloseableIteration <BindingSet > {
528568
529- private final BiConsumer <MutableBindingSet , Statement > action ;
569+ private final BiConsumer <MutableBindingSet , Statement > converter ;
530570 private final QueryEvaluationContext context ;
531571 private final CloseableIteration <? extends Statement > iteration ;
532572 private boolean closed = false ;
533573
534574 private ConvertStatementToBindingSetIterator (
535575 CloseableIteration <? extends Statement > iteration ,
536- BiConsumer <MutableBindingSet , Statement > action , QueryEvaluationContext context ) {
576+ BiConsumer <MutableBindingSet , Statement > converter , QueryEvaluationContext context ) {
537577 assert iteration != null ;
538578 this .iteration = iteration ;
539- this .action = action ;
579+ this .converter = converter ;
540580 this .context = context ;
541581 }
542582
543583 private BindingSet convert (Statement st ) {
544584 MutableBindingSet made = context .createBindingSet ();
545- action .accept (made , st );
585+ converter .accept (made , st );
546586 return made ;
547587 }
548588
@@ -573,27 +613,28 @@ public void close() throws QueryEvaluationException {
573613 private static final class JoinStatementWithBindingSetIterator
574614 implements CloseableIteration <BindingSet > {
575615
576- private final BiConsumer <MutableBindingSet , Statement > action ;
616+ private final BiConsumer <MutableBindingSet , Statement > converter ;
577617 private final QueryEvaluationContext context ;
578618 private final BindingSet bindings ;
579619 private final CloseableIteration <? extends Statement > iteration ;
580620 private boolean closed = false ;
581621
582622 private JoinStatementWithBindingSetIterator (
583623 CloseableIteration <? extends Statement > iteration ,
584- BiConsumer <MutableBindingSet , Statement > action , BindingSet bindings , QueryEvaluationContext context ) {
624+ BiConsumer <MutableBindingSet , Statement > converter , BindingSet bindings ,
625+ QueryEvaluationContext context ) {
585626 assert iteration != null ;
586627 this .iteration = iteration ;
587628 assert !bindings .isEmpty ();
588- this .action = action ;
629+ this .converter = converter ;
589630 this .context = context ;
590631 this .bindings = bindings ;
591632
592633 }
593634
594635 private BindingSet convert (Statement st ) {
595636 MutableBindingSet made = context .createBindingSet (bindings );
596- action .accept (made , st );
637+ converter .accept (made , st );
597638 return made ;
598639 }
599640
@@ -683,6 +724,60 @@ private static BiConsumer<MutableBindingSet, Statement> makeConverter(QueryEvalu
683724
684725 }
685726
727+ private static BiConsumer <MutableBindingSet , Statement > makeConvertStatementConverter (
728+ QueryEvaluationContext context ,
729+ Var s , Var p , Var o , Var c ) {
730+
731+ if (s != null && !s .isConstant ()) {
732+ if (p != null && !p .isConstant ()) {
733+ if (o != null && !o .isConstant ()) {
734+ if (c != null && !c .isConstant ()) {
735+ return StatementConvertorWithoutBindingChecks .spoc (context , s , p , o , c );
736+ } else {
737+ return StatementConvertorWithoutBindingChecks .spo (context , s , p , o );
738+ }
739+ } else if (c != null && !c .isConstant ()) {
740+ return StatementConvertorWithoutBindingChecks .spc (context , s , p , c );
741+ } else {
742+ return StatementConvertorWithoutBindingChecks .sp (context , s , p );
743+ }
744+ } else if (o != null && !o .isConstant ()) {
745+ if (c != null && !c .isConstant ()) {
746+ return StatementConvertorWithoutBindingChecks .soc (context , s , o , c );
747+ } else {
748+ return StatementConvertorWithoutBindingChecks .so (context , s , o );
749+ }
750+ } else if (c != null && !c .isConstant ()) {
751+ return StatementConvertorWithoutBindingChecks .sc (context , s , c );
752+ } else {
753+ return StatementConvertorWithoutBindingChecks .s (context , s );
754+ }
755+ } else if (p != null && !p .isConstant ()) {
756+ if (o != null && !o .isConstant ()) {
757+ if (c != null && !c .isConstant ()) {
758+ return StatementConvertorWithoutBindingChecks .poc (context , p , o , c );
759+ } else {
760+ return StatementConvertorWithoutBindingChecks .po (context , p , o );
761+ }
762+ } else if (c != null && !c .isConstant ()) {
763+ return StatementConvertorWithoutBindingChecks .pc (context , p , c );
764+ } else {
765+ return StatementConvertorWithoutBindingChecks .p (context , p );
766+ }
767+ } else if (o != null && !o .isConstant ()) {
768+ if (c != null && !c .isConstant ()) {
769+ return StatementConvertorWithoutBindingChecks .oc (context , o , c );
770+ } else {
771+ return StatementConvertorWithoutBindingChecks .o (context , o );
772+ }
773+ } else if (c != null && !c .isConstant ()) {
774+ return StatementConvertorWithoutBindingChecks .c (context , c );
775+ }
776+
777+ return (a , b ) -> {
778+ };
779+ }
780+
686781 private static Predicate <Statement > andThen (Predicate <Statement > pred , Predicate <Statement > and ) {
687782 if (pred == null ) {
688783 return and ;
0 commit comments