Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
G
go-ipfs
概览
概览
详情
活动
周期分析
版本库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
jihao
go-ipfs
Commits
dfd5e9aa
提交
dfd5e9aa
authored
10月 05, 2016
作者:
Kevin Atkinson
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Make BlockService an interface.
License: MIT Signed-off-by:
Kevin Atkinson
<
k@kevina.org
>
上级
edf2b52f
隐藏空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
53 行增加
和
35 行删除
+53
-35
blockservice.go
blockservice/blockservice.go
+45
-27
mock.go
blockservice/test/mock.go
+2
-2
core.go
core/core.go
+1
-1
merkledag.go
merkledag/merkledag.go
+4
-4
merkledag_test.go
merkledag/merkledag_test.go
+1
-1
没有找到文件。
blockservice/blockservice.go
浏览文件 @
dfd5e9aa
...
...
@@ -23,34 +23,52 @@ var ErrNotFound = errors.New("blockservice: key not found")
// BlockService is a hybrid block datastore. It stores data in a local
// datastore and may retrieve data from a remote Exchange.
// It uses an internal `datastore.Datastore` instance to store values.
type
BlockService
struct
{
// TODO don't expose underlying impl details
Blockstore
blockstore
.
Blockstore
Exchange
exchange
.
Interface
type
BlockService
interface
{
Blockstore
()
blockstore
.
Blockstore
Exchange
()
exchange
.
Interface
AddBlock
(
o
blocks
.
Block
)
(
*
cid
.
Cid
,
error
)
AddBlocks
(
bs
[]
blocks
.
Block
)
([]
*
cid
.
Cid
,
error
)
GetBlock
(
ctx
context
.
Context
,
c
*
cid
.
Cid
)
(
blocks
.
Block
,
error
)
GetBlocks
(
ctx
context
.
Context
,
ks
[]
*
cid
.
Cid
)
<-
chan
blocks
.
Block
DeleteBlock
(
o
blocks
.
Block
)
error
Close
()
error
}
type
blockService
struct
{
blockstore
blockstore
.
Blockstore
exchange
exchange
.
Interface
}
// NewBlockService creates a BlockService with given datastore instance.
func
New
(
bs
blockstore
.
Blockstore
,
rem
exchange
.
Interface
)
*
BlockService
{
func
New
(
bs
blockstore
.
Blockstore
,
rem
exchange
.
Interface
)
BlockService
{
if
rem
==
nil
{
log
.
Warning
(
"blockservice running in local (offline) mode."
)
}
return
&
B
lockService
{
B
lockstore
:
bs
,
E
xchange
:
rem
,
return
&
b
lockService
{
b
lockstore
:
bs
,
e
xchange
:
rem
,
}
}
func
(
bs
*
blockService
)
Blockstore
()
blockstore
.
Blockstore
{
return
bs
.
blockstore
}
func
(
bs
*
blockService
)
Exchange
()
exchange
.
Interface
{
return
bs
.
exchange
}
// AddBlock adds a particular block to the service, Putting it into the datastore.
// TODO pass a context into this if the remote.HasBlock is going to remain here.
func
(
s
*
B
lockService
)
AddBlock
(
o
blocks
.
Block
)
(
*
cid
.
Cid
,
error
)
{
func
(
s
*
b
lockService
)
AddBlock
(
o
blocks
.
Block
)
(
*
cid
.
Cid
,
error
)
{
// TODO: while this is a great optimization, we should think about the
// possibility of streaming writes directly to disk. If we can pass this object
// all the way down to the datastore without having to 'buffer' its data,
// we could implement a `WriteTo` method on it that could do a streaming write
// of the content, saving us (probably) considerable memory.
c
:=
o
.
Cid
()
has
,
err
:=
s
.
B
lockstore
.
Has
(
c
)
has
,
err
:=
s
.
b
lockstore
.
Has
(
c
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -59,22 +77,22 @@ func (s *BlockService) AddBlock(o blocks.Block) (*cid.Cid, error) {
return
c
,
nil
}
err
=
s
.
B
lockstore
.
Put
(
o
)
err
=
s
.
b
lockstore
.
Put
(
o
)
if
err
!=
nil
{
return
nil
,
err
}
if
err
:=
s
.
E
xchange
.
HasBlock
(
o
);
err
!=
nil
{
if
err
:=
s
.
e
xchange
.
HasBlock
(
o
);
err
!=
nil
{
return
nil
,
errors
.
New
(
"blockservice is closed"
)
}
return
c
,
nil
}
func
(
s
*
B
lockService
)
AddBlocks
(
bs
[]
blocks
.
Block
)
([]
*
cid
.
Cid
,
error
)
{
func
(
s
*
b
lockService
)
AddBlocks
(
bs
[]
blocks
.
Block
)
([]
*
cid
.
Cid
,
error
)
{
var
toput
[]
blocks
.
Block
for
_
,
b
:=
range
bs
{
has
,
err
:=
s
.
B
lockstore
.
Has
(
b
.
Cid
())
has
,
err
:=
s
.
b
lockstore
.
Has
(
b
.
Cid
())
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -86,14 +104,14 @@ func (s *BlockService) AddBlocks(bs []blocks.Block) ([]*cid.Cid, error) {
toput
=
append
(
toput
,
b
)
}
err
:=
s
.
B
lockstore
.
PutMany
(
toput
)
err
:=
s
.
b
lockstore
.
PutMany
(
toput
)
if
err
!=
nil
{
return
nil
,
err
}
var
ks
[]
*
cid
.
Cid
for
_
,
o
:=
range
toput
{
if
err
:=
s
.
E
xchange
.
HasBlock
(
o
);
err
!=
nil
{
if
err
:=
s
.
e
xchange
.
HasBlock
(
o
);
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"blockservice is closed (%s)"
,
err
)
}
...
...
@@ -104,19 +122,19 @@ func (s *BlockService) AddBlocks(bs []blocks.Block) ([]*cid.Cid, error) {
// GetBlock retrieves a particular block from the service,
// Getting it from the datastore using the key (hash).
func
(
s
*
B
lockService
)
GetBlock
(
ctx
context
.
Context
,
c
*
cid
.
Cid
)
(
blocks
.
Block
,
error
)
{
func
(
s
*
b
lockService
)
GetBlock
(
ctx
context
.
Context
,
c
*
cid
.
Cid
)
(
blocks
.
Block
,
error
)
{
log
.
Debugf
(
"BlockService GetBlock: '%s'"
,
c
)
block
,
err
:=
s
.
B
lockstore
.
Get
(
c
)
block
,
err
:=
s
.
b
lockstore
.
Get
(
c
)
if
err
==
nil
{
return
block
,
nil
}
if
err
==
blockstore
.
ErrNotFound
&&
s
.
E
xchange
!=
nil
{
if
err
==
blockstore
.
ErrNotFound
&&
s
.
e
xchange
!=
nil
{
// TODO be careful checking ErrNotFound. If the underlying
// implementation changes, this will break.
log
.
Debug
(
"Blockservice: Searching bitswap"
)
blk
,
err
:=
s
.
E
xchange
.
GetBlock
(
ctx
,
c
)
blk
,
err
:=
s
.
e
xchange
.
GetBlock
(
ctx
,
c
)
if
err
!=
nil
{
if
err
==
blockstore
.
ErrNotFound
{
return
nil
,
ErrNotFound
...
...
@@ -137,13 +155,13 @@ func (s *BlockService) GetBlock(ctx context.Context, c *cid.Cid) (blocks.Block,
// GetBlocks gets a list of blocks asynchronously and returns through
// the returned channel.
// NB: No guarantees are made about order.
func
(
s
*
B
lockService
)
GetBlocks
(
ctx
context
.
Context
,
ks
[]
*
cid
.
Cid
)
<-
chan
blocks
.
Block
{
func
(
s
*
b
lockService
)
GetBlocks
(
ctx
context
.
Context
,
ks
[]
*
cid
.
Cid
)
<-
chan
blocks
.
Block
{
out
:=
make
(
chan
blocks
.
Block
,
0
)
go
func
()
{
defer
close
(
out
)
var
misses
[]
*
cid
.
Cid
for
_
,
c
:=
range
ks
{
hit
,
err
:=
s
.
B
lockstore
.
Get
(
c
)
hit
,
err
:=
s
.
b
lockstore
.
Get
(
c
)
if
err
!=
nil
{
misses
=
append
(
misses
,
c
)
continue
...
...
@@ -160,7 +178,7 @@ func (s *BlockService) GetBlocks(ctx context.Context, ks []*cid.Cid) <-chan bloc
return
}
rblocks
,
err
:=
s
.
E
xchange
.
GetBlocks
(
ctx
,
misses
)
rblocks
,
err
:=
s
.
e
xchange
.
GetBlocks
(
ctx
,
misses
)
if
err
!=
nil
{
log
.
Debugf
(
"Error with GetBlocks: %s"
,
err
)
return
...
...
@@ -178,11 +196,11 @@ func (s *BlockService) GetBlocks(ctx context.Context, ks []*cid.Cid) <-chan bloc
}
// DeleteBlock deletes a block in the blockservice from the datastore
func
(
s
*
B
lockService
)
DeleteBlock
(
o
blocks
.
Block
)
error
{
return
s
.
B
lockstore
.
DeleteBlock
(
o
.
Cid
())
func
(
s
*
b
lockService
)
DeleteBlock
(
o
blocks
.
Block
)
error
{
return
s
.
b
lockstore
.
DeleteBlock
(
o
.
Cid
())
}
func
(
s
*
B
lockService
)
Close
()
error
{
func
(
s
*
b
lockService
)
Close
()
error
{
log
.
Debug
(
"blockservice is shutting down..."
)
return
s
.
E
xchange
.
Close
()
return
s
.
e
xchange
.
Close
()
}
blockservice/test/mock.go
浏览文件 @
dfd5e9aa
...
...
@@ -9,13 +9,13 @@ import (
)
// Mocks returns |n| connected mock Blockservices
func
Mocks
(
n
int
)
[]
*
BlockService
{
func
Mocks
(
n
int
)
[]
BlockService
{
net
:=
tn
.
VirtualNetwork
(
mockrouting
.
NewServer
(),
delay
.
Fixed
(
0
))
sg
:=
bitswap
.
NewTestSessionGenerator
(
net
)
instances
:=
sg
.
Instances
(
n
)
var
servs
[]
*
BlockService
var
servs
[]
BlockService
for
_
,
i
:=
range
instances
{
servs
=
append
(
servs
,
New
(
i
.
Blockstore
(),
i
.
Exchange
))
}
...
...
core/core.go
浏览文件 @
dfd5e9aa
...
...
@@ -96,7 +96,7 @@ type IpfsNode struct {
// Services
Peerstore
pstore
.
Peerstore
// storage for other Peer instances
Blockstore
bstore
.
GCBlockstore
// the block store (lower level)
Blocks
*
bserv
.
BlockService
// the block service, get/add blocks.
Blocks
bserv
.
BlockService
// the block service, get/add blocks.
DAG
merkledag
.
DAGService
// the merkle dag service, get/add objects.
Resolver
*
path
.
Resolver
// the path resolution system
Reporter
metrics
.
Reporter
...
...
merkledag/merkledag.go
浏览文件 @
dfd5e9aa
...
...
@@ -41,7 +41,7 @@ type LinkService interface {
GetOfflineLinkService
()
LinkService
}
func
NewDAGService
(
bs
*
bserv
.
BlockService
)
*
dagService
{
func
NewDAGService
(
bs
bserv
.
BlockService
)
*
dagService
{
return
&
dagService
{
Blocks
:
bs
}
}
...
...
@@ -51,7 +51,7 @@ func NewDAGService(bs *bserv.BlockService) *dagService {
// TODO: should cache Nodes that are in memory, and be
// able to free some of them when vm pressure is high
type
dagService
struct
{
Blocks
*
bserv
.
BlockService
Blocks
bserv
.
BlockService
}
// Add adds a node to the dagService, storing the block in the BlockService
...
...
@@ -113,8 +113,8 @@ func (n *dagService) GetLinks(ctx context.Context, c *cid.Cid) ([]*Link, error)
}
func
(
n
*
dagService
)
GetOfflineLinkService
()
LinkService
{
if
n
.
Blocks
.
Exchange
.
IsOnline
()
{
bsrv
:=
bserv
.
New
(
n
.
Blocks
.
Blockstore
,
offline
.
Exchange
(
n
.
Blocks
.
Blockstore
))
if
n
.
Blocks
.
Exchange
()
.
IsOnline
()
{
bsrv
:=
bserv
.
New
(
n
.
Blocks
.
Blockstore
(),
offline
.
Exchange
(
n
.
Blocks
.
Blockstore
()
))
return
NewDAGService
(
bsrv
)
}
else
{
return
n
...
...
merkledag/merkledag_test.go
浏览文件 @
dfd5e9aa
...
...
@@ -237,7 +237,7 @@ func TestFetchGraph(t *testing.T) {
}
// create an offline dagstore and ensure all blocks were fetched
bs
:=
bserv
.
New
(
bsis
[
1
]
.
Blockstore
,
offline
.
Exchange
(
bsis
[
1
]
.
Blockstore
))
bs
:=
bserv
.
New
(
bsis
[
1
]
.
Blockstore
(),
offline
.
Exchange
(
bsis
[
1
]
.
Blockstore
()
))
offline_ds
:=
NewDAGService
(
bs
)
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论