设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间10 现在时间10 缓存数据 只要你的心是晴的,人生就没有雨天。就像好事情总是发生在那些微笑着的人身上。调整心情,保持微笑。早安!

只要你的心是晴的,人生就没有雨天。就像好事情总是发生在那些微笑着的人身上。调整心情,保持微笑。早安!

查看: 856|回复: 2

go实现一个内存缓存系统的示例代码

[复制链接]

  离线 

TA的专栏

  • 打卡等级:无名新人
  • 打卡总天数:1
  • 打卡月天数:0
  • 打卡总奖励:15
  • 最近打卡:2024-09-18 11:53:47
等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
39
主题
33
精华
0
金钱
134
积分
76
注册时间
2023-9-30
最后登录
2025-3-14

发表于 2024-10-18 21:17:03 | 显示全部楼层 |阅读模式
目录


  • 面试内容:

面试内容:


  • 支持设定过期时间,精度到秒
  • 支持设定最大内存,当内存超出时做出合适的处理
  • 支持并发安全
  • 要求按照以下接口实现
  1. SetMemory(size string) bool
  2.         Set(key string, val interface{}, expire time.Duration) bool
  3.         Get(key string) (interface{}, bool)
  4.         Del(key string) bool
  5.         Exists(key string) bool
  6.         Flush() bool
  7.         Keys() int64
复制代码
下面为具体实现代码:
接口
  1. package cacheimport "time"type Cache interface {        SetMemory(size string) bool
  2.         Set(key string, val interface{}, expire time.Duration) bool
  3.         Get(key string) (interface{}, bool)
  4.         Del(key string) bool
  5.         Exists(key string) bool
  6.         Flush() bool
  7.         Keys() int64}
复制代码
实现类
  1. package cache

  2. import (
  3.         "fmt"
  4.         "sync"
  5.         "time"
  6. )

  7. type MemCache struct {
  8.         //最大内存
  9.         maxMemorySize int64
  10.         // 当前已使用的内存
  11.         currMemorySize int64
  12.         // 最大内存字符串表示
  13.         maxMemorySizeStr string
  14.         // 缓存键值对
  15.         values map[string]*memCacheValue
  16.         // 读写锁
  17.         lock sync.RWMutex
  18.         //设置清除过期缓存的时间间隔
  19.         clearExpireTime time.Duration
  20. }

  21. type memCacheValue struct {
  22.         //value 值
  23.         val interface{}
  24.         // 过期时间
  25.         expireTime time.Time
  26.         //有效时间
  27.         expire time.Duration
  28.         //value 大小
  29.         size int64
  30. }

  31. func NewMemCache() Cache {
  32.         mc := &MemCache{
  33.                 clearExpireTime: time.Second * 10,
  34.                 values:          make(map[string]*memCacheValue),
  35.         }
  36.         go mc.clearExpireItm()
  37.         return mc
  38. }

  39. // SetMemory size 1KB 100KB 1M 2M 1GB
  40. func (mc *MemCache) SetMemory(size string) bool {
  41.         mc.maxMemorySize, mc.maxMemorySizeStr = ParseSize(size)
  42.         return true
  43. }

  44. // Set 设置缓存
  45. func (mc *MemCache) Set(key string, val interface{}, expire time.Duration) bool {
  46.         mc.lock.Lock()
  47.         defer mc.lock.Unlock()
  48.         v := &memCacheValue{val: val, expireTime: time.Now().Add(expire),
  49.                 expire: expire,
  50.                 size:   GetValSize(val)}
  51.         //mc.values[key] = v
  52.         mc.del(key)
  53.         mc.add(key, v)
  54.         if mc.currMemorySize > mc.maxMemorySize {
  55.                 mc.del(key)
  56.                 panic(fmt.Sprintf("max memory size %d", mc.maxMemorySize))
  57.         }
  58.         return true
  59. }

  60. func (mc *MemCache) get(key string) (*memCacheValue, bool) {
  61.         val, ok := mc.values[key]
  62.         return val, ok
  63. }

  64. func (mc *MemCache) del(key string) {
  65.         tmp, ok := mc.get(key)
  66.         if ok && tmp != nil {
  67.                 mc.currMemorySize -= tmp.size
  68.                 delete(mc.values, key)
  69.         }
  70. }

  71. func (mc *MemCache) add(key string, val *memCacheValue) {
  72.         mc.values[key] = val
  73.         mc.currMemorySize += val.size
  74. }

  75. // Get 获取缓存值
  76. func (mc *MemCache) Get(key string) (interface{}, bool) {
  77.         mc.lock.RLock()
  78.         defer mc.lock.RUnlock()
  79.         mcv, ok := mc.get(key)
  80.         if ok {
  81.                 if mcv.expire != 0 && mcv.expireTime.Before(time.Now()) {
  82.                         mc.del(key)
  83.                         return nil, false
  84.                 }
  85.                 return mcv.val, ok
  86.         }
  87.         return nil, false
  88. }

  89. // Del 删除缓存值
  90. func (mc *MemCache) Del(key string) bool {
  91.         mc.lock.Lock()
  92.         defer mc.lock.Unlock()
  93.         mc.del(key)
  94.         return true
  95. }

  96. func (mc *MemCache) Exists(key string) bool {
  97.         mc.lock.RLock()
  98.         defer mc.lock.RUnlock()
  99.         _, ok := mc.get(key)
  100.         return ok
  101. }

  102. func (mc *MemCache) Flush() bool {
  103.         mc.lock.Lock()
  104.         defer mc.lock.Unlock()
  105.         mc.values = make(map[string]*memCacheValue, 0)
  106.         mc.currMemorySize = 0
  107.         return true
  108. }

  109. func (mc *MemCache) Keys() int64 {
  110.         mc.lock.RLock()
  111.         defer mc.lock.RUnlock()
  112.         return int64(len(mc.values))
  113. }

  114. func (mc *MemCache) clearExpireItm() {
  115.         ticker := time.NewTicker(mc.clearExpireTime)
  116.         defer ticker.Stop()
  117.         for {
  118.                 select {
  119.                 case <-ticker.C:
  120.                         for key, v := range mc.values {
  121.                                 if v.expire != 0 && time.Now().After(v.expireTime) {
  122.                                         mc.lock.Lock()
  123.                                         mc.del(key)
  124.                                         mc.lock.Unlock()
  125.                                 }
  126.                         }
  127.                 }
  128.         }
  129. }

  130. //
  131. //var Cache = NewMemCache()
  132. //
  133. //func Set(key string, val interface{}) bool {
  134. //
  135. //        return false
  136. //}
