~whereswaldon/forest-go

bc84a589753cc08c8bdaa8f9319e9f58470dba93 — Chris Waldon 2 years ago 2a1e177
Start implmenting in-memory node store

The Store is a glorified Map that persists Nodes. The goal with the
Store interface is to be implementable both as a memory-backed storage
and a file-backed storage.

Creating it led me to also create the
Node interface that gathers operations that all node types support.
The Node interface is missing a few methods right now, but they'll
be added as they are needed.
3 files changed, 101 insertions(+), 3 deletions(-)

M nodes.go
A store.go
A store_test.go
M nodes.go => nodes.go +25 -3
@@ 7,6 7,12 @@ import (
	"git.sr.ht/~whereswaldon/forest-go/fields"
)

type Node interface {
	ID() *fields.QualifiedHash
	ParentID() *fields.QualifiedHash
	Equals(interface{}) bool
}

// NodeTypeOf returns the NodeType of the provided binary-marshaled node.
// If the provided bytes are not a forest node or the type cannot be determined,
// an error will be returned and the first return value must be ignored.


@@ 76,6 82,10 @@ func (n commonNode) ID() *fields.QualifiedHash {
	}
}

func (n commonNode) ParentID() *fields.QualifiedHash {
	return &fields.QualifiedHash{n.Parent.Descriptor, n.Parent.Value}
}

func (n *commonNode) presignSerializationOrder() []fields.BidirectionalBinaryMarshaler {
	order := []fields.BidirectionalBinaryMarshaler{
		&n.SchemaVersion,


@@ 208,7 218,11 @@ func (i *Identity) UnmarshalBinary(b []byte) error {
	return nil
}

func (i *Identity) Equals(i2 *Identity) bool {
func (i *Identity) Equals(other interface{}) bool {
	i2, valid := other.(*Identity)
	if !valid {
		return false
	}
	return i.commonNode.Equals(&i2.commonNode) &&
		i.Name.Equals(&i2.Name) &&
		i.PublicKey.Equals(&i2.PublicKey)


@@ 280,7 294,11 @@ func (c *Community) UnmarshalBinary(b []byte) error {
	return nil
}

func (c *Community) Equals(c2 *Community) bool {
func (c *Community) Equals(other interface{}) bool {
	c2, valid := other.(*Community)
	if !valid {
		return false
	}
	return c.commonNode.Equals(&c2.commonNode) &&
		c.Name.Equals(&c2.Name)
}


@@ 353,7 371,11 @@ func (r *Reply) UnmarshalBinary(b []byte) error {
	return nil
}

func (r *Reply) Equals(r2 *Reply) bool {
func (r *Reply) Equals(other interface{}) bool {
	r2, valid := other.(*Reply)
	if !valid {
		return false
	}
	return r.commonNode.Equals(&r2.commonNode) &&
		r.Content.Equals(&r2.Content)
}

A store.go => store.go +33 -0
@@ 0,0 1,33 @@
package forest

import "git.sr.ht/~whereswaldon/forest-go/fields"

type Store interface {
	Size() (int, error)
	Has(*fields.QualifiedHash) (bool, error)
	Get(*fields.QualifiedHash) (Node, error)
	Add(Node) error
}

type MemoryStore struct {
}

func NewMemoryStore() *MemoryStore {
	return &MemoryStore{}
}

func (m *MemoryStore) Size() (int, error) {
	return 0, nil
}

func (m *MemoryStore) Has(id *fields.QualifiedHash) (bool, error) {
	return false, nil
}

func (m *MemoryStore) Get(id *fields.QualifiedHash) (Node, error) {
	return nil, nil
}

func (m *MemoryStore) Add(node Node) error {
	return nil
}

A store_test.go => store_test.go +43 -0
@@ 0,0 1,43 @@
package forest_test

import (
	"testing"

	"git.sr.ht/~whereswaldon/forest-go"
)

func TestMemoryStoreAdd(t *testing.T) {
	s := forest.NewMemoryStore()
	if size, err := s.Size(); size != 0 {
		t.Errorf("Expected new store to have size 0, had %d", size)
	} else if err != nil {
		t.Errorf("Expected new store Size() to succeed, failed with %s", err)
	}
	id, _, com, rep := MakeReplyOrSkip(t)
	nodes := []forest.Node{id, com, rep}
	for _, i := range nodes {
		if has, err := s.Has(i.ID()); has {
			t.Errorf("Empty store should not contain element %v", i.ID())
		} else if err != nil {
			t.Errorf("Empty store Has() should not err with %s", err)
		}
		if _, err := s.Get(i.ID()); err == nil {
			t.Errorf("Empty store Get() should err")
		}
	}
	for _, i := range nodes {
		if err := s.Add(i); err != nil {
			t.Errorf("MemoryStore Add() should not err on Add(): %s", err)
		}
		if has, err := s.Has(i.ID()); !has {
			t.Errorf("MemoryStore should contain element %v", i.ID())
		} else if err != nil {
			t.Errorf("MemoryStore Has() should not err with %s", err)
		}
		if node, err := s.Get(i.ID()); err != nil {
			t.Errorf("MemoryStore Get() should not err with %s", err)
		} else if !i.Equals(node) {
			t.Errorf("MemoryStore Get() should return a node equal to the one that was Add()ed. Got %v, expected %v", node, i)
		}
	}
}