func (cache *multiCache) copyPairs() map[string]Pair {
	pairs, _ := cache.load().(map[string]Pair)
	newPairs := make(map[string]Pair, len(pairs)+1)
	for keyID, pair := range pairs {
		newPairs[keyID] = pair
	}
	return newPairs
}
copyPairs creates a copy of the current key cache.  If no keys are present
yet, this method returns a non-nil empty map.
package key
import (
	"sync"
	"sync/atomic"
	"time"
	"github.com/xmidt-org/webpa-common/v2/concurrent"
)
const (
	dummyKeyId = ""
)
type Cache interface {
	Resolver
	UpdateKeys() (int, []error)
}
type basicCache struct {
	delegate   Resolver
	value      atomic.Value
	updateLock sync.Mutex
}
func (b *basicCache) load() interface{} {
	return b.value.Load()
}
func (b *basicCache) store(newValue interface{}) {
	b.value.Store(newValue)
}
func (b *basicCache) update(operation func()) {
	b.updateLock.Lock()
	defer b.updateLock.Unlock()
	operation()
}
type singleCache struct {
	basicCache
}
func (cache *singleCache) ResolveKey(keyID string) (pair Pair, err error) {
	var ok bool
	pair, ok = cache.load().(Pair)
	if !ok {
		cache.update(func() {
			pair, ok = cache.load().(Pair)
			if !ok {
				pair, err = cache.delegate.ResolveKey(keyID)
				if err == nil {
					cache.store(pair)
				}
			}
		})
	}
	return
}
func (cache *singleCache) UpdateKeys() (count int, errors []error) {
	count = 1
	cache.update(func() {
		if pair, err := cache.delegate.ResolveKey(dummyKeyId); err == nil {
			cache.store(pair)
		} else {
			errors = []error{err}
		}
	})
	return
}
type multiCache struct {
	basicCache
}
func (cache *multiCache) fetchPair(keyID string) (pair Pair, ok bool) {
	pairs, ok := cache.load().(map[string]Pair)
	if ok {
		pair, ok = pairs[keyID]
	}
	return
}