在 Go 中,如何实现一个带过期时间的字典映射
有些时候,应用系统用不上 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!
在 Go 中,如何实现一个带过期时间的字典映射的更多相关文章
- php中实现精确设置session过期时间的方法
http://www.jb51.net/article/52309.htm 大多数据情况下我们对于session过期时间使用的是默认设置的时间,而对于一些有特殊要求的情况下我们可以设置一下sessio ...
- 转:php中实现精确设置session过期时间的方法
原文来自于:http://www.jb51.net/article/52309.htm 大多数据情况下我们对于session过期时间使用的是默认设置的时间,而对于一些有特殊要求的情况下我们可以设置一下 ...
- localstorage实现带过期时间的缓存功能
前言 一般可以使用cookie,localstorage,sessionStorage来实现浏览器端的数据缓存,减少对服务器的请求. 1.cookie数据存放在本地硬盘中,只要在过期时间之前,都是有效 ...
- redis中获取没有设置ttl过期时间的key
需求:redis作为一个内存型的数据库,我们需要对过期key保持关注,从info keyspace中可以看出有多少key没有设置过期时间,那么到底是哪些呢? 说明:关于redis ttl 的返回值,请 ...
- java实现带过期时间的缓存
private static ScheduledExecutorService swapExpiredPool = new ScheduledThreadPoolExecutor(10); priva ...
- python中使用redis模块, 设置过期时间
# 链接数据库self.handle = redis.Redis(host=host, port=port, db=db, password=password, decode_responses=Tr ...
- Redis中取得所有Key、过期时间配置与获取、Key过期通知。
string connection = "127.0.0.1:6379,password=xxxxx,connectRetry=5"; [TestMethod] public vo ...
- golang中time包一个简单的时间格式输出
一.代码 package main import ( "fmt" "time" ) func main() { //"2006-01-02 15:04 ...
- 关于web会话中的session过期时间的设置
关于web会话中的session过期时间的设置 1.操作系统: 步骤:开始——〉管理工具——〉Internet信息服务(IIS)管理器——〉网站——〉默认网站——〉右键“属性”——〉主目录——〉配置— ...
- asp中设置session过期时间方法总结
http://www.jb51.net/article/31217.htm asp中设置session过期时间方法总结 作者: 字体:[增加 减小] 类型:转载 asp中默认session过期时间 ...
随机推荐
- 深入理解Mybatis分库分表执行原理
前言 工作多年,分库分表的场景也见到不少了,但是我仍然对其原理一知半解.趁着放假前时间比较富裕,我想要解答三个问题: 为什么mybatis的mapper.xml文件里的sql不需要拼接表名中的分表? ...
- 第2章 C# 语言基础
第2章 C# 语言基础 难点提纲 mindmap 第2章 C#语言基础 数值类型 数值字面量 溢出检查 特殊的浮点值 decimal 舍入误差 数组 简化初始化的<br/>两种方式 变量和 ...
- 一款由 .NET 官方团队开源的电子商务系统 - eShop
项目介绍 eShop是一款由.NET官方开源的,基于.NET Aspire构建的用于参考学习的服务架构电子商务系统,旨在展示如何利用.NET框架及其相关技术栈构建一个现代化的电子商务网站.该项目采用服 ...
- 开源数据库生态遇新变数,天翼云TeleDB提供企业数据管理更优解!
近日,知名开源大规模并行处理 (MPP) 数据库Greenplum的源代码在其官方GitHub页面突然消失,引发了用户和开发者的广泛关注, PostgreSQL生态系统或将产生新变数.开源软件在面对商 ...
- Jenkins使用maven打包项目
Jenkins使用maven打包项目 作为一名软件测试工程师,在日常工作中,我们经常需要使用Jenkins进行持续集成和持续部署(CI/CD).而Maven作为Java项目的构建工具,更是不可或缺.今 ...
- Q:查看服务器内存和cpu占用排名
pid 表示进程 ID,cmd 表示进程命令行,%mem 表示进程占用内存百分比,%cpu 表示进程占用 CPU 百分比,--sort=-%mem 表示按照内存占用率从高到低排序. 1.内存占比排序 ...
- shell 数组函数进阶练习
一维数组的定义.统计.引用和删除等操作. A=( test1 test2 test3 ) ,定义数组一般以括号的方式来定义, 数组的值可以随机定义. echo ${A[0]} ,代表引用第一个数组变量 ...
- Idea下载插件报错
报错内容Plugin Python was not installed: Cannot download 'https://plugins.jetbrains. 解决办法 file -> se ...
- presto解析jsonArr转多行
一.假数据解析 SELECT r1.col.dataSourceId, r1.col.database, r1.col.dataTable FROM (SELECT explode(r.json) A ...
- Codeforces 232 B Table 题解 [ 蓝 ] [ 分组背包 ] [ 组合数学 ] [ 循环节 ]
Codeforces 232B Table. 蒟蒻模拟赛上场切的一道蓝,非常难以置信我竟然能做蓝题. 这题的数据范围初看还是比较坑的,\(10^{18}\) 的值域很容易让人往矩阵加速那方面想.实际上 ...