func (m Map) computeDistance(sourceEntity, targetEntity *entity, distance uint16, visitedResources map[string]struct{}) uint16 {
	for _, o := range sourceEntity.Overrides {
		if o.Target == targetEntity.Resource {
			return o.Distance
		}
		if _, ok := visitedResources[o.Target]; !ok {
			visitedResources[o.Target] = struct{}{}
			if e, okB := m[o.Target]; okB {
				if _, ok = e.descendants[targetEntity.Resource]; ok {
					return o.Distance
				}
			}
			delete(visitedResources, o.Target)
		}
	}
	for _, e := range sourceEntity.parent.Entities {
		if e == targetEntity {
			return sourceEntity.parent.Distance
		}
		if _, ok := visitedResources[e.Resource]; !ok {
			visitedResources[e.Resource] = struct{}{}
			if _, ok = e.descendants[targetEntity.Resource]; ok {
				return sourceEntity.parent.Distance
			}
			delete(visitedResources, e.Resource)
		}
	}
	visitedResources[sourceEntity.parent.Resource] = struct{}{}
	return m.computeDistance(sourceEntity.parent, targetEntity, distance, visitedResources)
}
Recursively compute the distance between source and target.
package distance
import (
	"errors"
	"math/rand"
	"github.com/uber/cherami-server/common/configure"
	"github.com/uber-common/bark"
)
const (
	ZeroDistance = 0
	InfiniteDistance = ^uint16(0)
)
type Map map[string]*entity
var (
	errSource = errors.New("Cannot find source")
	errTarget = errors.New("Cannot find target")
)
type override struct {
	source *entity
	Target   string `yaml:"target"`
	Distance uint16 `yaml:"distance"`
}
type entity struct {
	parent      *entity
	descendants map[string]struct{}  
	Resource  string      `yaml:"resource"`
	Type      string      `yaml:"type"`
	Distance  uint16      `yaml:"distance"`
	Entities  []*entity   `yaml:"entities"`
	Overrides []*override `yaml:"overrides"`
}
func New(path string, log bark.Logger) (m Map, err error) {
	var e entity
	if err = configure.NewCommonConfigure().LoadFile(&e, path); err == nil {
		m = make(Map)
		m.init(&e, log)
	}
	return
}
func (m Map) init(e *entity, log bark.Logger) (resources []string) {
	m[e.Resource] = e
	for _, f := range e.Entities {
		if f.Distance > e.Distance {
			log.WithFields(bark.Fields{"entity": f.Resource, "parent": e.Resource}).Fatal("Distance cannot be greater than its parent")
		}
		f.parent = e
		resources = append(resources, m.init(f, log)...)
	}
	e.descendants = make(map[string]struct{})
	for _, r := range resources {
		e.descendants[r] = struct{}{}
	}
	resources = append(resources, e.Resource)
	return
}