gcs/gcs: ensure match zero hash

This commit is contained in:
Conner Fromknecht 2019-04-24 17:05:02 -07:00 committed by Olaoluwa Osuntokun
parent 6f51807c27
commit 8cea9a2e28

View file

@ -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