예제 #1
0
func (r *RoutingTree) Apply(update RoutingTreeUpdate) {
	r.lock.Lock()
	defer r.lock.Unlock()
	for _, delete := range update.Deletes {
		r.trie.Delete(patricia.Prefix(delete))
	}
	for prefix, service := range update.Services {
		r.trie.Insert(patricia.Prefix(prefix), service)
	}
	for prefix, shard := range update.Services {
		r.trie.Insert(patricia.Prefix(prefix), shard)
	}
}
예제 #2
0
func (r *RoutingTree) Route(destination string) Addresses {
	if strings.HasPrefix(destination, "x:") {
		parts := strings.Split(destination, "/")
		if len(parts) < 2 {
			return Addresses([]Address{})
		} else {
			nid, err := strconv.ParseInt(parts[0], 10, 32)
			pid, err := strconv.ParseInt(parts[1], 10, 32)
			if err != nil {
				return Addresses([]Address{})
			}
			return Addresses([]Address{Address{uint32(nid), uint32(pid)}})
		}
	} else {
		r.lock.Lock()
		defer r.lock.Unlock()
		var longestKey patricia.Prefix
		var ruleItem patricia.Item
		r.trie.VisitPrefixes(patricia.Prefix(destination), func(key patricia.Prefix, value patricia.Item) error {
			if len(key) > len(longestKey) {
				longestKey = key
				ruleItem = value
			}
			return nil
		})
		switch t := ruleItem.(type) {
		case Sharded:
			{
				shardParts := strings.Split(destination[len(longestKey):], "/")
				if len(shardParts) < 1 {
					return Addresses([]Address{})
				}
				shard := shardParts[0]
				for _, r := range t {
					if shard >= r.From && shard <= r.To {
						return r.Addresses()
					}
				}
			}
		case Simple:
			{
				return t.Addresses()
			}
		}
	}
	return Addresses([]Address{})
}
예제 #3
0
func (r *RoutingTree) UpsertShardedRule(prefix string, rule Sharded) {
	r.lock.Lock()
	defer r.lock.Unlock()
	r.trie.Insert(patricia.Prefix(prefix), rule)
}
예제 #4
0
func (r *RoutingTree) RemoveRule(prefix string) {
	r.lock.Lock()
	defer r.lock.Unlock()
	r.trie.Delete(patricia.Prefix(prefix))
}