首页 > 其他分享 >在 Go 中,如何实现一个带过期时间的字典映射

在 Go 中,如何实现一个带过期时间的字典映射

时间:2024-10-24 16:24:23浏览次数:7  
标签:map 映射 过期 go test ttl Go expired 字典

有些时候,应用系统用不上 redis,我们也可以用锁和 goroutine 实现一个带有过期时间的线程安全的字典。

这种字典的应用场景,比较倾向于数据规模较小,没有分布式要求。

下面是实现:

1、定义结构

type Item struct {  
    value    interface{}  
    expireAt int64  
}  
  
type TTLMap struct {  
    m  map[string]*Item  
    mu sync.Mutex  
}

字典的值是一个可以接收任何类型的 interface{}

2、定义行为

  
func NewTTLMap(size int) (m *TTLMap) {  
    m = &TTLMap{m: make(map[string]*Item, size)}  
    go func() {  
       for now := range time.Tick(time.Second) {  
          m.mu.Lock()  
          for k, v := range m.m {  
             if v.expireAt <= now.Unix() {  
                delete(m.m, k)  
             }  
          }  
          m.mu.Unlock()  
       }  
    }()  
    return  
}  
  
func (m *TTLMap) Set(key string, value interface{}, ttl int64) {  
    m.mu.Lock()  
    defer m.mu.Unlock()  
    m.m[key] = &Item{value: value, expireAt: time.Now().Unix() + ttl}  
}  
  
func (m *TTLMap) Get(key string) (v interface{}, ok bool) {  
    m.mu.Lock()  
    defer m.mu.Unlock()  
    if item, ok := m.m[key]; ok && item.expireAt > time.Now().Unix() {  
       return item.value, true  
    }  
    return nil, false  
}

NewTTLMap 函数用来初始化字典,然后使用 goroutine 开启新的轻量级线程,按照一定的频率从字典里删除项。

Get 函数用来获取字典的值,然后这里也判断一下过期时间,如果已经过期了,就不再返回了。

3、验证结果

func TestTTLMap(t *testing.T) {  
    m := NewTTLMap(10)  
    m.Set("hello", "world", 5)  
    for i := 0; i < 10; i++ {  
       time.Sleep(time.Second)  
       if v, ok := m.Get("hello"); ok {  
          t.Log(v)  
       } else {  
          t.Log("expired")  
       }  
    }  
}

输出结果:

=== RUN   TestTTLMap
    ttl_map_test.go:64: world
    ttl_map_test.go:64: world
    ttl_map_test.go:64: world
    ttl_map_test.go:64: world
    ttl_map_test.go:66: expired
    ttl_map_test.go:66: expired
    ttl_map_test.go:66: expired
    ttl_map_test.go:66: expired
    ttl_map_test.go:66: expired
    ttl_map_test.go:66: expired
--- PASS: TestTTLMap (10.00s)
PASS

每秒读取一次,由于过期时间是 5 秒,因此,5 秒之后就读取不到值了。

Over!

标签:map,映射,过期,go,test,ttl,Go,expired,字典
From: https://www.cnblogs.com/denglei1024/p/18499819

相关文章

  • Django中的ModelForm组件
    昨天开发项目的时候,发现在表单创建时,流程很繁琐,想这有没有简易方式去创建表单,结果查资料,发现django提供了一个非常简单实用且人性化的组件modelform,用起来贼快,还能做表单校验,很爽,记录一下。在Django中,modelform是一个非常有用的功能,它允许你基于Django的模型(Model)自动......
  • Go 中,`...` 运算符
    在Go语言中,...运算符有两个主要用途,分别用于变长参数函数和切片展开。1.变长参数函数在Go语言中,使用...运算符可以定义一个接受可变数量参数的函数,也就是“变长参数函数”。这种函数可以接收不确定数量的参数,并将这些参数当作切片来处理。语法:funcfunctionName(args......
  • Go语言中的位运算符
    位运算(bitwiseoperations)是计算机科学中非常基础且重要的运算类型,它直接操作二进制位。Go语言中提供了一组位运算符,用于执行位级别的操作。Go语言中的位运算符按位与(&):作用:对两个操作数的每个位进行与运算,只有对应位都为1时,结果位才为1。示例:5&3(0101&0011=0001),结......
  • Go 语言中的 切片 --slice
    为了更好地理解Go语言中的切片(slice),我们可以将它与C++中的数组或容器(如std::vector)进行比较,但要注意的是,它们之间有一些关键的区别。让我们逐步将Go的切片与C++中的概念进行对应:1.数组vs切片在C++中,数组(array)是一种固定大小的数据结构,大小必须在编译时确定,并且......
  • GO:可变长参数和切片作为函数参数
    在Go语言中,可变函数参数(可变长参数)和切片作为函数参数是两个不同的概念,虽然它们都能处理多个元素,但它们的用途和处理方式有所不同。以下是它们之间的详细区别:1.可变函数参数(VariadicFunctionParameters)可变参数函数可以接受不定数量的参数,使用...运算符来定义。这些参数......
  • Go语言中的range
    在Go语言中,range是一个用于遍历各种数据结构(如数组、切片、字符串、map和通道)的关键字。range可以返回一个索引和值,或者是键和值,具体取决于你遍历的是什么类型的数据结构。1.range的用法range常用于for循环,来遍历集合中的元素。它可以遍历数组、切片、字符串、map、甚至......
  • MyBatis 如何映射 Enum(使用 EnumTypeHandler、自定义 TypeHandler)
    文章目录1.MyBatis中的Enum映射概述2.使用EnumTypeHandler2.1代码示例:将Enum映射为字符串2.2代码示例:将Enum映射为整数2.3如何配置EnumTypeHandler3.自定义TypeHandler3.1为什么需要自定义TypeHandler3.2自定义TypeHandler的实现3.3如何注册自定......
  • Golang 中使用 JSON 的一些小技巧
    临时忽略struct字段typeUserstruct{Emailstring`json:"email"`Passwordstring`json:"password"`//manymorefields…}临时忽略掉Password字段json.Marshal(struct{*UserPasswordbool`json:"password,omitempty"`}{Us......
  • 什么是 SAP ABAP 的 Logon Procedure?
    SAPABAP系统的LogonProcedure(登录过程)是SAP系统中用于管理用户如何连接到系统并访问相关功能与数据的一套复杂流程与验证机制。通过这一登录过程,SAP系统可以确保用户访问的安全性、审计记录的完整性,并有效地管理用户的权限和身份认证。作为企业级信息系统的重要组成......
  • 怎么搭建图片转文本GOT-OCR2.0
    Github地址http://gitlab.xiaoxingcloud.com/ai/GOT-OCR2.0.git介绍GOT-OCR2.0是一款用于图片转文字开源软件环境查看系统环境#lsb_release-aNoLSBmodulesareavailable.DistributorID: UbuntuDescription: Ubuntu22.04.5LTSRelease: 22.04Codename: jammy#......