Skip to content

Instantly share code, notes, and snippets.

@0verIords
Last active May 27, 2020 18:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 0verIords/b5afbe4eaee9881c6c1c9b69104ebfd7 to your computer and use it in GitHub Desktop.
Save 0verIords/b5afbe4eaee9881c6c1c9b69104ebfd7 to your computer and use it in GitHub Desktop.
func newCache(cfg config.GdmCacheConfig,
pf func(from, to geometry.Coordinate) (durationDistancePair, error)) *Cache {
res := Cache{
cacheItems: make(map[string]gdmCacheItem),
ttlSec: cfg.CacheItemTTLSec,
invalidatePeriodSec: cfg.InvalidationPeriodSec,
pfGetP2PDurationAndDistance: pf,
}
return &res
}
func (c *Cache) get(from, to geometry.Coordinate) (gdmCacheItem, bool) {
c.mut.RLock()
defer c.mut.RUnlock()
keyStr := geometry.EncodeRawCoordinates([]geometry.Coordinate{from, to})
val, exist := c.cacheItems[keyStr]
if exist {
return val, exist
}
itemsWithToEq := make([]gdmCacheItem, 0, len(c.cacheItems))
for _, v := range c.cacheItems {
if v.to == to {
itemsWithToEq = append(itemsWithToEq, v)
}
}
for _, itwt := range itemsWithToEq {
p1 := geometry.Coordinate2Point(from)
p2 := geometry.Coordinate2Point(itwt.from)
if c.geom.DistancePointToPoint(p1, p2) > 10.0 {
continue
}
return itwt, true
}
return gdmCacheItem{}, false
}
func (c *Cache) set(from, to geometry.Coordinate) (gdmCacheItem, error) {
keyStr := geometry.EncodeRawCoordinates([]geometry.Coordinate{from, to})
c.mut.Lock()
defer c.mut.Unlock()
if v, ex := c.cacheItems[keyStr]; ex {
return v, nil
}
resp, err := c.pfGetP2PDurationAndDistance(from, to)
if err != nil {
return gdmCacheItem{}, err
}
neuItem := gdmCacheItem{
from: from,
to: to,
data: durationDistancePair{
dur: resp.dur,
distanceMeters: resp.distanceMeters},
invalidationTime: time.Now().Add(time.Duration(c.ttlSec) * time.Second),
}
c.cacheItems[keyStr] = neuItem
return neuItem, nil
}
func (c *Cache) invalidate() {
c.mut.Lock()
defer c.mut.Unlock()
toDelete := make([]string, 0, len(c.cacheItems))
for k, v := range c.cacheItems {
if time.Now().Before(v.invalidationTime) {
continue
}
toDelete = append(toDelete, k)
}
for _, td := range toDelete {
delete(c.cacheItems, td)
}
}
func (c *Cache) run() {
ticker := time.NewTicker(time.Duration(c.invalidatePeriodSec) * time.Second)
for {
select {
case <-ticker.C:
c.invalidate()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment