Skip to content

Commit

Permalink
Add encoding stdlib interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
Shaptic committed May 12, 2022
1 parent ffa5923 commit d65c6b3
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 39 deletions.
103 changes: 65 additions & 38 deletions exp/lighthorizon/index/trie.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package index

import (
"bufio"
"encoding"
"io"
"sync"

Expand Down Expand Up @@ -224,20 +225,48 @@ func (i *TrieIndex) Merge(other *TrieIndex) error {
return nil
}

func (i *TrieIndex) ReadFrom(r io.Reader) (int64, error) {
i.Lock()
defer i.Unlock()
func (i *TrieIndex) MarshalBinary() ([]byte, error) {
i.RLock()
defer i.RUnlock()

br := bufio.NewReader(r)
bytes, err := io.ReadAll(br)
xdrRoot := xdr.TrieNode{}

// Apparently this is possible?
if i.Root != nil {
xdrRoot.Prefix = i.Root.Prefix
xdrRoot.Value = i.Root.Value
xdrRoot.Children = make([]xdr.TrieNodeChild, 0, len(i.Root.Children))

for key, node := range i.Root.Children {
buildXdrTrie(key, node, &xdrRoot)
}
}

xdrIndex := xdr.TrieIndex{Version: TrieIndexVersion, Root: xdrRoot}
return xdrIndex.MarshalBinary()
}

func (i *TrieIndex) WriteTo(w io.Writer) (int64, error) {
i.RLock()
defer i.RUnlock()

bytes, err := i.MarshalBinary()
if err != nil {
return int64(len(bytes)), err
}

count, err := w.Write(bytes)
return int64(count), err
}

func (i *TrieIndex) UnmarshalBinary(bytes []byte) error {
i.RLock()
defer i.RUnlock()

xdrIndex := xdr.TrieIndex{}
err = xdrIndex.UnmarshalBinary(bytes)
err := xdrIndex.UnmarshalBinary(bytes)
if err != nil {
return int64(len(bytes)), err
return err
}

i.Root = &trieNode{
Expand All @@ -250,9 +279,28 @@ func (i *TrieIndex) ReadFrom(r io.Reader) (int64, error) {
buildTrie(&node, i.Root)
}

return int64(len(bytes)), nil
return nil
}

func (i *TrieIndex) ReadFrom(r io.Reader) (int64, error) {
i.RLock()
defer i.RUnlock()

br := bufio.NewReader(r)
bytes, err := io.ReadAll(br)
if err != nil {
return int64(len(bytes)), err
}

return int64(len(bytes)), i.UnmarshalBinary(bytes)
}

// buildTrie recursively builds the equivalent `TrieNode` structure from raw
// XDR, creating the key->value child mapping from the flat list of children.
// Here, `xdrNode` is the node we're processing and `parent` is its non-XDR
// parent (i.e. the parent was already converted from XDR).
//
// This is the opposite of buildXdrTrie.
func buildTrie(xdrNode *xdr.TrieNodeChild, parent *trieNode) {
node := &trieNode{
Prefix: xdrNode.Node.Prefix,
Expand All @@ -266,36 +314,12 @@ func buildTrie(xdrNode *xdr.TrieNodeChild, parent *trieNode) {
}
}

func (i *TrieIndex) WriteTo(w io.Writer) (int64, error) {
i.RLock()
defer i.RUnlock()

xdrRoot := xdr.TrieNode{}

// Apparently this is possible?
if i.Root != nil {
xdrRoot.Prefix = i.Root.Prefix
xdrRoot.Value = i.Root.Value
xdrRoot.Children = make([]xdr.TrieNodeChild, 0, len(i.Root.Children))

for key, node := range i.Root.Children {
buildXdrTrie(key, node, &xdrRoot)
}
}

xdrIndex := xdr.TrieIndex{Version: TrieIndexVersion, Root: xdrRoot}
bytes, err := xdrIndex.MarshalBinary()
if err != nil {
return int64(len(bytes)), err
}

count, err := w.Write(bytes)
return int64(count), err
}

// Recursively builds the XDR-equivalent Trie structure, where `i` is the node
// we're converting and `parent` is the already-converted parent. That is, the
// non-XDR version of `parent` should have had (`key`, `i`) as a child.
// buildXdrTrie recursively builds the XDR-equivalent TrieNode structure, where
// `i` is the node we're converting and `parent` is the already-converted
// parent. That is, the non-XDR version of `parent` should have had (`key`, `i`)
// as a child.
//
// This is the opposite of buildTrie.
func buildXdrTrie(key byte, node *trieNode, parent *xdr.TrieNode) {
self := xdr.TrieNode{
Prefix: node.Prefix,
Expand All @@ -316,3 +340,6 @@ func buildXdrTrie(key byte, node *trieNode, parent *xdr.TrieNode) {
// Ensure we're compatible with stdlib interfaces.
var _ io.WriterTo = &TrieIndex{}
var _ io.ReaderFrom = &TrieIndex{}

var _ encoding.BinaryMarshaler = &TrieIndex{}
var _ encoding.BinaryUnmarshaler = &TrieIndex{}
2 changes: 1 addition & 1 deletion exp/lighthorizon/index/xdr/xdr_generated.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"fmt"
"io"

"github.com/stellar/go-xdr/xdr3"
xdr "github.com/stellar/go-xdr/xdr3"
)

type xdrType interface {
Expand Down

0 comments on commit d65c6b3

Please sign in to comment.