Skip to content

Commit b56cf04

Browse files
committed
geerpc init project, add feature: decode & encode args, reply
1 parent 4aa0663 commit b56cf04

File tree

13 files changed

+594
-0
lines changed

13 files changed

+594
-0
lines changed

gee-bolt/day2-mmap/db.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package geebolt
2+
3+
import "os"
4+
5+
type DB struct {
6+
data []byte
7+
file *os.File
8+
}
9+
10+
const maxMapSize = 1 << 31
11+
12+
func (db *DB) mmap(sz int) error {
13+
b, err := syscall.Mmap()
14+
}
15+
16+
func Open(path string) {
17+
18+
}

gee-bolt/day2-mmap/go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module geebolt
2+
3+
go 1.13

gee-bolt/day3-tree/go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module geebolt
2+
3+
go 1.13

gee-bolt/day3-tree/meta.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package geebolt
2+
3+
import (
4+
"errors"
5+
"hash/fnv"
6+
"unsafe"
7+
)
8+
9+
// Represent a marker value to indicate that a file is a gee-bolt DB
10+
const magic uint32 = 0xED0CDAED
11+
12+
type meta struct {
13+
magic uint32
14+
pageSize uint32
15+
pgid uint64
16+
checksum uint64
17+
}
18+
19+
func (m *meta) sum64() uint64 {
20+
var h = fnv.New64a()
21+
_, _ = h.Write((*[unsafe.Offsetof(meta{}.checksum)]byte)(unsafe.Pointer(m))[:])
22+
return h.Sum64()
23+
}
24+
25+
func (m *meta) validate() error {
26+
if m.magic != magic {
27+
return errors.New("invalid magic number")
28+
}
29+
if m.checksum != m.sum64() {
30+
return errors.New("invalid checksum")
31+
}
32+
return nil
33+
}

gee-bolt/day3-tree/node.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package geebolt
2+
3+
import (
4+
"bytes"
5+
"sort"
6+
)
7+
8+
type kv struct {
9+
key []byte
10+
value []byte
11+
}
12+
13+
type node struct {
14+
isLeaf bool
15+
key []byte
16+
parent *node
17+
children []*node
18+
kvs []kv
19+
}
20+
21+
func (n *node) root() *node {
22+
if n.parent == nil {
23+
return n
24+
}
25+
return n.parent.root()
26+
}
27+
28+
func (n *node) index(key []byte) (index int, exact bool) {
29+
index = sort.Search(len(n.kvs), func(i int) bool {
30+
return bytes.Compare(n.kvs[i].key, key) != -1
31+
})
32+
exact = len(n.kvs) > 0 && index < len(n.kvs) && bytes.Equal(n.kvs[index].key, key)
33+
return
34+
}
35+
36+
func (n *node) put(oldKey, newKey, value []byte) {
37+
index, exact := n.index(oldKey)
38+
if !exact {
39+
n.kvs = append(n.kvs, kv{})
40+
copy(n.kvs[index+1:], n.kvs[index:])
41+
}
42+
kv := &n.kvs[index]
43+
kv.key = newKey
44+
kv.value = value
45+
}
46+
47+
func (n *node) del(key []byte) {
48+
index, exact := n.index(key)
49+
if exact {
50+
n.kvs = append(n.kvs[:index], n.kvs[index+1:]...)
51+
}
52+
}
53+

gee-bolt/day3-tree/page.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package geebolt
2+
3+
import (
4+
"fmt"
5+
"reflect"
6+
"unsafe"
7+
)
8+
9+
const pageHeaderSize = unsafe.Sizeof(page{})
10+
const branchPageElementSize = unsafe.Sizeof(branchPageElement{})
11+
const leafPageElementSize = unsafe.Sizeof(leafPageElement{})
12+
const maxKeysPerPage = 1024
13+
14+
const (
15+
branchPageFlag uint16 = iota
16+
leafPageFlag
17+
metaPageFlag
18+
freelistPageFlag
19+
)
20+
21+
type page struct {
22+
id uint64
23+
flags uint16
24+
count uint16
25+
overflow uint32
26+
}
27+
28+
type leafPageElement struct {
29+
pos uint32
30+
ksize uint32
31+
vsize uint32
32+
}
33+
34+
type branchPageElement struct {
35+
pos uint32
36+
ksize uint32
37+
pgid uint64
38+
}
39+
40+
func (p *page) typ() string {
41+
switch p.flags {
42+
case branchPageFlag:
43+
return "branch"
44+
case leafPageFlag:
45+
return "leaf"
46+
case metaPageFlag:
47+
return "meta"
48+
case freelistPageFlag:
49+
return "freelist"
50+
}
51+
return fmt.Sprintf("unknown<%02x>", p.flags)
52+
}
53+
54+
func (p *page) meta() *meta {
55+
return (*meta)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + pageHeaderSize))
56+
}
57+
58+
func (p *page) dataPtr() unsafe.Pointer {
59+
return unsafe.Pointer(&reflect.SliceHeader{
60+
Data: uintptr(unsafe.Pointer(p)) + pageHeaderSize,
61+
Len: int(p.count),
62+
Cap: int(p.count),
63+
})
64+
}
65+
66+
func (p *page) leafPageElement(index uint16) *leafPageElement {
67+
off := pageHeaderSize + uintptr(index)*leafPageElementSize
68+
return (*leafPageElement)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + off))
69+
}
70+
71+
func (p *page) leafPageElements() []leafPageElement {
72+
if p.count == 0 {
73+
return nil
74+
}
75+
return *(*[]leafPageElement)(p.dataPtr())
76+
}
77+
78+
func (p *page) branchPageElement(index uint16) *branchPageElement {
79+
off := pageHeaderSize + uintptr(index)*branchPageElementSize
80+
return (*branchPageElement)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + off))
81+
}
82+
83+
func (p *page) branchPageElements() []branchPageElement {
84+
if p.count == 0 {
85+
return nil
86+
}
87+
return *(*[]branchPageElement)(p.dataPtr())
88+
}

