@@ -56,48 +56,46 @@ public TriplePatternFragment getFragment(Resource subject, Property predicate, R
5656 if (subjectId < 0 || predicateId < 0 || objectId < 0 ) {
5757 return new TriplePatternFragmentBase ();
5858 }
59- final IteratorTripleID result = datasource .getTriples ().search (new TripleID (subjectId , predicateId , objectId ));
60- // estimates can be wrong; ensure 0 is returned if and only if there are no results
61- final long totalSize = result .hasNext () ? Math .max (result .estimatedNumResults (), 1 ) : 0 ;
59+ final Model triples = ModelFactory .createDefaultModel ();
60+ final IteratorTripleID matches = datasource .getTriples ().search (new TripleID (subjectId , predicateId , objectId ));
61+ final boolean hasMatches = matches .hasNext ();
62+
63+ if (hasMatches ) {
64+ // try to jump directly to the offset
65+ boolean atOffset ;
66+ if (matches .canGoTo ()) {
67+ try {
68+ matches .goTo (offset );
69+ atOffset = true ;
70+ }
71+ // if the offset is outside the bounds, this page has no matches
72+ catch (IndexOutOfBoundsException exception ) { atOffset = false ; }
73+ }
74+ // if not possible, advance to the offset iteratively
75+ else {
76+ matches .goToStart ();
77+ for (int i = 0 ; !(atOffset = i == offset ) && matches .hasNext (); i ++)
78+ matches .next ();
79+ }
80+ // try to add `limit` triples to the result model
81+ if (atOffset ) {
82+ for (int i = 0 ; i < limit && matches .hasNext (); i ++)
83+ triples .add (triples .asStatement (toTriple (matches .next ())));
84+ }
85+ }
86+
87+ // estimates can be wrong; ensure 0 is returned if there are no results, and always more than actual results
88+ final long estimatedTotal = triples .size () > 0 ? Math .max (offset + triples .size () + 1 , matches .estimatedNumResults ())
89+ : hasMatches ? Math .max (matches .estimatedNumResults (), 1 ) : 0 ;
6290
6391 // create the fragment
6492 return new TriplePatternFragment () {
65- @ Override
66- public Model getTriples () {
67- final Model triples = ModelFactory .createDefaultModel ();
68-
69- // try to jump directly to the offset
70- boolean atOffset ;
71- if (result .canGoTo ()) {
72- try {
73- result .goTo (offset );
74- atOffset = true ;
75- } // if the offset is outside the bounds, this page has no matches
76- catch (IndexOutOfBoundsException exception ) {
77- atOffset = false ;
78- }
79- } // if not possible, advance to the offset iteratively
80- else {
81- result .goToStart ();
82- for (int i = 0 ; !(atOffset = i == offset ) && result .hasNext (); i ++) {
83- result .next ();
84- }
85- }
86-
87- // add `limit` triples to the result model
88- if (atOffset ) {
89- for (int i = 0 ; i < limit && result .hasNext (); i ++) {
90- triples .add (triples .asStatement (toTriple (result .next ())));
91- }
92- }
93- return triples ;
94- }
95-
96- @ Override
97- public long getTotalSize () {
98- return totalSize ;
99- }
100- };
93+ @ Override
94+ public Model getTriples () { return triples ; }
95+
96+ @ Override
97+ public long getTotalSize () { return estimatedTotal ; }
98+ };
10199 }
102100
103101 /**
0 commit comments