55 "encoding/binary"
66 "io/fs"
77 "reflect"
8+ "sync"
89
910 "github.com/willscott/go-nfs"
1011
@@ -24,12 +25,11 @@ func NewCachingHandlerWithVerifierLimit(h nfs.Handler, limit int, verifierLimit
2425 nfs .Log .Warnf ("Caching handler created with insufficient cache to support directory listing" , "size" , limit , "verifiers" , verifierLimit )
2526 }
2627 cache , _ := lru.New [uuid.UUID , entry ](limit )
27- reverseCache := make (map [string ][]uuid.UUID )
2828 verifiers , _ := lru.New [uint64 , verifier ](verifierLimit )
2929 return & CachingHandler {
3030 Handler : h ,
3131 activeHandles : cache ,
32- reverseHandles : reverseCache ,
32+ reverseHandles : make ( map [ string ][]uuid. UUID ) ,
3333 activeVerifiers : verifiers ,
3434 cacheLimit : limit ,
3535 }
@@ -38,10 +38,11 @@ func NewCachingHandlerWithVerifierLimit(h nfs.Handler, limit int, verifierLimit
3838// CachingHandler implements to/from handle via an LRU cache.
3939type CachingHandler struct {
4040 nfs.Handler
41- activeHandles * lru.Cache [uuid.UUID , entry ]
42- reverseHandles map [string ][]uuid.UUID
43- activeVerifiers * lru.Cache [uint64 , verifier ]
44- cacheLimit int
41+ activeHandles * lru.Cache [uuid.UUID , entry ]
42+ reverseHandles map [string ][]uuid.UUID
43+ reverseHandlesMu sync.RWMutex
44+ activeVerifiers * lru.Cache [uint64 , verifier ]
45+ cacheLimit int
4546}
4647
4748type entry struct {
@@ -70,10 +71,7 @@ func (c *CachingHandler) ToHandle(f billy.Filesystem, path []string) []byte {
7071 c .evictReverseCache (rk , evictedKey )
7172 }
7273
73- if _ , ok := c .reverseHandles [joinedPath ]; ! ok {
74- c .reverseHandles [joinedPath ] = []uuid.UUID {}
75- }
76- c .reverseHandles [joinedPath ] = append (c .reverseHandles [joinedPath ], id )
74+ c .appendReverseHandle (joinedPath , id )
7775 b , _ := id .MarshalBinary ()
7876
7977 return b
@@ -103,11 +101,7 @@ func (c *CachingHandler) FromHandle(fh []byte) (billy.Filesystem, []string, erro
103101}
104102
105103func (c * CachingHandler ) searchReverseCache (f billy.Filesystem , path string ) []byte {
106- uuids , exists := c .reverseHandles [path ]
107-
108- if ! exists {
109- return nil
110- }
104+ uuids := c .getReverseHandles (path )
111105
112106 for _ , id := range uuids {
113107 if candidate , ok := c .activeHandles .Get (id ); ok {
@@ -121,20 +115,33 @@ func (c *CachingHandler) searchReverseCache(f billy.Filesystem, path string) []b
121115}
122116
123117func (c * CachingHandler ) evictReverseCache (path string , handle uuid.UUID ) {
124- uuids , exists := c .reverseHandles [path ]
118+ c .reverseHandlesMu .Lock ()
119+ defer c .reverseHandlesMu .Unlock ()
125120
126- if ! exists {
121+ uuids , ok := c .reverseHandles [path ]
122+ if ! ok {
127123 return
128124 }
129125 for i , u := range uuids {
130126 if u == handle {
131- uuids = append (uuids [:i ], uuids [i + 1 :]... )
132- c .reverseHandles [path ] = uuids
127+ c .reverseHandles [path ] = append (uuids [:i ], uuids [i + 1 :]... )
133128 return
134129 }
135130 }
136131}
137132
133+ func (c * CachingHandler ) getReverseHandles (path string ) []uuid.UUID {
134+ c .reverseHandlesMu .RLock ()
135+ defer c .reverseHandlesMu .RUnlock ()
136+ return c .reverseHandles [path ]
137+ }
138+
139+ func (c * CachingHandler ) appendReverseHandle (path string , id uuid.UUID ) {
140+ c .reverseHandlesMu .Lock ()
141+ defer c .reverseHandlesMu .Unlock ()
142+ c .reverseHandles [path ] = append (c .reverseHandles [path ], id )
143+ }
144+
138145func (c * CachingHandler ) InvalidateHandle (fs billy.Filesystem , handle []byte ) error {
139146 //Remove from cache
140147 id , _ := uuid .FromBytes (handle )
0 commit comments