| // dataCache is a thread-safe map for any two types. |
| m map[interface{}]interface{} |
| func newDataCache() *dataCache { |
| return &dataCache{m: make(map[interface{}]interface{})} |
| // GetOrInsert first checks if the key exists in the cache with a reader lock. |
| // If it doesn't exist, it instead acquires a writer lock, creates and stores the new value |
| // with create and returns value. |
| func (c *dataCache) GetOrInsert(key interface{}, create func() interface{}) interface{} { |
| // We use the read lock for the fastpath. This should be the more common case, so we rarely |
| value, exists := c.m[key] |
| // We acquire the writer lock for the slowpath, and need to re-check if the key exists |
| // in the map, since other thread may have snuck in. |