--- /dev/null
+package part
+
+import (
+ "unsafe"
+ "runtime"
+ "sync/atomic"
+)
+
+type Map struct {
+ lock pLock //sync
+ num int
+ m map[interface{}]*ptr
+ readOnly atomic.Value //sync
+}
+
+func (t *Map) Store(k,v interface{}) {
+
+ m,_ := t.readOnly.Load().(map[interface{}]*ptr)
+ if p,ok := m[k];ok{
+ p.tryStore(&v)
+ return
+ }
+
+ t.lock.Lock()
+
+ m,_ = t.readOnly.Load().(map[interface{}]*ptr)
+ if p,ok := m[k];ok{
+ p.tryStore(&v)
+ } else if p,ok := t.m[k];ok{
+ p.tryStore(&v)
+ } else {
+ if t.m == nil {t.mapFrom(&m)}
+ t.m[k] = &ptr{p:unsafe.Pointer(&v)}
+ t.num += 1
+ }
+
+ t.lock.Unlock()
+}
+
+func (t *Map) Load(k interface{}) (v interface{}) {
+
+ m,_ := t.readOnly.Load().(map[interface{}]*ptr)
+ p,ok := m[k]
+ if !ok && t.num != 0{
+ t.lock.Lock()
+
+ m,_ = t.readOnly.Load().(map[interface{}]*ptr)
+ p,ok = m[k]
+ if !ok && t.num != 0{
+ if t.m == nil {t.mapFrom(&m)}
+ p,ok = t.m[k]
+ if ok && t.num > 1e3{
+ t.readOnly.Store(t.m)
+ t.m = nil
+ t.num = 0
+ }
+ }
+
+ t.lock.Unlock()
+ }
+
+ if !ok{
+ return nil
+ }
+
+ return p.tryLoad()
+}
+
+func (t *Map) Delete(k interface{}) {
+ m,_ := t.readOnly.Load().(map[interface{}]*ptr)
+
+ if p,ok := m[k];ok && p != nil{
+ delete(m, k)
+ return
+ }
+
+ t.lock.Lock()
+
+ delete(t.m, k)
+
+ t.lock.Unlock()
+}
+
+func (t *Map) Len() int {
+ m,_ := t.readOnly.Load().(map[interface{}]*ptr)
+ return len(m) + t.num
+}
+
+func (t *Map) mapFrom(from *map[interface{}]*ptr) {
+ if t.m == nil {t.m = make(map[interface{}]*ptr)}
+ for k,v := range *from{
+ if v == nil {continue}
+ t.m[k] = v
+ }
+}
+
+type ptr struct {
+ p unsafe.Pointer
+}
+
+func (t *ptr) tryStore(v *interface{}) {
+ t.p = unsafe.Pointer(v)
+ // atomic.StorePointer(&t.p, unsafe.Pointer(v))
+}
+
+func (t *ptr) tryLoad() (interface{}) {
+ // p := atomic.LoadPointer(&t.p)
+ if t.p == nil{
+ return nil
+ }
+ return *(*interface{})(t.p)
+}
+
+type pLock struct{
+ i unsafe.Pointer
+ busy unsafe.Pointer
+}
+
+func (l *pLock) Lock() {
+ if l.busy == nil{l.busy = unsafe.Pointer(&struct{}{})}
+ for !atomic.CompareAndSwapPointer(&l.i, nil, l.busy) {
+ runtime.Gosched()
+ }
+}
+
+func (l *pLock) Locking() (bool) {
+ return atomic.LoadPointer(&l.i) != nil
+}
+
+func (l *pLock) Unlock() {
+ atomic.CompareAndSwapPointer(&l.i, l.busy, nil)
+}
--- /dev/null
+package part
+
+import (
+ "sync"
+ "testing"
+)
+
+func Test_customMap(t *testing.T) {
+ var c Map
+ //set
+ c.Store(0, 3)
+ if c.Load(0) != 3{t.Error(`1`)}
+ //change
+ c.Store(0, 1)
+ if c.Load(0) != 1{t.Error(`2`)}
+ //del
+ c.Store(0, nil)
+ if c.Load(0) != nil{t.Error(`3`)}
+}
+
+func Benchmark_customMap_Set(b *testing.B) {
+ var c Map
+ var w = &sync.WaitGroup{}
+
+ w.Add(b.N)
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ go func(index int) {
+ c.Store(index, nil)
+ w.Done()
+ }(i)
+ }
+ w.Wait()
+}
+
+func Benchmark_customMap_Del(b *testing.B) {
+ c := new(Map)
+ var w = &sync.WaitGroup{}
+
+ w.Add(b.N)
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ go func(index int) {
+ c.Store(index, 0)
+ w.Done()
+ }(i)
+ }
+ w.Wait()
+
+ w.Add(b.N)
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ go func(index int) {
+ c.Delete(index)
+ w.Done()
+ }(i)
+ }
+ w.Wait()
+}
+
+func Benchmark_customMap_Get(b *testing.B) {
+ var c Map
+ var w = &sync.WaitGroup{}
+ var t = b.N
+
+ w.Add(t)
+ b.ResetTimer()
+ for i := 0; i < t; i++ {
+ go func(index int) {
+ c.Store(index, index)
+ w.Done()
+ }(i)
+ }
+ w.Wait()
+
+ b.ResetTimer()
+
+ w.Add(t)
+ b.ResetTimer()
+ for i := 0; i < t; i++ {
+ go func(index int) {
+ if c.Load(index).(int) != index {
+ b.Error("q")
+ }
+ w.Done()
+ }(i)
+ }
+ w.Wait()
+}
+
+func Benchmark_customMap_SetGet(b *testing.B) {
+ var c Map
+ var w = &sync.WaitGroup{}
+
+ w.Add(b.N)
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ go func(index int) {
+ c.Store(index, index)
+ w.Done()
+ }(i)
+ }
+ w.Wait()
+
+ b.Log(c.Len())
+
+ w.Add(b.N)
+ w.Add(b.N)
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ go func(index int) {
+ c.Store(index, index+1)
+ w.Done()
+ }(i)
+ go func(index int) {
+ if t,ok := c.Load(index).(int);!ok || t != index && t != index+1{
+ b.Error(`E`, index, t)
+ }
+ w.Done()
+ }(i)
+ }
+ w.Wait()
+}
+
+func Benchmark_syncMap_Set(b *testing.B) {
+ c:=new(sync.Map)
+ var w = &sync.WaitGroup{}
+
+ w.Add(b.N)
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ go func(index int) {
+ c.Store(index, nil)
+ w.Done()
+ }(i)
+ }
+ w.Wait()
+ }
+
+ func Benchmark_syncMap_Del(b *testing.B) {
+ c := new(sync.Map)
+ var w = &sync.WaitGroup{}
+
+ w.Add(b.N)
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ go func(index int) {
+ c.Store(index, 0)
+ w.Done()
+ }(i)
+ }
+ w.Wait()
+
+ w.Add(b.N)
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ go func(index int) {
+ c.Delete(index)
+ w.Done()
+ }(i)
+ }
+ w.Wait()
+}
+
+func Benchmark_syncMap_Get(b *testing.B) {
+ c := new(sync.Map)
+ var w = &sync.WaitGroup{}
+
+ w.Add(b.N)
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ go func(index int) {
+ c.Store(index, 0)
+ w.Done()
+ }(i)
+ }
+ w.Wait()
+
+ w.Add(b.N)
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ go func(index int) {
+ if v,ok := c.Load(index);!ok || v.(int) != 0 {b.Error("q")}
+ w.Done()
+ }(i)
+ }
+ w.Wait()
+}
+
+func Benchmark_syncMap_SetGet(b *testing.B) {
+ c := new(sync.Map)
+ var w = &sync.WaitGroup{}
+
+ w.Add(b.N)
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ go func(index int) {
+ c.Store(index, 0)
+ w.Done()
+ }(i)
+ }
+ w.Wait()
+
+ w.Add(b.N)
+ w.Add(b.N)
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ go func(index int) {
+ c.Store(index, 1)
+ w.Done()
+ }(i)
+ go func(index int) {
+ c.Load(index)
+ w.Done()
+ }(i)
+ }
+ w.Wait()
+}