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

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