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  }