Skip to content

Commit eff9544

Browse files
authored
Merge pull request ipld/go-car#37 from ipld/feat/two-step-user-funcs
Allow user defined block hooks when using two step write for selective cars This commit was moved from ipld/go-car@8fe0b74
2 parents d76751b + 76030f7 commit eff9544

File tree

2 files changed

+33
-6
lines changed

2 files changed

+33
-6
lines changed

ipld/car/car_test.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@ func TestRoundtripSelective(t *testing.T) {
117117
// write car in one step
118118
buf := new(bytes.Buffer)
119119
blockCount := 0
120+
var oneStepBlocks []Block
120121
err := sc.Write(buf, func(block Block) error {
122+
oneStepBlocks = append(oneStepBlocks, block)
121123
blockCount++
122124
return nil
123125
})
@@ -128,7 +130,11 @@ func TestRoundtripSelective(t *testing.T) {
128130
sc2 := NewSelectiveCar(context.Background(), sourceBs, []Dag{Dag{Root: nd3.Cid(), Selector: selector}})
129131

130132
// write car in two steps
131-
scp, err := sc2.Prepare()
133+
var twoStepBlocks []Block
134+
scp, err := sc2.Prepare(func(block Block) error {
135+
twoStepBlocks = append(twoStepBlocks, block)
136+
return nil
137+
})
132138
require.NoError(t, err)
133139
buf2 := new(bytes.Buffer)
134140
err = scp.Dump(buf2)
@@ -141,6 +147,9 @@ func TestRoundtripSelective(t *testing.T) {
141147
// verify equal data written by both methods
142148
require.Equal(t, buf.Bytes(), buf2.Bytes())
143149

150+
// verify equal blocks were passed to user block hook funcs
151+
require.Equal(t, oneStepBlocks, twoStepBlocks)
152+
144153
// readout car and verify contents
145154
bserv := dstest.Bserv()
146155
ch, err := LoadCar(bserv.Blockstore(), buf)

ipld/car/selectivecar.go

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,10 @@ type OnNewCarBlockFunc func(Block) error
5050
// the Car file like size and number of blocks that go into it
5151
type SelectiveCarPrepared struct {
5252
SelectiveCar
53-
size uint64
54-
header CarHeader
55-
cids []cid.Cid
53+
size uint64
54+
header CarHeader
55+
cids []cid.Cid
56+
userOnNewCarBlocks []OnNewCarBlockFunc
5657
}
5758

5859
// NewSelectiveCar creates a new SelectiveCar for the given car file based
@@ -72,7 +73,7 @@ func (sc SelectiveCar) traverse(onCarHeader OnCarHeaderFunc, onNewCarBlock OnNew
7273

7374
// Prepare traverse a car file and collects data on what is about to be written, but
7475
// does not actually write the file
75-
func (sc SelectiveCar) Prepare() (SelectiveCarPrepared, error) {
76+
func (sc SelectiveCar) Prepare(userOnNewCarBlocks ...OnNewCarBlockFunc) (SelectiveCarPrepared, error) {
7677
var header CarHeader
7778
var cids []cid.Cid
7879

@@ -88,7 +89,7 @@ func (sc SelectiveCar) Prepare() (SelectiveCarPrepared, error) {
8889
if err != nil {
8990
return SelectiveCarPrepared{}, err
9091
}
91-
return SelectiveCarPrepared{sc, size, header, cids}, nil
92+
return SelectiveCarPrepared{sc, size, header, cids, userOnNewCarBlocks}, nil
9293
}
9394

9495
func (sc SelectiveCar) Write(w io.Writer, userOnNewCarBlocks ...OnNewCarBlockFunc) error {
@@ -133,6 +134,10 @@ func (sc SelectiveCarPrepared) Cids() []cid.Cid {
133134
// Dump writes the car file as quickly as possible based on information already
134135
// collected
135136
func (sc SelectiveCarPrepared) Dump(w io.Writer) error {
137+
offset, err := HeaderSize(&sc.header)
138+
if err != nil {
139+
return fmt.Errorf("failed to size car header: %s", err)
140+
}
136141
if err := WriteHeader(&sc.header, w); err != nil {
137142
return fmt.Errorf("failed to write car header: %s", err)
138143
}
@@ -142,10 +147,23 @@ func (sc SelectiveCarPrepared) Dump(w io.Writer) error {
142147
return err
143148
}
144149
raw := blk.RawData()
150+
size := util.LdSize(c.Bytes(), raw)
145151
err = util.LdWrite(w, c.Bytes(), raw)
146152
if err != nil {
147153
return err
148154
}
155+
for _, userOnNewCarBlock := range sc.userOnNewCarBlocks {
156+
err := userOnNewCarBlock(Block{
157+
BlockCID: c,
158+
Data: raw,
159+
Offset: offset,
160+
Size: size,
161+
})
162+
if err != nil {
163+
return err
164+
}
165+
}
166+
offset += size
149167
}
150168
return nil
151169
}

0 commit comments

Comments
 (0)