Commit 4e0fea7b authored by hannahhoward's avatar hannahhoward

refactor(metadata): convert to array structure

parent 567b71a7
......@@ -5,9 +5,15 @@ import (
"github.com/ipld/go-ipld-prime"
)
// Item is a single link traversed in a repsonse
type Item struct {
Link ipld.Link
BlockPresent bool
}
// Metadata is information about metadata contained in a response, which can be
// serialized back and forth to bytes
type Metadata map[ipld.Link]bool
type Metadata []Item
// DecodeMetadata assembles metadata from a raw byte array, first deserializing
// as a node and then assembling into a metadata struct.
......@@ -18,12 +24,16 @@ func DecodeMetadata(data []byte, ipldBridge ipldbridge.IPLDBridge) (Metadata, er
}
decodedData, err := ipldBridge.ExtractData(node, func(simpleNode ipldbridge.SimpleNode) interface{} {
iterator := simpleNode.ListIterator()
metadata := make(Metadata)
var metadata Metadata
if simpleNode.Length() != -1 {
metadata = make(Metadata, 0, simpleNode.Length())
}
for !iterator.Done() {
_, item := iterator.Next()
link := item.TraverseField("link").AsLink()
blockPresent := item.TraverseField("blockPresent").AsBool()
metadata[link] = blockPresent
metadata = append(metadata, Item{link, blockPresent})
}
return metadata
})
......@@ -37,11 +47,11 @@ func DecodeMetadata(data []byte, ipldBridge ipldbridge.IPLDBridge) (Metadata, er
func EncodeMetadata(entries Metadata, ipldBridge ipldbridge.IPLDBridge) ([]byte, error) {
node, err := ipldBridge.BuildNode(func(nb ipldbridge.NodeBuilder) ipld.Node {
return nb.CreateList(func(lb ipldbridge.ListBuilder, nb ipldbridge.NodeBuilder) {
for link, blockPresent := range entries {
for _, item := range entries {
lb.Append(
nb.CreateMap(func(mb ipldbridge.MapBuilder, knb ipldbridge.NodeBuilder, vnb ipldbridge.NodeBuilder) {
mb.Insert(knb.CreateString("link"), vnb.CreateLink(link))
mb.Insert(knb.CreateString("blockPresent"), vnb.CreateBool(blockPresent))
mb.Insert(knb.CreateString("link"), vnb.CreateLink(item.Link))
mb.Insert(knb.CreateString("blockPresent"), vnb.CreateBool(item.BlockPresent))
}),
)
}
......
......@@ -14,11 +14,11 @@ import (
func TestDecodeEncodeMetadata(t *testing.T) {
cids := testutil.GenerateCids(10)
initialMetadata := make(Metadata)
initialMetadata := make(Metadata, 0, 10)
for _, k := range cids {
link := cidlink.Link{Cid: k}
blockPresent := rand.Int31()%2 == 0
initialMetadata[link] = blockPresent
initialMetadata = append(initialMetadata, Item{link, blockPresent})
}
bridge := testbridge.NewMockIPLDBridge()
encoded, err := EncodeMetadata(initialMetadata, bridge)
......
......@@ -33,12 +33,7 @@ func (rb *ResponseBuilder) AddBlock(block blocks.Block) {
// AddLink adds the given link and whether its block is present
// to the response for the given request ID.
func (rb *ResponseBuilder) AddLink(requestID gsmsg.GraphSyncRequestID, link ipld.Link, blockPresent bool) {
linksForRequest, ok := rb.outgoingResponses[requestID]
if !ok {
linksForRequest = make(map[ipld.Link]bool)
rb.outgoingResponses[requestID] = linksForRequest
}
linksForRequest[link] = blockPresent
rb.outgoingResponses[requestID] = append(rb.outgoingResponses[requestID], metadata.Item{Link: link, BlockPresent: blockPresent})
}
// AddCompletedRequest marks the given request as completed in the response,
......@@ -49,7 +44,7 @@ func (rb *ResponseBuilder) AddCompletedRequest(requestID gsmsg.GraphSyncRequestI
// make sure this completion goes out in next response even if no links are sent
_, ok := rb.outgoingResponses[requestID]
if !ok {
rb.outgoingResponses[requestID] = make(map[ipld.Link]bool)
rb.outgoingResponses[requestID] = nil
}
}
......
......@@ -35,6 +35,7 @@ func TestMessageBuilding(t *testing.T) {
rb.AddLink(requestID2, links[1], true)
rb.AddLink(requestID2, links[2], true)
rb.AddLink(requestID2, links[1], true)
rb.AddCompletedRequest(requestID2, gsmsg.RequestCompletedFull)
......@@ -64,9 +65,9 @@ func TestMessageBuilding(t *testing.T) {
response1Metadata, err := metadata.DecodeMetadata(response1.Extra(), ipldBridge)
if err != nil || !reflect.DeepEqual(response1Metadata, metadata.Metadata{
links[0]: true,
links[1]: false,
links[2]: true,
metadata.Item{Link: links[0], BlockPresent: true},
metadata.Item{Link: links[1], BlockPresent: false},
metadata.Item{Link: links[2], BlockPresent: true},
}) {
t.Fatal("Metadata did not match expected")
}
......@@ -77,8 +78,9 @@ func TestMessageBuilding(t *testing.T) {
}
response2Metadata, err := metadata.DecodeMetadata(response2.Extra(), ipldBridge)
if err != nil || !reflect.DeepEqual(response2Metadata, metadata.Metadata{
links[1]: true,
links[2]: true,
metadata.Item{Link: links[1], BlockPresent: true},
metadata.Item{Link: links[2], BlockPresent: true},
metadata.Item{Link: links[1], BlockPresent: true},
}) {
t.Fatal("Metadata did not match expected")
}
......@@ -89,8 +91,8 @@ func TestMessageBuilding(t *testing.T) {
}
response3Metadata, err := metadata.DecodeMetadata(response3.Extra(), ipldBridge)
if err != nil || !reflect.DeepEqual(response3Metadata, metadata.Metadata{
links[0]: true,
links[1]: true,
metadata.Item{Link: links[0], BlockPresent: true},
metadata.Item{Link: links[1], BlockPresent: true},
}) {
t.Fatal("Metadata did not match expected")
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment