func splitID(entryID string) (string, string) {
	segments := strings.Split(entryID, "/")
	parentID := strings.Join(segments[:len(segments)-1], "/")
	cname := segments[len(segments)-1]
	return parentID, cname
}
returns (parentID, cname)
package plugin
import (
	"context"
	"fmt"
	"regexp"
	"strings"
	"time"
	"github.com/puppetlabs/wash/datastore"
)
type keyType int
const parentID keyType = iota
var cache datastore.Cache
func InitCache() {
	if notRunningTests() {
		cache = datastore.NewMemCache()
	} else {
		panic("InitCache can only be called in production. Tests should call SetTestCache instead.")
	}
}
func SetTestCache(c datastore.Cache) context.Context {
	if notRunningTests() {
		panic("SetTestCache can only be called when running the tests")
	}
	if cache != nil {
		panic("The test cache has already been set")
	}
	cache = c
	return context.WithValue(context.Background(), parentID, "/")
}
func UnsetTestCache() {
	if notRunningTests() {
		panic("UnsetTestCache can only be called when running the tests")
	}
	if cache == nil {
		panic("The test cache has already been unset")
	}
	cache = nil
}
var opNameRegex = regexp.MustCompile("^[a-zA-Z]+$")
const opQualifier = "^[a-zA-Z]+::"
func opKeyRegex(op string, path string) *regexp.Regexp {
	opRegex := "^" + regexp.QuoteMeta(op+"::")
	var expr string
	if path == "/" {
		expr = opRegex + "/$"
	} else {
		expr = opRegex + "/" + regexp.QuoteMeta(strings.Trim(path, "/")) + "$"
	}
	return regexp.MustCompile(expr)
}
func allOpKeysIncludingChildrenRegex(path string) *regexp.Regexp {
	var expr string
	if path == "/" {
		expr = opQualifier + "/.*"
	} else {
		expr = opQualifier + "/" + regexp.QuoteMeta(strings.Trim(path, "/")) + "($|/.*)"
	}
	return regexp.MustCompile(expr)
}
func ClearCacheFor(path string, clearAncestorList bool) []string {
	rx := allOpKeysIncludingChildrenRegex(path)
	deleted := cache.Delete(rx)
	if clearAncestorList {
		if sourceAncestorID := getSourceAncestorPathFromCache(path); sourceAncestorID != "" {
			listOpName := defaultOpCodeToNameMap[ListOp]
			deleted = append(deleted, cache.Delete(opKeyRegex(listOpName, sourceAncestorID))...)
		}
	}
	return deleted
}
func getSourceAncestorPathFromCache(path string) string {
	if e := getCachedEntry(path); e != nil && !IsPrefetched(e) {
		parentID, _ := splitID(path)
		return parentID
	}
	for path, _ = splitID(path); path != ""; path, _ = splitID(path) {
		if e := getCachedEntry(path); e != nil && !IsPrefetched(e) {
			return path
		}
	}
	return ""
}
func getCachedEntry(path string) Entry {
	parentID, cname := splitID(path)
	if entries, _ := cache.Get(defaultOpCodeToNameMap[ListOp], parentID); entries != nil {
		e, ok := entries.(*EntryMap).Load(cname)
		if ok {
			return e
		}  
	}
	return nil
}