22
33package cal
44
5- import "time"
5+ import (
6+ "sync"
7+ "time"
8+ )
69
710// DefaultLoc is the default time.Location to use in functions that do not
811// require a full time.Time value.
@@ -23,6 +26,9 @@ type Calendar struct {
2326 Cacheable bool // indicates that holiday calcs can be cached (don't change holiday defs while enabled)
2427
2528 isHolCache map [holCacheKey ]* holCacheEntry // cached results for IsHoliday
29+
30+ isHolCacheInitOnce sync.Once
31+ isHolCacheMutex sync.RWMutex
2632}
2733
2834type holCacheKey struct {
@@ -76,12 +82,16 @@ func (c *Calendar) IsHoliday(date time.Time) (actual, observed bool, h *Holiday)
7682 year , month , day := date .Date ()
7783
7884 if c .Cacheable {
79- if c . isHolCache == nil {
85+ c . isHolCacheInitOnce . Do ( func () {
8086 c .isHolCache = make (map [holCacheKey ]* holCacheEntry )
81- }
87+ })
88+
89+ c .isHolCacheMutex .RLock ()
8290 if v , ok := c .isHolCache [holCacheKey {year : year , month : month , day : day }]; ok {
91+ c .isHolCacheMutex .RUnlock ()
8392 return v .act , v .obs , v .hol
8493 }
94+ c .isHolCacheMutex .RUnlock ()
8595 }
8696
8797 for _ , hol := range c .Holidays {
@@ -99,9 +109,11 @@ func (c *Calendar) IsHoliday(date time.Time) (actual, observed bool, h *Holiday)
99109 }
100110 if actMatch || obsMatch {
101111 if c .Cacheable {
112+ c .isHolCacheMutex .Lock ()
102113 c .evict ()
103114 c .isHolCache [holCacheKey {year : year , month : month , day : day }] =
104115 & holCacheEntry {act : actMatch , obs : obsMatch , hol : hol }
116+ c .isHolCacheMutex .Unlock ()
105117 }
106118 return actMatch , obsMatch , hol
107119 }
@@ -122,9 +134,11 @@ func (c *Calendar) IsHoliday(date time.Time) (actual, observed bool, h *Holiday)
122134 }
123135 if obsMatch {
124136 if c .Cacheable {
137+ c .isHolCacheMutex .Lock ()
125138 c .evict ()
126139 c .isHolCache [holCacheKey {year : year , month : month , day : day }] =
127140 & holCacheEntry {act : false , obs : obsMatch , hol : hol }
141+ c .isHolCacheMutex .Unlock ()
128142 }
129143 return false , obsMatch , hol
130144 }
@@ -137,9 +151,11 @@ func (c *Calendar) IsHoliday(date time.Time) (actual, observed bool, h *Holiday)
137151 }
138152 if obsMatch {
139153 if c .Cacheable {
154+ c .isHolCacheMutex .Lock ()
140155 c .evict ()
141156 c .isHolCache [holCacheKey {year : year , month : month , day : day }] =
142157 & holCacheEntry {act : false , obs : obsMatch , hol : hol }
158+ c .isHolCacheMutex .Unlock ()
143159 }
144160 return false , obsMatch , hol
145161 }
@@ -148,8 +164,10 @@ func (c *Calendar) IsHoliday(date time.Time) (actual, observed bool, h *Holiday)
148164 }
149165
150166 if c .Cacheable {
167+ c .isHolCacheMutex .Lock ()
151168 c .evict ()
152169 c .isHolCache [holCacheKey {year : year , month : month , day : day }] = holFalseEntry
170+ c .isHolCacheMutex .Unlock ()
153171 }
154172 return false , false , nil
155173}
0 commit comments