-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtrace.go
68 lines (59 loc) · 1.05 KB
/
trace.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
package main
import (
"bytes"
"fmt"
"hash"
"hash/crc32"
"sync"
)
func NewTrace() *Trace {
return &Trace{
checksum: crc32.NewIEEE(),
}
}
type Trace struct {
b bytes.Buffer
checksum hash.Hash32
offset int
m sync.Mutex
readMu sync.Mutex
lastRead int
}
func (t *Trace) Write(p []byte) (n int, err error) {
t.m.Lock()
defer t.m.Unlock()
t.checksum.Write(p)
return t.b.Write(p)
}
func (t *Trace) NextChunk() ([]byte, int) {
t.readMu.Lock()
t.m.Lock()
defer t.m.Unlock()
outAlias := t.b.Bytes()[t.offset:]
t.lastRead = len(outAlias)
out := make([]byte, len(outAlias))
copy(out, outAlias)
return out, t.offset
}
func (t *Trace) CommitChunk() {
t.m.Lock()
defer t.m.Unlock()
t.offset += t.lastRead
t.readMu.Unlock()
}
func (t *Trace) AbortChunk() {
t.m.Lock()
defer t.m.Unlock()
t.lastRead = 0
t.readMu.Unlock()
}
func (t *Trace) Offset() int {
t.m.Lock()
defer t.m.Unlock()
return t.offset
}
func (t *Trace) Checksum() string {
t.m.Lock()
defer t.m.Unlock()
return fmt.Sprintf("crc32:%08x", t.checksum.Sum32())
}