From 7ce89d19ed780e51e2460b1b0a8f550f12cf0b05 Mon Sep 17 00:00:00 2001
From: Ryan Allen <rallen090@gmail.com>
Date: Mon, 9 Mar 2020 15:52:45 -0400
Subject: [PATCH 01/11] Fixing prof

---
 .../ts/m3db/encoded_step_iterator_test.go     | 84 +++++++++++--------
 1 file changed, 50 insertions(+), 34 deletions(-)

diff --git a/src/query/ts/m3db/encoded_step_iterator_test.go b/src/query/ts/m3db/encoded_step_iterator_test.go
index 5b523045a2..8a7fb30277 100644
--- a/src/query/ts/m3db/encoded_step_iterator_test.go
+++ b/src/query/ts/m3db/encoded_step_iterator_test.go
@@ -398,6 +398,7 @@ func (t iterType) name(name string) string {
 }
 
 type reset func()
+type stop func()
 
 // newTestOptions provides options with very small/non-existent pools
 // so that memory profiles don't get cluttered with pooled allocated objects.
@@ -423,7 +424,7 @@ func newTestOptions() Options {
 	return newOptions(bytesPool, iteratorPools)
 }
 
-func setupBlock(b *testing.B, iterations int, t iterType) (block.Block, reset) {
+func setupBlock(b *testing.B, iterations int, t iterType) (block.Block, reset, stop) {
 	var (
 		seriesCount   = 1000
 		replicasCount = 3
@@ -509,6 +510,39 @@ func setupBlock(b *testing.B, iterations int, t iterType) (block.Block, reset) {
 	}
 
 	usePools := t == stepParallel
+
+	opts := newTestOptions()
+	if usePools {
+		poolOpts := xsync.NewPooledWorkerPoolOptions()
+		readWorkerPools, err := xsync.NewPooledWorkerPool(1024, poolOpts)
+		require.NoError(b, err)
+		readWorkerPools.Init()
+		opts = opts.SetReadWorkerPool(readWorkerPools)
+	}
+
+	for _, reset := range itersReset {
+		reset()
+	}
+
+	block, err := NewEncodedBlock(iters, models.Bounds{
+		Start:    start,
+		StepSize: stepSize,
+		Duration: window,
+	}, false, block.NewResultMetadata(), opts)
+
+	require.NoError(b, err)
+	return block, func() {
+			for _, reset := range itersReset {
+				reset()
+			}
+		},
+		setupProf(usePools, iterations)
+}
+
+func setupProf(usePools bool, iterations int) stop {
+	var pCPU, pMem interface {
+		Stop()
+	}
 	if os.Getenv("PROFILE_TEST_CPU") == "true" {
 		key := profileTakenKey{
 			profile:    "cpu",
@@ -516,8 +550,7 @@ func setupBlock(b *testing.B, iterations int, t iterType) (block.Block, reset) {
 			iterations: iterations,
 		}
 		if v := profilesTaken[key]; v == 2 {
-			p := profile.Start(profile.CPUProfile)
-			defer p.Stop()
+			pCPU = profile.Start(profile.CPUProfile)
 		}
 
 		profilesTaken[key] = profilesTaken[key] + 1
@@ -531,42 +564,25 @@ func setupBlock(b *testing.B, iterations int, t iterType) (block.Block, reset) {
 		}
 
 		if v := profilesTaken[key]; v == 2 {
-			p := profile.Start(profile.MemProfile)
-			defer p.Stop()
+			pMem = profile.Start(profile.MemProfile)
 		}
 
 		profilesTaken[key] = profilesTaken[key] + 1
 	}
-
-	opts := newTestOptions()
-	if usePools {
-		poolOpts := xsync.NewPooledWorkerPoolOptions()
-		readWorkerPools, err := xsync.NewPooledWorkerPool(1024, poolOpts)
-		require.NoError(b, err)
-		readWorkerPools.Init()
-		opts = opts.SetReadWorkerPool(readWorkerPools)
-	}
-
-	for _, reset := range itersReset {
-		reset()
-	}
-
-	block, err := NewEncodedBlock(iters, models.Bounds{
-		Start:    start,
-		StepSize: stepSize,
-		Duration: window,
-	}, false, block.NewResultMetadata(), opts)
-
-	require.NoError(b, err)
-	return block, func() {
-		for _, reset := range itersReset {
-			reset()
+	return func() {
+		if pCPU != nil {
+			pCPU.Stop()
+		}
+		if pMem != nil {
+			pMem.Stop()
 		}
 	}
 }
 
 func benchmarkNextIteration(b *testing.B, iterations int, t iterType) {
-	bl, reset := setupBlock(b, iterations, t)
+	bl, reset, close := setupBlock(b, iterations, t)
+	defer close()
+
 	if t == seriesSequential {
 		it, err := bl.SeriesIter()
 		require.NoError(b, err)
@@ -673,13 +689,13 @@ var (
 */
 func BenchmarkNextIteration(b *testing.B) {
 	iterTypes := []iterType{
-		stepSequential,
-		stepParallel,
+		// stepSequential,
+		// stepParallel,
 		seriesSequential,
-		seriesBatch,
+		// seriesBatch,
 	}
 
-	for _, s := range []int{10, 100, 200, 500, 1000, 2000} {
+	for _, s := range []int{10} {
 		for _, t := range iterTypes {
 			name := t.name(fmt.Sprintf("%d", s))
 			b.Run(name, func(b *testing.B) {

From fcb9927ba6aa05586c8c2651a80dd5198bdb807e Mon Sep 17 00:00:00 2001
From: Ryan Allen <rallen090@gmail.com>
Date: Wed, 11 Mar 2020 13:06:12 -0400
Subject: [PATCH 02/11] WIP 1

---
 src/dbnode/encoding/istream.go                | 32 ++++++++++++++++---
 src/dbnode/encoding/m3tsz/encoder.go          |  8 ++++-
 src/dbnode/ts/segment.go                      | 18 +++++++++++
 src/dbnode/x/xio/segment_reader.go            |  8 ++---
 .../ts/m3db/encoded_step_iterator_test.go     |  5 +--
 5 files changed, 57 insertions(+), 14 deletions(-)

diff --git a/src/dbnode/encoding/istream.go b/src/dbnode/encoding/istream.go
index cc6686c409..0ab3370847 100644
--- a/src/dbnode/encoding/istream.go
+++ b/src/dbnode/encoding/istream.go
@@ -22,6 +22,7 @@ package encoding
 
 import (
 	"bufio"
+	"encoding/binary"
 	"io"
 	"math"
 )
@@ -31,12 +32,13 @@ type istream struct {
 	r         *bufio.Reader // encoded stream
 	err       error         // error encountered
 	current   byte          // current byte we are working off of
+	buffer    []byte        // current byte we are working off of
 	remaining int           // bits remaining in current to be read
 }
 
 // NewIStream creates a new Istream
 func NewIStream(reader io.Reader, bufioSize int) IStream {
-	return &istream{r: bufio.NewReaderSize(reader, bufioSize)}
+	return &istream{r: bufio.NewReaderSize(reader, bufioSize), buffer: make([]byte, 8, 8)}
 }
 
 // ReadBit reads the next Bit
@@ -98,16 +100,36 @@ func (is *istream) ReadBits(numBits int) (uint64, error) {
 		return 0, is.err
 	}
 
+	//var res uint64
+	//fmt.Println("NUM", numBits)
 	var res uint64
-	for numBits >= 8 {
-		byteRead, err := is.ReadByte()
+	numBytes := numBits / 8
+	numBits = numBits % 8
+	if numBytes > 0 {
+		fullBytes := is.buffer[0:numBytes]
+		_, err := is.Read(fullBytes)
 		if err != nil {
 			return 0, err
 		}
-		res = (res << 8) | uint64(byteRead)
-		numBits -= 8
+		// var res2 uint64
+		// for _, b := range fullBytes {
+		// 	res2 = (res2 << 8) | uint64(b)
+		// }
+		res = binary.BigEndian.Uint64(is.buffer)
+		// if res != res2 {
+		// 	panic(fmt.Sprintf("A %d %d", int(res), int(res2)))
+		// }
 	}
 
+	// for numBits >= 8 {
+	// 	byteRead, err := is.ReadByte()
+	// 	if err != nil {
+	// 		return 0, err
+	// 	}
+	// 	res = (res << 8) | uint64(byteRead)
+	// 	numBits -= 8
+	// }
+
 	for numBits > 0 {
 		// This is equivalent to calling is.ReadBit() in a loop but some manual inlining
 		// has been performed to optimize this loop as its heavily used in the hot path.
diff --git a/src/dbnode/encoding/m3tsz/encoder.go b/src/dbnode/encoding/m3tsz/encoder.go
index 302c43be16..24c732f6ae 100644
--- a/src/dbnode/encoding/m3tsz/encoder.go
+++ b/src/dbnode/encoding/m3tsz/encoder.go
@@ -430,5 +430,11 @@ func (enc *encoder) segmentTakeOwnership() ts.Segment {
 	// NB(r): Finalize the head bytes whether this is by ref or copy. If by
 	// ref we have no ref to it anymore and if by copy then the owner should
 	// be finalizing the bytes when the segment is finalized.
-	return ts.NewSegment(head, tail, 0, ts.FinalizeHead)
+	head.IncRef()
+	abc := head.Bytes()
+	head.DecRef()
+	tail.IncRef()
+	def := tail.Bytes()
+	tail.DecRef()
+	return ts.NewRawSegment(abc, def, 0, ts.FinalizeHead)
 }
diff --git a/src/dbnode/ts/segment.go b/src/dbnode/ts/segment.go
index 285fed4920..c53c4940c3 100644
--- a/src/dbnode/ts/segment.go
+++ b/src/dbnode/ts/segment.go
@@ -36,6 +36,10 @@ type Segment struct {
 	Head checked.Bytes
 	// Tail is the tail of the segment.
 	Tail checked.Bytes
+	// RawHead is the head of the segment.
+	RawHead []byte
+	// RawTail is the tail of the segment.
+	RawTail []byte
 	// SegmentFlags declares whether to finalize when finalizing the segment.
 	Flags SegmentFlags
 	// checksum is the checksum for the segment.
@@ -94,6 +98,20 @@ func NewSegment(
 	}
 }
 
+// NewRawSegment creates a new RawSegment.
+func NewRawSegment(
+	head, tail []byte,
+	checksum uint32,
+	flags SegmentFlags,
+) Segment {
+	return Segment{
+		RawHead:  head,
+		RawTail:  tail,
+		Flags:    flags,
+		checksum: checksum,
+	}
+}
+
 // Len returns the length of the head and tail.
 func (s *Segment) Len() int {
 	var total int
diff --git a/src/dbnode/x/xio/segment_reader.go b/src/dbnode/x/xio/segment_reader.go
index 352c8feeea..cdda51485c 100644
--- a/src/dbnode/x/xio/segment_reader.go
+++ b/src/dbnode/x/xio/segment_reader.go
@@ -51,11 +51,11 @@ func (sr *segmentReader) Read(b []byte) (int, error) {
 		return 0, nil
 	}
 
-	if b := sr.segment.Head; b != nil && len(sr.lazyHead) == 0 {
-		sr.lazyHead = b.Bytes()
+	if b := sr.segment.RawHead; b != nil && len(sr.lazyHead) == 0 {
+		sr.lazyHead = b
 	}
-	if b := sr.segment.Tail; b != nil && len(sr.lazyTail) == 0 {
-		sr.lazyTail = b.Bytes()
+	if b := sr.segment.RawTail; b != nil && len(sr.lazyTail) == 0 {
+		sr.lazyTail = b
 	}
 
 	nh, nt := len(sr.lazyHead), len(sr.lazyTail)
diff --git a/src/query/ts/m3db/encoded_step_iterator_test.go b/src/query/ts/m3db/encoded_step_iterator_test.go
index 8a7fb30277..bc5add3f65 100644
--- a/src/query/ts/m3db/encoded_step_iterator_test.go
+++ b/src/query/ts/m3db/encoded_step_iterator_test.go
@@ -689,13 +689,10 @@ var (
 */
 func BenchmarkNextIteration(b *testing.B) {
 	iterTypes := []iterType{
-		// stepSequential,
-		// stepParallel,
 		seriesSequential,
-		// seriesBatch,
 	}
 
-	for _, s := range []int{10} {
+	for _, s := range []int{500} {
 		for _, t := range iterTypes {
 			name := t.name(fmt.Sprintf("%d", s))
 			b.Run(name, func(b *testing.B) {

From e1787ac186136728f568e521cc5c779b3e74f74e Mon Sep 17 00:00:00 2001
From: Ryan Allen <rallen090@gmail.com>
Date: Wed, 11 Mar 2020 13:09:34 -0400
Subject: [PATCH 03/11] WIP 2

---
 src/dbnode/encoding/m3tsz/encoder.go |  8 +-------
 src/dbnode/ts/segment.go             | 18 ------------------
 src/dbnode/x/xio/segment_reader.go   |  8 ++++----
 3 files changed, 5 insertions(+), 29 deletions(-)

diff --git a/src/dbnode/encoding/m3tsz/encoder.go b/src/dbnode/encoding/m3tsz/encoder.go
index 24c732f6ae..302c43be16 100644
--- a/src/dbnode/encoding/m3tsz/encoder.go
+++ b/src/dbnode/encoding/m3tsz/encoder.go
@@ -430,11 +430,5 @@ func (enc *encoder) segmentTakeOwnership() ts.Segment {
 	// NB(r): Finalize the head bytes whether this is by ref or copy. If by
 	// ref we have no ref to it anymore and if by copy then the owner should
 	// be finalizing the bytes when the segment is finalized.
-	head.IncRef()
-	abc := head.Bytes()
-	head.DecRef()
-	tail.IncRef()
-	def := tail.Bytes()
-	tail.DecRef()
-	return ts.NewRawSegment(abc, def, 0, ts.FinalizeHead)
+	return ts.NewSegment(head, tail, 0, ts.FinalizeHead)
 }
diff --git a/src/dbnode/ts/segment.go b/src/dbnode/ts/segment.go
index c53c4940c3..285fed4920 100644
--- a/src/dbnode/ts/segment.go
+++ b/src/dbnode/ts/segment.go
@@ -36,10 +36,6 @@ type Segment struct {
 	Head checked.Bytes
 	// Tail is the tail of the segment.
 	Tail checked.Bytes
-	// RawHead is the head of the segment.
-	RawHead []byte
-	// RawTail is the tail of the segment.
-	RawTail []byte
 	// SegmentFlags declares whether to finalize when finalizing the segment.
 	Flags SegmentFlags
 	// checksum is the checksum for the segment.
@@ -98,20 +94,6 @@ func NewSegment(
 	}
 }
 
-// NewRawSegment creates a new RawSegment.
-func NewRawSegment(
-	head, tail []byte,
-	checksum uint32,
-	flags SegmentFlags,
-) Segment {
-	return Segment{
-		RawHead:  head,
-		RawTail:  tail,
-		Flags:    flags,
-		checksum: checksum,
-	}
-}
-
 // Len returns the length of the head and tail.
 func (s *Segment) Len() int {
 	var total int
diff --git a/src/dbnode/x/xio/segment_reader.go b/src/dbnode/x/xio/segment_reader.go
index cdda51485c..352c8feeea 100644
--- a/src/dbnode/x/xio/segment_reader.go
+++ b/src/dbnode/x/xio/segment_reader.go
@@ -51,11 +51,11 @@ func (sr *segmentReader) Read(b []byte) (int, error) {
 		return 0, nil
 	}
 
-	if b := sr.segment.RawHead; b != nil && len(sr.lazyHead) == 0 {
-		sr.lazyHead = b
+	if b := sr.segment.Head; b != nil && len(sr.lazyHead) == 0 {
+		sr.lazyHead = b.Bytes()
 	}
-	if b := sr.segment.RawTail; b != nil && len(sr.lazyTail) == 0 {
-		sr.lazyTail = b
+	if b := sr.segment.Tail; b != nil && len(sr.lazyTail) == 0 {
+		sr.lazyTail = b.Bytes()
 	}
 
 	nh, nt := len(sr.lazyHead), len(sr.lazyTail)

From 701d39d0c6dc969c8359688adce276a1908f07bd Mon Sep 17 00:00:00 2001
From: Ryan Allen <rallen090@gmail.com>
Date: Wed, 11 Mar 2020 13:50:19 -0400
Subject: [PATCH 04/11] WIP 3

---
 src/dbnode/encoding/istream.go | 26 +++++++-------------------
 1 file changed, 7 insertions(+), 19 deletions(-)

diff --git a/src/dbnode/encoding/istream.go b/src/dbnode/encoding/istream.go
index 0ab3370847..fb5bedcb1f 100644
--- a/src/dbnode/encoding/istream.go
+++ b/src/dbnode/encoding/istream.go
@@ -100,8 +100,6 @@ func (is *istream) ReadBits(numBits int) (uint64, error) {
 		return 0, is.err
 	}
 
-	//var res uint64
-	//fmt.Println("NUM", numBits)
 	var res uint64
 	numBytes := numBits / 8
 	numBits = numBits % 8
@@ -111,25 +109,15 @@ func (is *istream) ReadBits(numBits int) (uint64, error) {
 		if err != nil {
 			return 0, err
 		}
-		// var res2 uint64
-		// for _, b := range fullBytes {
-		// 	res2 = (res2 << 8) | uint64(b)
-		// }
-		res = binary.BigEndian.Uint64(is.buffer)
-		// if res != res2 {
-		// 	panic(fmt.Sprintf("A %d %d", int(res), int(res2)))
-		// }
+		if numBytes == 8 {
+			res = binary.BigEndian.Uint64(fullBytes)
+		} else {
+			for _, b := range fullBytes {
+				res = (res << 8) | uint64(b)
+			}
+		}
 	}
 
-	// for numBits >= 8 {
-	// 	byteRead, err := is.ReadByte()
-	// 	if err != nil {
-	// 		return 0, err
-	// 	}
-	// 	res = (res << 8) | uint64(byteRead)
-	// 	numBits -= 8
-	// }
-
 	for numBits > 0 {
 		// This is equivalent to calling is.ReadBit() in a loop but some manual inlining
 		// has been performed to optimize this loop as its heavily used in the hot path.

From 7eeda348876eec622002b3edc646c7706d7a458e Mon Sep 17 00:00:00 2001
From: Ryan Allen <rallen090@gmail.com>
Date: Wed, 11 Mar 2020 14:03:35 -0400
Subject: [PATCH 05/11] WIP 4

---
 src/dbnode/encoding/istream.go | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/src/dbnode/encoding/istream.go b/src/dbnode/encoding/istream.go
index fb5bedcb1f..e1eebcb2bb 100644
--- a/src/dbnode/encoding/istream.go
+++ b/src/dbnode/encoding/istream.go
@@ -27,6 +27,10 @@ import (
 	"math"
 )
 
+const (
+	numBytesInInt64 = 8
+)
+
 // istream encapsulates a readable stream.
 type istream struct {
 	r         *bufio.Reader // encoded stream
@@ -38,7 +42,7 @@ type istream struct {
 
 // NewIStream creates a new Istream
 func NewIStream(reader io.Reader, bufioSize int) IStream {
-	return &istream{r: bufio.NewReaderSize(reader, bufioSize), buffer: make([]byte, 8, 8)}
+	return &istream{r: bufio.NewReaderSize(reader, bufioSize), buffer: make([]byte, numBytesInInt64, numBytesInInt64)}
 }
 
 // ReadBit reads the next Bit
@@ -104,15 +108,17 @@ func (is *istream) ReadBits(numBits int) (uint64, error) {
 	numBytes := numBits / 8
 	numBits = numBits % 8
 	if numBytes > 0 {
-		fullBytes := is.buffer[0:numBytes]
-		_, err := is.Read(fullBytes)
+		// Use Read call rather than individual ReadByte calls since it has
+		// optimized path for when the iterator is aligned on a byte boundary.
+		bytes := is.buffer[0:numBytes]
+		_, err := is.Read(bytes)
 		if err != nil {
 			return 0, err
 		}
-		if numBytes == 8 {
-			res = binary.BigEndian.Uint64(fullBytes)
+		if numBytes == numBytesInInt64 {
+			res = binary.BigEndian.Uint64(bytes)
 		} else {
-			for _, b := range fullBytes {
+			for _, b := range bytes {
 				res = (res << 8) | uint64(b)
 			}
 		}

From 2aeb9b5773c545048d84cffade0d5f362df90085 Mon Sep 17 00:00:00 2001
From: Ryan Allen <rallen090@gmail.com>
Date: Wed, 11 Mar 2020 14:04:41 -0400
Subject: [PATCH 06/11] WIP 5

---
 src/dbnode/encoding/istream.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/dbnode/encoding/istream.go b/src/dbnode/encoding/istream.go
index e1eebcb2bb..356be0de4a 100644
--- a/src/dbnode/encoding/istream.go
+++ b/src/dbnode/encoding/istream.go
@@ -111,11 +111,11 @@ func (is *istream) ReadBits(numBits int) (uint64, error) {
 		// Use Read call rather than individual ReadByte calls since it has
 		// optimized path for when the iterator is aligned on a byte boundary.
 		bytes := is.buffer[0:numBytes]
-		_, err := is.Read(bytes)
+		read, err := is.Read(bytes)
 		if err != nil {
 			return 0, err
 		}
-		if numBytes == numBytesInInt64 {
+		if read == numBytesInInt64 {
 			res = binary.BigEndian.Uint64(bytes)
 		} else {
 			for _, b := range bytes {

From d9e021c1758ccfb001acffce9e96d76040cc326e Mon Sep 17 00:00:00 2001
From: Ryan Allen <rallen090@gmail.com>
Date: Wed, 11 Mar 2020 14:39:05 -0400
Subject: [PATCH 07/11] Comment

---
 src/dbnode/encoding/istream.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/dbnode/encoding/istream.go b/src/dbnode/encoding/istream.go
index 356be0de4a..7dd325bb5f 100644
--- a/src/dbnode/encoding/istream.go
+++ b/src/dbnode/encoding/istream.go
@@ -36,7 +36,7 @@ type istream struct {
 	r         *bufio.Reader // encoded stream
 	err       error         // error encountered
 	current   byte          // current byte we are working off of
-	buffer    []byte        // current byte we are working off of
+	buffer    []byte        // buffer for reading in multiple bytes
 	remaining int           // bits remaining in current to be read
 }
 

From d2c9c98cf17cffa656841c8dd92e9b8f74d1c4f6 Mon Sep 17 00:00:00 2001
From: Ryan Allen <rallen090@gmail.com>
Date: Wed, 11 Mar 2020 15:43:29 -0400
Subject: [PATCH 08/11] Merged in master 2

---
 src/query/ts/m3db/encoded_step_iterator_test.go | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/query/ts/m3db/encoded_step_iterator_test.go b/src/query/ts/m3db/encoded_step_iterator_test.go
index 239f487653..02b7af1568 100644
--- a/src/query/ts/m3db/encoded_step_iterator_test.go
+++ b/src/query/ts/m3db/encoded_step_iterator_test.go
@@ -686,10 +686,13 @@ var (
 */
 func BenchmarkNextIteration(b *testing.B) {
 	iterTypes := []iterType{
+		stepSequential,
+		stepParallel,
 		seriesSequential,
+		seriesBatch,
 	}
 
-	for _, s := range []int{500} {
+	for _, s := range []int{10, 100, 200, 500, 1000, 2000} {
 		for _, t := range iterTypes {
 			name := t.name(fmt.Sprintf("%d", s))
 			b.Run(name, func(b *testing.B) {

From 04a60395e999ee0e3c056b6b7492ec0d7695dba0 Mon Sep 17 00:00:00 2001
From: Ryan Allen <rallen090@gmail.com>
Date: Wed, 11 Mar 2020 17:22:10 -0400
Subject: [PATCH 09/11] Feedback 1

---
 src/dbnode/encoding/istream.go | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/dbnode/encoding/istream.go b/src/dbnode/encoding/istream.go
index 01d9c7f5de..553d4d1e77 100644
--- a/src/dbnode/encoding/istream.go
+++ b/src/dbnode/encoding/istream.go
@@ -27,10 +27,6 @@ import (
 	"math"
 )
 
-const (
-	numBytesInInt64 = 8
-)
-
 // istream encapsulates a readable stream.
 type istream struct {
 	r         *bufio.Reader // encoded stream
@@ -42,7 +38,11 @@ type istream struct {
 
 // NewIStream creates a new Istream
 func NewIStream(reader io.Reader, bufioSize int) IStream {
-	return &istream{r: bufio.NewReaderSize(reader, bufioSize), buffer: make([]byte, numBytesInInt64, numBytesInInt64)}
+	return &istream{
+		r: bufio.NewReaderSize(reader, bufioSize),
+		// Buffer meant to hold uint64 size of bytes.
+		buffer: make([]byte, 8),
+	}
 }
 
 // ReadBit reads the next Bit
@@ -105,7 +105,6 @@ func (is *istream) ReadBits(numBits uint) (uint64, error) {
 	}
 	var res uint64
 	numBytes := numBits / 8
-	numBits = numBits % 8
 	if numBytes > 0 {
 		// Use Read call rather than individual ReadByte calls since it has
 		// optimized path for when the iterator is aligned on a byte boundary.
@@ -114,7 +113,7 @@ func (is *istream) ReadBits(numBits uint) (uint64, error) {
 		if err != nil {
 			return 0, err
 		}
-		if read == numBytesInInt64 {
+		if read == 8 {
 			res = binary.BigEndian.Uint64(bytes)
 		} else {
 			for _, b := range bytes {
@@ -123,6 +122,7 @@ func (is *istream) ReadBits(numBits uint) (uint64, error) {
 		}
 	}
 
+	numBits = numBits % 8
 	for numBits > 0 {
 		// This is equivalent to calling is.ReadBit() in a loop but some manual inlining
 		// has been performed to optimize this loop as its heavily used in the hot path.

From e93f3916fc34ec0f7bc0048fbc9586a41105a5cc Mon Sep 17 00:00:00 2001
From: Ryan Allen <rallen090@gmail.com>
Date: Mon, 16 Mar 2020 11:22:40 -0400
Subject: [PATCH 10/11] Inlining 8 byte conversion

---
 src/dbnode/encoding/istream.go | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/dbnode/encoding/istream.go b/src/dbnode/encoding/istream.go
index 553d4d1e77..c2017c7275 100644
--- a/src/dbnode/encoding/istream.go
+++ b/src/dbnode/encoding/istream.go
@@ -22,7 +22,6 @@ package encoding
 
 import (
 	"bufio"
-	"encoding/binary"
 	"io"
 	"math"
 )
@@ -114,7 +113,10 @@ func (is *istream) ReadBits(numBits uint) (uint64, error) {
 			return 0, err
 		}
 		if read == 8 {
-			res = binary.BigEndian.Uint64(bytes)
+			// Inlined copy of native code for performance: binary.BigEndian.Uint64(bytes).
+			_ = bytes[7]
+			res = uint64(bytes[7]) | uint64(bytes[6])<<8 | uint64(bytes[5])<<16 | uint64(bytes[4])<<24 |
+				uint64(bytes[3])<<32 | uint64(bytes[2])<<40 | uint64(bytes[1])<<48 | uint64(bytes[0])<<56
 		} else {
 			for _, b := range bytes {
 				res = (res << 8) | uint64(b)

From bd55766011d1839714a69ef7b465e607408a750d Mon Sep 17 00:00:00 2001
From: Ryan Allen <rallen090@gmail.com>
Date: Mon, 16 Mar 2020 14:08:24 -0400
Subject: [PATCH 11/11] Removing inlining

---
 src/dbnode/encoding/istream.go | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/src/dbnode/encoding/istream.go b/src/dbnode/encoding/istream.go
index c2017c7275..96de36345b 100644
--- a/src/dbnode/encoding/istream.go
+++ b/src/dbnode/encoding/istream.go
@@ -108,19 +108,12 @@ func (is *istream) ReadBits(numBits uint) (uint64, error) {
 		// Use Read call rather than individual ReadByte calls since it has
 		// optimized path for when the iterator is aligned on a byte boundary.
 		bytes := is.buffer[0:numBytes]
-		read, err := is.Read(bytes)
+		_, err := is.Read(bytes)
 		if err != nil {
 			return 0, err
 		}
-		if read == 8 {
-			// Inlined copy of native code for performance: binary.BigEndian.Uint64(bytes).
-			_ = bytes[7]
-			res = uint64(bytes[7]) | uint64(bytes[6])<<8 | uint64(bytes[5])<<16 | uint64(bytes[4])<<24 |
-				uint64(bytes[3])<<32 | uint64(bytes[2])<<40 | uint64(bytes[1])<<48 | uint64(bytes[0])<<56
-		} else {
-			for _, b := range bytes {
-				res = (res << 8) | uint64(b)
-			}
+		for _, b := range bytes {
+			res = (res << 8) | uint64(b)
 		}
 	}