-
Notifications
You must be signed in to change notification settings - Fork 0
/
unixfs.go
83 lines (71 loc) · 1.78 KB
/
unixfs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package unixfs
import (
"errors"
"fmt"
"github.com/ipfs/go-unixfsnode/data"
dagpb "github.com/ipld/go-codec-dagpb"
"github.com/ipld/go-ipld-prime"
"github.com/spaolacci/murmur3"
)
func ToPbnode(node ipld.Node) (dagpb.PBNode, error) {
pbb := dagpb.Type.PBNode.NewBuilder()
if err := pbb.AssignNode(node); err != nil {
return nil, err
}
return pbb.Build().(dagpb.PBNode), nil
}
func ToData(node dagpb.PBNode) (data.UnixFSData, error) {
if !node.Data.Exists() {
return nil, fmt.Errorf("no data")
}
ufsBytes := node.Data.Must().Bytes()
ufsNode, err := data.DecodeUnixFSData(ufsBytes)
if err != nil {
return nil, err
}
return ufsNode, nil
}
/* --------- HAMT --------- */
func Hash(val []byte) []byte {
h := murmur3.New64()
h.Write(val)
return h.Sum(nil)
}
// HashBits is a helper that allows the reading of the 'next n bits' as an integer.
type HashBits struct {
Bits []byte
Consumed int
}
func mkmask(n int) byte {
return (1 << uint(n)) - 1
}
// Next returns the next 'i' bits of the hashBits value as an integer, or an
// error if there aren't enough bits.
func (hb *HashBits) Next(i int) (int, error) {
if hb.Consumed+i > len(hb.Bits)*8 {
return 0, errors.New("hamt is too deep")
}
return hb.next(i), nil
}
func (hb *HashBits) next(i int) int {
curbi := hb.Consumed / 8
leftb := 8 - (hb.Consumed % 8)
curb := hb.Bits[curbi]
if i == leftb {
out := int(mkmask(i) & curb)
hb.Consumed += i
return out
}
if i < leftb {
a := curb & mkmask(leftb) // mask out the high bits we don't want
b := a & ^mkmask(leftb-i) // mask out the low bits we don't want
c := b >> uint(leftb-i) // shift whats left down
hb.Consumed += i
return int(c)
}
out := int(mkmask(leftb) & curb)
out <<= uint(i - leftb)
hb.Consumed += leftb
out += hb.next(i - leftb)
return out
}