Browse Source

raft: make Entry a protobuf type

Xiang Li 11 years ago
parent
commit
38ec659cd6
5 changed files with 269 additions and 17 deletions
  1. 243 0
      raft/entry.pb.go
  2. 15 0
      raft/entry.proto
  3. 0 7
      raft/log.go
  4. 5 4
      wal/wal.go
  5. 6 6
      wal/wal_test.go

+ 243 - 0
raft/entry.pb.go

@@ -0,0 +1,243 @@
+// Code generated by protoc-gen-gogo.
+// source: entry.proto
+// DO NOT EDIT!
+
+/*
+	Package raft is a generated protocol buffer package.
+
+	It is generated from these files:
+		entry.proto
+
+	It has these top-level messages:
+		Entry
+*/
+package raft
+
+import proto "code.google.com/p/gogoprotobuf/proto"
+import json "encoding/json"
+import math "math"
+
+// discarding unused import gogoproto "code.google.com/p/gogoprotobuf/gogoproto/gogo.pb"
+
+import io "io"
+import code_google_com_p_gogoprotobuf_proto "code.google.com/p/gogoprotobuf/proto"
+
+// Reference proto, json, and math imports to suppress error if they are not otherwise used.
+var _ = proto.Marshal
+var _ = &json.SyntaxError{}
+var _ = math.Inf
+
+type Entry struct {
+	Type             int64  `protobuf:"varint,1,req,name=type" json:"type"`
+	Term             int64  `protobuf:"varint,2,req,name=term" json:"term"`
+	Index            int64  `protobuf:"varint,3,req,name=index" json:"index"`
+	Data             []byte `protobuf:"bytes,4,opt,name=data" json:"data,omitempty"`
+	XXX_unrecognized []byte `json:"-"`
+}
+
+func (m *Entry) Reset()         { *m = Entry{} }
+func (m *Entry) String() string { return proto.CompactTextString(m) }
+func (*Entry) ProtoMessage()    {}
+
+func init() {
+}
+func (m *Entry) Unmarshal(data []byte) error {
+	l := len(data)
+	index := 0
+	for index < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if index >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := data[index]
+			index++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return code_google_com_p_gogoprotobuf_proto.ErrWrongType
+			}
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				m.Type |= (int64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 2:
+			if wireType != 0 {
+				return code_google_com_p_gogoprotobuf_proto.ErrWrongType
+			}
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				m.Term |= (int64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 3:
+			if wireType != 0 {
+				return code_google_com_p_gogoprotobuf_proto.ErrWrongType
+			}
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				m.Index |= (int64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 4:
+			if wireType != 2 {
+				return code_google_com_p_gogoprotobuf_proto.ErrWrongType
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			postIndex := index + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Data = append(m.Data, data[index:postIndex]...)
+			index = postIndex
+		default:
+			var sizeOfWire int
+			for {
+				sizeOfWire++
+				wire >>= 7
+				if wire == 0 {
+					break
+				}
+			}
+			index -= sizeOfWire
+			skippy, err := code_google_com_p_gogoprotobuf_proto.Skip(data[index:])
+			if err != nil {
+				return err
+			}
+			if (index + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...)
+			index += skippy
+		}
+	}
+	return nil
+}
+func (m *Entry) Size() (n int) {
+	var l int
+	_ = l
+	n += 1 + sovEntry(uint64(m.Type))
+	n += 1 + sovEntry(uint64(m.Term))
+	n += 1 + sovEntry(uint64(m.Index))
+	if m.Data != nil {
+		l = len(m.Data)
+		n += 1 + l + sovEntry(uint64(l))
+	}
+	if m.XXX_unrecognized != nil {
+		n += len(m.XXX_unrecognized)
+	}
+	return n
+}
+
+func sovEntry(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
+}
+func sozEntry(x uint64) (n int) {
+	return sovEntry(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *Entry) Marshal() (data []byte, err error) {
+	size := m.Size()
+	data = make([]byte, size)
+	n, err := m.MarshalTo(data)
+	if err != nil {
+		return nil, err
+	}
+	return data[:n], nil
+}
+
+func (m *Entry) MarshalTo(data []byte) (n int, err error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	data[i] = 0x8
+	i++
+	i = encodeVarintEntry(data, i, uint64(m.Type))
+	data[i] = 0x10
+	i++
+	i = encodeVarintEntry(data, i, uint64(m.Term))
+	data[i] = 0x18
+	i++
+	i = encodeVarintEntry(data, i, uint64(m.Index))
+	if m.Data != nil {
+		data[i] = 0x22
+		i++
+		i = encodeVarintEntry(data, i, uint64(len(m.Data)))
+		i += copy(data[i:], m.Data)
+	}
+	if m.XXX_unrecognized != nil {
+		i += copy(data[i:], m.XXX_unrecognized)
+	}
+	return i, nil
+}
+func encodeFixed64Entry(data []byte, offset int, v uint64) int {
+	data[offset] = uint8(v)
+	data[offset+1] = uint8(v >> 8)
+	data[offset+2] = uint8(v >> 16)
+	data[offset+3] = uint8(v >> 24)
+	data[offset+4] = uint8(v >> 32)
+	data[offset+5] = uint8(v >> 40)
+	data[offset+6] = uint8(v >> 48)
+	data[offset+7] = uint8(v >> 56)
+	return offset + 8
+}
+func encodeFixed32Entry(data []byte, offset int, v uint32) int {
+	data[offset] = uint8(v)
+	data[offset+1] = uint8(v >> 8)
+	data[offset+2] = uint8(v >> 16)
+	data[offset+3] = uint8(v >> 24)
+	return offset + 4
+}
+func encodeVarintEntry(data []byte, offset int, v uint64) int {
+	for v >= 1<<7 {
+		data[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	data[offset] = uint8(v)
+	return offset + 1
+}

+ 15 - 0
raft/entry.proto

@@ -0,0 +1,15 @@
+package raft;
+
+import "code.google.com/p/gogoprotobuf/gogoproto/gogo.proto";
+
+option (gogoproto.marshaler_all) = true;
+option (gogoproto.sizer_all) = true;
+option (gogoproto.unmarshaler_all) = true;
+option (gogoproto.goproto_getters_all) = false;
+
+message Entry {
+	required int64 type  = 1 [(gogoproto.nullable) = false];
+	required int64 term  = 2 [(gogoproto.nullable) = false];
+	required int64 index = 3 [(gogoproto.nullable) = false];
+	optional bytes data  = 4;
+}

+ 0 - 7
raft/log.go

@@ -14,13 +14,6 @@ const (
 	defaultCompactThreshold = 10000
 )
 
-type Entry struct {
-	Type  int64
-	Term  int64
-	Index int64
-	Data  []byte
-}
-
 func (e *Entry) isConfig() bool {
 	return e.Type == AddNode || e.Type == RemoveNode
 }

+ 5 - 4
wal/wal.go

@@ -20,7 +20,6 @@ import (
 	"bufio"
 	"bytes"
 	"encoding/binary"
-	"encoding/json"
 	"fmt"
 	"io"
 	"os"
@@ -92,8 +91,7 @@ func (w *WAL) SaveInfo(id int64) error {
 }
 
 func (w *WAL) SaveEntry(e *raft.Entry) error {
-	// protobuf?
-	b, err := json.Marshal(e)
+	b, err := e.Marshal()
 	if err != nil {
 		panic(err)
 	}
@@ -181,7 +179,10 @@ func loadInfo(d []byte) (int64, error) {
 
 func loadEntry(d []byte) (raft.Entry, error) {
 	var e raft.Entry
-	err := json.Unmarshal(d, &e)
+	err := e.Unmarshal(d)
+	if err != nil {
+		panic(err)
+	}
 	return e, err
 }
 

+ 6 - 6
wal/wal_test.go

@@ -33,8 +33,8 @@ var (
 	stateData  = []byte("\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00")
 	stateBlock = append([]byte("\x03\x00\x00\x00\x00\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00"), stateData...)
 
-	entryJsonData = []byte("{\"Type\":1,\"Term\":1,\"Data\":\"AQ==\"}")
-	entryBlock    = append([]byte("\x02\x00\x00\x00\x00\x00\x00\x00\x21\x00\x00\x00\x00\x00\x00\x00"), entryJsonData...)
+	entryData  = []byte("\b\x01\x10\x01\x18\x01\x22\x01\x01")
+	entryBlock = append([]byte("\x02\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00"), entryData...)
 )
 
 func TestNew(t *testing.T) {
@@ -68,7 +68,7 @@ func TestSaveEntry(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	e := &raft.Entry{1, 1, []byte{1}}
+	e := &raft.Entry{Type: 1, Index: 1, Term: 1, Data: []byte{1}}
 	err = w.SaveEntry(e)
 	if err != nil {
 		t.Fatal(err)
@@ -168,11 +168,11 @@ func TestLoadInfo(t *testing.T) {
 }
 
 func TestLoadEntry(t *testing.T) {
-	e, err := loadEntry(entryJsonData)
+	e, err := loadEntry(entryData)
 	if err != nil {
 		t.Fatal(err)
 	}
-	we := raft.Entry{1, 1, []byte{1}}
+	we := raft.Entry{Type: 1, Index: 1, Term: 1, Data: []byte{1}}
 	if !reflect.DeepEqual(e, we) {
 		t.Errorf("ent = %v, want %v", e, we)
 	}
@@ -199,7 +199,7 @@ func TestLoadNode(t *testing.T) {
 	if err = w.SaveInfo(id); err != nil {
 		t.Fatal(err)
 	}
-	ents := []raft.Entry{{1, 1, []byte{1}}, {2, 2, []byte{2}}}
+	ents := []raft.Entry{{Type: 1, Index: 1, Term: 1, Data: []byte{1}}, {Type: 2, Index: 2, Term: 2, Data: []byte{2}}}
 	for _, e := range ents {
 		if err = w.SaveEntry(&e); err != nil {
 			t.Fatal(err)