github.com/matrixorigin/matrixone@v1.2.0/pkg/common/mpool/mpool_test.go (about) 1 // Copyright 2021 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package mpool 16 17 import ( 18 "sync" 19 "testing" 20 21 "github.com/stretchr/testify/require" 22 ) 23 24 func TestMPool(t *testing.T) { 25 m, err := NewMPool("test-mpool-small", 0, 0) 26 require.True(t, err == nil, "new mpool failed %v", err) 27 28 nb0 := m.CurrNB() 29 hw0 := m.Stats().HighWaterMark.Load() 30 nalloc0 := m.Stats().NumAlloc.Load() 31 nfree0 := m.Stats().NumFree.Load() 32 33 require.True(t, nalloc0 == 0, "bad nalloc") 34 require.True(t, nfree0 == 0, "bad nfree") 35 36 for i := 1; i <= 10000; i++ { 37 a, err := m.Alloc(i * 10) 38 require.True(t, err == nil, "alloc failure, %v", err) 39 require.True(t, len(a) == i*10, "allocation i size error") 40 a[0] = 0xF0 41 require.True(t, a[1] == 0, "allocation result not zeroed.") 42 a[i*10-1] = 0xBA 43 a, err = m.reAlloc(a, i*20) 44 require.True(t, err == nil, "realloc failure %v", err) 45 require.True(t, len(a) == i*20, "allocation i size error") 46 require.True(t, a[0] == 0xF0, "reallocation not copied") 47 require.True(t, a[i*10-1] == 0xBA, "reallocation not copied") 48 require.True(t, a[i*10] == 0, "reallocation not zeroed") 49 require.True(t, a[i*20-1] == 0, "reallocation not zeroed") 50 m.Free(a) 51 } 52 53 require.True(t, nb0 == m.CurrNB(), "leak") 54 // 30 -- we realloc, need alloc first, then copy. 55 // therefore, (10 + 20) * max(i) and 2 header size (old and new), is the high water. 56 require.True(t, (hw0+10000*30+2*kMemHdrSz) == m.Stats().HighWaterMark.Load(), "hw") 57 // >, because some alloc is absorbed by fixed pool 58 require.True(t, nalloc0+10000*2 > m.Stats().NumAlloc.Load(), "alloc") 59 require.True(t, nalloc0-nfree0 == m.Stats().NumAlloc.Load()-m.Stats().NumFree.Load(), "free") 60 } 61 62 func TestReportMemUsage(t *testing.T) { 63 // Just test a mid sized 64 m, err := NewMPool("testjson", 0, 0) 65 m.EnableDetailRecording() 66 67 require.True(t, err == nil, "new mpool failed %v", err) 68 mem, err := m.Alloc(1000000) 69 require.True(t, err == nil, "mpool alloc failed %v", err) 70 71 j1 := ReportMemUsage("") 72 j2 := ReportMemUsage("global") 73 j3 := ReportMemUsage("testjson") 74 t.Logf("mem usage: %s", j1) 75 t.Logf("global mem usage: %s", j2) 76 t.Logf("testjson mem usage: %s", j3) 77 78 m.Free(mem) 79 j1 = ReportMemUsage("") 80 j2 = ReportMemUsage("global") 81 j3 = ReportMemUsage("testjson") 82 t.Logf("mem usage: %s", j1) 83 t.Logf("global mem usage: %s", j2) 84 t.Logf("testjson mem usage: %s", j3) 85 86 DeleteMPool(m) 87 j1 = ReportMemUsage("") 88 j2 = ReportMemUsage("global") 89 j3 = ReportMemUsage("testjson") 90 t.Logf("mem usage: %s", j1) 91 t.Logf("global mem usage: %s", j2) 92 t.Logf("testjson mem usage: %s", j3) 93 } 94 95 func TestMP(t *testing.T) { 96 pool, err := NewMPool("default", 0, 0) 97 if err != nil { 98 panic(err) 99 } 100 var wg sync.WaitGroup 101 run := func() { 102 defer wg.Done() 103 for i := 0; i < 1000; i++ { 104 buf, err := pool.Alloc(10) 105 if err != nil { 106 panic(err) 107 } 108 pool.Free(buf) 109 } 110 } 111 for i := 0; i < 800; i++ { 112 wg.Add(1) 113 go run() 114 } 115 wg.Wait() 116 117 } 118 119 func TestMpoolReAllocate(t *testing.T) { 120 m := MustNewZero() 121 d1, err := m.Alloc(1023) 122 require.NoError(t, err) 123 require.Equal(t, int64(cap(d1)+kMemHdrSz), m.CurrNB()) 124 125 d2, err := m.reAlloc(d1, cap(d1)-1) 126 require.NoError(t, err) 127 require.Equal(t, cap(d1), cap(d2)) 128 require.Equal(t, int64(cap(d1)+kMemHdrSz), m.CurrNB()) 129 130 d3, err := m.reAlloc(d2, cap(d2)+1025) 131 require.NoError(t, err) 132 require.Equal(t, int64(cap(d3)+kMemHdrSz), m.CurrNB()) 133 134 if cap(d3) > 5 { 135 d3 = d3[:cap(d3)-4] 136 d3_1, err := m.Grow(d3, cap(d3)-2) 137 require.NoError(t, err) 138 require.Equal(t, cap(d3), cap(d3_1)) 139 require.Equal(t, int64(cap(d3)+kMemHdrSz), m.CurrNB()) 140 d3 = d3_1 141 } 142 143 d4, err := m.Grow(d3, cap(d3)+10) 144 require.NoError(t, err) 145 require.Equal(t, int64(cap(d4)+kMemHdrSz), m.CurrNB()) 146 147 if cap(d4) > 0 { 148 d4 = d4[:cap(d4)-1] 149 } 150 m.Free(d4) 151 require.Equal(t, int64(0), m.CurrNB()) 152 }