mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Remove the old version of buffer.
This is no longer used anywhere in gVisor. Everything has been migrated to bufferv2. PiperOrigin-RevId: 474655746
This commit is contained in:
committed by
gVisor bot
parent
a1d3ba274a
commit
a13fbe75e4
@@ -1,46 +0,0 @@
|
||||
load("//tools:defs.bzl", "go_library", "go_test")
|
||||
load("//tools/go_generics:defs.bzl", "go_template_instance")
|
||||
|
||||
package(licenses = ["notice"])
|
||||
|
||||
go_template_instance(
|
||||
name = "buffer_list",
|
||||
out = "buffer_list.go",
|
||||
package = "buffer",
|
||||
prefix = "buffer",
|
||||
template = "//pkg/ilist:generic_list",
|
||||
types = {
|
||||
"Element": "*buffer",
|
||||
"Linker": "*buffer",
|
||||
},
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "buffer",
|
||||
srcs = [
|
||||
"buffer.go",
|
||||
"buffer_list.go",
|
||||
"pool.go",
|
||||
"view.go",
|
||||
"view_unsafe.go",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/context",
|
||||
"//pkg/log",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "buffer_test",
|
||||
size = "small",
|
||||
srcs = [
|
||||
"buffer_test.go",
|
||||
"pool_test.go",
|
||||
"view_test.go",
|
||||
],
|
||||
library = ":buffer",
|
||||
deps = [
|
||||
"//pkg/state",
|
||||
],
|
||||
)
|
||||
@@ -1,114 +0,0 @@
|
||||
// Copyright 2020 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package buffer provides the implementation of a buffer view.
|
||||
//
|
||||
// A view is an flexible buffer, supporting the safecopy operations natively as
|
||||
// well as the ability to grow via either prepend or append, as well as shrink.
|
||||
package buffer
|
||||
|
||||
import "bytes"
|
||||
|
||||
// buffer encapsulates a queueable byte buffer.
|
||||
//
|
||||
// +stateify savable
|
||||
type buffer struct {
|
||||
data []byte
|
||||
read int
|
||||
write int
|
||||
bufferEntry
|
||||
}
|
||||
|
||||
// init performs in-place initialization for zero value.
|
||||
func (b *buffer) init(size int) {
|
||||
b.data = make([]byte, size)
|
||||
}
|
||||
|
||||
// initWithData initializes b with data, taking ownership.
|
||||
func (b *buffer) initWithData(data []byte) {
|
||||
b.data = data
|
||||
b.read = 0
|
||||
b.write = len(data)
|
||||
}
|
||||
|
||||
// Reset resets read and write locations, effectively emptying the buffer.
|
||||
func (b *buffer) Reset() {
|
||||
b.read = 0
|
||||
b.write = 0
|
||||
}
|
||||
|
||||
// Remove removes r from the unread portion. It returns false if r does not
|
||||
// fully reside in b.
|
||||
func (b *buffer) Remove(r Range) bool {
|
||||
sz := b.ReadSize()
|
||||
switch {
|
||||
case r.Len() != r.Intersect(Range{end: sz}).Len():
|
||||
return false
|
||||
case r.Len() == 0:
|
||||
// Noop
|
||||
case r.begin == 0:
|
||||
b.read += r.end
|
||||
case r.end == sz:
|
||||
b.write -= r.Len()
|
||||
default:
|
||||
// Remove from the middle of b.data.
|
||||
copy(b.data[b.read+r.begin:], b.data[b.read+r.end:b.write])
|
||||
b.write -= r.Len()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Full indicates the buffer is full.
|
||||
//
|
||||
// This indicates there is no capacity left to write.
|
||||
func (b *buffer) Full() bool {
|
||||
return b.write == len(b.data)
|
||||
}
|
||||
|
||||
// ReadSize returns the number of bytes available for reading.
|
||||
func (b *buffer) ReadSize() int {
|
||||
return b.write - b.read
|
||||
}
|
||||
|
||||
// ReadMove advances the read index by the given amount.
|
||||
func (b *buffer) ReadMove(n int) {
|
||||
b.read += n
|
||||
}
|
||||
|
||||
// ReadSlice returns the read slice for this buffer.
|
||||
func (b *buffer) ReadSlice() []byte {
|
||||
return b.data[b.read:b.write]
|
||||
}
|
||||
|
||||
// WriteSize returns the number of bytes available for writing.
|
||||
func (b *buffer) WriteSize() int {
|
||||
return len(b.data) - b.write
|
||||
}
|
||||
|
||||
// WriteMove advances the write index by the given amount.
|
||||
func (b *buffer) WriteMove(n int) {
|
||||
b.write += n
|
||||
}
|
||||
|
||||
// WriteSlice returns the write slice for this buffer.
|
||||
func (b *buffer) WriteSlice() []byte {
|
||||
return b.data[b.write:]
|
||||
}
|
||||
|
||||
// Reader returns a bytes.Reader for v.
|
||||
func (b *buffer) Reader() bytes.Reader {
|
||||
var r bytes.Reader
|
||||
r.Reset(b.ReadSlice())
|
||||
return r
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
// Copyright 2021 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package buffer
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBufferRemove(t *testing.T) {
|
||||
sample := []byte("01234567")
|
||||
|
||||
// Success cases
|
||||
for _, tc := range []struct {
|
||||
desc string
|
||||
data []byte
|
||||
rng Range
|
||||
want []byte
|
||||
}{
|
||||
{
|
||||
desc: "empty slice",
|
||||
},
|
||||
{
|
||||
desc: "empty range",
|
||||
data: sample,
|
||||
want: sample,
|
||||
},
|
||||
{
|
||||
desc: "empty range with positive begin",
|
||||
data: sample,
|
||||
rng: Range{begin: 1, end: 1},
|
||||
want: sample,
|
||||
},
|
||||
{
|
||||
desc: "range at beginning",
|
||||
data: sample,
|
||||
rng: Range{begin: 0, end: 1},
|
||||
want: sample[1:],
|
||||
},
|
||||
{
|
||||
desc: "range in middle",
|
||||
data: sample,
|
||||
rng: Range{begin: 2, end: 4},
|
||||
want: []byte("014567"),
|
||||
},
|
||||
{
|
||||
desc: "range at end",
|
||||
data: sample,
|
||||
rng: Range{begin: 7, end: 8},
|
||||
want: sample[:7],
|
||||
},
|
||||
{
|
||||
desc: "range all",
|
||||
data: sample,
|
||||
rng: Range{begin: 0, end: 8},
|
||||
},
|
||||
} {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
var buf buffer
|
||||
buf.initWithData(tc.data)
|
||||
if ok := buf.Remove(tc.rng); !ok {
|
||||
t.Errorf("buf.Remove(%#v) = false, want true", tc.rng)
|
||||
} else if got := buf.ReadSlice(); !bytes.Equal(got, tc.want) {
|
||||
t.Errorf("buf.ReadSlice() = %q, want %q", got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Failure cases
|
||||
for _, tc := range []struct {
|
||||
desc string
|
||||
data []byte
|
||||
rng Range
|
||||
}{
|
||||
{
|
||||
desc: "begin out-of-range",
|
||||
data: sample,
|
||||
rng: Range{begin: -1, end: 4},
|
||||
},
|
||||
{
|
||||
desc: "end out-of-range",
|
||||
data: sample,
|
||||
rng: Range{begin: 4, end: 9},
|
||||
},
|
||||
{
|
||||
desc: "both out-of-range",
|
||||
data: sample,
|
||||
rng: Range{begin: -100, end: 100},
|
||||
},
|
||||
} {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
var buf buffer
|
||||
buf.initWithData(tc.data)
|
||||
if ok := buf.Remove(tc.rng); ok {
|
||||
t.Errorf("buf.Remove(%#v) = true, want false", tc.rng)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
// Copyright 2020 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package buffer
|
||||
|
||||
const (
|
||||
// embeddedCount is the number of buffer structures embedded in the pool. It
|
||||
// is also the number for overflow allocations.
|
||||
embeddedCount = 8
|
||||
|
||||
// defaultBufferSize is the default size for each underlying storage buffer.
|
||||
//
|
||||
// It is slightly less than two pages. This is done intentionally to ensure
|
||||
// that the buffer object aligns with runtime internals. This two page size
|
||||
// will effectively minimize internal fragmentation, but still have a large
|
||||
// enough chunk to limit excessive segmentation.
|
||||
defaultBufferSize = 8144
|
||||
)
|
||||
|
||||
// pool allocates buffer.
|
||||
//
|
||||
// It contains an embedded buffer storage for fast path when the number of
|
||||
// buffers needed is small.
|
||||
//
|
||||
// +stateify savable
|
||||
type pool struct {
|
||||
bufferSize int
|
||||
avail []buffer `state:"nosave"`
|
||||
embeddedStorage [embeddedCount]buffer `state:"wait"`
|
||||
}
|
||||
|
||||
// get gets a new buffer from p.
|
||||
func (p *pool) get() *buffer {
|
||||
buf := p.getNoInit()
|
||||
buf.init(p.bufferSize)
|
||||
return buf
|
||||
}
|
||||
|
||||
// get gets a new buffer from p without initializing it.
|
||||
func (p *pool) getNoInit() *buffer {
|
||||
if p.avail == nil {
|
||||
p.avail = p.embeddedStorage[:]
|
||||
}
|
||||
if len(p.avail) == 0 {
|
||||
p.avail = make([]buffer, embeddedCount)
|
||||
}
|
||||
if p.bufferSize <= 0 {
|
||||
p.bufferSize = defaultBufferSize
|
||||
}
|
||||
buf := &p.avail[0]
|
||||
p.avail = p.avail[1:]
|
||||
return buf
|
||||
}
|
||||
|
||||
// put releases buf.
|
||||
func (p *pool) put(buf *buffer) {
|
||||
// Remove reference to the underlying storage, allowing it to be garbage
|
||||
// collected.
|
||||
buf.data = nil
|
||||
buf.Reset()
|
||||
}
|
||||
|
||||
// setBufferSize sets the size of underlying storage buffer for future
|
||||
// allocations. It can be called at any time.
|
||||
func (p *pool) setBufferSize(size int) {
|
||||
p.bufferSize = size
|
||||
}
|
||||
|
||||
// afterLoad is invoked by stateify.
|
||||
func (p *pool) afterLoad() {
|
||||
// S/R does not save subslice into embeddedStorage correctly. Restore
|
||||
// available portion of embeddedStorage manually. Restore as nil if none used.
|
||||
for i := len(p.embeddedStorage); i > 0; i-- {
|
||||
if p.embeddedStorage[i-1].data != nil {
|
||||
p.avail = p.embeddedStorage[i:]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
// Copyright 2020 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package buffer
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetDefaultBufferSize(t *testing.T) {
|
||||
var p pool
|
||||
for i := 0; i < embeddedCount*2; i++ {
|
||||
buf := p.get()
|
||||
if got, want := len(buf.data), defaultBufferSize; got != want {
|
||||
t.Errorf("#%d len(buf.data) = %d, want %d", i, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCustomBufferSize(t *testing.T) {
|
||||
const size = 100
|
||||
|
||||
var p pool
|
||||
p.setBufferSize(size)
|
||||
for i := 0; i < embeddedCount*2; i++ {
|
||||
buf := p.get()
|
||||
if got, want := len(buf.data), size; got != want {
|
||||
t.Errorf("#%d len(buf.data) = %d, want %d", i, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPut(t *testing.T) {
|
||||
var p pool
|
||||
buf := p.get()
|
||||
p.put(buf)
|
||||
if buf.data != nil {
|
||||
t.Errorf("buf.data = %x, want nil", buf.data)
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,25 +0,0 @@
|
||||
// Copyright 2020 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package buffer
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// minBatch is the smallest Read or Write operation that the
|
||||
// WriteFromReader and ReadToWriter functions will use.
|
||||
//
|
||||
// This is defined as the size of a native pointer.
|
||||
const minBatch = int(unsafe.Sizeof(uintptr(0)))
|
||||
Reference in New Issue
Block a user