@@ -28,19 +28,28 @@ type Blockstore struct {
28
28
Getter AccessorGetter
29
29
}
30
30
31
- func (b * Blockstore ) getBlock (ctx context.Context , cid cid.Cid ) (blocks. Block , error ) {
31
+ func (b * Blockstore ) getBlockAndAccessor (ctx context.Context , cid cid.Cid ) (Block , eds. AccessorStreamer , error ) {
32
32
blk , err := EmptyBlock (cid )
33
33
if err != nil {
34
- return nil , err
34
+ return nil , nil , err
35
35
}
36
36
37
37
acc , err := b .Getter .GetByHeight (ctx , blk .Height ())
38
38
if errors .Is (err , store .ErrNotFound ) {
39
39
log .Debugf ("no EDS Accessor for height %v found" , blk .Height ())
40
- return nil , ipld.ErrNotFound {Cid : cid }
40
+ return nil , nil , ipld.ErrNotFound {Cid : cid }
41
41
}
42
42
if err != nil {
43
- return nil , fmt .Errorf ("getting EDS Accessor for height %v: %w" , blk .Height (), err )
43
+ return nil , nil , fmt .Errorf ("getting EDS Accessor for height %v: %w" , blk .Height (), err )
44
+ }
45
+
46
+ return blk , acc , nil
47
+ }
48
+
49
+ func (b * Blockstore ) Get (ctx context.Context , cid cid.Cid ) (blocks.Block , error ) {
50
+ blk , acc , err := b .getBlockAndAccessor (ctx , cid )
51
+ if err != nil {
52
+ return nil , err
44
53
}
45
54
defer func () {
46
55
if err := acc .Close (); err != nil {
@@ -55,24 +64,28 @@ func (b *Blockstore) getBlock(ctx context.Context, cid cid.Cid) (blocks.Block, e
55
64
return convertBitswap (blk )
56
65
}
57
66
58
- func (b * Blockstore ) Get (ctx context.Context , cid cid.Cid ) (blocks.Block , error ) {
59
- blk , err := b .getBlock (ctx , cid )
67
+ func (b * Blockstore ) GetSize (ctx context.Context , cid cid.Cid ) (int , error ) {
68
+ // NOTE: Bitswap prioritizes peers based on their active/pending work and the priority that peers set for requests(work)
69
+ // themselves. The prioritization happens on the Get operation of Blockstore not GetSize, while GetSize is expected
70
+ // to be as lightweight as possible.
71
+ //
72
+ // Here is the best case we only open the Accessor and getting its size, avoiding expensive compute to get the size.
73
+ blk , acc , err := b .getBlockAndAccessor (ctx , cid )
60
74
if err != nil {
61
- return nil , err
75
+ return 0 , err
62
76
}
77
+ defer func () {
78
+ if err := acc .Close (); err != nil {
79
+ log .Warnf ("failed to close EDS accessor for height %v: %s" , blk .Height (), err )
80
+ }
81
+ }()
63
82
64
- return blk , nil
65
- }
66
-
67
- func (b * Blockstore ) GetSize (ctx context.Context , cid cid.Cid ) (int , error ) {
68
- // TODO(@Wondertan): Bitswap checks the size of the data(GetSize) before serving it via Get. This means
69
- // GetSize may do an unnecessary read from disk which we can avoid by either caching on Blockstore level
70
- // or returning constant size(we know at that point that we have requested data)
71
- blk , err := b .Get (ctx , cid )
83
+ size , err := blk .Size (ctx , acc )
72
84
if err != nil {
73
- return 0 , err
85
+ return 0 , fmt . Errorf ( "getting block size: %w" , err )
74
86
}
75
- return len (blk .RawData ()), nil
87
+
88
+ return size , nil
76
89
}
77
90
78
91
func (b * Blockstore ) Has (ctx context.Context , cid cid.Cid ) (bool , error ) {
0 commit comments