github.com/min1324/cmap@v1.0.3-0.20220418125848-74e72bbe3be4/README.md (about)

     1  # cmap 
     2  [![Build Status](https://travis-ci.com/min1324/cmap.svg?branch=main)](https://travis-ci.com/min1324/cmap) [![codecov](https://codecov.io/gh/min1324/cmap/branch/main/graph/badge.svg)](https://codecov.io/gh/min1324/cmap) [![Go Report Card](https://goreportcard.com/badge/github.com/min1324/cmap)](https://goreportcard.com/report/github.com/min1324/cmap) [![GoDoc](https://godoc.org/github.com/min1324/cmap?status.png)](https://godoc.org/github.com/min1324/cmap)
     3  
     4  ConcurrentMap (cmap) 是 **go** 分片加锁 map 的一种。它在通过减小锁的粒度和持有的时间来提高并发性。
     5  
     6  ## 原理
     7  
     8  ConcurrentMap 和 MutexMap 主要区别就是围绕着锁的粒度以及如何锁。如图
     9  
    10  ![](doc/aab3105d-568e-3ce3-96c3-5ee2b854a494.jpeg)
    11  
    12  左边便是MutexMap的实现方式---锁整个hash表;而右边则是ConcurrentMap的实现方式---锁桶(或段)。ConcurrentMap将hash表分为8个桶(默认值),诸如load,store,delete等常用操作只锁当前需要用到的桶。
    13  
    14   ConcurrentMap中主要实体类就是三个:ConcurrentMap(整个Hash表),Node(节点),Bucket(桶),对应上面的图可以看出之间的关系。
    15  
    16  ## grow 和 shrink
    17  
    18  ### 扩容gorw
    19  
    20  增加key后,hash表总key数量count满足条件:count > 1<<2*B,或在buckut储存的key数量size满足条件:size > 1<<(B+1),就会对hash表进行扩容。
    21  
    22  ### 收缩shrink
    23  
    24  删除key后,hash表总key数量count满足条件:count > initSize && count < 1<<(B-1),hash表进行收缩。
    25  
    26  **扩容收缩操作:**
    27  
    28  1. 将 resize 置为1。
    29  2. newLen = 1<<B,申请新 node 。
    30  3. 将旧node疏散到新node。
    31  4. 完成疏散后,将旧node置空,resize置0。
    32  
    33  
    34  ## compare
    35  The `map` type in Go doesn't support concurrent reads and writes. 
    36  
    37  `cmap(concurrent-map)` provides a high-performance solution to this by sharding the map with minimal time spent waiting for locks.
    38  
    39  The `sync.Map` has a few key differences from this map. The stdlib `sync.Map` is designed for append-only scenarios.
    40  
    41   So if you want to use the map for something more like in-memory db, you might benefit from using our version. You can read more about it in the golang repo, for example [here](https://github.com/golang/go/issues/21035) and [here](https://stackoverflow.com/questions/11063473/map-with-concurrent-access)
    42  
    43  _Here we fork some README document from [concurrent-map](https://github.com/orcaman/concurrent-map)_
    44  
    45  ## usage
    46  
    47  Import the package:
    48  
    49  ```go
    50  import (
    51  	"github.com/min1324/cmap"
    52  )
    53  
    54  ```
    55  
    56  ```bash
    57  go get "github.com/min1324/cmap"
    58  ```
    59  
    60  The package is now imported under the "cmap" namespace.
    61  
    62  ## example
    63  
    64  ```go
    65  
    66  	// Create a new map.
    67  	var m cmap.Cmap
    68  
    69  	// Stores item within map, sets "bar" under key "foo"
    70  	m.Store("foo", "bar")
    71  
    72  	// Retrieve item from map.
    73  	if tmp, ok := m.Load("foo"); ok {
    74  		bar := tmp.(string)
    75  	}
    76  
    77  	// Deletes item under key "foo"
    78  	m.Delete("foo")
    79  
    80  ```
    81  
    82  ## bench
    83  
    84  
    85  
    86  | name                                            | count     |    time     |     ps     |    allocs    |
    87  | :---------------------------------------------- | :-------- | :---------: | :--------: | :----------: |
    88  | 读取大多数命中                                  |           |             |            |              |
    89  | LoadMostlyHits/*cmap_test.DeepCopyMap-4         | 31570358  | 35.60 ns/op |   6 B/op   | 0 allocs/op  |
    90  | LoadMostlyHits/*cmap_test.RWMutexMap-4          | 19840526  | 58.49 ns/op |   5 B/op   | 0 allocs/op  |
    91  | LoadMostlyHits/*sync.Map-4                      | 33907821  | 35.90 ns/op |   6 B/op   | 0 allocs/op  |
    92  | LoadMostlyHits/*cmap.Map-4                      | 20905459  | 57.21 ns/op |   6 B/op   | 0 allocs/op  |
    93  | 读取大多数不命中                                |           |             |            |              |
    94  | LoadMostlyMisses/*cmap_test.DeepCopyMap-4       | 45099246  | 26.39 ns/op |   6 B/op   | 0 allocs/op  |
    95  | LoadMostlyMisses/*cmap_test.RWMutexMap-4        | 22111984  | 54.36 ns/op |   6 B/op   | 0 allocs/op  |
    96  | LoadMostlyMisses/*sync.Map-4                    | 51615075  | 23.64 ns/op |   6 B/op   | 0 allocs/op  |
    97  | LoadMostlyMisses/*cmap.Map-4                    | 26444559  | 45.25 ns/op |   6 B/op   | 0 allocs/op  |
    98  | 读写平衡                                        |           |             |            |              |
    99  | LoadOrStoreBalanced/*cmap_test.RWMutexMap-4     | 2086924   | 557.8 ns/op |  89 B/op   | 1 allocs/op  |
   100  | LoadOrStoreBalanced/*sync.Map-4                 | 2409666   | 616.8 ns/op |  75 B/op   | 2 allocs/op  |
   101  | LoadOrStoreBalanced/*cmap.Map-4                 | 3032516   | 415.5 ns/op |  143 B/op  | 1 allocs/op  |
   102  | 读写独立                                        |           |             |            |              |
   103  | LoadOrStoreUnique/*cmap_test.RWMutexMap-4       | 1000000   | 1011 ns/op  |  178 B/op  | 2 allocs/op  |
   104  | LoadOrStoreUnique/*sync.Map-4                   | 1000000   | 1280 ns/op  |  163 B/op  | 4 allocs/op  |
   105  | LoadOrStoreUnique/*cmap.Map-4                   | 2135676   | 730.6 ns/op |  282 B/op  | 2 allocs/op  |
   106  | 读写冲突                                        |           |             |            |              |
   107  | LoadOrStoreCollision/*cmap_test.DeepCopyMap-4   | 56008429  | 20.92 ns/op |   0 B/op   | 0 allocs/op  |
   108  | LoadOrStoreCollision/*cmap_test.RWMutexMap-4    | 7257867   | 163.1 ns/op |   0 B/op   | 0 allocs/op  |
   109  | LoadOrStoreCollision/*sync.Map-4                | 44704843  | 26.09 ns/op |   0 B/op   | 0 allocs/op  |
   110  | LoadOrStoreCollision/*cmap.Map-4                | 5274472   | 232.9 ns/op |   0 B/op   | 0 allocs/op  |
   111  | 读删平衡                                        |           |             |            |              |
   112  | LoadAndDeleteBalanced/*cmap_test.RWMutexMap-4   | 6776074   | 176.8 ns/op |   3 B/op   | 0 allocs/op  |
   113  | LoadAndDeleteBalanced/*sync.Map-4               | 42597236  | 28.90 ns/op |   4 B/op   | 0 allocs/op  |
   114  | LoadAndDeleteBalanced/*cmap.Map-4               | 17372445  | 66.46 ns/op |   4 B/op   | 0 allocs/op  |
   115  | 读删独立                                        |           |             |            |              |
   116  | LoadAndDeleteUnique/*cmap_test.RWMutexMap-4     | 6245928   | 192.7 ns/op |   7 B/op   | 0 allocs/op  |
   117  | LoadAndDeleteUnique/*sync.Map-4                 | 54371384  | 22.42 ns/op |   8 B/op   | 0 allocs/op  |
   118  | LoadAndDeleteUnique/*cmap.Map-4                 | 17595276  | 69.03 ns/op |   8 B/op   | 0 allocs/op  |
   119  | 读删冲突                                        |           |             |            |              |
   120  | LoadAndDeleteCollision/*cmap_test.DeepCopyMap-4 | 5193744   | 240.9 ns/op |  48 B/op   | 1 allocs/op  |
   121  | LoadAndDeleteCollision/*cmap_test.RWMutexMap-4  | 8262384   | 147.3 ns/op |   0 B/op   | 0 allocs/op  |
   122  | LoadAndDeleteCollision/*sync.Map-4              | 100000000 | 11.72 ns/op |   0 B/op   | 0 allocs/op  |
   123  | LoadAndDeleteCollision/*cmap.Map-4              | 6053292   | 203.6 ns/op |   0 B/op   | 0 allocs/op  |
   124  | 删除冲突                                        |           |             |            |              |
   125  | DeleteCollision/*cmap_test.DeepCopyMap-4        | 5107717   | 212.8 ns/op |  48 B/op   | 1 allocs/op  |
   126  | DeleteCollision/*cmap_test.RWMutexMap-4         | 8154603   | 144.8 ns/op |   0 B/op   | 0 allocs/op  |
   127  | DeleteCollision/*sync.Map-4                     | 92244220  | 12.90 ns/op |   0 B/op   | 0 allocs/op  |
   128  | DeleteCollision/*cmap.Map-4                     | 5844783   | 205.7 ns/op |   0 B/op   | 0 allocs/op  |
   129  | 遍历                                            |           |             |            |              |
   130  | Range/*cmap_test.DeepCopyMap-4                  | 121210    | 10327 ns/op |   0 B/op   | 0 allocs/op  |
   131  | Range/*cmap_test.RWMutexMap-4                   | 19650     | 62535 ns/op | 16384 B/op | 1 allocs/op  |
   132  | Range/*sync.Map-4                               | 111723    | 10640 ns/op |   0 B/op   | 0 allocs/op  |
   133  | Range/*cmap.Map-4                               | 47502     | 25803 ns/op | 33410 B/op | 64 allocs/op |
   134  |                                                 |           |             |            |              |
   135  | AdversarialAlloc/*cmap_test.DeepCopyMap-4       | 1648602   | 1626 ns/op  |  276 B/op  | 1 allocs/op  |
   136  | AdversarialAlloc/*cmap_test.RWMutexMap-4        | 15540801  | 74.92 ns/op |   8 B/op   | 1 allocs/op  |
   137  | AdversarialAlloc/*sync.Map-4                    | 3247868   | 387.6 ns/op |  49 B/op   | 1 allocs/op  |
   138  | AdversarialAlloc/*cmap.Map-4                    | 19950106  | 60.10 ns/op |   8 B/op   | 1 allocs/op  |
   139  |                                                 |           |             |            |              |
   140  | AdversarialDelete/*cmap_test.DeepCopyMap-4      | 2879204   | 437.9 ns/op |  168 B/op  | 1 allocs/op  |
   141  | AdversarialDelete/*cmap_test.RWMutexMap-4       | 10290254  | 107.8 ns/op |  25 B/op   | 1 allocs/op  |
   142  | AdversarialDelete/*sync.Map-4                   | 5462886   | 218.0 ns/op |  34 B/op   | 1 allocs/op  |
   143  | AdversarialDelete/*cmap.Map-4                   | 23674045  | 49.53 ns/op |   8 B/op   | 1 allocs/op  |
   144