in executor/collision_matrix.go [167:222]
func calculateSignature(object interface{}) (sign float64) {
if object == nil {
// prime number. different from boolean
return 3
}
switch o := object.(type) {
case bson.M: // recursive
for k, v := range o {
sign += calculateSignature(k)
sign += calculateSignature(v)
}
case []interface{}: // recursive
for _, v := range o {
sign += calculateSignature(v)
}
case primitive.Binary: // byte array
for _, c := range o.Data {
// consult from Java String.hashcode()
sign = 31.0*sign + float64(c)
}
case string:
for _, c := range o {
// consult from Java String.hashcode()
sign = 31.0*sign + float64(c)
}
case []byte:
for _, c := range o {
// consult from Java String.hashcode()
sign = 31.0*sign + float64(c)
}
case primitive.Timestamp: // numbers
sign = float64(int64(o.T<<32) + int64(o.I))
case int, uint, int8, uint8, int16, uint16, int32, uint32, int64, uint64, float32, float64:
if v, ok := object.(float64); ok {
sign = float64(v)
}
case bool: // boolean
sign++
if o {
sign++
}
default:
nimo.Assert(fmt.Sprintf("bson value signature type is not recognized [%d, %s]", reflect.TypeOf(object).Kind(),
reflect.TypeOf(object).Name()))
LOG.Critical("Bson value signature type is not recognized [%d, %s]", reflect.TypeOf(object).Kind(),
reflect.TypeOf(object).Name())
// default value represents may be conflict. the signature is unsafe. just speed up !
// so simply sum zero value here
return 0
}
return sign
}