[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/unigraph-dev/dgraph/dgraph-personal/worker/stringfilter.go [Back]  [Original]

/*
 * Copyright 2017-2018 Dgraph Labs, Inc. and Contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package worker

import (
	"strings"

	"github.com/dgraph-io/dgraph/tok"
	"github.com/dgraph-io/dgraph/types"
	"github.com/dgraph-io/dgraph/x"
	"github.com/golang/glog"
)

type matchFunc func(types.Val, *stringFilter) bool

type stringFilter struct {
	funcName  string
	funcType  FuncType
	lang      string
	tokens    []string
	match     matchFunc
	ineqValue types.Val
	eqVals    []types.Val
	tokName   string
}

func matchStrings(filter *stringFilter, values []types.Val) bool {
	if len(values) == 0 {
		return false
	}
	if filter == nil {
		// Handle a nil filter as filtering all the elements out.
		return true
	}
	for i := 0; i < len(values); i++ {
		if filter.match(values[i], filter) {
			return true
		}
	}
	return false
}

func defaultMatch(value types.Val, filter *stringFilter) bool {
	tokenMap := map[string]bool{}
	for _, t := range filter.tokens {
		tokenMap[t] = false
	}

	tokens := tokenizeValue(value, filter)
	cnt := 0
	for _, token := range tokens {
		previous, ok := tokenMap[token]
		if ok {
			tokenMap[token] = true
			if !previous { // count only once
				cnt++
			}
		}
	}

	all := strings.HasPrefix(filter.funcName, "allof") // anyofterms or anyoftext

	if all {
		return cnt == len(filter.tokens)
	}
	return cnt > 0
}

func ineqMatch(value types.Val, filter *stringFilter) bool {
	if filter.funcName == eq {
		for _, v := range filter.eqVals {
			if types.CompareVals(filter.funcName, value, v) {
				return true
			}
		}
		return false
	} else if filter.funcName == between {
		return types.CompareVals("ge", value, filter.eqVals[0]) &&
			types.CompareVals("le", value, filter.eqVals[1])
	}

	return types.CompareVals(filter.funcName, value, filter.eqVals[0])
}

func tokenizeValue(value types.Val, filter *stringFilter) []string {
	tokenizer, found := tok.GetTokenizer(filter.tokName)
	// tokenizer was used in previous stages of query processing, it has to be available
	x.AssertTrue(found)

	tokens, err := tok.BuildTokens(value.Value, tok.GetTokenizerForLang(tokenizer, filter.lang))
	if err != nil {
		glog.Errorf("Error while building tokens: %s", err)
		return []string{}
	}
	return tokens
}

Web Proxy Viewer  |  New URL  |  Original Page