gcs/gcs: ensure match zero hash
This commit is contained in:
parent
6f51807c27
commit
8cea9a2e28
1 changed files with 59 additions and 37 deletions
90
gcs/gcs.go
90
gcs/gcs.go
|
@ -304,12 +304,11 @@ func (f *Filter) Match(key [KeySize]byte, data []byte) (bool, error) {
|
||||||
term = fastReduction(term, nphi, nplo)
|
term = fastReduction(term, nphi, nplo)
|
||||||
|
|
||||||
// Go through the search filter and look for the desired value.
|
// Go through the search filter and look for the desired value.
|
||||||
var lastValue uint64
|
var value uint64
|
||||||
for lastValue < term {
|
for i := uint32(0); i < f.N(); i++ {
|
||||||
|
|
||||||
// Read the difference between previous and new value from
|
// Read the difference between previous and new value from
|
||||||
// bitstream.
|
// bitstream.
|
||||||
value, err := f.readFullUint64(b)
|
delta, err := f.readFullUint64(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
return false, nil
|
return false, nil
|
||||||
|
@ -317,15 +316,25 @@ func (f *Filter) Match(key [KeySize]byte, data []byte) (bool, error) {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the previous value to it.
|
// Add the delta to the previous value.
|
||||||
value += lastValue
|
value += delta
|
||||||
if value == term {
|
switch {
|
||||||
|
|
||||||
|
// The current value matches our query term, success.
|
||||||
|
case value == term:
|
||||||
return true, nil
|
return true, nil
|
||||||
|
|
||||||
|
// The current value is greater than our query term, thus no
|
||||||
|
// future decoded value can match because the values
|
||||||
|
// monotonically increase.
|
||||||
|
case value > term:
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lastValue = value
|
// All values were decoded and none produced a successful match. This
|
||||||
}
|
// indicates that the items in the filter were all smaller than our
|
||||||
|
// target.
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,42 +391,55 @@ func (f *Filter) ZipMatchAny(key [KeySize]byte, data [][]byte) (bool, error) {
|
||||||
}
|
}
|
||||||
sort.Sort(values)
|
sort.Sort(values)
|
||||||
|
|
||||||
|
querySize := len(values)
|
||||||
|
|
||||||
// Zip down the filters, comparing values until we either run out of
|
// Zip down the filters, comparing values until we either run out of
|
||||||
// values to compare in one of the filters or we reach a matching
|
// values to compare in one of the filters or we reach a matching
|
||||||
// value.
|
// value.
|
||||||
var lastValue1, lastValue2 uint64
|
var (
|
||||||
lastValue2 = values[0]
|
value uint64
|
||||||
i := 1
|
queryIndex int
|
||||||
for lastValue1 != lastValue2 {
|
)
|
||||||
// Check which filter to advance to make sure we're comparing
|
out:
|
||||||
// the right values.
|
for i := uint32(0); i < f.N(); i++ {
|
||||||
switch {
|
// Advance filter we're searching or return false if we're at
|
||||||
case lastValue1 > lastValue2:
|
// the end because nothing matched.
|
||||||
// Advance filter created from search terms or return
|
delta, err := f.readFullUint64(b)
|
||||||
// false if we're at the end because nothing matched.
|
|
||||||
if i < len(values) {
|
|
||||||
lastValue2 = values[i]
|
|
||||||
i++
|
|
||||||
} else {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
case lastValue2 > lastValue1:
|
|
||||||
// Advance filter we're searching or return false if
|
|
||||||
// we're at the end because nothing matched.
|
|
||||||
value, err := f.readFullUint64(b)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
lastValue1 += value
|
value += delta
|
||||||
|
|
||||||
|
for {
|
||||||
|
switch {
|
||||||
|
|
||||||
|
// All query items have been exhausted and we haven't
|
||||||
|
// had a match, therefore there are no matches.
|
||||||
|
case queryIndex == querySize:
|
||||||
|
return false, nil
|
||||||
|
|
||||||
|
// The current item in the query matches the decoded
|
||||||
|
// value, success.
|
||||||
|
case values[queryIndex] == value:
|
||||||
|
return true, nil
|
||||||
|
|
||||||
|
// The current item in the query is greater than the
|
||||||
|
// current decoded value, continue to decode the next
|
||||||
|
// delta and try again.
|
||||||
|
case values[queryIndex] > value:
|
||||||
|
continue out
|
||||||
|
}
|
||||||
|
|
||||||
|
queryIndex++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we've made it this far, an element matched between filters so we
|
// All items in the filter were decoded and none produced a successful
|
||||||
// return true.
|
// match.
|
||||||
return true, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// HashMatchAny returns checks whether any []byte value is likely (within
|
// HashMatchAny returns checks whether any []byte value is likely (within
|
||||||
|
|
Loading…
Reference in a new issue