███╗ ███╗███████╗███╗ ███╗███████╗████████╗ ██████╗ ██████╗ █████╗ ██████╗ ███████╗
████╗ ████║██╔════╝████╗ ████║██╔════╝╚══██╔══╝██╔═══██╗██╔══██╗██╔══██╗██╔════╝ ██╔════╝
██╔████╔██║█████╗ ██╔████╔██║███████╗ ██║ ██║ ██║██████╔╝███████║██║ ███╗█████╗
██║╚██╔╝██║██╔══╝ ██║╚██╔╝██║╚════██║ ██║ ██║ ██║██╔══██╗██╔══██║██║ ██║██╔══╝
██║ ╚═╝ ██║███████╗██║ ╚═╝ ██║███████║ ██║ ╚██████╔╝██║ ██║██║ ██║╚██████╔╝███████╗
╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝
memStorage 是一个面向对象的内存型暂存库
memStorage is an object oriented redis-like temporary repository lib.
-
半成品数据
传统基于内存的数据库将会提供确切类型数据,使用时需要一系列计算从而面临大量的中间转换。
例如:针对正则表达式,传统内存型 NoSQL 仅提供经典的字符串记录,如
^\{\d{1,}\}$
,每次取出后都需要执行正则表达式的Compile
操作,进而在中间过程浪费可观的时间。使用 memStorage,需要存储的内容只需要是Compile
后的正则实例,即每次从 memStorage 取出的内容即可立刻投入使用,做到开箱即用。 -
时效性数据
如果使用全局映射看上去能解决传统内存数据库的问题,但是面临临时数据的治理,如果无效数据过多淤积可能造成内存的浪费甚至是诱发 OOM。
例如:针对正则表达式,如果以组的形式存取正则表达式,全局映射在某一组正则在程序结束前都不再被使用的场景下将不会自动清除内存中的此类数据。使用 memStorage,可以为对象设置 TTL,并使用
GetnRenew
(Get&Renew)方法访问并刷新对象的时效。 -
上下文共享访问
全局变量、常量可能会构造庞大的表格甚至形成反复的独立文件,针对长效的数据,如果使用独立的变量可能因为作用域问题导致一个数据出现在不合理或者难以维护的位置上。
例如,中间件 FilePath 需要与主程序进行联动,具体的工作路径应该由主程序告知。如果主程序的工作路径发生了变化,需要通知中间件新的确切地址是多少。在此期间可能造成因为逻辑上的延迟产生不必要的意外情况。使用 memStorage,可以直接通过统一的上下文减少数据的传递。
一切的一切需要从引入 memStorage 开始:
go get -u github.com/johnwiichang/memstorage
示例:
package demo
import (
"fmt"
"github.com/johnwiichang/memstorage"
"time"
)
func demo() {
//创建新的存储容器
mem := memstorage.New()
//虽然很不推荐,但是确实可以这么写:
// mem := &memstorage.MemStorage{}
//存储一个对象
mem.Set("hello", "memStorage")
//存储一个时效对象
mem.Set("hi", "memElement", time.Second)
//更新对象的时效
mem.SetTTL("hello", 5*time.Second)
//获取一个对象
obj, existed := mem.Get("test")
if existed {
fmt.Println(obj)
} else {
fmt.Println("该对象不存在")
}
//抓取一个对象
fmt.Println(mem.Fetch("hi"))
//获取对象时效信息
fmt.Println(mem.GetTTL("hi"))
//清空容器
mem.Clear()
}
输出:
该对象不存在
memElement
999.966768ms
上面列出的是基础的用法,此外,还提供 GetnRenew
、FetchnRenew
用以访问时顺带刷新时间信息,或者使用 SetRange
批量添加数据到暂存。