Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "fmt"
- "sync"
- )
- type ChainData struct {
- data interface{}
- // chain
- prev *ChainData
- next *ChainData
- }
- type ChainCache struct {
- // mutx
- sync.RWMutex
- // internals
- size int
- full bool
- none bool
- data map[string]*ChainData
- // chain
- root *ChainData
- last *ChainData
- }
- func NewLUCache(size int) *ChainCache {
- c := &ChainCache{
- size: size,
- data: make(map[string]*ChainData),
- none: true,
- }
- return c
- }
- func (c *ChainCache) Read(key string) (interface{}, bool) {
- c.Lock()
- defer c.Unlock()
- item, ok := c.data[key]
- if ok {
- next := item.next
- if next != nil {
- // promote
- if next.next != nil {
- next.next.prev = item
- }
- item.next = next.next
- next.prev = item.prev
- if item.prev != nil {
- item.prev.next = next
- } else {
- c.root = next
- }
- item.prev = next
- next.next = item
- } else {
- c.last = item
- }
- return item.data, true
- }
- return nil, false
- }
- func (c *ChainCache) Save(key string, val interface{}) {
- // lock
- c.Lock()
- defer c.Unlock()
- // add to the end
- last := c.last
- c.last = &ChainData{data: val, prev: last}
- if last != nil {
- last.next = c.last
- }
- // insert
- c.data[key] = c.last
- // pop from the front
- if c.full {
- fmt.Println("full")
- c.root = c.root.next
- c.root.prev = nil
- // quick exit
- return
- }
- if c.none {
- c.root = c.last
- }
- c.none = false
- c.full = len(c.data) == c.size
- }
- func (c *ChainCache) Debug() {
- if c.root != nil {
- item := c.root
- fmt.Printf("%v", *item)
- for item.next != nil {
- item = item.next
- fmt.Printf(" %v", *item)
- }
- fmt.Print("\n")
- } else {
- fmt.Println("nil")
- }
- }
- func main() {
- c := NewLUCache(5)
- c.Read("-")
- c.Debug()
- fmt.Println("save:one")
- c.Save("one", int(1))
- c.Debug()
- fmt.Println("save:two")
- c.Save("two", int(11))
- c.Debug()
- fmt.Println("save:three")
- c.Save("three", int(123))
- c.Debug()
- fmt.Println("read:one")
- c.Read("one")
- c.Debug()
- fmt.Println("save:four")
- c.Save("four", int(1234))
- c.Debug()
- fmt.Println("save:five")
- c.Save("five", int(12345))
- c.Debug()
- fmt.Println("read:three")
- c.Read("three")
- c.Debug()
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement