github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/dbnode/encoding/ostream_test.go (about) 1 // Copyright (c) 2016 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package encoding 22 23 import ( 24 "testing" 25 26 "github.com/m3db/m3/src/x/pool" 27 28 "github.com/stretchr/testify/require" 29 ) 30 31 var ( 32 nilBytes []byte 33 testBytesPool = newTestCheckedBytesPool() 34 ) 35 36 func TestWriteBits(t *testing.T) { 37 testWriteBits(t, NewOStream(nil, true, nil)) 38 } 39 40 func TestWriteBitsWithPooling(t *testing.T) { 41 testWriteBits(t, NewOStream(nil, true, testBytesPool)) 42 } 43 44 func testWriteBits(t *testing.T, o OStream) { 45 inputs := []struct { 46 value uint64 47 numBits int 48 expectedBytes []byte 49 expectedPos int 50 }{ 51 {0x1, 1, []byte{0x80}, 1}, 52 {0x4, 3, []byte{0xc0}, 4}, 53 {0xa, 4, []byte{0xca}, 8}, 54 {0xfe, 8, []byte{0xca, 0xfe}, 8}, 55 {0xaafe, 7, []byte{0xca, 0xfe, 0xfc}, 7}, 56 {0x3, 2, []byte{0xca, 0xfe, 0xfd, 0x80}, 1}, 57 {0x1234567890abcdef, 64, []byte{0xca, 0xfe, 0xfd, 0x89, 0x1a, 0x2b, 0x3c, 0x48, 0x55, 0xe6, 0xf7, 0x80}, 1}, 58 {0x1, 0, []byte{0xca, 0xfe, 0xfd, 0x89, 0x1a, 0x2b, 0x3c, 0x48, 0x55, 0xe6, 0xf7, 0x80}, 1}, 59 {0x1, 65, []byte{0xca, 0xfe, 0xfd, 0x89, 0x1a, 0x2b, 0x3c, 0x48, 0x55, 0xe6, 0xf7, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80}, 1}, 60 } 61 62 os := o.(*ostream) 63 require.True(t, os.Empty()) 64 for _, input := range inputs { 65 os.WriteBits(input.value, input.numBits) 66 require.Equal(t, input.expectedBytes, os.rawBuffer) 67 b, _ := os.RawBytes() 68 require.Equal(t, input.expectedBytes, b) 69 require.Equal(t, input.expectedPos, os.pos) 70 } 71 require.False(t, os.Empty()) 72 } 73 74 func TestWriteBytes(t *testing.T) { 75 testWriteBytes(t, NewOStream(nil, true, nil)) 76 } 77 78 func TestWriteBytesWithPooling(t *testing.T) { 79 testWriteBytes(t, NewOStream(nil, true, testBytesPool)) 80 } 81 82 func testWriteBytes(t *testing.T, o OStream) { 83 os := o.(*ostream) 84 rawBytes := []byte{0x1, 0x2} 85 os.WriteBytes(rawBytes) 86 87 require.Equal(t, rawBytes, os.rawBuffer) 88 89 b, pos := os.RawBytes() 90 require.Equal(t, rawBytes, b) 91 require.Equal(t, 8, pos) 92 require.Equal(t, 8, os.pos) 93 } 94 95 func TestResetOStream(t *testing.T) { 96 testResetOStream(t, NewOStream(nil, true, testBytesPool)) 97 } 98 99 func TestResetOStreamWithPooling(t *testing.T) { 100 testResetOStream(t, NewOStream(nil, true, testBytesPool)) 101 } 102 103 func testResetOStream(t *testing.T, o OStream) { 104 os := o.(*ostream) 105 os.WriteByte(0xfe) 106 os.Reset(nil) 107 108 require.True(t, os.Empty()) 109 require.Equal(t, 0, os.Len()) 110 require.Equal(t, 0, os.pos) 111 112 b, _ := os.RawBytes() 113 require.Equal(t, nilBytes, b) 114 } 115 116 func BenchmarkWriteBytes(b *testing.B) { 117 var ( 118 bytes = make([]byte, 298) 119 bytesPool = testBytesPool 120 o = NewOStream(nil, false, bytesPool) 121 ) 122 for n := 0; n < b.N; n++ { 123 o.Reset(nil) 124 o.WriteBytes(bytes) 125 } 126 } 127 128 func newTestCheckedBytesPool() pool.CheckedBytesPool { 129 bytesPoolOpts := pool.NewObjectPoolOptions() 130 131 bytesPool := pool.NewCheckedBytesPool([]pool.Bucket{ 132 pool.Bucket{ 133 Capacity: 16, 134 Count: 1, 135 }, 136 pool.Bucket{ 137 Capacity: 32, 138 Count: 1, 139 }, 140 pool.Bucket{ 141 Capacity: 64, 142 Count: 1, 143 }, 144 pool.Bucket{ 145 Capacity: 1, 146 Count: 1, 147 }, 148 pool.Bucket{ 149 Capacity: 256, 150 Count: 1, 151 }, 152 pool.Bucket{ 153 Capacity: 1440, 154 Count: 1, 155 }, 156 pool.Bucket{ 157 Capacity: 4096, 158 Count: 1, 159 }, 160 pool.Bucket{ 161 Capacity: 8192, 162 Count: 1, 163 }, 164 }, bytesPoolOpts, func(s []pool.Bucket) pool.BytesPool { 165 return pool.NewBytesPool(s, bytesPoolOpts) 166 }) 167 bytesPool.Init() 168 return bytesPool 169 }