forked from TrueCloudLab/frostfs-sdk-go
[#248] object: Introduce SplitByMaxChunkLength
method
* Add unit-test to test `SplitByMaxChunkLength`. Signed-off-by: Airat Arifullin <a.arifullin@yadro.com>
This commit is contained in:
parent
5e9cf6a8ae
commit
895a2ef0e2
2 changed files with 103 additions and 0 deletions
|
@ -78,6 +78,42 @@ type PayloadPatch struct {
|
|||
Chunk []byte
|
||||
}
|
||||
|
||||
// SplitByMaxChunkLength splits a payload patch into a few payload patches if its `Chunk` size
|
||||
// exceeds `maxChunkLen`.
|
||||
func (p *PayloadPatch) SplitByMaxChunkLength(maxChunkLen int) []*PayloadPatch {
|
||||
if len(p.Chunk) <= maxChunkLen {
|
||||
return []*PayloadPatch{p}
|
||||
}
|
||||
|
||||
var result []*PayloadPatch
|
||||
remainingChunk := p.Chunk
|
||||
currentOffset := p.Range.GetOffset()
|
||||
remainingLength := p.Range.GetLength()
|
||||
|
||||
for len(remainingChunk) > 0 {
|
||||
chunkSize := uint64(min(len(remainingChunk), maxChunkLen))
|
||||
newLength := min(remainingLength, chunkSize)
|
||||
|
||||
rng := NewRange()
|
||||
rng.SetOffset(currentOffset)
|
||||
rng.SetLength(newLength)
|
||||
|
||||
newPatch := &PayloadPatch{
|
||||
Range: rng,
|
||||
Chunk: remainingChunk[:chunkSize],
|
||||
}
|
||||
result = append(result, newPatch)
|
||||
|
||||
remainingChunk = remainingChunk[chunkSize:]
|
||||
currentOffset += chunkSize
|
||||
if remainingLength > 0 {
|
||||
remainingLength -= newLength
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (p *PayloadPatch) ToV2() *v2object.PatchRequestBodyPatch {
|
||||
if p == nil {
|
||||
return nil
|
||||
|
|
|
@ -10,6 +10,73 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func newRange(offest, length uint64) *Range {
|
||||
rng := &Range{}
|
||||
rng.SetOffset(offest)
|
||||
rng.SetLength(length)
|
||||
return rng
|
||||
}
|
||||
|
||||
func TestSplitByMaxChunkLength(t *testing.T) {
|
||||
t.Run("no break down", func(t *testing.T) {
|
||||
payloadPatch := &PayloadPatch{
|
||||
Range: newRange(0, 42),
|
||||
Chunk: []byte("100000|010000|001000|000100|000010|000001|"),
|
||||
}
|
||||
|
||||
payloadPatches := payloadPatch.SplitByMaxChunkLength(42)
|
||||
|
||||
require.Len(t, payloadPatches, 1)
|
||||
require.Equal(t, []byte("100000|010000|001000|000100|000010|000001|"), payloadPatches[0].Chunk)
|
||||
|
||||
require.Equal(t, uint64(0), payloadPatches[0].Range.GetOffset())
|
||||
require.Equal(t, uint64(42), payloadPatches[0].Range.GetLength())
|
||||
})
|
||||
|
||||
t.Run("one replacing and two inserting patches", func(t *testing.T) {
|
||||
payloadPatch := &PayloadPatch{
|
||||
Range: newRange(0, 15),
|
||||
Chunk: []byte("100000|010000|001000|000100|000010|000001|"),
|
||||
}
|
||||
|
||||
payloadPatches := payloadPatch.SplitByMaxChunkLength(15)
|
||||
|
||||
require.Len(t, payloadPatches, 3)
|
||||
|
||||
require.Equal(t, []byte("100000|010000|0"), payloadPatches[0].Chunk)
|
||||
require.Equal(t, uint64(0), payloadPatches[0].Range.GetOffset())
|
||||
require.Equal(t, uint64(15), payloadPatches[0].Range.GetLength())
|
||||
|
||||
require.Equal(t, []byte("01000|000100|00"), payloadPatches[1].Chunk)
|
||||
require.Equal(t, uint64(15), payloadPatches[1].Range.GetOffset())
|
||||
require.Equal(t, uint64(0), payloadPatches[1].Range.GetLength())
|
||||
|
||||
require.Equal(t, []byte("0010|000001|"), payloadPatches[2].Chunk)
|
||||
require.Equal(t, uint64(30), payloadPatches[2].Range.GetOffset())
|
||||
require.Equal(t, uint64(0), payloadPatches[2].Range.GetLength())
|
||||
})
|
||||
|
||||
t.Run("one replacing and one inserting patches", func(t *testing.T) {
|
||||
payloadPatch := &PayloadPatch{
|
||||
Range: newRange(0, 30),
|
||||
Chunk: []byte("100000|010000|001000|000100|000010|000001|"),
|
||||
}
|
||||
|
||||
payloadPatches := payloadPatch.SplitByMaxChunkLength(30)
|
||||
|
||||
require.Len(t, payloadPatches, 2)
|
||||
require.Equal(t, []byte("100000|010000|001000|000100|00"), payloadPatches[0].Chunk)
|
||||
|
||||
require.Equal(t, uint64(0), payloadPatches[0].Range.GetOffset())
|
||||
require.Equal(t, uint64(30), payloadPatches[0].Range.GetLength())
|
||||
|
||||
require.Equal(t, []byte("0010|000001|"), payloadPatches[1].Chunk)
|
||||
|
||||
require.Equal(t, uint64(30), payloadPatches[1].Range.GetOffset())
|
||||
require.Equal(t, uint64(0), payloadPatches[1].Range.GetLength())
|
||||
})
|
||||
}
|
||||
|
||||
func TestPatch(t *testing.T) {
|
||||
t.Run("to v2", func(t *testing.T) {
|
||||
t.Run("only attributes", func(t *testing.T) {
|
||||
|
|
Loading…
Reference in a new issue