Browse Source

wal: reduce allocation when encoding entries

Xiang Li 10 years ago
parent
commit
c32cca3a4f
2 changed files with 22 additions and 3 deletions
  1. 21 3
      wal/encoder.go
  2. 1 0
      wal/wal.go

+ 21 - 3
wal/encoder.go

@@ -30,12 +30,15 @@ type encoder struct {
 	bw *bufio.Writer
 	bw *bufio.Writer
 
 
 	crc hash.Hash32
 	crc hash.Hash32
+	buf []byte
 }
 }
 
 
 func newEncoder(w io.Writer, prevCrc uint32) *encoder {
 func newEncoder(w io.Writer, prevCrc uint32) *encoder {
 	return &encoder{
 	return &encoder{
 		bw:  bufio.NewWriter(w),
 		bw:  bufio.NewWriter(w),
 		crc: crc.New(prevCrc, crcTable),
 		crc: crc.New(prevCrc, crcTable),
+		// 1MB buffer
+		buf: make([]byte, 1024*1024),
 	}
 	}
 }
 }
 
 
@@ -45,9 +48,23 @@ func (e *encoder) encode(rec *walpb.Record) error {
 
 
 	e.crc.Write(rec.Data)
 	e.crc.Write(rec.Data)
 	rec.Crc = e.crc.Sum32()
 	rec.Crc = e.crc.Sum32()
-	data, err := rec.Marshal()
-	if err != nil {
-		return err
+	var (
+		data []byte
+		err  error
+		n    int
+	)
+
+	if rec.Size() > len(e.buf) {
+		data, err = rec.Marshal()
+		if err != nil {
+			return err
+		}
+	} else {
+		n, err = rec.MarshalTo(e.buf)
+		if err != nil {
+			return err
+		}
+		data = e.buf[:n]
 	}
 	}
 	if err := writeInt64(e.bw, int64(len(data))); err != nil {
 	if err := writeInt64(e.bw, int64(len(data))); err != nil {
 		return err
 		return err
@@ -63,5 +80,6 @@ func (e *encoder) flush() error {
 }
 }
 
 
 func writeInt64(w io.Writer, n int64) error {
 func writeInt64(w io.Writer, n int64) error {
+	// TODO: use putuint64 to reduce two alloctions
 	return binary.Write(w, binary.LittleEndian, n)
 	return binary.Write(w, binary.LittleEndian, n)
 }
 }

+ 1 - 0
wal/wal.go

@@ -387,6 +387,7 @@ func (w *WAL) Close() error {
 }
 }
 
 
 func (w *WAL) saveEntry(e *raftpb.Entry) error {
 func (w *WAL) saveEntry(e *raftpb.Entry) error {
+	// TODO: add MustMarshalTo to reduce one allocation.
 	b := pbutil.MustMarshal(e)
 	b := pbutil.MustMarshal(e)
 	rec := &walpb.Record{Type: entryType, Data: b}
 	rec := &walpb.Record{Type: entryType, Data: b}
 	if err := w.encoder.encode(rec); err != nil {
 	if err := w.encoder.encode(rec); err != nil {