func calculateSignature()

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
}