复制代码
工具类
  1. package cache

  2. import (
  3.         "log"
  4.         "regexp"
  5.         "strconv"
  6.         "strings"
  7. )

  8. const (
  9.         B = 1 << (iota * 10)
  10.         KB
  11.         MB
  12.         GB
  13.         TB
  14.         PB
  15. )

  16. func ParseSize(size string) (int64, string) {

  17.         //默认大小为 100M
  18.         re, _ := regexp.Compile("[0-9]+")
  19.         unit := string(re.ReplaceAll([]byte(size), []byte("")))
  20.         num, _ := strconv.ParseInt(strings.Replace(size, unit, "", 1), 10, 64)
  21.         unit = strings.ToUpper(unit)
  22.         var byteNum int64 = 0
  23.         switch unit {
  24.         case "B":
  25.                 byteNum = num
  26.                 break
  27.         case "KB":
  28.                 byteNum = num * KB
  29.                 break
  30.         case "MB":
  31.                 byteNum = num * MB
  32.                 break
  33.         case "GB":
  34.                 byteNum = num * GB
  35.                 break
  36.         case "TB":
  37.                 byteNum = num * TB
  38.                 break
  39.         case "PB":
  40.                 byteNum = num * PB
  41.                 break
  42.         default:
  43.                 num = 0
  44.                 byteNum = 0

  45.         }
  46.         if num == 0 {
  47.                 log.Println("ParseSize 仅支持B,KB,MB,GB,TB,PB")
  48.                 num = 100 * MB
  49.                 byteNum = num
  50.                 unit = "MB"
  51.         }
  52.         sizeStr := strconv.FormatInt(num, 10) + unit
  53.         return byteNum, sizeStr

  54. }

  55. func GetValSize(val interface{}) int64 {
  56.         return 0
  57. }
复制代码
代理类
  1. package server

  2. import (
  3.         "go_lang_pro/cache"
  4.         "time"
  5. )

  6. type cacheServer struct {
  7.         memCache cache.Cache
  8. }

  9. func NewMemoryCache() *cacheServer {
  10.         return &cacheServer{
  11.                 memCache: cache.NewMemCache(),
  12.         }
  13. }

  14. func (cs *cacheServer) SetMemory(size string) bool {
  15.         return cs.memCache.SetMemory(size)
  16. }

  17. func (cs *cacheServer) Set(key string, val interface{}, expire ...time.Duration) bool {
  18.         expirets := time.Second * 0
  19.         if len(expire) > 0 {
  20.                 expirets = expire[0]
  21.         }
  22.         return cs.memCache.Set(key, val, expirets)
  23. }

  24. func (cs *cacheServer) Get(key string) (interface{}, bool) {
  25.         return cs.memCache.Get(key)
  26. }
  27. func (cs *cacheServer) Del(key string) bool {
  28.         return cs.memCache.Del(key)
  29. }

  30. func (cs *cacheServer) Exists(key string) bool {
  31.         return cs.memCache.Exists(key)
  32. }

  33. func (cs *cacheServer) Flush() bool {
  34.         return cs.memCache.Flush()
  35. }

  36. func (cs *cacheServer) Keys() int64 {
  37.         return cs.memCache.Keys()
  38. }
复制代码
main 方法
  1. package main

  2. import (
  3.         "go_lang_pro/cache"
  4.         "time"
  5. )

  6. func main() {

  7.         cache := cache.NewMemCache()
  8.         cache.SetMemory("100MB")
  9.         cache.Set("int", 1, time.Second)
  10.         cache.Set("bool", false, time.Second)
  11.         cache.Set("data", map[string]interface{}{"a": 1}, time.Second)
  12.         cache.Get("int")
  13.         cache.Del("int")
  14.         cache.Flush()
  15.         cache.Keys()

  16. }
复制代码
到此这篇关于go实现一个内存缓存系统的示例代码的文章就介绍到这了,更多相关go 内存缓存系统内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
16
积分
12
注册时间
2022-12-26
最后登录
2022-12-26

发表于 2025-3-5 14:59:48 | 显示全部楼层
感谢楼主,顶。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
14
积分
8
注册时间
2022-12-24
最后登录
2022-12-24

发表于 2025-3-30 23:55:01 | 显示全部楼层
感谢楼主分享。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1楼
2楼
3楼

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表