gee-rpc/day1-encode/go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module geerpc
2+
3+
go 1.13

gee-rpc/day1-encode/protocol/codec.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package protocol
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
)
7+
8+
type Codec interface {
9+
Encode(i interface{}) ([]byte, error)
10+
Decode(data []byte, i interface{}) error
11+
}
12+
13+
// JSONCodec uses json marshaler and unmarshaler.
14+
type JSONCodec struct{}
15+
16+
// Encode encodes an object into slice of bytes.
17+
func (c JSONCodec) Encode(i interface{}) ([]byte, error) {
18+
return json.Marshal(i)
19+
}
20+
21+
// Decode decodes an object from slice of bytes.
22+
func (c JSONCodec) Decode(data []byte, i interface{}) error {
23+
d := json.NewDecoder(bytes.NewBuffer(data))
24+
d.UseNumber()
25+
return d.Decode(i)
26+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package protocol
2+
3+
import (
4+
"bytes"
5+
"encoding/binary"
6+
"fmt"
7+
"io"
8+
"strings"
9+
)
10+
11+
const MagicNumber int32 = 0xECABCD
12+
13+
type SerializeType int8
14+
15+
const (
16+
JSON SerializeType = iota
17+
)
18+
19+
var Codecs = map[SerializeType]Codec{
20+
JSON: &JSONCodec{},
21+
}
22+
23+
type Status int8
24+
25+
const (
26+
OK Status = iota
27+
ExecError
28+
NotFoundError
29+
)
30+
31+
type Header struct {
32+
Magic int32
33+
Status Status
34+
SerializeType SerializeType
35+
ServiceMethodSize int32
36+
PayloadSize int32
37+
}
38+
39+
type Message struct {
40+
*Header
41+
ServiceMethod string
42+
Payload []byte
43+
}
44+
45+
func NewMessage() *Message {
46+
return &Message{
47+
Header: &Header{Magic: MagicNumber},
48+
}
49+
}
50+
51+
func (m *Message) HandleError(status Status, err error) *Message {
52+
m.Status = status
53+
_ = m.SetPayload(err)
54+
return m
55+
}
56+
57+
func (m *Message) SetServiceMethod(name string) {
58+
m.ServiceMethod = name
59+
}
60+
61+
func (m *Message) GetServiceMethod() (service, method string, err error) {
62+
parts := strings.Split(m.ServiceMethod, ".")
63+
if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
64+
return "", "", fmt.Errorf("<service.method> format error")
65+
}
66+
return parts[0], parts[1], nil
67+
}
68+
69+
func (m *Message) GetPayload(i interface{}) error {
70+
return Codecs[m.SerializeType].Decode(m.Payload, i)
71+
}
72+
73+
func (m *Message) SetPayload(i interface{}) (err error) {
74+
m.Payload, err = Codecs[m.SerializeType].Encode(i)
75+
return
76+
}
77+
78+
func (m *Message) Clone() *Message {
79+
m2 := NewMessage()
80+
*m2.Header = *m.Header
81+
m2.ServiceMethod = m.ServiceMethod
82+
return m2
83+
}
84+
func Read(r io.Reader) (*Message, error) {
85+
m := NewMessage()
86+
if err := binary.Read(r, binary.BigEndian, m.Header); err != nil {
87+
return nil, err
88+
}
89+
if m.Magic != MagicNumber {
90+
return nil, fmt.Errorf("invalid message: wrong magic number")
91+
}
92+
93+
buf := make([]byte, m.ServiceMethodSize+m.PayloadSize)
94+
if err := binary.Read(r, binary.BigEndian, buf); err != nil {
95+
return nil, err
96+
}
97+
m.ServiceMethod = string(buf[:m.ServiceMethodSize])
98+
m.Payload = buf[m.ServiceMethodSize:]
99+
return m, nil
100+
}
101+
func (m *Message) Write(w io.Writer) error {
102+
m.PayloadSize = int32(len(m.Payload))
103+
m.ServiceMethodSize = int32(len(m.ServiceMethod))
104+
buf := bytes.NewBufferString(m.ServiceMethod)
105+
buf.Write(m.Payload)
106+
if err := binary.Write(w, binary.BigEndian, m.Header); err != nil {
107+
return err
108+
}
109+
if err := binary.Write(w, binary.BigEndian, buf.Bytes()); err != nil {
110+
return err
111+
}
112+
return nil
113+
}

gee-rpc/day1-encode/protocol/path.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package protocol
2+
3+
const DefaultRPCPath = "/_geerpc"

0 commit comments

Comments
 (0)