重点关注
本次学习的主要的工具集是 IPLD\DB\FILE 模块,具体如下:
Files
- go-unixfs : the core ‘filesystem’ logic
- go-mfs : a mutable filesystem editor for unixfs
- go-ipfs-posinfo : helper datatypes for the filestore
- go-ipfs-chunker : file chunkers
Datastores
- go-datastore : datastore interfaces, adapters, and basic implementations
- go-ipfs-ds-help : datastore utility functions
- go-ds-flatfs : a filesystem-based datastore
- go-ds-measure : a metric-collecting database adapter
- go-ds-leveldb : a leveldb based datastore
- go-ds-badger : a badgerdb based datastore
IPLD
- go-block-format : block interfaces and implementations
- go-ipfs-blockstore : blockstore interfaces and implementations
- go-ipld-format : IPLD interfaces
- go-ipld-cbor : IPLD-CBOR implementation
- go-ipld-git : IPLD-Git implementation
- go-merkledag : IPLD-Merkledag implementation (and then some)
学习入口
- core/commands/add.go

添加文件也就是ipfs add的关键调用栈如下:
Run() -> //core/commands/add.go
UnixfsAPI.Add() -> // core/coreapi/unixfs.go
Adder.AddAllAndPin() -> //core/coreunix/add.go
Adder.addFileNode() ->
Adder.addFile() ->
Adder.addNode() ->
主要完成了三个工作
- 通过
Layout函数拆散并组成一个符合IPLD规范的DAG对象; - 通过
mfs库生成模拟的目录对象来存放于代表文件的nd对象的关系; - 把以上两个工作的结果放入
db;
文件是通过 DAGService.Add 保存到 db 中的,这个调用发生在 Adder.addNode() 中,文件和目录的关系是单独存储的,通过 root.Flush 函数存储 db,这个调用发生在 Adder.AddAllAndPin 中
// 目录入库的代码片段
func (adder *Adder) AddAllAndPin(file files.Node) (ipld.Node, error) {
...
// get root
mr, err := adder.mfsRoot()
...
var root mfs.FSNode
rootdir := mr.GetDirectory()
root = rootdir
err = root.Flush()
...
TODO LIST
- Layout 的实现原理
- IPLD Node 数据的存储方案
Layout 的实现原理
数据先进行分块,然后把块组合成一棵树,当然也可以称作 DAG,有想无环图本身就是一棵树,这棵树的叶子节点是数据块,默认是 256k 一个块,么一层默认是 174 个节点,树是自上而下填充的,用最终的树根 ID 来代表这个资源;
chunks
关于 chunker.FromString 返回的 Splitter 接口有如下描述:
// A Splitter reads bytes from a Reader and creates "chunks" (byte slices)
// that can be used to build DAG nodes.
type Splitter interface {
Reader() io.Reader
NextBytes() ([]byte, error)
}
这个接口有好几个实现,默认使用的是基于 size 的实现 sizeSplitterv2
//构造函数
func NewSizeSplitter(r io.Reader, size int64) Splitter {
return &sizeSplitterv2{
r: r,
size: uint32(size),
}
}
// 切分函数
func (ss *sizeSplitterv2) NextB

这篇博客主要探讨了IPFS/IPLD的学习,包括files模块、数据存储和IPLD的相关接口。重点讨论了Layout的实现原理,即数据分块、构建DAG的过程,并介绍了IPLD Node数据的存储方案,采用平衡布局和分块策略以优化存储效率。此外,还提到了DagBuilderParams和DagBuilderHelper在构建DAG过程中的作用。
最低0.47元/天 解锁文章
497

被折叠的 条评论
为什么被折叠?



