func (c *Cache) lookup(vcenter, section string) *map[string]interface{} {
	lock.RLock()
	defer lock.RUnlock()
	result := make(map[string]interface{})
	for e := range *c {
		m := strings.Split(e, "|")
		if len(m) != 3 {
			continue
		}
		if m[0] != vcenter || m[1] != section {
			continue
		}
		result[m[2]] = (*c)[e]
	}
	return &result
}
lookup items in the cache
package vsphere
import (
	"bytes"
	"log"
	"strings"
	"sync"
	"github.com/cblomart/vsphere-graphite/utils"
	"github.com/vmware/govmomi/vim25/types"
)
type Cache map[string]interface{}
var lock = sync.RWMutex{}
func index(vcenter, section, i string) string {
	var buffer bytes.Buffer
	_, err := buffer.WriteString(vcenter)
	if err != nil {
		return ""
	}
	_, err = buffer.WriteString("|")
	if err != nil {
		return ""
	}
	_, err = buffer.WriteString(section)
	if err != nil {
		return ""
	}
	_, err = buffer.WriteString("|")
	if err != nil {
		return ""
	}
	_, err = buffer.WriteString(i)
	if err != nil {
		return ""
	}
	return buffer.String()
}
func (c *Cache) Add(vcenter, section, i string, v interface{}) {
	if len(vcenter) == 0 || len(section) == 0 || len(i) == 0 || v == nil {
		return
	}
	switch typed := v.(type) {
	case string:
		c.add(vcenter, section, i, &typed)
	case []string:
		if len(typed) > 0 {
			c.add(vcenter, section, i, &typed)
		}
	case int32:
		c.add(vcenter, section, i, &typed)
	case types.ManagedObjectReference:
		c.add(vcenter, section, i, &(typed.Value))
	case types.ArrayOfManagedObjectReference:
		if len(typed.ManagedObjectReference) > 0 {
			c.add(vcenter, section, i, &(typed.ManagedObjectReference))
		}
	case types.ArrayOfTag:
		if len(typed.Tag) > 0 {
			c.add(vcenter, section, i, &(typed.Tag))
		}
	case types.ArrayOfGuestDiskInfo:
		if len(typed.GuestDiskInfo) > 0 {
			c.add(vcenter, section, i, &(typed.GuestDiskInfo))
		}
	case types.VirtualMachineConnectionState:
		c.add(vcenter, section, i, &typed)
	case types.VirtualMachinePowerState:
		c.add(vcenter, section, i, &typed)
	case types.HostSystemConnectionState:
		c.add(vcenter, section, i, &typed)
	case types.HostSystemPowerState:
		c.add(vcenter, section, i, &typed)
	case types.DVSTrafficShapingPolicy:
		c.add(vcenter, section, i, &typed)
	case types.ArrayOfVirtualDevice:
		c.add(vcenter, section, i, &typed)
	default:
		log.Printf("cache %s/%s: unhandled type %T for %s\n", vcenter, section, v, i)
	}
}
func (c *Cache) add(vcenter, section, i string, v interface{}) {
	lock.Lock()
	defer lock.Unlock()
	if v != nil {
		(*c)[index(vcenter, section, i)] = v
	}
}
func (c *Cache) get(vcenter, section, i string) interface{} {
	lock.RLock()
	defer lock.RUnlock()
	if v, ok := (*c)[index(vcenter, section, i)]; ok {
		return v
	}
	return nil
}
func (c *Cache) GetString(vcenter, section, i string) *string {
	if v, ok := c.get(vcenter, section, i).(*string); ok {
		return v
	}
	return nil
}
func (c *Cache) GetStrings(vcenter, section, i string) *[]string {
	if v, ok := c.get(vcenter, section, i).(*[]string); ok {
		return v
	}
	return nil
}
func (c *Cache) GetInt32(vcenter, section, i string) *int32 {
	if v, ok := c.get(vcenter, section, i).(*int32); ok {
		return v
	}
	return nil
}
func (c *Cache) GetMoref(vcenter, section, i string) *types.ManagedObjectReference {
	if v, ok := c.get(vcenter, section, i).(*types.ManagedObjectReference); ok {
		return v
	}
	return nil
}
func (c *Cache) GetMorefs(vcenter, section, i string) *[]types.ManagedObjectReference {
	if v, ok := c.get(vcenter, section, i).(*[]types.ManagedObjectReference); ok {
		return v
	}
	return nil
}
func (c *Cache) GetTags(vcenter, section, i string) *[]types.Tag {
	if v, ok := c.get(vcenter, section, i).(*[]types.Tag); ok {
		return v
	}
	return nil
}
func (c *Cache) GetDiskInfos(vcenter, section, i string) *[]types.GuestDiskInfo {
	if v, ok := c.get(vcenter, section, i).(*[]types.GuestDiskInfo); ok {
		return v
	}
	return nil
}
func (c *Cache) GetVirtualMachineConnectionState(vcenter, section, i string) *types.VirtualMachineConnectionState {
	if v, ok := c.get(vcenter, section, i).(*types.VirtualMachineConnectionState); ok {
		return v
	}
	return nil
}
func (c *Cache) GetHostSystemConnectionState(vcenter, section, i string) *types.HostSystemConnectionState {
	if v, ok := c.get(vcenter, section, i).(*types.HostSystemConnectionState); ok {
		return v
	}
	return nil
}
func (c *Cache) GetVirtualMachinePowerState(vcenter, section, i string) *types.VirtualMachinePowerState {
	if v, ok := c.get(vcenter, section, i).(*types.VirtualMachinePowerState); ok {
		return v
	}
	return nil
}
func (c *Cache) GetHostSystemPowerState(vcenter, section, i string) *types.HostSystemPowerState {
	if v, ok := c.get(vcenter, section, i).(*types.HostSystemPowerState); ok {
		return v
	}
	return nil
}
func (c *Cache) GetConnectionState(vcenter, section, i string) *string {
	value := ""
	if strings.HasPrefix(i, "vm-") {
		state := c.GetVirtualMachineConnectionState(vcenter, section, i)
		if state == nil {
			return nil
		}
		value = (string)(*state)
		return &value
	} else if strings.HasPrefix(i, "host-") {
		state := c.GetHostSystemConnectionState(vcenter, section, i)
		if state == nil {
			return nil
		}
		value = (string)(*state)
		return &value
	}
	return nil
}
func (c *Cache) GetPowerState(vcenter, section, i string) *string {
	value := ""
	if strings.HasPrefix(i, "vm-") {
		state := c.GetVirtualMachinePowerState(vcenter, section, i)
		if state == nil {
			return nil
		}
		value = (string)(*state)
		return &value
	} else if strings.HasPrefix(i, "host-") {
		state := c.GetHostSystemPowerState(vcenter, section, i)
		if state == nil {
			return nil
		}
		value = (string)(*state)
		return &value
	}
	return nil
}
func (c *Cache) GetNetworkShapingInfo(vcenter, section, i string) *types.DVSTrafficShapingPolicy {
	if v, ok := c.get(vcenter, section, i).(*types.DVSTrafficShapingPolicy); ok {
		return v
	}
	return nil
}
func (c *Cache) GetDevices(vcenter, section, i string) *types.ArrayOfVirtualDevice {
	if v, ok := c.get(vcenter, section, i).(*types.ArrayOfVirtualDevice); ok {
		return v
	}
	return nil
}
func (c *Cache) Clean(vcenter string, section string, refs []string) {
	lock.Lock()
	defer lock.Unlock()
	for e := range *c {
		m := strings.Split(e, "|")
		if len(m) != 3 {
			delete(*c, e)
		}
		if m[0] != vcenter || m[1] != section {
			continue
		}
		found := false
		for _, ref := range refs {
			if m[2] == ref {
				found = true
				break
			}
		}
		if !found {
			log.Printf("removing %s from cache\n", e)
			delete(*c, e)
		}
	}
}
func (c *Cache) CleanAll(vcenter string, refs []string) {
	lock.Lock()
	defer lock.Unlock()
	for e := range *c {
		m := strings.Split(e, "|")
		if len(m) != 3 {
			delete(*c, e)
		}
		if m[0] != vcenter || m[1] == "metrics" || m[1] == "poolpaths" || m[1] == "datastoreids" {
			continue
		}
		found := false
		for _, ref := range refs {
			if m[2] == ref {
				found = true
				break
			}
		}
		if !found {
			log.Printf("removing %s from cache\n", e)
			delete(*c, e)
		}
	}
}
func (c *Cache) Purge(vcenter, section string) {
	lock.Lock()
	defer lock.Unlock()
	for e := range *c {
		m := strings.Split(e, "|")
		if len(m) != 3 {
			continue
		}
		if m[0] != vcenter || m[1] != section {
			continue
		}
		delete(*c, e)
	}
}