Skip to content

Commit e3ceeeb

Browse files
committed
Correct estimate based on actual triple count.
1 parent ea92603 commit e3ceeeb

File tree

1 file changed

+37
-39
lines changed

1 file changed

+37
-39
lines changed

src/org/linkeddatafragments/datasource/HdtDataSource.java

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)