go.temporal.io/server/common/cache/simple.go
175 LOC · 87 covered · 88 uncovered · 22 ranges · 13 concepts · 11 introducers · 5 tests
File neighbourhood
The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.
Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file
In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.
Graph controls are ready.
Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.
package cache
import (
"container/list"
"sync"
"time"
)
var (
// DummyCreateTime is the create time used by all entries in the cache.
DummyCreateTime = time.Time{}
)
type (
simple struct {
sync.RWMutex
accessMap map[any]*list.Element
iterateList *list.List
rmFunc RemovedFunc
}
simpleItr struct {
simple *simple
nextItem *list.Element
}
simpleEntry struct {
key any
value any
}
)
// Close closes the iterator
it.simple.RUnlock()
}
// HasNext return true if there is more items to be returned
return it.nextItem != nil
}
// Next returns the next item
if it.nextItem == nil {
panic("Simple cache iterator Next called when there is no next item")
}
// nolint:revive
it.nextItem = it.nextItem.Next()
// make a copy of the entry so there will be no concurrent access to this entry
entry = &simpleEntry{
key: entry.key,
value: entry.value,
}
return entry
}
return e.key
}
return e.value
}
// CreateTime is not implemented for simple cache entries
func (e *simpleEntry) CreateTime() time.Time {
return DummyCreateTime
}
// NewSimple creates a new simple cache with given options.
// Simple cache will never evict entries and it will never reorder the elements.
// Simple cache also does not have the concept of pinning that LRU cache has.
// Internally simple cache uses a RWMutex instead of the exclusive Mutex that LRU cache uses.
// The RWMutex makes simple cache readable by many threads without introducing lock contention.
if opts == nil {
}
iterateList: list.New(),
accessMap: make(map[any]*list.Element),
rmFunc: opts.RemovedFunc,
}
}
// Get retrieves the value stored under the given key
c.RLock()
defer c.RUnlock()
element := c.accessMap[key]
if element == nil {
}
}
// Put puts a new value associated with a given key, returning the existing value (if present).
c.Lock()
defer c.Unlock()
existing := c.putInternal(key, value, true)
return existing
}
// PutIfNotExist puts a value associated with a given key if it does not exist
func (c *simple) PutIfNotExist(key any, value any) (any, error) {
c.Lock()
defer c.Unlock()
existing := c.putInternal(key, value, false)
if existing == nil {
// This is a new value
return value, nil
}
return existing, nil
}
// Delete deletes a key, value pair associated with a key
c.Lock()
defer c.Unlock()
element := c.accessMap[key]
if element == nil {
return
}
// nolint:revive
if c.rmFunc != nil {
}
}
// Release does nothing for simple cache
func (c *simple) Release(_ any) {}
// Size returns the number of entries currently in the cache
c.RLock()
defer c.RUnlock()
return len(c.accessMap)
}
c.RLock()
iterator := &simpleItr{
simple: c,
nextItem: c.iterateList.Front(),
}
return iterator
}
elt := c.accessMap[key]
if elt != nil {
entry := elt.Value.(*simpleEntry)
existing := entry.value
if allowUpdate {
entry.value = value
}
return existing
}
key: key,
value: value,
}
c.accessMap[key] = c.iterateList.PushFront(entry)
return nil
}