HTRACE-307. htraced: queries sometimes return no results even when many results exist due to confusion in iterator usage (Colin Patrick McCabe via iwasakims)
diff --git a/htrace-htraced/go/src/org/apache/htrace/htraced/datastore.go b/htrace-htraced/go/src/org/apache/htrace/htraced/datastore.go
index 3f17a61..2a3d65c 100644
--- a/htrace-htraced/go/src/org/apache/htrace/htraced/datastore.go
+++ b/htrace-htraced/go/src/org/apache/htrace/htraced/datastore.go
@@ -1228,12 +1228,20 @@
}
src.numRead[shardIdx]++
key := iter.Key()
- if !bytes.HasPrefix(key, []byte{src.keyPrefix}) {
- if lg.DebugEnabled() {
- lg.Debugf("Can't populate: Iterator for shard %s does not have prefix %s\n",
- shdPath, string(src.keyPrefix))
- }
+ if len(key) < 1 {
+ lg.Warnf("Encountered invalid zero-byte key in shard %s.\n", shdPath)
+ break
+ }
+ ret := src.checkKeyPrefix(key[0], iter)
+ if ret == NOT_SATISFIED {
break // Can't read past end of indexed section
+ } else if ret == NOT_YET_SATISFIED {
+ if src.pred.Op.IsDescending() {
+ iter.Prev()
+ } else {
+ iter.Next()
+ }
+ continue // Try again because we are not yet at the indexed section.
}
var span *common.Span
var sid common.SpanId
@@ -1265,7 +1273,7 @@
} else {
iter.Next()
}
- ret := src.pred.satisfiedBy(span)
+ ret = src.pred.satisfiedBy(span)
switch ret {
case NOT_SATISFIED:
break // This and subsequent entries don't satisfy predicate
@@ -1284,6 +1292,26 @@
src.iters[shardIdx] = nil
}
+// Check the key prefix against the key prefix of the query.
+func (src *source) checkKeyPrefix(kp byte, iter *levigo.Iterator) satisfiedByReturn {
+ if kp == src.keyPrefix {
+ return SATISFIED
+ } else if kp < src.keyPrefix {
+ if src.pred.Op.IsDescending() {
+ return NOT_SATISFIED
+ } else {
+ return NOT_YET_SATISFIED
+ }
+ } else {
+ if src.pred.Op.IsDescending() {
+ return NOT_YET_SATISFIED
+ } else {
+ return NOT_SATISFIED
+ }
+ }
+}
+
+
func (src *source) next() *common.Span {
for shardIdx := range src.shards {
src.populateNextFromShard(shardIdx)
diff --git a/htrace-htraced/go/src/org/apache/htrace/htraced/datastore_test.go b/htrace-htraced/go/src/org/apache/htrace/htraced/datastore_test.go
index 05fabfd..4fc400a 100644
--- a/htrace-htraced/go/src/org/apache/htrace/htraced/datastore_test.go
+++ b/htrace-htraced/go/src/org/apache/htrace/htraced/datastore_test.go
@@ -390,6 +390,20 @@
},
Lim: 500,
}, []common.Span{TEST_QUERIES5_SPANS[0], TEST_QUERIES5_SPANS[2]})
+
+ testQuery(t, ht, &common.Query{
+ Predicates: []common.Predicate{
+ common.Predicate{
+ Op: common.LESS_THAN_OR_EQUALS,
+ Field: common.END_TIME,
+ Val: "999",
+ },
+ },
+ Lim: 500,
+ }, []common.Span{TEST_QUERIES5_SPANS[2],
+ TEST_QUERIES5_SPANS[0],
+ TEST_QUERIES5_SPANS[1],
+ })
}
func BenchmarkDatastoreWrites(b *testing.B) {