6.go开源groupcache项目笔记——consistenthash_test代码

原文地址为: 6.go开源groupcache项目笔记——consistenthash_test代码

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[i]>=hash,在i=0就满足,而m.keys[0]=2,而2对应的哈希值也是2,和v相等。

第二个就是hash.Get(11),返回12。因为12对应的哈希hash值为12,因为m.keys[i]>=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中获取值(键值就是数组中值)


转载请注明本文地址: 6.go开源groupcache项目笔记——consistenthash_test代码

猜你喜欢

转载自blog.csdn.net/hong2511/article/details/80940013