golang 实现cache

golang 实现cache

1. 支持 set get 方法,有容量 和  过期时间配置项

2. 数据带过期时间,过期自动老化

3. lru 机制,当达到总量时,删除掉最晚被访问的数据

package main

import (
	"fmt"
	"time"
)

func main() {
	fmt.Println("hello world!")
	cache := NewCache(10, 5)
	fmt.Println(" now timestamp: ", time.Now().Unix())
	cache.Put(1, 2)
	fmt.Println(cache.Get(1))

	time.Sleep(6 * time.Second)
	fmt.Println(cache.Get(1))

}

type Cache struct {
	head, tail *entry
	cache      map[int]*entry
	capacity   int
	ttl        int
}

type entry struct {
	key, value int
	expire     int
	prev, next *entry
}

func NewCache(capacity, ttl int) *Cache {
	return &Cache{
		cache:    make(map[int]*entry),
		capacity: capacity,
		ttl:      ttl,
	}
}

func (c *Cache) Get(key int) int {
	if elem, ok := c.cache[key]; ok {
		if elem.expire < int(time.Now().Unix()) {
			delete(c.cache, elem.key)
			return -1
		}
		// 更新节点位置
		c.moveToHead(elem)
		return elem.value
	}
	return -1
}

func (c *Cache) moveToHead(elem *entry) {
	if elem == c.head {
		return
	} else if elem == c.tail {
		c.tail = elem.prev
	} else {
		elem.prev.next = elem.next
		elem.next.prev = elem.prev
	}
	elem.prev = nil
	elem.next = c.head
	c.head.prev = elem
	c.head = elem

}

func (c *Cache) Put(key, value int) {
	if elem, ok := c.cache[key]; ok {
		elem.value = value
		c.moveToHead(elem)
	} else {
		// 创建新节点
		elem := &entry{
			key:    key,
			value:  value,
			expire: int(time.Now().Unix()) + c.ttl,
		}
		c.cache[key] = elem
		if c.head == nil {
			c.head = elem
			c.tail = elem
		} else {
			// 在链表头插入新节点
			elem.next = c.head
			c.head.prev = elem
			c.head = elem
		}
		// 判断缓存是否达到预设上限
		if len(c.cache) > c.capacity {
			// 删除链表尾部节点和哈希表中的数据
			delete(c.cache, c.tail.key)
			c.tail = c.tail.prev
			c.tail.next = nil
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值