# go-redis-dict **Repository Path**: ifaceless/go-redis-dict ## Basic Information - **Project Name**: go-redis-dict - **Description**: Go 语言实现 Redis 字典。 - **Primary Language**: Go - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2019-12-17 - **Last Updated**: 2020-12-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README Redis DICT Go 语言实现 ======================== 对于 Redis 而言,字典是一个非常关键的数据结构,在内部实现中有很多应用,比如存储用户输入的 Key-Value,维护命令及命令处理器的关系等等。总的来说,Redis 字典有如下几个特点: 1. 支持海量 key-value 存储; 2. 使用渐进式 Rehash 策略,避免因为需要迁移的 buckets 太多导致阻塞时间过久(Redis 核心处理逻辑是单线程模型); 3. 默认使用 siph hash 算法计算键的 hash 值; 4. 对于哈希冲突问题,采用了常见的链地址法,且新加入的节点会插入到链表的头部; 5. 字典内部维护了两张哈希表,其中第二个哈希表会在扩容期间(rehash)使用。 看完了 Redis 字典源码后是不是想要自己实现下?要不用 Go 语言实现下呢?考虑到 Go 语言实现时不需要太多操心内存管理的问题(GC 助攻),更加方便容易理解 Redis 字典的核心知识点。 关于这个用 Go 实现的 Redis 字典有几点需要说明: 1. 字典的 key 必须是可比较,且可哈希的,目前支持字符串类型和整数类型,其它类型都会直接 panic 掉; 2. 并没有完全实现 Redis 字典所有的接口,本实现聚焦于 Redis 字典实现的一些要点; 3. 没有照搬原有 Redis 字典提供的接口。毕竟「入乡随俗」嘛,因此提供了和标准库 `sync.Map` 类似的接口。 目前提供的接口如下: ```go // Store 向字典中添加新的 key-value func (d *Dict) Store(key interface{}, value interface{}) // Load 从字典中获取指定 key 对应的值 func (d *Dict) Load(key interface{}) (value interface{}, ok bool) // LoadOrStore 用于根据指定 key 先查找对应值,如果存在则返回对应值; // 否则,会将给定 key-value 存储到字典中,并返回传入的 value。 func (d *Dict) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool) // Delete 删除指定的 key func (d *Dict) Delete(key interface{}) // Len 返回字典的元素个数 func (d *Dict) Len() uint64 // Cap 返回字典的容量 func (d *Dict) Cap() uint64 // Range 模拟 Redis 字典普通迭代器行为,不支持非安全的操作 func (d *Dict) Range(fn func(key, value interface{}) bool) // RangeSafely 模拟 Redis 字典安全迭代器行为,迭代期间不做 rehash 操作 func (d *Dict) RangeSafely(fn func(key, value interface{}) bool) // Resize 用于调整字典容量(扩容或缩容,但是 rehash 还是渐进式的) func (d *Dict) Resize() error // RehashForAWhile 执行一段时间的 rehash func (d *Dict) RehashForAWhile(duration time.Duration) ```