-
Notifications
You must be signed in to change notification settings - Fork 337
/
loadsave.go
81 lines (67 loc) · 2.01 KB
/
loadsave.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// Copyright 2021 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package loadsave provides lightweight persistence abstraction
// for manifest operations.
package loadsave
import (
"bytes"
"context"
"errors"
"github.com/ethersphere/bee/pkg/file"
"github.com/ethersphere/bee/pkg/file/joiner"
"github.com/ethersphere/bee/pkg/file/pipeline"
"github.com/ethersphere/bee/pkg/file/pipeline/builder"
"github.com/ethersphere/bee/pkg/storage"
"github.com/ethersphere/bee/pkg/swarm"
)
var readonlyLoadsaveError = errors.New("readonly manifest loadsaver")
type PutGetter interface {
storage.Putter
storage.Getter
}
// loadSave is needed for manifest operations and provides
// simple wrapping over load and save operations using file
// package abstractions. use with caution since Loader will
// load all of the subtrie of a given hash in memory.
type loadSave struct {
storer PutGetter
pipelineFn func() pipeline.Interface
}
// New returns a new read-write load-saver.
func New(storer PutGetter, pipelineFn func() pipeline.Interface) file.LoadSaver {
return &loadSave{
storer: storer,
pipelineFn: pipelineFn,
}
}
// NewReadonly returns a new read-only load-saver
// which will error on write.
func NewReadonly(storer PutGetter) file.LoadSaver {
return &loadSave{
storer: storer,
}
}
func (ls *loadSave) Load(ctx context.Context, ref []byte) ([]byte, error) {
j, _, err := joiner.New(ctx, ls.storer, swarm.NewAddress(ref))
if err != nil {
return nil, err
}
buf := bytes.NewBuffer(nil)
_, err = file.JoinReadAll(ctx, j, buf)
if err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func (ls *loadSave) Save(ctx context.Context, data []byte) ([]byte, error) {
if ls.pipelineFn == nil {
return nil, readonlyLoadsaveError
}
pipe := ls.pipelineFn()
address, err := builder.FeedPipeline(ctx, pipe, bytes.NewReader(data))
if err != nil {
return swarm.ZeroAddress.Bytes(), err
}
return address.Bytes(), nil
}