func ExactlyMatch()

in executor/collision_matrix.go [224:286]


func ExactlyMatch(first, second interface{}) bool {
	if (first != nil && second == nil) || (first == nil && second != nil) ||
		reflect.TypeOf(first).Kind() != reflect.TypeOf(second).Kind() {
		return false
	}

	// both of them are null is accept
	if first == nil && second == nil {
		return true
	}

	switch o := first.(type) {
	case bson.M: // recursive
		for key := range o {
			if v, ok := second.(map[string]interface{}); ok && !ExactlyMatch(o[key], v[key]) {
				return false
			}
		}
	case []interface{}: // recursive
		if v, ok := second.([]interface{}); ok {
			if len(o) != len(v) {
				return false
			}
		}
		for i := range o {
			if v, ok := second.([]interface{}); ok && !ExactlyMatch(o[i], v[i]) {
				return false
			}
		}
	case []byte: // byte array
		if v, ok := second.([]byte); ok {
			return bytes.Compare(o, v) == 0
		}
	case primitive.Binary:
		if v, ok := second.(primitive.Binary); ok {
			return bytes.Compare(o.Data, v.Data) == 0
		}
	case string:
		if v, ok := second.(string); ok {
			return o == v
		}
	case primitive.Timestamp: // numbers
		return (first.(primitive.Timestamp)).Equal(second.(primitive.Timestamp))
	case int, uint, int8, uint8, int16, uint16, int32, uint32, int64, uint64, float32, float64:
		if v1, ok := first.(float64); ok {
			if v2, ok := second.(float64); ok {
				return v1 == v2
			}
		}
	case bool: // boolean
		if v, ok := second.(bool); ok {
			return o == v
		}
	default:
		nimo.Assert(fmt.Sprintf("bson value check similar. not recognized [%s]", reflect.TypeOf(first).Name()))
		LOG.Critical("bson value check similar. not recognized [%s]", reflect.TypeOf(first).Name())
	}

	// TODO: execute path may be walked from DEFAULT we meet something that the type
	// we don't know now. for safety, we treat these oplogs' unique indexes as equal exactly !!
	// This may cause more segments splitted but more safe.
	return true
}