github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/zarray/hashmap_test.go (about)

     1  //go:build go1.18
     2  // +build go1.18
     3  
     4  package zarray_test
     5  
     6  import (
     7  	"encoding/json"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/sohaha/zlsgo"
    12  	"github.com/sohaha/zlsgo/zarray"
    13  	"github.com/sohaha/zlsgo/zsync"
    14  )
    15  
    16  func TestHashMap(t *testing.T) {
    17  	tt := zlsgo.NewTest(t)
    18  	m := zarray.NewHashMap[int, string]()
    19  
    20  	m.Set(1, "name")
    21  	m.Set(2, "name2")
    22  	m.Set(9, "name9")
    23  	tt.Equal(3, int(m.Len()))
    24  
    25  	item, ok := m.Get(1)
    26  	tt.EqualTrue(ok)
    27  	tt.Equal("name", item)
    28  
    29  	item, ok = m.Get(2)
    30  	tt.EqualTrue(ok)
    31  	tt.Equal("name2", item)
    32  
    33  	item, ok = m.Get(3)
    34  	tt.EqualTrue(!ok)
    35  	tt.Equal("", item)
    36  
    37  	m.Delete(2)
    38  	m.Delete(9)
    39  
    40  	tt.Equal(1, int(m.Len()))
    41  
    42  	_, ok = m.Get(2)
    43  	tt.EqualTrue(!ok)
    44  
    45  	m.Set(2, "reset name2")
    46  	m.ForEach(func(key int, value string) bool {
    47  		t.Log("ForEach:", key, value)
    48  		return true
    49  	})
    50  
    51  	j, err := json.Marshal(m)
    52  	tt.NoError(err)
    53  	t.Log(string(j))
    54  
    55  	j = []byte(`{"2":"hobby","1":"new name","8":"886"}`)
    56  	err = json.Unmarshal(j, &m)
    57  	tt.NoError(err)
    58  	mlen := m.Len()
    59  
    60  	v2, ok := m.Get(2)
    61  	tt.EqualTrue(ok)
    62  	tt.Equal("hobby", v2)
    63  
    64  	v1, ok := m.GetAndDelete(1)
    65  	tt.EqualTrue(ok)
    66  	tt.Equal("new name", v1)
    67  	tt.Equal(mlen-1, m.Len())
    68  
    69  	m.ForEach(func(key int, value string) bool {
    70  		t.Log("n:", key, value)
    71  		return true
    72  	})
    73  
    74  	t.Log(m.Keys())
    75  	m.Clear()
    76  	t.Log(m.Keys())
    77  	m.Set(9, "yes")
    78  	t.Log(m.Keys())
    79  }
    80  
    81  func TestHashMapOverwrite(t *testing.T) {
    82  	tt := zlsgo.NewTest(t)
    83  	m := zarray.NewHashMap[int, string]()
    84  	key := 1
    85  	name := "luffy"
    86  	name2 := "ace"
    87  
    88  	m.Set(key, name)
    89  	m.Set(key, name2)
    90  	tt.Equal(1, int(m.Len()))
    91  
    92  	item, ok := m.Get(key)
    93  	tt.EqualTrue(ok)
    94  	tt.EqualTrue(name != item)
    95  	tt.Equal(name2, item)
    96  }
    97  
    98  func TestHashMapSwap(t *testing.T) {
    99  	tt := zlsgo.NewTest(t)
   100  	m := zarray.NewHashMap[int, int]()
   101  	m.Set(1, 100)
   102  
   103  	oldValue, swapped := m.Swap(1, 200)
   104  	t.Log(oldValue, swapped)
   105  	tt.EqualTrue(swapped)
   106  	tt.Equal(100, oldValue)
   107  
   108  	oldValue, swapped = m.Swap(1, 200)
   109  	t.Log(oldValue, swapped)
   110  
   111  	tt.EqualTrue(!m.CAS(1, 100, 200))
   112  	tt.EqualTrue(m.CAS(1, 200, 100))
   113  	tt.EqualTrue(m.CAS(1, 100, 200))
   114  	tt.EqualTrue(!m.CAS(1, 100, 200))
   115  }
   116  
   117  func TestHashMapProvideGet(t *testing.T) {
   118  	tt := zlsgo.NewTest(t)
   119  	m := zarray.NewHashMap[int, int]()
   120  
   121  	{
   122  		i := 0
   123  		one, ok, computed := m.ProvideGet(0, func() (int, bool) {
   124  			t.Log("ProvideGet set", 110)
   125  			i++
   126  			return 110, false
   127  		})
   128  		t.Log(one, ok)
   129  		tt.EqualTrue(!computed)
   130  
   131  		one, ok, computed = m.ProvideGet(0, func() (int, bool) {
   132  			t.Log("ProvideGet set", 119)
   133  			i++
   134  			return 119, true
   135  		})
   136  		t.Log(one, ok)
   137  		tt.EqualTrue(computed)
   138  
   139  		one, ok, computed = m.ProvideGet(0, func() (int, bool) {
   140  			i++
   141  			return 120, true
   142  		})
   143  		tt.EqualTrue(!computed)
   144  
   145  		tt.EqualTrue(ok)
   146  		tt.Equal(119, one)
   147  		tt.Equal(2, i)
   148  	}
   149  
   150  	var wg zsync.WaitGroup
   151  
   152  	for i := 0; i < 1000; i++ {
   153  		wg.Go(func() {
   154  			v, ok, _ := m.ProvideGet(1, func() (int, bool) {
   155  				t.Log("set", 99)
   156  				time.Sleep(time.Millisecond * 100)
   157  				return 99, true
   158  			})
   159  			tt.EqualTrue(ok)
   160  			tt.Equal(99, v)
   161  		})
   162  	}
   163  
   164  	_ = wg.Wait()
   165  
   166  	v, ok := m.Get(1)
   167  	tt.EqualTrue(ok)
   168  	tt.Equal(99, v)
   169  
   170  	m.Delete(1)
   171  
   172  	for i := 0; i < 10; i++ {
   173  		wg.Go(func() {
   174  			v, ok, _ := m.ProvideGet(1, func() (int, bool) {
   175  				time.Sleep(time.Millisecond * 100)
   176  				t.Log("new set", 100)
   177  				return 100, true
   178  			})
   179  			tt.EqualTrue(ok)
   180  			tt.Equal(100, v)
   181  		})
   182  	}
   183  
   184  	_ = wg.Wait()
   185  
   186  	v, ok = m.Get(1)
   187  	tt.EqualTrue(ok)
   188  	tt.Equal(100, v)
   189  }