Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >[Go小技巧] 实现常用的KV缓存(有序且并发安全)

[Go小技巧] 实现常用的KV缓存(有序且并发安全)

作者头像
henrylee2cn
发布于 2019-04-04 07:17:17
发布于 2019-04-04 07:17:17
72700
代码可运行
举报
文章被收录于专栏:Go实战Go实战
运行总次数:0
代码可运行
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type KV struct {
	count int
	keys  []string
	hash  map[string]interface{}
	lock  sync.RWMutex
}

// 新建KV缓存(preCapacity为预申请内存容量)
func NewKV(preCapacity uint) *KV {
	return &KV{
		keys: make([]string, 0, int(preCapacity)),
		hash: make(map[string]interface{}, int(preCapacity)),
	}
}

// 添加kv键值对
func (this *KV) Set(k string, v interface{}) {
	this.lock.Lock()
	if _, ok := this.hash[k]; !ok {
		this.keys = append(this.keys, k)
		sort.Strings(this.keys)
		this.count++
	}
	this.hash[k] = v
	this.lock.Unlock()
}

// 获取数据长度
func (this *KV) Count() int {
	this.lock.RLock()
	defer this.lock.RUnlock()
	return this.count
}

// 由key检索value
func (this *KV) Get(k string) (interface{}, bool) {
	this.lock.RLock()
	defer this.lock.RUnlock()
	v, ok := this.hash[k]
	return v, ok
}

// 根据key排序,返回有序的vaule切片
func (this *KV) Values() []interface{} {
	this.lock.RLock()
	defer this.lock.RUnlock()
	vals := make([]interface{}, this.count)
	for i := 0; i < this.count; i++ {
		vals[i] = this.hash[this.keys[i]]
	}
	return vals
}

