@@ -29,6 +29,38 @@ import (
2929// ErrDataNotFound is the error resulting if failed to find a container in memory cache.
3030var ErrDataNotFound = errors .New ("unable to find data in memory cache" )
3131
32+ // containerCacheMap is a typed wrapper around sync.Map that eliminates the need
33+ // for type assertions at every call site. It stores container name strings
34+ // mapped to *containerCache values.
35+ type containerCacheMap struct {
36+ m sync.Map
37+ }
38+
39+ // Load retrieves a container cache by name. Returns nil, false if not found.
40+ func (c * containerCacheMap ) Load (name string ) (* containerCache , bool ) {
41+ v , ok := c .m .Load (name )
42+ if ! ok {
43+ return nil , false
44+ }
45+ return v .(* containerCache ), true
46+ }
47+
48+ // Store saves a container cache with the given name.
49+ func (c * containerCacheMap ) Store (name string , cache * containerCache ) {
50+ c .m .Store (name , cache )
51+ }
52+
53+ // LoadOrStore returns the existing cache if present, otherwise stores and returns the given one.
54+ func (c * containerCacheMap ) LoadOrStore (name string , cache * containerCache ) (* containerCache , bool ) {
55+ v , loaded := c .m .LoadOrStore (name , cache )
56+ return v .(* containerCache ), loaded
57+ }
58+
59+ // Delete removes a container cache by name.
60+ func (c * containerCacheMap ) Delete (name string ) {
61+ c .m .Delete (name )
62+ }
63+
3264// TODO(vmarmol): See about refactoring this class, we have an unnecessary redirection of containerCache and InMemoryCache.
3365// containerCache is used to store per-container information
3466type containerCache struct {
@@ -67,24 +99,18 @@ func newContainerStore(ref info.ContainerReference, maxAge time.Duration) *conta
6799}
68100
69101type InMemoryCache struct {
70- lock sync.RWMutex
71- containerCacheMap map [string ]* containerCache
102+ containerCacheMap containerCacheMap
72103 maxAge time.Duration
73104 backend []storage.StorageDriver
74105}
75106
76107func (c * InMemoryCache ) AddStats (cInfo * info.ContainerInfo , stats * info.ContainerStats ) error {
77- var cstore * containerCache
78- var ok bool
79-
80- func () {
81- c .lock .Lock ()
82- defer c .lock .Unlock ()
83- if cstore , ok = c .containerCacheMap [cInfo .ContainerReference .Name ]; ! ok {
84- cstore = newContainerStore (cInfo .ContainerReference , c .maxAge )
85- c .containerCacheMap [cInfo .ContainerReference .Name ] = cstore
86- }
87- }()
108+ name := cInfo .ContainerReference .Name
109+ cstore , ok := c .containerCacheMap .Load (name )
110+ if ! ok {
111+ newStore := newContainerStore (cInfo .ContainerReference , c .maxAge )
112+ cstore , _ = c .containerCacheMap .LoadOrStore (name , newStore )
113+ }
88114
89115 for _ , backend := range c .backend {
90116 // TODO(monnand): To deal with long delay write operations, we
@@ -98,45 +124,29 @@ func (c *InMemoryCache) AddStats(cInfo *info.ContainerInfo, stats *info.Containe
98124}
99125
100126func (c * InMemoryCache ) RecentStats (name string , start , end time.Time , maxStats int ) ([]* info.ContainerStats , error ) {
101- var cstore * containerCache
102- var ok bool
103- err := func () error {
104- c .lock .RLock ()
105- defer c .lock .RUnlock ()
106- if cstore , ok = c .containerCacheMap [name ]; ! ok {
107- return ErrDataNotFound
108- }
109- return nil
110- }()
111- if err != nil {
112- return nil , err
127+ cstore , ok := c .containerCacheMap .Load (name )
128+ if ! ok {
129+ return nil , ErrDataNotFound
113130 }
114-
115131 return cstore .RecentStats (start , end , maxStats )
116132}
117133
118134func (c * InMemoryCache ) Close () error {
119- c .lock .Lock ()
120- c .containerCacheMap = make (map [string ]* containerCache , 32 )
121- c .lock .Unlock ()
135+ c .containerCacheMap = containerCacheMap {}
122136 return nil
123137}
124138
125139func (c * InMemoryCache ) RemoveContainer (containerName string ) error {
126- c .lock .Lock ()
127- delete (c .containerCacheMap , containerName )
128- c .lock .Unlock ()
140+ c .containerCacheMap .Delete (containerName )
129141 return nil
130142}
131143
132144func New (
133145 maxAge time.Duration ,
134146 backend []storage.StorageDriver ,
135147) * InMemoryCache {
136- ret := & InMemoryCache {
137- containerCacheMap : make (map [string ]* containerCache , 32 ),
138- maxAge : maxAge ,
139- backend : backend ,
148+ return & InMemoryCache {
149+ maxAge : maxAge ,
150+ backend : backend ,
140151 }
141- return ret
142152}
0 commit comments