IPFS / IPLD 阅读笔记 (持续更新中...)

重点关注

本次学习的主要的工具集是 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) NextBytes() 
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值