<|start_filename|>splitio/engine/grammar/matchers/anyofset.go<|end_filename|>
package matchers

import (
	"github.com/splitio/go-toolkit/datastructures/set"
)

// ContainsAnyOfSetMatcher matches if the set supplied to the getTreatment is a superset of the one in the split
type ContainsAnyOfSetMatcher struct {
	Matcher
	comparisonSet *set.ThreadUnsafeSet
}

// Match returns true if the set provided is a superset of the one in the split
func (m *ContainsAnyOfSetMatcher) Match(key string, attributes map[string]interface{}, bucketingKey *string) bool {
	matchingKey, err := m.matchingKey(key, attributes)
	if err != nil {
		m.logger.Error("AnyOfSetMatcher: ", err)
		return false
	}

	conv, ok := matchingKey.([]string)
	if !ok {
		m.logger.Error("AnyOfSetMatcher: Failed to parse the key as a []string")
		return false
	}

	matchingSet := set.NewSet()
	for _, x := range conv {
		matchingSet.Add(x)
	}

	intersection := set.Intersection(matchingSet, m.comparisonSet)

	return intersection.Size() > 0
}

// NewContainsAnyOfSetMatcher returns a pointer to a new instance of ContainsAnyOfSetMatcher
func NewContainsAnyOfSetMatcher(negate bool, setItems []string, attributeName *string) *ContainsAnyOfSetMatcher {
	setObj := set.NewSet()
	for _, item := range setItems {
		setObj.Add(item)
	}

	return &ContainsAnyOfSetMatcher{
		Matcher: Matcher{
			negate:        negate,
			attributeName: attributeName,
		},
		comparisonSet: setObj,
	}
}


<|start_filename|>splitio/engine/grammar/matchers/equaltoset.go<|end_filename|>
package matchers

import (
	"github.com/splitio/go-toolkit/datastructures/set"
)

// EqualToSetMatcher matches if the set supplied to the getTreatment is equal to the one in the split
type EqualToSetMatcher struct {
	Matcher
	comparisonSet *set.ThreadUnsafeSet
}

// Match returns true if the match provided and the one in the split are equal
func (m *EqualToSetMatcher) Match(key string, attributes map[string]interface{}, bucketingKey *string) bool {
	matchingKey, err := m.matchingKey(key, attributes)
	if err != nil {
		m.logger.Error("EqualToSetMatcher: ", err)
		return false
	}

	conv, ok := matchingKey.([]string)
	if !ok {
		m.logger.Error("EqualToSetMatcher: Cannot type assert to []string")
		return false
	}

	matchingSet := set.NewSet()
	for _, x := range conv {
		matchingSet.Add(x)
	}

	return matchingSet.IsEqual(m.comparisonSet)

}

// NewEqualToSetMatcher returns a pointer to a new instance of EqualToSetMatcher
func NewEqualToSetMatcher(negate bool, setItems []string, attributeName *string) *EqualToSetMatcher {
	setObj := set.NewSet()
	for _, item := range setItems {
		setObj.Add(item)
	}

	return &EqualToSetMatcher{
		Matcher: Matcher{
			negate:        negate,
			attributeName: attributeName,
		},
		comparisonSet: setObj,
	}
}


<|start_filename|>splitio/engine/grammar/matchers/equalto.go<|end_filename|>
package matchers

import (
	"fmt"
	"github.com/splitio/go-client/splitio/engine/grammar/matchers/datatypes"
	"reflect"
)

// EqualToMatcher will match if two numbers or two datetimes are equal
type EqualToMatcher struct {
	Matcher
	ComparisonDataType string
	ComparisonValue    int64
}

// Match will match if the comparisonValue is equal to the matchingValue
func (m *EqualToMatcher) Match(key string, attributes map[string]interface{}, bucketingKey *string) bool {

	matchingRaw, err := m.matchingKey(key, attributes)
	if err != nil {
		m.logger.Error("EqualToMatcher: ", err)
		return false
	}

	matchingValue, ok := matchingRaw.(int64)
	if !ok {
		var asInt int
		asInt, ok = matchingRaw.(int)
		if ok {
			matchingValue = int64(asInt)
		}
	}
	if !ok {
		m.base().logger.Error(
			"EqualToMatcher: Error type-asserting matching key to an int",
			fmt.Sprintf("%s is a %s\n", matchingRaw, reflect.TypeOf(matchingRaw).String()),
		)
		return false
	}

	var comparisonValue int64
	switch m.ComparisonDataType {
	case datatypes.Number:
		comparisonValue = m.ComparisonValue
	case datatypes.Datetime:
		matchingValue = datatypes.ZeroTimeTS(matchingValue)
		comparisonValue = datatypes.ZeroTimeTS(datatypes.TsFromJava(m.ComparisonValue))
	default:
		m.logger.Error(fmt.Sprintf("EqualToMatcher: Invalid comparison type %s\n", m.ComparisonDataType))
		return false
	}
	return matchingValue == comparisonValue
}

// NewEqualToMatcher returns a pointer to a new instance of EqualToMatcher
func NewEqualToMatcher(negate bool, cmpVal int64, cmpType string, attributeName *string) *EqualToMatcher {
	return &EqualToMatcher{
		Matcher: Matcher{
			negate:        negate,
			attributeName: attributeName,
		},
		ComparisonValue:    cmpVal,
		ComparisonDataType: cmpType,
	}
}


<|start_filename|>splitio/engine/hash/legacy_test.go<|end_filename|>
package hash

import (
	"bufio"
	"encoding/json"
	"os"
	"testing"
)

func TestLegacyHashOnAlphanumericData(t *testing.T) {
	inFile, _ := os.Open("../../../testdata/sample-data.jsonl")
	defer inFile.Close()

	scanner := bufio.NewScanner(inFile)
	scanner.Split(bufio.ScanLines)

	for scanner.Scan() {
		arr := make([]interface{}, 4)
		json.Unmarshal(scanner.Bytes(), &arr)
		seed := uint32(arr[0].(float64))
		str := []byte(arr[1].(string))
		digest := uint32(arr[2].(float64))

		calculated := Legacy(str, seed)
		if calculated != digest {
			t.Errorf("Legacy hash calculation failed for string %s. Should be %d and was %d", str, digest, calculated)
		}
	}
}

// func TestLegacyHashOnNonAlphanumericData(t *testing.T) {
// 	inFile, _ := os.Open("../../../testdata/sample-data-non-alpha-numeric.jsonl")
// 	defer inFile.Close()
//
// 	scanner := bufio.NewScanner(inFile)
// 	scanner.Split(bufio.ScanLines)
//
// 	i := 0
// 	for scanner.Scan() && i < 10 {
// 		i++
// 		arr := make([]interface{}, 4)
// 		json.Unmarshal(scanner.Bytes(), &arr)
// 		seed := int32(arr[0].(float64))
// 		str := arr[1].(string)
// 		digest := int32(arr[2].(float64))
//
// 		calculated := Legacy(str, seed)
// 		if calculated != digest {
// 			t.Errorf("Legacy hash calculation failed for string %s. Should be %d and was %d", str, digest, calculated)
// 		}
// 	}
// }