(adsbygoogle = window.adsbygoogle || []).push({});

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016/09/02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
一次生产环境高效利用Go Concurrent Map的记录
(嗨,大家好,首先本文并非本人撰写,为友人投稿,其次我是谢顶道人 --- 老李,本人擅鸽且不勤政。下周呢我和我之前的老板原上草来接着和大家一起唠唠日志或者Trace之类的,其实主要是原上草,他对于系统可观测性方面比较牛逼或者说过于牛逼,下周一定!)
老李秀
2022/08/31
5820
一次生产环境高效利用Go Concurrent Map的记录
从应用层面细说map
在2万字图解map文章主要讲述了Go中map的是如何实现的。本文将从应用的角度来总结map使用过程中容易出现的问题,如何保证map并发读写,以及并发读写的优化。
数据小冰
2022/08/15
3980
从应用层面细说map
client-go 之 DeltaFIFO 实现原理
前文我们讲到 Reflector 中通过 ListAndWatch 获取到数据后传入到了本地的存储中,也就是 DeltaFIFO 中。从 DeltaFIFO 的名字可以看出它是一个 FIFO,也就是一个先进先出的队列,而 Delta 表示的是变化的资源对象存储,包含操作资源对象的类型和数据,Reflector 就是这个队列的生产者。
我是阳明
2020/09/04
2.9K0
Go语言实战笔记(十七)| Go 读写锁
前面的有篇文章在讲资源竞争的时候,讲互斥锁,互斥锁的根本就是当一个goroutine访问的时候,其他goroutine都不能访问,这样肯定保证了资源的同步,避免了竞争,不过也降低了性能。
飞雪无情
2018/08/28
3700
什么?你现在都还不会处理并发 map 的问题,这就安排...
key-value 类型的数据结构,在项目中是非常常见的数据结构,属于基础的数据结构。
小锟哥哥
2022/05/10
1720
什么?你现在都还不会处理并发 map 的问题,这就安排...
Go每日一库之81:go-cache(单机缓存库)
基于内存的 K/V 存储/缓存 : (类似于Memcached),适用于单机应用程序
luckpunk
2023/09/30
3.9K0
Golang并发的次优选择:sync包
我们都知道Golang并发优选channel,但channel不是万能的,Golang为我们提供了另一种选择:sync。通过这篇文章,你会了解sync包最基础、最常用的方法,至于sync和channel之争留给下一篇文章。
大彬
2019/04/11
6250
client-go 之 Indexer 的理解
前面我们讲到 DeltaFIFO 中的元素通过 Pop 函数弹出后,在指定的回调函数中将元素添加到了 Indexer 中。Indexer 是什么?字面意思是索引器,它就是 Informer 中的 LocalStore 部分,我们可以和数据库进行类比,数据库是建立在存储之上的,索引也是构建在存储之上,只是和数据做了一个映射,使得按照某些条件查询速度会非常快,所以说 Indexer 本身也是一个存储,只是它在存储的基础上扩展了索引功能。从 Indexer 接口的定义可以证明这一点:
我是阳明
2020/09/04
2.7K0
client-go 之 Indexer 的理解
Golang缓存库 go-cache
go-cache 是一个类似Memcached的go库,key:value存储在内存中。适合单机应用调用。
后端云
2022/11/25
1.8K0
InfluxDB中的inmem内存索引结构解析
tagKeyValueEntry 定义: type tagKeyValueEntry struct { m map[uint64]struct{} // series id set a seriesIDs // lazily sorted list of series.这两个字段存储的是相同的series id的集合 } 获取series id集合 func (e *tagKeyValueEntry) ids() seriesIDs { if e == nil {
扫帚的影子
2018/12/28
1.1K0
【Golang语言社区】Golang语言面试题
最近在很多地方看到了golang的面试题,看到了很多人对Golang的面试题心存恐惧,也是为了复习基础,我把解题的过程总结下来。
李海彬
2018/03/07
3.9K2
【Golang语言社区】Golang语言面试题
golang练手小项目系列(6)-使用map实现set
源码来自:https://github.com/deckarep/golang-set
全栈程序员站长
2022/11/17
5100
go 并发安全map之concurrent-map
concurrent-map的readme中说,这是一个高性能的并发安全的map,一起看源码来解读下他是如何实现高性能的。
tabbyzhou
2021/12/05
6.3K1
go 安全map 实现, 互斥锁和读写锁
其中Mutex为互斥锁,Lock()加锁,Unlock()解锁,使用Lock()加锁后,便不能再次对其进行加锁,直到利用Unlock()解锁对其解锁后,才能再次加锁.适用于读写不确定场景,即读写次数没有明显的区别,并且只允许只有一个读或者写的场景,所以该锁叶叫做全局锁.
solate
2019/07/22
5K0
Go语言map并发安全,互斥锁和读写锁谁更优?
并发编程是 Go 语言的一大特色,合理地使用锁对于保证数据一致性和提高程序性能至关重要。
南山竹
2024/07/12
1200
Go语言map并发安全,互斥锁和读写锁谁更优?
Go并发编程
百度Go语言优势,肯定有一条是说Go天生就有支持并发的优势,其他语言支持多线程并发,需要一定的门槛,基础的积累,学习多线程、进程语法。在Go中,就不需要考虑这些,原生提供goroutine(协程),自动帮你处理任务,
用户9022575
2021/10/01
5730
手摸手Go 简单聊聊sync.RWMutex
各位早上好~今天来聊聊Go提供的读写互斥锁sync.RWMutex,它可以加任意数量的读锁或者一个写锁。读写锁占用规则:
用户3904122
2022/06/29
4840
手摸手Go 简单聊聊sync.RWMutex
《快学 Go 语言》第 13 课 —— 并发与安全
上一节我们提到并发编程不同的协程共享数据的方式除了通道之外还有就是共享变量。虽然 Go 语言官方推荐使用通道的方式来共享数据,但是通过变量来共享才是基础,因为通道在底层也是通过共享变量的方式来实现的。通道的内部数据结构包含一个数组,对通道的读写就是对内部数组的读写。
老钱
2018/12/26
4440
GO语言并发编程之互斥锁、读写锁详解
在本节,我们对Go语言所提供的与锁有关的API进行说明。这包括了互斥锁和读写锁。我们在第6章描述过互斥锁,但却没有提到过读写锁。这两种锁对于传统的并发程序来说都是非常常用和重要的。 一、互斥锁 互斥锁是传统的并发程序对共享资源进行访问控制的主要手段。它由标准库代码包sync中的Mutex结构体类型代表。sync.Mutex类型(确切地说,是*sync.Mutex类型)只有两个公开方法——Lock和Unlock。顾名思义,前者被用于锁定当前的互斥量,而后者则被用来对当前的互斥量进行解锁。 类型sync.Mut
李海彬
2018/03/19
8140
记录几个go的工具,写的非常全面
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
地球流浪猫
2019/11/28
3540
推荐阅读
相关推荐
一次生产环境高效利用Go Concurrent Map的记录
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验