0%

通过Go+Map写k-v数据库(SET-GET简单实现函数版)

通过实现一个简单的K–V存储数据库,学习Go语言(一)

实现本地读写功能(使用map)

  1. 使用结构体,实现myRedis类

注意 map 中值为 any 等同于 interface{} 本人使用go 1.18 any 为 interface{} 的自定义类型名称

使用 any 就可以存储任意类型

type myRedis struct {
	mymap map[string]any
}

func newRedis() *myRedis {
	return &myRedis{mymap: map[string]any{}}
}
  1. 实现SET-GET功能
unc (r *myRedis) Set(key string, value any) (int, error) {
	if key != "" && value != nil {
		r.mymap[key] = value
		return 1, nil
	}
	return 0, errors.New("空值")
}
func (r *myRedis) Get(key string) (any, error) {
	if v, ok := r.mymap[key]; ok {
		return v, nil
	}
	return nil, errors.New("无该元素")
}

测试myRedis

  1. 单元测试

创建文件名为 myMap_test.go 即在原myMap后加上_test即可

函数名称改为Test【XXX】

import "testing"

//样例测试
//go test -v 样例测试命令
func TestMyRedis_Set(t *testing.T) {
	redis := newRedis()
	if i, e := redis.Set("test", "success"); i != 1 || e != nil { //try a unit test on function
		t.Error("Set函数测试没通过") // 如果不是如预期的那么就报错
	} else {
		t.Log("Set测试通过了") //记录一些你期望记录的信息
	}
}
func TestMyRedis_Get(t *testing.T) {
	redis := newRedis()
	redis.Set("test", 1)
	if v, e := redis.Get("test"); e != nil { //try a unit test on function
		t.Error("Get函数测试没通过") // 如果不是如预期的那么就报错
	} else {
		t.Log("Get测试通过了") //记录一些你期望记录的信息
		t.Log("值为:", v)
	}
}

运行测试文件,输出:

=== RUN   TestMyRedis_Set
    mymap_test.go:12: Set测试通过了
--- PASS: TestMyRedis_Set (0.00s)
=== RUN   TestMyRedis_Get
    mymap_test.go:21: Get测试通过了
    mymap_test.go:22: 值为: 1
--- PASS: TestMyRedis_Get (0.00s)
PASS
  1. 压力测试

函数名称改为Benchmark【XXX】

func BenchmarkMyRedis_Set(b *testing.B) {
	redis := newRedis()
	for i := 0; i < b.N; i++ { //use b.N for looping
		redis.Set("test", "success")
	}
}
func BenchmarkMyRedis_Set2(b *testing.B) {
	b.StopTimer() //调用该函数停止压力测试的时间计数

	//做一些初始化的工作,例如读取文件数据,数据库连接之类的,
	//这样这些时间不影响我们测试函数本身的性能
	redis := newRedis()
	b.StartTimer() //重新开始时间
	for i := 0; i < b.N; i++ {
		redis.Set("test", "success")
	}
}
func BenchmarkMyRedis_Get(b *testing.B) {
	b.StopTimer() //调用该函数停止压力测试的时间计数
	//做一些初始化的工作,例如读取文件数据,数据库连接之类的,
	//这样这些时间不影响我们测试函数本身的性能
	redis := newRedis()
	redis.Set("test", "success")
	b.StartTimer() //重新开始时间
	for i := 0; i < b.N; i++ {
		redis.Get("test")
	}
}

运行测试文件,输出:

goos: windows
goarch: amd64
pkg: 7days_test/key-value
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkMyRedis_Set
BenchmarkMyRedis_Set-12         130041237                8.598 ns/op
BenchmarkMyRedis_Set2
BenchmarkMyRedis_Set2-12        138570001                8.876 ns/op
BenchmarkMyRedis_Get
BenchmarkMyRedis_Get-12         327336081                3.726 ns/op
PASS

327336081为运行次数 3.726 ns/op为运行速度

以上说明GET读性能远大于写性能

未完待续~

-------------本文结束感谢您的阅读-------------
打赏一瓶矿泉水