github.com/better-concurrent/guc@v0.0.0-20190520022744-eb29266403a1/concurrenthashmap_test.go (about) 1 package guc 2 3 import ( 4 "fmt" 5 "runtime" 6 "testing" 7 "unsafe" 8 ) 9 10 type testKey struct { 11 i int32 12 s string 13 k *testKey 14 } 15 16 func TestBase(t *testing.T) { 17 testMap := make(map[interface{}]bool) 18 k1 := testKey{i: 1, s: ""} 19 k2 := testKey{i: 1, s: "1"} 20 k2.s = "" 21 testMap[k1] = true 22 fmt.Println(testMap[k1]) 23 fmt.Println(testMap[k2]) 24 25 iMap := make(map[interface{}]interface{}) 26 iMap[k1] = 1 27 fmt.Println(iMap[k2]) 28 29 piMap := make(map[*int32]bool) 30 var i1 int32 = 1 31 var i2 int32 = 1 32 piMap[&i1] = true 33 fmt.Println(piMap[&i2]) 34 35 pMap := make(map[unsafe.Pointer]bool) 36 pMap[unsafe.Pointer(&k1)] = true 37 fmt.Println(pMap[unsafe.Pointer(&k1)]) 38 } 39 40 func TestTableSizeAlign(t *testing.T) { 41 if tableSizeFor(1) != 1 { 42 t.Error("resize error") 43 } 44 if tableSizeFor(14) != 16 { 45 t.Error("resize error") 46 } 47 } 48 49 func TestTabAt(t *testing.T) { 50 n0 := node{hash: 1} 51 tab := make([]unsafe.Pointer, 4) 52 if tabAt(&tab, 0) != nil { 53 t.Error("tab at error") 54 } 55 if casTabAt(&tab, 0, nil, &n0) { 56 if tabAt(&tab, 0) != &n0 { 57 t.Error("tab at error") 58 } 59 } 60 } 61 62 type innerStruct struct { 63 j int32 64 } 65 66 type keyObject struct { 67 i int32 68 s string 69 inner innerStruct 70 } 71 72 type keyObject2 struct { 73 i int 74 } 75 76 type valueObject struct { 77 v string 78 } 79 80 func TestBasicOperation(t *testing.T) { 81 key0 := keyObject{i: 0, s: "a", inner: innerStruct{32}} 82 value0 := valueObject{v: "v"} 83 84 cmap := ConcurrentHashMap{} 85 cmap.init(16, 4) 86 fmt.Println(cmap) 87 oldValue := cmap.Store(key0, value0) 88 if oldValue != nil { 89 t.Fatalf("Store error") 90 } 91 oldValue1 := cmap.Store(key0, value0) 92 if oldValue1 == nil || value0 != oldValue1 { 93 t.Fatalf("Store error") 94 } 95 value1, _ := cmap.Load(key0) 96 if value0 != value1 { 97 t.Fatalf("Load error") 98 } 99 fmt.Println(cmap) 100 } 101 102 func TestMapResize(t *testing.T) { 103 cmap := NewConcurrentHashMap(4, 4) 104 total := 32 105 for i := 0; i < total; i++ { 106 key := keyObject{i: int32(i), s: "a", inner: innerStruct{32}} 107 value0 := valueObject{v: "v"} 108 cmap.Store(key, value0) 109 _, ok := cmap.Load(key) 110 if !ok { 111 t.Fatalf("get error") 112 } 113 } 114 if cmap.Size() != total { 115 t.Fatalf("cmap size is %d\n", cmap.Size()) 116 } 117 cmap.printTableDetail() 118 } 119 120 func TestContendedCell(t *testing.T) { 121 cc := CounterCell{} 122 fmt.Println(unsafe.Sizeof(cc)) 123 if unsafe.Sizeof(cc) != CacheLineSize { 124 t.Fatalf("padding error") 125 } 126 } 127 128 func TestMultiGoroutine(t *testing.T) { 129 runtime.GOMAXPROCS(4) 130 gc := 4 131 countPerG := 1024 * 32 132 cmap := NewConcurrentHashMap(4, 4) 133 endCh := make(chan int) 134 value0 := valueObject{v: "v"} 135 for i := 0; i < gc; i++ { 136 go func() { 137 begin := i * countPerG 138 for n := 0; n < begin+countPerG; n++ { 139 key := keyObject2{i: n} 140 cmap.Store(key, value0) 141 } 142 endCh <- 1 143 }() 144 } 145 for i := 0; i < gc; i++ { 146 <-endCh 147 } 148 cmap.printTableDetail() 149 cmap.printCountDetail() 150 fmt.Println("end") 151 }