-
Notifications
You must be signed in to change notification settings - Fork 202
/
chunk.go
78 lines (64 loc) · 1.98 KB
/
chunk.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
package chunk
import (
logger "github.com/multiversx/mx-chain-logger-go"
)
var log = logger.GetOrCreate("process/interceptors/processor")
type chunk struct {
reference []byte
maxChunks uint32
data map[uint32][]byte
size int
}
// NewChunk creates a new chunk instance able to account for the existing and missing chunks of a larger buffer
// Not a concurrent safe component
func NewChunk(maxChunks uint32, reference []byte) *chunk {
return &chunk{
reference: reference,
data: make(map[uint32][]byte),
maxChunks: maxChunks,
}
}
// Put will add or rewrite an existing chunk
func (c *chunk) Put(chunkIndex uint32, buff []byte) {
if chunkIndex >= c.maxChunks {
return
}
existing := c.data[chunkIndex]
c.data[chunkIndex] = buff
c.size = c.size - len(existing) + len(buff)
}
// TryAssembleAllChunks will try to assemble the original payload by iterating all available chunks
// It returns nil if at least one chunk is missing
func (c *chunk) TryAssembleAllChunks() []byte {
gotAllParts := c.maxChunks > 0 && len(c.data) == int(c.maxChunks)
if !gotAllParts {
log.Trace("not all parts received", "reference", c.reference, "max chunks", c.maxChunks, "len chunk", len(c.data))
return nil
}
buff := make([]byte, 0, c.size)
for i := uint32(0); i < c.maxChunks; i++ {
part := c.data[i]
buff = append(buff, part...)
}
return buff
}
// GetAllMissingChunkIndexes returns all missing chunk indexes
func (c *chunk) GetAllMissingChunkIndexes() []uint32 {
missing := make([]uint32, 0)
for i := uint32(0); i < c.maxChunks; i++ {
_, partFound := c.data[i]
if !partFound {
missing = append(missing, i)
}
}
log.Trace("chunk.GetAllMissingChunkIndexes", "reference", c.reference, "missing chunks", missing)
return missing
}
// Size returns the size in bytes stored in the values of the inner map
func (c *chunk) Size() int {
return c.size
}
// IsInterfaceNil returns true if there is no value under the interface
func (c *chunk) IsInterfaceNil() bool {
return c == nil
}