4 "github.com/Kovensky/go-fscache"
9 type notification interface{}
11 type intentStruct struct {
13 chs []chan notification
16 type intentMapStruct struct {
18 intentLock sync.Mutex // used by the Intent function
20 m map[string]*intentStruct
23 var intentMap = &intentMapStruct{
24 m: map[string]*intentStruct{},
27 func intentKey(key ...fscache.CacheKey) string {
28 return strings.Join(fscache.Stringify(key...), "-")
31 // Register a channel to be notified when the specified keys are notified.
32 // Returns whether the caller was the first to register intent for the given
35 // Cache checks should be done after registering intent, since it's possible to
36 // register Intent while a Notify is running, and the Notify is done after
38 func (m *intentMapStruct) Intent(ch chan notification, keys ...fscache.CacheKey) bool {
39 key := intentKey(keys...)
42 defer m.intentLock.Unlock()
52 s.chs = append(s.chs, ch)
56 // key might have been deleted while only the struct itself was locked -- recheck
64 // Locks the requested keys and return the locked intentStruct.
66 // The intentStruct can be directly unlocked, or given to Free to also
67 // remove it from the intent map.
68 func (m *intentMapStruct) LockIntent(keys ...fscache.CacheKey) *intentStruct {
72 return m._lockIntent(keys...)
75 func (m *intentMapStruct) _lockIntent(keys ...fscache.CacheKey) *intentStruct {
76 s, ok := m.m[intentKey(keys...)]
85 // Removes the given intent from the intent map and unlocks the intentStruct.
86 func (m *intentMapStruct) Free(is *intentStruct, keys ...fscache.CacheKey) {
93 func (m *intentMapStruct) _free(is *intentStruct, keys ...fscache.CacheKey) {
94 // deletes the key before unlocking, Intent needs to recheck key status
95 delete(m.m, intentKey(keys...))
96 // better than unlocking then deleting -- could delete a "brand new" entry
102 // Notifies and closes all channels that are listening for the specified keys;
103 // also removes them from the intent map.
105 // Should be called after setting the cache.
106 func (m *intentMapStruct) NotifyClose(v notification, keys ...fscache.CacheKey) {
110 is := m._lockIntent(keys...)
111 defer m._free(is, keys...)
118 // Closes all channels that are listening for the specified keys
119 // and removes them from the intent map.
120 func (m *intentMapStruct) Close(keys ...fscache.CacheKey) {
124 is := m._lockIntent(keys...)
125 defer m._free(is, keys...)
132 // Notifies all channels that are listening for the specified keys,
133 // but doesn't close or remove them from the intent map.
134 func (m *intentMapStruct) Notify(v notification, keys ...fscache.CacheKey) {
138 is := m._lockIntent(keys...)
146 // NOTE: does not lock the stuct
147 func (s *intentStruct) Notify(v notification) {
148 for _, ch := range s.chs {
155 // NOTE: does not lock the struct
156 func (s *intentStruct) Close() {
157 for _, ch := range s.chs {
165 // NOTE: does not lock the struct
166 func (s *intentStruct) NotifyClose(v notification) {
167 for _, ch := range s.chs {