Commit 5e12ff76 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent f1278d15
...@@ -23,8 +23,8 @@ import ( ...@@ -23,8 +23,8 @@ import (
"../xmath" "../xmath"
) )
// Grow increase length of slice by n elements. // Grow increases length of byte slice by n elements.
// If there is not enough capacity the slice is reallocated. // If there is not enough capacity the slice is reallocated and copied.
// The memory for grown elements is not initialized. // The memory for grown elements is not initialized.
func Grow(b []byte, n int) []byte { func Grow(b []byte, n int) []byte {
ln := len(b) + n ln := len(b) + n
...@@ -37,8 +37,22 @@ func Grow(b []byte, n int) []byte { ...@@ -37,8 +37,22 @@ func Grow(b []byte, n int) []byte {
return bb return bb
} }
// Resize resized the slice to be of length n. // MakeRoom makes sure cap(b) - len(b) >= n
// If slice length is increased and there is not enough capacity the slice is reallocated. // If there is not enough capacity the slice is reallocated and copied.
// Length of the slice remains unchanged.
func MakeRoom(b []byte, n int) []byte {
ln := len(b) + n
if ln <= cap(b) {
return b
}
bb := make([]byte, len(b), xmath.CeilPow2(uint64(ln)))
copy(bb, b)
return bb
}
// Resize resized byte slice to be of length n.
// If slice length is increased and there is not enough capacity the slice is reallocated and copied.
// The memory for grown elements, if any, is not initialized. // The memory for grown elements, if any, is not initialized.
func Resize(b []byte, n int) []byte { func Resize(b []byte, n int) []byte {
if cap(b) >= n { if cap(b) >= n {
...@@ -51,10 +65,12 @@ func Resize(b []byte, n int) []byte { ...@@ -51,10 +65,12 @@ func Resize(b []byte, n int) []byte {
} }
// Realloc resizes the slice to be of length n not preserving content. // Realloc resizes byte slice to be of length n not preserving content.
// If slice length is increased and there is not enough capacity the slice is reallocated. // If slice length is increased and there is not enough capacity the slice is reallocated but not copied.
// The memory for all elements becomes uninitialized. // The memory for all elements becomes uninitialized.
// XXX semantic clash with C realloc(3) ? or it does not matter? //
// NOTE semantic is different from C realloc(3) where content is preserved
// NOTE use Resize when you need to preserve slice content
func Realloc(b []byte, n int) []byte { func Realloc(b []byte, n int) []byte {
return Realloc64(b, int64(n)) return Realloc64(b, int64(n))
} }
...@@ -67,28 +83,3 @@ func Realloc64(b []byte, n int64) []byte { ...@@ -67,28 +83,3 @@ func Realloc64(b []byte, n int64) []byte {
return make([]byte, n, xmath.CeilPow2(uint64(n))) return make([]byte, n, xmath.CeilPow2(uint64(n)))
} }
// TODO MakeRoom
// TODO Prealloc (make sure cap is enough but length stays unchanged) (was GrowSlice)
// TODO Resize without copy ?
// // GrowSlice makes sure cap(b) >= n.
// // If not it reallocates/copies the slice appropriately.
// // len of returned slice remains original len(b).
// func GrowSlice(b []byte, n int) []byte {
// if cap(b) >= n {
// return b
// }
//
// bb := make([]byte, len(b), CeilPow2(uint64(n)))
// copy(bb, b)
// return bb
// }
//
// // makeRoom makes sure len([len(b):cap(b)]) >= n.
// // If it is not it reallocates the slice appropriately.
// // len of returned slice remains original len(b).
// func MakeRoom(b []byte, n int) []byte {
// return GrowSlice(b, len(b) + n)
// }
...@@ -40,10 +40,12 @@ func TestSlice(t *testing.T) { ...@@ -40,10 +40,12 @@ func TestSlice(t *testing.T) {
// here "Hello" is assigned // here "Hello" is assigned
{Grow, 6, 11, 16, false, []byte("Hello\x00\x00\x00\x00\x00\x00")}, {Grow, 6, 11, 16, false, []byte("Hello\x00\x00\x00\x00\x00\x00")},
{Resize, 8, 8, 16, true, []byte("Hello\x00\x00\x00")}, {MakeRoom, 4, 11, 16, true, []byte("Hello\x00\x00\x00\x00\x00\x00")},
{Resize, 17, 17, 32, false, []byte("Hello\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")}, {MakeRoom, 6, 11, 32, false, []byte("Hello\x00\x00\x00\x00\x00\x00")},
{Realloc, 16, 16, 32, true, []byte("Hello\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")}, {Resize, 8, 8, 32, true, []byte("Hello\x00\x00\x00")},
{Realloc, 33, 33, 64, false, make([]byte, 33)}, {Resize, 33, 33, 64, false, append([]byte("Hello"), bytes.Repeat([]byte{0}, 33-5)...)},
{Realloc, 16, 16, 64, true, []byte("Hello\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")},
{Realloc, 65, 65, 128, false, make([]byte, 65)},
} }
for i, tt := range testv { for i, tt := range testv {
...@@ -51,7 +53,7 @@ func TestSlice(t *testing.T) { ...@@ -51,7 +53,7 @@ func TestSlice(t *testing.T) {
s = tt.op(s, tt.n) s = tt.op(s, tt.n)
if !(len(s) == tt.Len && cap(s) == tt.Cap && bytes.Equal(s, tt.content)) { if !(len(s) == tt.Len && cap(s) == tt.Cap && bytes.Equal(s, tt.content)) {
t.Fatalf("step %d: %v: unexpected slice state: %v", i, tt, s) t.Fatalf("step %d: %v: unexpected slice state: %v (cap: %v)", i, tt, s, cap(s))
} }
if !(aliases(s, sprev) == tt.aliased) { if !(aliases(s, sprev) == tt.aliased) {
...@@ -59,7 +61,7 @@ func TestSlice(t *testing.T) { ...@@ -59,7 +61,7 @@ func TestSlice(t *testing.T) {
} }
// assign data after fisrt iteration // assign data after first iteration
if i == 0 { if i == 0 {
copy(s, "Hello") copy(s, "Hello")
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment