@@ -5,13 +5,16 @@ package blockservice
5
5
6
6
import (
7
7
"errors"
8
+ "fmt"
8
9
9
10
blocks "github.com/ipfs/go-ipfs/blocks"
10
11
"github.com/ipfs/go-ipfs/blocks/blockstore"
11
12
key "github.com/ipfs/go-ipfs/blocks/key"
12
13
exchange "github.com/ipfs/go-ipfs/exchange"
14
+
13
15
logging "gx/ipfs/QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52/go-log"
14
16
context "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context"
17
+ cid "gx/ipfs/QmfSc2xehWmWLnwwYR91Y8QF4xdASypTFVknutoKQS3GHp/go-cid"
15
18
)
16
19
17
20
var log = logging .Logger ("blockservice" )
@@ -27,6 +30,12 @@ type BlockService struct {
27
30
Exchange exchange.Interface
28
31
}
29
32
33
+ // an Object is simply a typed block
34
+ type Object interface {
35
+ Cid () * cid.Cid
36
+ blocks.Block
37
+ }
38
+
30
39
// NewBlockService creates a BlockService with given datastore instance.
31
40
func New (bs blockstore.Blockstore , rem exchange.Interface ) * BlockService {
32
41
if rem == nil {
@@ -41,30 +50,41 @@ func New(bs blockstore.Blockstore, rem exchange.Interface) *BlockService {
41
50
42
51
// AddBlock adds a particular block to the service, Putting it into the datastore.
43
52
// TODO pass a context into this if the remote.HasBlock is going to remain here.
44
- func (s * BlockService ) AddBlock (b blocks.Block ) (key.Key , error ) {
45
- k := b .Key ()
46
- has , err := s .Blockstore .Has (k )
53
+ func (s * BlockService ) AddObject (o Object ) (* cid.Cid , error ) {
54
+ // TODO: while this is a great optimization, we should think about the
55
+ // possibility of streaming writes directly to disk. If we can pass this object
56
+ // all the way down to the datastore without having to 'buffer' its data,
57
+ // we could implement a `WriteTo` method on it that could do a streaming write
58
+ // of the content, saving us (probably) considerable memory.
59
+ c := o .Cid ()
60
+ has , err := s .Blockstore .Has (key .Key (c .Hash ()))
47
61
if err != nil {
48
- return k , err
62
+ return nil , err
49
63
}
64
+
50
65
if has {
51
- return k , nil
66
+ return c , nil
52
67
}
53
68
54
- err = s .Blockstore .Put (b )
69
+ err = s .Blockstore .Put (o )
55
70
if err != nil {
56
- return k , err
71
+ return nil , err
57
72
}
58
- if err := s .Exchange .HasBlock (b ); err != nil {
59
- return "" , errors .New ("blockservice is closed" )
73
+
74
+ if err := s .Exchange .HasBlock (o ); err != nil {
75
+ return nil , errors .New ("blockservice is closed" )
60
76
}
61
- return k , nil
77
+
78
+ return c , nil
62
79
}
63
80
64
- func (s * BlockService ) AddBlocks (bs []blocks. Block ) ([]key. Key , error ) {
81
+ func (s * BlockService ) AddObjects (bs []Object ) ([]* cid. Cid , error ) {
65
82
var toput []blocks.Block
83
+ var toputcids []* cid.Cid
66
84
for _ , b := range bs {
67
- has , err := s .Blockstore .Has (b .Key ())
85
+ c := b .Cid ()
86
+
87
+ has , err := s .Blockstore .Has (key .Key (c .Hash ()))
68
88
if err != nil {
69
89
return nil , err
70
90
}
@@ -74,33 +94,33 @@ func (s *BlockService) AddBlocks(bs []blocks.Block) ([]key.Key, error) {
74
94
}
75
95
76
96
toput = append (toput , b )
97
+ toputcids = append (toputcids , c )
77
98
}
78
99
79
100
err := s .Blockstore .PutMany (toput )
80
101
if err != nil {
81
102
return nil , err
82
103
}
83
104
84
- var ks []key. Key
85
- for _ , b := range toput {
86
- if err := s .Exchange .HasBlock (b ); err != nil {
87
- return nil , errors . New ("blockservice is closed" )
105
+ var ks []* cid. Cid
106
+ for _ , o := range toput {
107
+ if err := s .Exchange .HasBlock (o ); err != nil {
108
+ return nil , fmt . Errorf ("blockservice is closed (%s)" , err )
88
109
}
89
- ks = append (ks , b .Key ())
110
+
111
+ c := o .(Object ).Cid () // cast is safe, we created these
112
+ ks = append (ks , c )
90
113
}
91
114
return ks , nil
92
115
}
93
116
94
117
// GetBlock retrieves a particular block from the service,
95
118
// Getting it from the datastore using the key (hash).
96
- func (s * BlockService ) GetBlock (ctx context.Context , k key.Key ) (blocks.Block , error ) {
97
- if k == "" {
98
- log .Debug ("BlockService GetBlock: Nil Key" )
99
- return nil , ErrNotFound
100
- }
119
+ func (s * BlockService ) GetBlock (ctx context.Context , c * cid.Cid ) (blocks.Block , error ) {
120
+ log .Debugf ("BlockService GetBlock: '%s'" , c )
101
121
102
- log . Debugf ( "BlockService GetBlock: '%s'" , k )
103
- block , err := s .Blockstore .Get (k )
122
+ // TODO: blockstore shouldnt care about Cids, need an easier way to strip the abstraction
123
+ block , err := s .Blockstore .Get (key . Key ( c . Hash ()) )
104
124
if err == nil {
105
125
return block , nil
106
126
}
@@ -109,7 +129,7 @@ func (s *BlockService) GetBlock(ctx context.Context, k key.Key) (blocks.Block, e
109
129
// TODO be careful checking ErrNotFound. If the underlying
110
130
// implementation changes, this will break.
111
131
log .Debug ("Blockservice: Searching bitswap" )
112
- blk , err := s .Exchange .GetBlock (ctx , k )
132
+ blk , err := s .Exchange .GetBlock (ctx , key . Key ( c . Hash ()) )
113
133
if err != nil {
114
134
if err == blockstore .ErrNotFound {
115
135
return nil , ErrNotFound
@@ -130,12 +150,13 @@ func (s *BlockService) GetBlock(ctx context.Context, k key.Key) (blocks.Block, e
130
150
// GetBlocks gets a list of blocks asynchronously and returns through
131
151
// the returned channel.
132
152
// NB: No guarantees are made about order.
133
- func (s * BlockService ) GetBlocks (ctx context.Context , ks []key. Key ) <- chan blocks.Block {
153
+ func (s * BlockService ) GetBlocks (ctx context.Context , ks []* cid. Cid ) <- chan blocks.Block {
134
154
out := make (chan blocks.Block , 0 )
135
155
go func () {
136
156
defer close (out )
137
157
var misses []key.Key
138
- for _ , k := range ks {
158
+ for _ , c := range ks {
159
+ k := key .Key (c .Hash ())
139
160
hit , err := s .Blockstore .Get (k )
140
161
if err != nil {
141
162
misses = append (misses , k )
@@ -171,11 +192,19 @@ func (s *BlockService) GetBlocks(ctx context.Context, ks []key.Key) <-chan block
171
192
}
172
193
173
194
// DeleteBlock deletes a block in the blockservice from the datastore
174
- func (s * BlockService ) DeleteBlock ( k key. Key ) error {
175
- return s .Blockstore .DeleteBlock (k )
195
+ func (s * BlockService ) DeleteObject ( o Object ) error {
196
+ return s .Blockstore .DeleteBlock (o . Key () )
176
197
}
177
198
178
199
func (s * BlockService ) Close () error {
179
200
log .Debug ("blockservice is shutting down..." )
180
201
return s .Exchange .Close ()
181
202
}
203
+
204
+ type RawBlockObject struct {
205
+ blocks.Block
206
+ }
207
+
208
+ func (rob * RawBlockObject ) Cid () * cid.Cid {
209
+ return cid .NewCidV0 (rob .Block .Multihash ())
210
+ }
0 commit comments