github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/structure/maps/hashmap/hashmap_test.go (about)

     1  package hashmap
     2  
     3  import (
     4  	"encoding/json"
     5  	"reflect"
     6  	"strings"
     7  	"testing"
     8  )
     9  
    10  func TestMapPut(t *testing.T) {
    11  	m := New[int, string]()
    12  	m.Put(5, "e")
    13  	m.Put(6, "f")
    14  	m.Put(7, "g")
    15  	m.Put(3, "c")
    16  	m.Put(4, "d")
    17  	m.Put(1, "x")
    18  	m.Put(2, "b")
    19  	m.Put(1, "a") //overwrite
    20  
    21  	if actualValue := m.Size(); actualValue != 7 {
    22  		t.Errorf("Got %v expected %v", actualValue, 7)
    23  	}
    24  	if actualValue, expectedValue := m.Keys(), []int{1, 2, 3, 4, 5, 6, 7}; !sameElements(actualValue, expectedValue) {
    25  		t.Errorf("Got %v expected %v", actualValue, expectedValue)
    26  	}
    27  	if actualValue, expectedValue := m.Values(), []string{"a", "b", "c", "d", "e", "f", "g"}; !sameElements(actualValue, expectedValue) {
    28  		t.Errorf("Got %v expected %v", actualValue, expectedValue)
    29  	}
    30  
    31  	// key,expectedValue,expectedFound
    32  	tests1 := [][]interface{}{
    33  		{1, "a", true},
    34  		{2, "b", true},
    35  		{3, "c", true},
    36  		{4, "d", true},
    37  		{5, "e", true},
    38  		{6, "f", true},
    39  		{7, "g", true},
    40  		{8, "", false},
    41  	}
    42  
    43  	for _, test := range tests1 {
    44  		// retrievals
    45  		actualValue, actualFound := m.Get(test[0].(int))
    46  		if actualValue != test[1] || actualFound != test[2] {
    47  			t.Errorf("Got %v expected %v", actualValue, test[1])
    48  		}
    49  	}
    50  }
    51  
    52  func TestMapRemove(t *testing.T) {
    53  	m := New[int, string]()
    54  	m.Put(5, "e")
    55  	m.Put(6, "f")
    56  	m.Put(7, "g")
    57  	m.Put(3, "c")
    58  	m.Put(4, "d")
    59  	m.Put(1, "x")
    60  	m.Put(2, "b")
    61  	m.Put(1, "a") //overwrite
    62  
    63  	m.Remove(5)
    64  	m.Remove(6)
    65  	m.Remove(7)
    66  	m.Remove(8)
    67  	m.Remove(5)
    68  
    69  	if actualValue, expectedValue := m.Keys(), []int{1, 2, 3, 4}; !sameElements(actualValue, expectedValue) {
    70  		t.Errorf("Got %v expected %v", actualValue, expectedValue)
    71  	}
    72  
    73  	if actualValue, expectedValue := m.Values(), []string{"a", "b", "c", "d"}; !sameElements(actualValue, expectedValue) {
    74  		t.Errorf("Got %v expected %v", actualValue, expectedValue)
    75  	}
    76  	if actualValue := m.Size(); actualValue != 4 {
    77  		t.Errorf("Got %v expected %v", actualValue, 4)
    78  	}
    79  
    80  	tests2 := [][]interface{}{
    81  		{1, "a", true},
    82  		{2, "b", true},
    83  		{3, "c", true},
    84  		{4, "d", true},
    85  		{5, "", false},
    86  		{6, "", false},
    87  		{7, "", false},
    88  		{8, "", false},
    89  	}
    90  
    91  	for _, test := range tests2 {
    92  		actualValue, actualFound := m.Get(test[0].(int))
    93  		if actualValue != test[1] || actualFound != test[2] {
    94  			t.Errorf("Got %v expected %v", actualValue, test[1])
    95  		}
    96  	}
    97  
    98  	m.Remove(1)
    99  	m.Remove(4)
   100  	m.Remove(2)
   101  	m.Remove(3)
   102  	m.Remove(2)
   103  	m.Remove(2)
   104  
   105  	if actualValue, expectedValue := m.Keys(), []int{}; !reflect.DeepEqual(actualValue, expectedValue) {
   106  		t.Errorf("Got %v expected %v", actualValue, expectedValue)
   107  	}
   108  	if actualValue, expectedValue := m.Values(), []string{}; !reflect.DeepEqual(actualValue, expectedValue) {
   109  		t.Errorf("Got %v expected %v", actualValue, expectedValue)
   110  	}
   111  	if actualValue := m.Size(); actualValue != 0 {
   112  		t.Errorf("Got %v expected %v", actualValue, 0)
   113  	}
   114  	if actualValue := m.Empty(); actualValue != true {
   115  		t.Errorf("Got %v expected %v", actualValue, true)
   116  	}
   117  }
   118  
   119  func TestMapSerialization(t *testing.T) {
   120  	m := New[string, float64]()
   121  	m.Put("a", 1.0)
   122  	m.Put("b", 2.0)
   123  	m.Put("c", 3.0)
   124  
   125  	var err error
   126  	assert := func() {
   127  		if actualValue, expectedValue := m.Keys(), []string{"a", "b", "c"}; !sameElements(actualValue, expectedValue) {
   128  			t.Errorf("Got %v expected %v", actualValue, expectedValue)
   129  		}
   130  		if actualValue, expectedValue := m.Values(), []float64{1.0, 2.0, 3.0}; !sameElements(actualValue, expectedValue) {
   131  			t.Errorf("Got %v expected %v", actualValue, expectedValue)
   132  		}
   133  		if actualValue, expectedValue := m.Size(), 3; actualValue != expectedValue {
   134  			t.Errorf("Got %v expected %v", actualValue, expectedValue)
   135  		}
   136  		if err != nil {
   137  			t.Errorf("Got error %v", err)
   138  		}
   139  	}
   140  
   141  	assert()
   142  
   143  	bytes, err := m.MarshalJSON()
   144  	assert()
   145  
   146  	err = m.UnmarshalJSON(bytes)
   147  	assert()
   148  
   149  	bytes, err = json.Marshal([]interface{}{"a", "b", "c", m})
   150  	if err != nil {
   151  		t.Errorf("Got error %v", err)
   152  	}
   153  
   154  	err = json.Unmarshal([]byte(`{"a":1,"b":2}`), &m)
   155  	if err != nil {
   156  		t.Errorf("Got error %v", err)
   157  	}
   158  }
   159  
   160  func TestMapString(t *testing.T) {
   161  	c := New[string, int]()
   162  	c.Put("a", 1)
   163  	if !strings.HasPrefix(c.String(), "HashMap") {
   164  		t.Errorf("String should start with container name")
   165  	}
   166  }
   167  
   168  func sameElements[E any](a []E, b []E) bool {
   169  	if len(a) != len(b) {
   170  		return false
   171  	}
   172  	for _, av := range a {
   173  		found := false
   174  		for _, bv := range b {
   175  			if reflect.DeepEqual(av, bv) {
   176  				found = true
   177  				break
   178  			}
   179  		}
   180  		if !found {
   181  			return false
   182  		}
   183  	}
   184  	return true
   185  }
   186  
   187  func benchmarkGet[K int, V struct{}](b *testing.B, m *Map[K, V], size int) {
   188  	for i := 0; i < b.N; i++ {
   189  		for n := 0; n < size; n++ {
   190  			m.Get(K(n))
   191  		}
   192  	}
   193  }
   194  
   195  func benchmarkPut[K int, V struct{}](b *testing.B, m *Map[K, V], size int) {
   196  	for i := 0; i < b.N; i++ {
   197  		for n := 0; n < size; n++ {
   198  			m.Put(K(n), struct{}{})
   199  		}
   200  	}
   201  }
   202  
   203  func benchmarkRemove[K int, V struct{}](b *testing.B, m *Map[K, V], size int) {
   204  	for i := 0; i < b.N; i++ {
   205  		for n := 0; n < size; n++ {
   206  			m.Remove(K(n))
   207  		}
   208  	}
   209  }
   210  
   211  func BenchmarkHashMapGet100(b *testing.B) {
   212  	b.StopTimer()
   213  	size := 100
   214  	m := New[int, struct{}]()
   215  	for n := 0; n < size; n++ {
   216  		m.Put(n, struct{}{})
   217  	}
   218  	b.StartTimer()
   219  	benchmarkGet(b, m, size)
   220  }
   221  
   222  func BenchmarkHashMapGet1000(b *testing.B) {
   223  	b.StopTimer()
   224  	size := 1000
   225  	m := New[int, struct{}]()
   226  	for n := 0; n < size; n++ {
   227  		m.Put(n, struct{}{})
   228  	}
   229  	b.StartTimer()
   230  	benchmarkGet(b, m, size)
   231  }
   232  
   233  func BenchmarkHashMapGet10000(b *testing.B) {
   234  	b.StopTimer()
   235  	size := 10000
   236  	m := New[int, struct{}]()
   237  	for n := 0; n < size; n++ {
   238  		m.Put(n, struct{}{})
   239  	}
   240  	b.StartTimer()
   241  	benchmarkGet(b, m, size)
   242  }
   243  
   244  func BenchmarkHashMapGet100000(b *testing.B) {
   245  	b.StopTimer()
   246  	size := 100000
   247  	m := New[int, struct{}]()
   248  	for n := 0; n < size; n++ {
   249  		m.Put(n, struct{}{})
   250  	}
   251  	b.StartTimer()
   252  	benchmarkGet(b, m, size)
   253  }
   254  
   255  func BenchmarkHashMapPut100(b *testing.B) {
   256  	b.StopTimer()
   257  	size := 100
   258  	m := New[int, struct{}]()
   259  	b.StartTimer()
   260  	benchmarkPut(b, m, size)
   261  }
   262  
   263  func BenchmarkHashMapPut1000(b *testing.B) {
   264  	b.StopTimer()
   265  	size := 1000
   266  	m := New[int, struct{}]()
   267  	for n := 0; n < size; n++ {
   268  		m.Put(n, struct{}{})
   269  	}
   270  	b.StartTimer()
   271  	benchmarkPut(b, m, size)
   272  }
   273  
   274  func BenchmarkHashMapPut10000(b *testing.B) {
   275  	b.StopTimer()
   276  	size := 10000
   277  	m := New[int, struct{}]()
   278  	for n := 0; n < size; n++ {
   279  		m.Put(n, struct{}{})
   280  	}
   281  	b.StartTimer()
   282  	benchmarkPut(b, m, size)
   283  }
   284  
   285  func BenchmarkHashMapPut100000(b *testing.B) {
   286  	b.StopTimer()
   287  	size := 100000
   288  	m := New[int, struct{}]()
   289  	for n := 0; n < size; n++ {
   290  		m.Put(n, struct{}{})
   291  	}
   292  	b.StartTimer()
   293  	benchmarkPut(b, m, size)
   294  }
   295  
   296  func BenchmarkHashMapRemove100(b *testing.B) {
   297  	b.StopTimer()
   298  	size := 100
   299  	m := New[int, struct{}]()
   300  	for n := 0; n < size; n++ {
   301  		m.Put(n, struct{}{})
   302  	}
   303  	b.StartTimer()
   304  	benchmarkRemove(b, m, size)
   305  }
   306  
   307  func BenchmarkHashMapRemove1000(b *testing.B) {
   308  	b.StopTimer()
   309  	size := 1000
   310  	m := New[int, struct{}]()
   311  	for n := 0; n < size; n++ {
   312  		m.Put(n, struct{}{})
   313  	}
   314  	b.StartTimer()
   315  	benchmarkRemove(b, m, size)
   316  }
   317  
   318  func BenchmarkHashMapRemove10000(b *testing.B) {
   319  	b.StopTimer()
   320  	size := 10000
   321  	m := New[int, struct{}]()
   322  	for n := 0; n < size; n++ {
   323  		m.Put(n, struct{}{})
   324  	}
   325  	b.StartTimer()
   326  	benchmarkRemove(b, m, size)
   327  }
   328  
   329  func BenchmarkHashMapRemove100000(b *testing.B) {
   330  	b.StopTimer()
   331  	size := 100000
   332  	m := New[int, struct{}]()
   333  	for n := 0; n < size; n++ {
   334  		m.Put(n, struct{}{})
   335  	}
   336  	b.StartTimer()
   337  	benchmarkRemove(b, m, size)
   338  }