|
|
@ -172,10 +172,10 @@ func (txi *TxIndex) Search(q *query.Query) ([]*types.TxResult, error) { |
|
|
|
|
|
|
|
for _, r := range ranges { |
|
|
|
if !hashesInitialized { |
|
|
|
hashes = txi.matchRange(r, []byte(r.key)) |
|
|
|
hashes = txi.matchRange(r, startKey(r.key)) |
|
|
|
hashesInitialized = true |
|
|
|
} else { |
|
|
|
hashes = intersect(hashes, txi.matchRange(r, []byte(r.key))) |
|
|
|
hashes = intersect(hashes, txi.matchRange(r, startKey(r.key))) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -190,10 +190,10 @@ func (txi *TxIndex) Search(q *query.Query) ([]*types.TxResult, error) { |
|
|
|
} |
|
|
|
|
|
|
|
if !hashesInitialized { |
|
|
|
hashes = txi.match(c, startKey(c, height)) |
|
|
|
hashes = txi.match(c, startKeyForCondition(c, height)) |
|
|
|
hashesInitialized = true |
|
|
|
} else { |
|
|
|
hashes = intersect(hashes, txi.match(c, startKey(c, height))) |
|
|
|
hashes = intersect(hashes, txi.match(c, startKeyForCondition(c, height))) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -359,14 +359,14 @@ func (txi *TxIndex) match(c query.Condition, startKey []byte) (hashes [][]byte) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
func (txi *TxIndex) matchRange(r queryRange, prefix []byte) (hashes [][]byte) { |
|
|
|
func (txi *TxIndex) matchRange(r queryRange, startKey []byte) (hashes [][]byte) { |
|
|
|
// create a map to prevent duplicates
|
|
|
|
hashesMap := make(map[string][]byte) |
|
|
|
|
|
|
|
lowerBound := r.lowerBoundValue() |
|
|
|
upperBound := r.upperBoundValue() |
|
|
|
|
|
|
|
it := dbm.IteratePrefix(txi.store, prefix) |
|
|
|
it := dbm.IteratePrefix(txi.store, startKey) |
|
|
|
defer it.Close() |
|
|
|
LOOP: |
|
|
|
for ; it.Valid(); it.Next() { |
|
|
@ -409,16 +409,6 @@ LOOP: |
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Keys
|
|
|
|
|
|
|
|
func startKey(c query.Condition, height int64) []byte { |
|
|
|
var key string |
|
|
|
if height > 0 { |
|
|
|
key = fmt.Sprintf("%s/%v/%d/", c.Tag, c.Operand, height) |
|
|
|
} else { |
|
|
|
key = fmt.Sprintf("%s/%v/", c.Tag, c.Operand) |
|
|
|
} |
|
|
|
return []byte(key) |
|
|
|
} |
|
|
|
|
|
|
|
func isTagKey(key []byte) bool { |
|
|
|
return strings.Count(string(key), tagKeySeparator) == 3 |
|
|
|
} |
|
|
@ -429,11 +419,36 @@ func extractValueFromKey(key []byte) string { |
|
|
|
} |
|
|
|
|
|
|
|
func keyForTag(tag cmn.KVPair, result *types.TxResult) []byte { |
|
|
|
return []byte(fmt.Sprintf("%s/%s/%d/%d", tag.Key, tag.Value, result.Height, result.Index)) |
|
|
|
return []byte(fmt.Sprintf("%s/%s/%d/%d", |
|
|
|
tag.Key, |
|
|
|
tag.Value, |
|
|
|
result.Height, |
|
|
|
result.Index, |
|
|
|
)) |
|
|
|
} |
|
|
|
|
|
|
|
func keyForHeight(result *types.TxResult) []byte { |
|
|
|
return []byte(fmt.Sprintf("%s/%d/%d/%d", types.TxHeightKey, result.Height, result.Height, result.Index)) |
|
|
|
return []byte(fmt.Sprintf("%s/%d/%d/%d", |
|
|
|
types.TxHeightKey, |
|
|
|
result.Height, |
|
|
|
result.Height, |
|
|
|
result.Index, |
|
|
|
)) |
|
|
|
} |
|
|
|
|
|
|
|
func startKeyForCondition(c query.Condition, height int64) []byte { |
|
|
|
if height > 0 { |
|
|
|
return startKey(c.Tag, c.Operand, height) |
|
|
|
} |
|
|
|
return startKey(c.Tag, c.Operand) |
|
|
|
} |
|
|
|
|
|
|
|
func startKey(fields ...interface{}) []byte { |
|
|
|
var b bytes.Buffer |
|
|
|
for _, f := range fields { |
|
|
|
b.Write([]byte(fmt.Sprintf("%v", f) + tagKeySeparator)) |
|
|
|
} |
|
|
|
return b.Bytes() |
|
|
|
} |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|