Advertisement
radu1986

go.chain.cache.rc1

Sep 25th, 2022
1,380
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 2.20 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "fmt"
  5.     "sync"
  6. )
  7.  
  8. type ChainData struct {
  9.     data interface{}
  10.     // chain
  11.     prev *ChainData
  12.     next *ChainData
  13. }
  14.  
  15. type ChainCache struct {
  16.     // mutx
  17.     sync.RWMutex
  18.     // internals
  19.  
  20.     size int
  21.     full bool
  22.     none bool
  23.     data map[string]*ChainData
  24.     // chain
  25.     root *ChainData
  26.     last *ChainData
  27. }
  28.  
  29. func NewLUCache(size int) *ChainCache {
  30.     c := &ChainCache{
  31.         size: size,
  32.         data: make(map[string]*ChainData),
  33.         none: true,
  34.     }
  35.     return c
  36. }
  37.  
  38. func (c *ChainCache) Read(key string) (interface{}, bool) {
  39.     c.Lock()
  40.     defer c.Unlock()
  41.     item, ok := c.data[key]
  42.     if ok {
  43.         next := item.next
  44.         if next != nil {
  45.             // promote
  46.             if next.next != nil {
  47.                 next.next.prev = item
  48.             }
  49.             item.next = next.next
  50.             next.prev = item.prev
  51.             if item.prev != nil {
  52.                 item.prev.next = next
  53.             } else {
  54.                 c.root = next
  55.             }
  56.             item.prev = next
  57.             next.next = item
  58.         } else {
  59.             c.last = item
  60.         }
  61.         return item.data, true
  62.     }
  63.     return nil, false
  64. }
  65.  
  66. func (c *ChainCache) Save(key string, val interface{}) {
  67.     // lock
  68.     c.Lock()
  69.     defer c.Unlock()
  70.     // add to the end
  71.     last := c.last
  72.     c.last = &ChainData{data: val, prev: last}
  73.     if last != nil {
  74.         last.next = c.last
  75.     }
  76.     // insert
  77.     c.data[key] = c.last
  78.     // pop from the front
  79.     if c.full {
  80.         fmt.Println("full")
  81.         c.root = c.root.next
  82.         c.root.prev = nil
  83.         // quick exit
  84.         return
  85.     }
  86.     if c.none {
  87.         c.root = c.last
  88.     }
  89.     c.none = false
  90.     c.full = len(c.data) == c.size
  91. }
  92.  
  93. func (c *ChainCache) Debug() {
  94.     if c.root != nil {
  95.         item := c.root
  96.         fmt.Printf("%v", *item)
  97.         for item.next != nil {
  98.             item = item.next
  99.             fmt.Printf(" %v", *item)
  100.         }
  101.         fmt.Print("\n")
  102.     } else {
  103.         fmt.Println("nil")
  104.     }
  105. }
  106.  
  107. func main() {
  108.  
  109.     c := NewLUCache(5)
  110.  
  111.     c.Read("-")
  112.     c.Debug()
  113.  
  114.     fmt.Println("save:one")
  115.     c.Save("one", int(1))
  116.     c.Debug()
  117.  
  118.     fmt.Println("save:two")
  119.     c.Save("two", int(11))
  120.     c.Debug()
  121.  
  122.     fmt.Println("save:three")
  123.     c.Save("three", int(123))
  124.     c.Debug()
  125.  
  126.     fmt.Println("read:one")
  127.     c.Read("one")
  128.     c.Debug()
  129.  
  130.     fmt.Println("save:four")
  131.     c.Save("four", int(1234))
  132.     c.Debug()
  133.  
  134.     fmt.Println("save:five")
  135.     c.Save("five", int(12345))
  136.     c.Debug()
  137.  
  138.     fmt.Println("read:three")
  139.     c.Read("three")
  140.     c.Debug()
  141.  
  142. }
  143.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement