TA的每日心情 | 开心 2021-12-13 21:45 |
---|
签到天数: 15 天 [LV.4]偶尔看看III
|
6.go开源groupcache项目笔记——consistenthash_test代码
用于测试consistenthash代码。
1 代码如下
packageconsistenthash
import(
"fmt"
"strconv"
"testing"
)
funcTestHashing(t*testing.T){
//Overridethehashfunctiontoreturneasiertoreasonaboutvalues.Assumes
//thekeyscanbeconvertedtoaninteger.
hash:=New(3,func(key[]byte)uint32{
i,err:=strconv.Atoi(string(key))
iferr!=nil{
panic(err)
}
returnuint32(i)
})
//Giventheabovehashfunction,thiswillgivereplicaswith"hashes":
//2,4,6,12,14,16,22,24,26
hash.Add("6","4","2")
testCases:=map[string]string{
"2": "2",
"11":"2",
"23":"4",
"27":"2",
}
fork,v:=rangetestCases{
ifhash.Get(k)!=v{
t.Errorf("Askingfor%s,shouldhaveyielded%s",k,v)
}
}
//Adds8,18,28
hash.Add("8")
//27shouldnowmapto8.
testCases["27"]="8"
fork,v:=rangetestCases{
ifhash.Get(k)!=v{
t.Errorf("Askingfor%s,shouldhaveyielded%s",k,v)
}
}
}
funcTestConsistency(t*testing.T){
hash1:=New(1,nil)
hash2:=New(1,nil)
hash1.Add("Bill","Bob","Bonny")
hash2.Add("Bob","Bonny","Bill")
ifhash1.Get("Ben")!=hash2.Get("Ben"){
t.Errorf("Fetching"Ben"frombothhasheSSHouldbethesame")
}
hash2.Add("Becky","Ben","Bobby")
ifhash1.Get("Ben")!=hash2.Get("Ben")||
hash1.Get("Bob")!=hash2.Get("Bob")||
hash1.Get("Bonny")!=hash2.Get("Bonny"){
t.Errorf("Directmatchesshouldalwaysreturnthesameentry")
}
}
funcBenchmarkGet8(b*testing.B) {benchmarkGet(b,8)}
funcBenchmarkGet32(b*testing.B) {benchmarkGet(b,32)}
funcBenchmarkGet128(b*testing.B){benchmarkGet(b,128)}
funcBenchmarkGet512(b*testing.B){benchmarkGet(b,512)}
funcbenchmarkGet(b*testing.B,shardsint){
hash:=New(50,nil)
varbuckets[]string
fori:=0;i<shards;i++{
buckets=append(buckets,fmt.Sprintf("shard-%d",i))
}
hash.Add(buckets...)
b.ResetTimer()
fori:=0;i<b.N;i++{
hash.Get(buckets[i&(shards-1)])
}
}
2 测试结果
执行如下:
=== RUN TestHashing
--- PASS: TestHashing(0.00s)
=== RUN TestConsistency
--- PASS: TestConsistency(0.00s)
PASS
ok test 0.244s
压测测试结果如下:
BenchmarkGet8-4 5000000 325ns/op
BenchmarkGet32-4 5000000329 ns/op
BenchmarkGet128-4 3000000457 ns/op
BenchmarkGet512-4 2000000654 ns/op
PASS
ok test 8.151s
3 测试说明
3.1 TestHashing
创建一个新的Map结构体,名字为hash,哈希函数是将键值简单转为整形。
然后调用Add函数往里面增加 6,4,2,其实会增加2, 4, 6, 12, 14, 16, 22, 24,26
其中2,12,22映射为2
其中4,14,24映射为4
其中6,16,26映射为6
因为add函数里面有两层循环。
然后是测试用例定义了一个map类,如下:
testCases:=map[string]string{
"2": "2",
"11":"2",
"23":"4",
"27":"2",
}
循环访问,k,v:=rangetestCases,第一个就是则hash.Get(k) ,就是hash.Get(2),而2对应的hash值为2,希望实现m.keys>=hash,在i=0就满足,而m.keys[0]=2,而2对应的哈希值也是2,和v相等。
第二个就是hash.Get(11),返回12。因为12对应的哈希hash值为12,因为m.keys>=hash,则i则为3,m.keys是按顺序排列的(2, 4, 6, 12, 14, 16, 22, 24,26),此时i=3,对应的m.keys[3]=12,而m.hashMap[m.keys[2]] ,即12对应的hash值是2..
其他同理。
3.2 TestConsistency
测试一致性
创建两个hash,分别是hash1和hash2,哈希函数为crc32.ChecksumIEEE
分别增加如下函数
hash1.Add("Bill","Bob","Bonny")
hash2.Add("Bob","Bonny","Bill")
增加后按顺序排列 均为Bill,Bob,Bonny
然后获取Ben,所有返回第一个值Bill 相等。
Hash2继续增加"Becky","Ben","Bobby"
然后继续测试
hash1.Get("Ben") !=hash2.Get("Ben") ||
hash1.Get("Bob")!= hash2.Get("Bob") ||
hash1.Get("Bonny")!= hash2.Get("Bonny")
还是一样的,此时Ben的结果两边还是相等的,hash2并没有加入ben而变化。
这也是groupcache的特点。
不支持多个版本的值。如果“foo”键对应的值是“bar”,那么键“foo”的值永远都是“bar”。
3.3 BenchmarkGet8
Benchmark是性能测试。调用benchmarkGet函数。参数决定hash结构的大小,大小决定执行需要的时间。
3.4 benchmarkGet
创建一个50个值对应一个HASH值的哈希hash,其中哈希函数为默认。
根据入参shards,将字符串数组buckets填充
然后将其加入到hash结构中。
然后设置测试定时器
从hash中获取值(键值就是数组中值)
|
|