-
Notifications
You must be signed in to change notification settings - Fork 5
/
append.go
104 lines (91 loc) · 3 KB
/
append.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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package example
import (
"bytes"
"io"
"io/ioutil"
"log"
"math/rand"
"go.beyondstorage.io/v5/pkg/randbytes"
"go.beyondstorage.io/v5/types"
)
func AppendToNewFile(appender types.Appender, path string) {
// content to append
size := rand.Int63n(4 * 1024 * 1024)
content, _ := ioutil.ReadAll(io.LimitReader(randbytes.NewRand(), size))
r := bytes.NewReader(content)
// CreateAppend needs at least one argument.
//
// `path` is the path of object.
// If path is relative path, the real path will be `store.WorkDir + path`.
// If path is absolute path, the real path will be `path`.
//
// CreateAppend will return two values.
// `o` is the created appendable object.
// `err` is the error during this operation.
o, err := appender.CreateAppend(path)
if err != nil {
log.Fatalf("CreateAppend %v: %v", path, err)
}
// WriteAppend could be called many times. The maximum size of the final appendable object ups to different services.
//
// WriteAppend needs at least three arguments.
//
// `o` is the appendable object returned by CreateAppend. It specifies the next call's append position, so the caller need not to maintain this information.
// `r` the read instance for reading the data to append.
// `size` is the size of content to append.
//
// WriteAppend will return two values.
// `n` is the next append position. It's valid when `err` is nil.
// `err` is the error during this operation.
n, err := appender.WriteAppend(o, r, size)
if err != nil {
log.Fatalf("WriteAppend %v: %v", path, err)
}
// CommitAppend needs at least one argument.
// `o` is the object returned by CreateAppend.
//
// CommitAppend will return one value.
// `err` is the error during this operation.
err = appender.CommitAppend(o)
if err != nil {
log.Fatalf("CommitAppend %v: %v", path, err)
}
log.Printf("append size: %d", n)
}
func AppendToExistingFile(store types.Storager, path string) {
// content to append
size := rand.Int63n(4 * 1024 * 1024)
content, _ := ioutil.ReadAll(io.LimitReader(randbytes.NewRand(), size))
r := bytes.NewReader(content)
// `store` should implement `Appender`
appender, ok := store.(types.Appender)
if !ok {
log.Fatalf("Appender unimplemented")
}
// Use `Stat` to get an appendable object.
//
// Stat needs at least one argument.
//
// `path` is the path of object.
// If path is relative path, the real path will be `store.WorkDir + path`.
// If path is absolute path, the real path will be `path`.
//
// Stat will return two values.
// `o` is the existing object.
// `err` is the error during this operation.
o, err := store.Stat(path)
if err != nil {
log.Fatalf("Stat %v: %v", path, err)
}
// `o` is the object returned by Stat.
// The service should check if the object `isAppend` and maintains the next call's append position.
n, err := appender.WriteAppend(o, r, size)
if err != nil {
log.Fatalf("WriteAppend %v: %v", path, err)
}
err = appender.CommitAppend(o)
if err != nil {
log.Fatalf("CommitAppend %v: %v", path, err)
}
log.Printf("append size: %d", n)
}