coreKV
https://github.com/hardcore-os/coreKV-CPP
https://github.com/hardcore-os/corekv
要做的应该只是将键值对放在内存中,并且将一些键值对放在磁盘中,不然内存中键值对太多,内存就会爆掉。
gofmt官方提供的格式化工具,整理一下代码中的缩进等排版问题。
go build编译的过程中,其实和c++也是类似的,都是要经过链接静态库文件等。这些都是通过go的工具链实现的,go的工具链可以在源码的pkg/tool/linux_amd64/下看到。
通过go build -n main.go
可以看到main.go编译的整个过程,可以看出编译过程会产生很多中间文件。
可以通过设置环境变量GOBIN来设置go install
的安装路径
安装bazel
https://bazel.build/start/cpp?hl=zh-cn
https://bazel.build/tutorials/cpp-use-cases?hl=zh-cn
课程中提出的优化思路\作业,都可以交给chatgpt,然后就是我的改进。
方便使用 CAS 机制来修改、读取 value.?
func (s *node) getValueOffset() (uint32, uint32) {
value := atomic.LoadUint64(&s.value)
return decodeValue(value)
}
其中 (s *node)
放在func后的意思:在 Go 语言中,函数可以在结构体类型上定义。这些函数称为方法,因为它们是与该结构体相关联的行为。(s *node)
表示这是一个名为 getValueOffset 的方法,它是在 node 结构体类型上定义的。通过使用 (s *node)
,我们可以访问 node 结构体类型中的字段和方法,并在方法中使用这些字段。
如何使用CAS 机制来修改、读取 value?
CAS保证原子执行,避免加锁操作
Bloom Filter的本质就是用哈希值判断key是否存在。
//根据公式计算 m/n, m 在给定的 False Positive 概率和确定的数据量 numEntries 下,是确定的
func BitsPerKey(numEntries int, fp float64) int {
size := -1 * float64(numEntries) * math.Log(fp) / math.Pow(0.69314718056, 2)
locs := math.Ceil(size / float64(numEntries))
return int(locs) // 返回平均每个key需要多少个bits
}
//根据公式计算出最佳 Hash 函数数量
func CalcHashNum(bitsPerKey int) (k uint32) {
k = uint32(float64(bitsPerKey) * 0.69)
if k < 1 {
k = 1
}
if k > 30 {
k = 30
}
return
}
func appendFilter(keys []uint32, bitsPerKey int) []int { // bitsPerKey可由上面的BitsPerKey得到
if bitsPerKey < 0 {
bitsPerKey = 0
}
k := CalcHashNum(bitsPerKey)
nBits := len(keys) * int(bitsPerKey)
filter := make([]int, nBits)
for _, h := range keys {
delta := h >> 17 | h << 15
for j := uint32(0); j < k; j++ { // 通过一个循环,模拟执行k个哈希函数
bitPos := h % uint32(nBits)
filter[bitPos] = 1
h += delta
}
}
return filter
}