-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
152 additions
and
103 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,91 +1,126 @@ | ||
package rux | ||
|
||
import ( | ||
"container/list" | ||
"sync" | ||
) | ||
|
||
// CachedRoutes struct | ||
type CachedRoutes struct { | ||
m map[string]*Route | ||
lock *sync.RWMutex | ||
// cacheNode struct | ||
type cacheNode struct { | ||
Key string | ||
Value *Route | ||
} | ||
|
||
// NewCachedRoutes get CachedRoutes pointer | ||
func NewCachedRoutes(size int) *CachedRoutes { | ||
return &CachedRoutes{ | ||
lock: new(sync.RWMutex), | ||
m: make(map[string]*Route, size), | ||
} | ||
// cachedRoutes struct | ||
type cachedRoutes struct { | ||
size int | ||
list *list.List | ||
hashMap map[string]*list.Element | ||
lock *sync.Mutex | ||
} | ||
|
||
// Get Router pointer | ||
func (c *CachedRoutes) Get(k string) *Route { | ||
c.lock.RLock() | ||
defer c.lock.RUnlock() | ||
|
||
if val, ok := c.m[k]; ok { | ||
return val | ||
// NewCachedRoutes Get Cache pointer | ||
func NewCachedRoutes(size int) *cachedRoutes { | ||
return &cachedRoutes{ | ||
size: size, | ||
list: list.New(), | ||
hashMap: make(map[string]*list.Element), | ||
lock: new(sync.Mutex), | ||
} | ||
} | ||
|
||
return nil | ||
// Len cache len | ||
func (c *cachedRoutes) Len() int { | ||
c.lock.Lock() | ||
defer c.lock.Unlock() | ||
|
||
return c.list.Len() | ||
} | ||
|
||
// Set Maps the given key and value. Returns false | ||
// if the key is already in the map and changes nothing. | ||
func (c *CachedRoutes) Set(k string, v *Route) bool { | ||
// Set route key and Route | ||
func (c *cachedRoutes) Set(k string, v *Route) bool { | ||
c.lock.Lock() | ||
defer c.lock.Unlock() | ||
|
||
if val, ok := c.m[k]; !ok { | ||
c.m[k] = v | ||
} else if val != v { | ||
c.m[k] = v | ||
} else { | ||
if c.list == nil { | ||
return false | ||
} | ||
|
||
if element, ok := c.hashMap[k]; ok { | ||
c.list.MoveToFront(element) | ||
element.Value.(*cacheNode).Value = v | ||
|
||
return true | ||
} | ||
|
||
var newElement = c.list.PushFront(&cacheNode{k, v}) | ||
|
||
c.hashMap[k] = newElement | ||
|
||
if c.list.Len() > c.size { | ||
lastElement := c.list.Back() | ||
|
||
if lastElement == nil { | ||
return true | ||
} | ||
|
||
cacheNode := lastElement.Value.(*cacheNode) | ||
|
||
delete(c.hashMap, cacheNode.Key) | ||
|
||
c.list.Remove(lastElement) | ||
} | ||
|
||
return true | ||
} | ||
|
||
// Has Returns true if k is exist in the map. | ||
func (c *CachedRoutes) Has(k string) (*Route, bool) { | ||
c.lock.RLock() | ||
defer c.lock.RUnlock() | ||
// Get Router by key | ||
func (c *cachedRoutes) Get(k string) *Route { | ||
c.lock.Lock() | ||
defer c.lock.Unlock() | ||
|
||
if _, ok := c.m[k]; ok { | ||
return c.m[k], true | ||
if c.hashMap == nil { | ||
return nil | ||
} | ||
|
||
return nil, false | ||
} | ||
if element, ok := c.hashMap[k]; ok { | ||
c.list.MoveToFront(element) | ||
|
||
// Len the given m total. | ||
func (c *CachedRoutes) Len() int { | ||
c.lock.RLock() | ||
defer c.lock.RUnlock() | ||
return element.Value.(*cacheNode).Value | ||
} | ||
|
||
return len(c.m) | ||
return nil | ||
} | ||
|
||
// Items the given m. | ||
func (c *CachedRoutes) Items() map[string]*Route { | ||
c.lock.RLock() | ||
defer c.lock.RUnlock() | ||
// Delete Router by key | ||
func (c *cachedRoutes) Delete(k string) bool { | ||
c.lock.Lock() | ||
defer c.lock.Unlock() | ||
|
||
if c.hashMap == nil { | ||
return false | ||
} | ||
|
||
if element, ok := c.hashMap[k]; ok { | ||
cacheNode := element.Value.(*cacheNode) | ||
|
||
r := make(map[string]*Route) | ||
delete(c.hashMap, cacheNode.Key) | ||
|
||
for k, v := range c.m { | ||
r[k] = v | ||
c.list.Remove(element) | ||
|
||
return true | ||
} | ||
|
||
return r | ||
return false | ||
} | ||
|
||
// Delete the given key and value. | ||
func (c *CachedRoutes) Delete(k string) { | ||
c.lock.Lock() | ||
defer c.lock.Unlock() | ||
// Has Returns true if k is exist in the hashmap. | ||
func (c *cachedRoutes) Has(k string) (*Route, bool) { | ||
var r = c.Get(k) | ||
|
||
if r != nil { | ||
return r, true | ||
} | ||
|
||
c.m[k] = nil | ||
delete(c.m, k) | ||
return nil, false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters