-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support HAMT #4
Merged
Merged
Support HAMT #4
Changes from 6 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
4574e41
feat(data): add unixfs data node decoding
hannahhoward cdb32f2
feat(hamt): add hamt implementation
hannahhoward 67a7e38
feat(directory): seperate directory implementation
hannahhoward d6733f6
fix(unixfsnode): have reifier add path selection to normal nodes
hannahhoward 1854f92
fix(unixfsnode): cleanup from comments
hannahhoward de45652
feat(reification): use new prime node reification
hannahhoward e56e007
fix(unixfsnode): respond to PR comments
hannahhoward File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
package builder | ||
|
||
import ( | ||
"errors" | ||
"strconv" | ||
"time" | ||
|
||
"github.com/ipfs/go-unixfsnode/data" | ||
"github.com/ipld/go-ipld-prime" | ||
"github.com/ipld/go-ipld-prime/fluent/qp" | ||
) | ||
|
||
// BuildUnixFS provides a clean, validated interface to building data structures | ||
// that match the UnixFS protobuf encoded in the Data member of a ProtoNode | ||
// with sensible defaults | ||
// | ||
// smallFileData, err := BuildUnixFS(func(b *Builder) { | ||
// Data(b, []byte{"hello world"}) | ||
// MTime(b, func(tb TimeBuilder) { | ||
// Time(tb, time.Now()) | ||
// }) | ||
// }) | ||
// | ||
func BuildUnixFS(fn func(*Builder)) (data.UnixFSData, error) { | ||
nd, err := qp.BuildMap(data.Type.UnixFSData, -1, func(ma ipld.MapAssembler) { | ||
b := &Builder{MapAssembler: ma} | ||
fn(b) | ||
if !b.hasBlockSizes { | ||
qp.MapEntry(ma, "BlockSizes", qp.List(0, func(ipld.ListAssembler) {})) | ||
} | ||
if !b.hasDataType { | ||
qp.MapEntry(ma, "DataType", qp.Int(data.Data_File)) | ||
} | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return nd.(data.UnixFSData), nil | ||
} | ||
|
||
// Builder is an interface for making UnixFS data nodes | ||
type Builder struct { | ||
ipld.MapAssembler | ||
hasDataType bool | ||
hasBlockSizes bool | ||
} | ||
|
||
// DataType sets the default on a builder for a UnixFS node - default is File | ||
func DataType(b *Builder, dataType int64) { | ||
_, ok := data.DataTypeNames[dataType] | ||
if !ok { | ||
panic(data.ErrInvalidDataType{dataType}) | ||
} | ||
qp.MapEntry(b.MapAssembler, "DataType", qp.Int(dataType)) | ||
b.hasDataType = true | ||
} | ||
|
||
// Data sets the data member inside the UnixFS data | ||
func Data(b *Builder, data []byte) { | ||
qp.MapEntry(b.MapAssembler, "Data", qp.Bytes(data)) | ||
} | ||
|
||
// FileSize sets the file size which should be the size of actual bytes underneath | ||
// this node for large files, w/o additional bytes to encode intermediate nodes | ||
func FileSize(b *Builder, fileSize uint64) { | ||
qp.MapEntry(b.MapAssembler, "FileSize", qp.Int(int64(fileSize))) | ||
} | ||
|
||
// BlockSizes encodes block sizes for each child node | ||
func BlockSizes(b *Builder, blockSizes []uint64) { | ||
qp.MapEntry(b.MapAssembler, "BlockSizes", qp.List(int64(len(blockSizes)), func(la ipld.ListAssembler) { | ||
for _, bs := range blockSizes { | ||
qp.ListEntry(la, qp.Int(int64(bs))) | ||
} | ||
})) | ||
b.hasBlockSizes = true | ||
} | ||
|
||
// HashFunc sets the hash function for this node -- only applicable to HAMT | ||
func HashFunc(b *Builder, hashFunc uint64) { | ||
qp.MapEntry(b.MapAssembler, "HashFunc", qp.Int(int64(hashFunc))) | ||
} | ||
|
||
// Fanout sets the fanout in a HAMT tree | ||
func Fanout(b *Builder, fanout uint64) { | ||
qp.MapEntry(b.MapAssembler, "Fanout", qp.Int(int64(fanout))) | ||
} | ||
|
||
// Permissions sets file permissions for the Mode member of the UnixFS node | ||
func Permissions(b *Builder, mode int) { | ||
mode = mode & 0xFFF | ||
qp.MapEntry(b.MapAssembler, "Mode", qp.Int(int64(mode))) | ||
} | ||
|
||
func parseModeString(modeString string) (uint64, error) { | ||
if len(modeString) > 0 && modeString[0] == '0' { | ||
return strconv.ParseUint(modeString, 8, 32) | ||
} | ||
return strconv.ParseUint(modeString, 10, 32) | ||
} | ||
|
||
// PermissionsString sets file permissions for the Mode member of the UnixFS node, | ||
// parsed from a typical octect encoded permission string (eg '0755') | ||
func PermissionsString(b *Builder, modeString string) { | ||
mode64, err := parseModeString(modeString) | ||
if err != nil { | ||
panic(err) | ||
} | ||
mode64 = mode64 & 0xFFF | ||
qp.MapEntry(b.MapAssembler, "Mode", qp.Int(int64(mode64))) | ||
} | ||
|
||
// Mtime sets the modification time for this node using the time builder interface | ||
// and associated methods | ||
func Mtime(b *Builder, fn func(tb TimeBuilder)) { | ||
qp.MapEntry(b.MapAssembler, "Mtime", qp.Map(-1, func(ma ipld.MapAssembler) { | ||
fn(ma) | ||
})) | ||
} | ||
|
||
// TimeBuilder is a simple interface for constructing the time member of UnixFS data | ||
type TimeBuilder ipld.MapAssembler | ||
|
||
// Time sets the modification time from a golang time value | ||
func Time(ma TimeBuilder, t time.Time) { | ||
Seconds(ma, t.Unix()) | ||
FractionalNanoseconds(ma, int32(t.Nanosecond())) | ||
} | ||
|
||
// Seconds sets the seconds for a modification time | ||
func Seconds(ma TimeBuilder, seconds int64) { | ||
qp.MapEntry(ma, "Seconds", qp.Int(seconds)) | ||
|
||
} | ||
|
||
// FractionalNanoseconds sets the nanoseconds for a modification time (must | ||
// be between 0 & a billion) | ||
func FractionalNanoseconds(ma TimeBuilder, nanoseconds int32) { | ||
if nanoseconds < 0 || nanoseconds > 999999999 { | ||
panic(errors.New("mtime-nsecs must be within the range [0,999999999]")) | ||
} | ||
qp.MapEntry(ma, "FractionalNanoseconds", qp.Int(int64(nanoseconds))) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package data | ||
|
||
const ( | ||
Data_Raw int64 = 0 | ||
Data_Directory int64 = 1 | ||
Data_File int64 = 2 | ||
Data_Metadata int64 = 3 | ||
Data_Symlink int64 = 4 | ||
Data_HAMTShard int64 = 5 | ||
gammazero marked this conversation as resolved.
Show resolved
Hide resolved
|
||
) | ||
|
||
var DataTypeNames = map[int64]string{ | ||
Data_Raw: "Raw", | ||
Data_Directory: "Directory", | ||
Data_File: "File", | ||
Data_Metadata: "Metadata", | ||
Data_Symlink: "Symlink", | ||
Data_HAMTShard: "HAMTShard", | ||
} | ||
|
||
var DataTypeValues = map[string]int64{ | ||
"Raw": Data_Raw, | ||
"Directory": Data_Directory, | ||
"File": Data_File, | ||
"Metadata": Data_Metadata, | ||
"Symlink": Data_Symlink, | ||
"HAMTShard": Data_HAMTShard, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/* | ||
Package data provides tools for working with the UnixFS data structure that | ||
is encoded in the "Data" field of the larger a DagPB encoded IPLD node. | ||
|
||
See https://github.com/ipfs/specs/blob/master/UNIXFS.md for more information | ||
about this data structure. | ||
|
||
This package provides an IPLD Prime compatible node interface for this data | ||
structure, as well as methods for serializing and deserializing the data | ||
structure to protobuf | ||
*/ | ||
package data | ||
|
||
//go:generate go run ./gen |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package data | ||
|
||
import ( | ||
"fmt" | ||
|
||
"google.golang.org/protobuf/encoding/protowire" | ||
) | ||
|
||
type ErrWrongNodeType struct { | ||
Expected int64 | ||
Actual int64 | ||
} | ||
|
||
func (e ErrWrongNodeType) Error() string { | ||
expectedName, ok := DataTypeNames[e.Expected] | ||
if !ok { | ||
expectedName = "Unknown Type" | ||
} | ||
actualName, ok := DataTypeNames[e.Actual] | ||
if !ok { | ||
actualName = "Unknown Type" | ||
} | ||
return fmt.Sprintf("Incorrect Node Type: (UnixFSData) expected type: %s, actual type: %s", expectedName, actualName) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: lower case error strings |
||
} | ||
|
||
type ErrWrongWireType struct { | ||
Module string | ||
Field string | ||
Expected protowire.Type | ||
Actual protowire.Type | ||
} | ||
|
||
func (e ErrWrongWireType) Error() string { | ||
return fmt.Sprintf("protobuf: (%s) invalid wireType, field: %s, expected %d, got %d", e.Module, e.Field, e.Expected, e.Actual) | ||
} | ||
|
||
type ErrInvalidDataType struct { | ||
DataType int64 | ||
} | ||
|
||
func (e ErrInvalidDataType) Error() string { | ||
return fmt.Sprintf("Type: %d is not valid", e.DataType) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Hello UnixFS |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Hello UnixFS |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Hello UnixFS | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Hello UnixFS | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Hello UnixFS |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
file.txt |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider a
const
for"BlockSizes"
and other map entry keys.