Go实现内存数据库 前面我们实现了一个简单的回发Redis,这里我们要实现一个真正的Redis内核 实现底层Dict数据结构 新建一个datastruct文件夹,放一些我们要用的数据结构,比如Redis的核心起始就是一个map,再新建一个包
前面我们实现了一个简单的回发Redis,这里我们要实现一个真正的Redis内核
新建一个datastruct文件夹,放一些我们要用的数据结构,比如Redis的核心起始就是一个map,再新建一个包实现这个map或者叫字典,字典的底层使用的就是map
dict.go
写一个Dict接口定义一些map要实现的功能,注意ForEach方法的入参是一个方法,把这个方法施加到全部k-v,和Range方法类似
// Consumer is used to traversal dict, if it returns false the traversal will be breaktype Consumer func(key string, val interface{}) bool// Dict is interface of a key-value data structuretype Dict interface {Get(key string) (val interface{}, exists bool) //返回相应key对应的value和key是否存在Len() int //字典中有多少个key - value键值对Put(key string, val interface{}) (result int) //将key - value存进dict,存进去回复1,没有存进去回复0PutIfAbsent(key string, val interface{}) (result int) //如果没有则存进对应的key - valuePutIfExists(key string, val interface{}) (result int) //如果有则修改对应的key - valueRemove(key string) (result int) //从字典中删除key - valueForEach(consumer Consumer)//遍历整个字典,传入的是一个方法Keys() []string //列出所有的keyRandomKeys(limit int) []string //随机列一定数量的键RandomDistincTKEys(limit int) []string //随机返回一定数据量不重复的keyClear() //清空字典}
然后就是实现刚才写的接口
sync_dict.go
首先是SyncDict结构体,他的成员只有一个就是sync.Map,然后写一个New方法,RandomKeys方法和RandomDistinctKeys方法实现逻辑上的区别是RandomKeys方法是在for循环里调用Range方法,Range方法里return false,每次for循环只调用一次Range方法,有可能遍历到相同的key,而RandomDistinctKeys方法是return true,直到计数器变量增加到limit时return false,Clear方法不用遍历map一个个删掉,只需要Make一个新的SyncDict,旧的SyncDict由GC做垃圾回收即可
// SyncDict wraps a map, it is not thread safetype SyncDict struct {m sync.Map}// MakeSyncDict makes a new mapfunc MakeSyncDict() *SyncDict {return &SyncDict{}}// Get returns the binding value and whether the key is existfunc (dict *SyncDict) Get(key string) (val interface{}, exists bool) {val, ok := dict.m.Load(key) //Load方法是sync.map的Get方法return val, ok}// Len returns the number of dictfunc (dict *SyncDict) Len() int {lenth := 0dict.m.Range(func(k, v interface{}) bool {lenth++return true})return lenth}// Put puts key value into dict and returns the number of new inserted key-valuefunc (dict *SyncDict) Put(key string, val interface{}) (result int) {_, existed := dict.m.Load(key)dict.m.Store(key, val)if existed {return 0 //仅修改,没有插入新的kv}return 1 //插入新的kv}// PutIfAbsent puts value if the key is not exists and returns the number of updated key-valuefunc (dict *SyncDict) PutIfAbsent(key string, val interface{}) (result int) {_, existed := dict.m.Load(key)if existed {return 0}dict.m.Store(key, val)return 1}// PutIfExists puts value if the key is exist and returns the number of inserted key-valuefunc (dict *SyncDict) PutIfExists(key string, val interface{}) (result int) {_, existed := dict.m.Load(key)if existed {dict.m.Store(key, val)return 1}return 0}// Remove removes the key and return the number of deleted key-valuefunc (dict *SyncDict) Remove(key string) (result int) {_, existed := dict.m.Load(key)dict.m.Delete(key)if existed {return 1}return 0}// Keys returns all keys in dictfunc (dict *SyncDict) Keys() []string {result := make([]string, dict.Len())i := 0dict.m.Range(func(key, value interface{}) bool {result[i] = key.(string)i++return true})return result}// ForEach traversal the dictfunc (dict *SyncDict) ForEach(consumer Consumer) {di
来源地址:https://blog.csdn.net/qq_47431008/article/details/131980077
--结束END--
本文标题: Go重写Redis中间件 - Go实现内存数据库
本文链接: https://www.lsjlt.com/news/409960.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-05-15
2024-05-15
2024-05-15
2024-05-15
2024-05-15
2024-05-15
2024-05-15
2024-05-15
2024-05-15
2024-05-15
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0