Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
124 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package fasthttp | ||
|
||
import ( | ||
"sync" | ||
) | ||
|
||
const ( | ||
defaultByteBufferSize = 128 | ||
) | ||
|
||
// ByteBuffer provides byte buffer, which can be used with fasthttp API | ||
// in order to minimize memory allocations. | ||
// | ||
// ByteBuffer may be used with functions appending data to the given []byte | ||
// slice. See example code for details. | ||
// | ||
// Use AcquireByteBuffer for obtaining an empty byte buffer. | ||
type ByteBuffer struct { | ||
B []byte | ||
} | ||
|
||
// AcquireByteBuffer returns an empty byte buffer from the pool. | ||
// | ||
// Acquired byte buffer may be returned to the pool via ReleaseByteBuffer call. | ||
// This reduces the number of memory allocations required for byte buffer | ||
// management. | ||
func AcquireByteBuffer() *ByteBuffer { | ||
v := byteBufferPool.Get() | ||
if v == nil { | ||
return &ByteBuffer{ | ||
B: make([]byte, 0, defaultByteBufferSize), | ||
} | ||
} | ||
return v.(*ByteBuffer) | ||
} | ||
|
||
// ReleaseByteBuffer returns byte buffer to the pool. | ||
// | ||
// ByteBuffer.B mustn't be touched after returning it to the pool. | ||
// Otherwise data races occur. | ||
func ReleaseByteBuffer(b *ByteBuffer) { | ||
b.B = b.B[:0] | ||
byteBufferPool.Put(b) | ||
} | ||
|
||
var byteBufferPool sync.Pool |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package fasthttp_test | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/valyala/fasthttp" | ||
) | ||
|
||
func ExampleByteBuffer() { | ||
// This request handler sets 'Your-IP' response header | ||
// to 'Your IP is <ip>'. It uses ByteBuffer for constructing response | ||
// header value with zero memory allocations. | ||
yourIPRequestHandler := func(ctx *fasthttp.RequestCtx) { | ||
b := fasthttp.AcquireByteBuffer() | ||
b.B = append(b.B, "Your IP is <"...) | ||
b.B = fasthttp.AppendIPv4(b.B, ctx.RemoteIP()) | ||
b.B = append(b.B, ">"...) | ||
ctx.Response.Header.SetBytesV("Your-IP", b.B) | ||
|
||
fmt.Fprintf(ctx, "Check response headers - they must contain 'Your-IP: %s", b.B) | ||
|
||
// It is safe to release byte buffer now, since it is | ||
// no longer used. | ||
fasthttp.ReleaseByteBuffer(b) | ||
} | ||
|
||
// Start fasthttp server returning your ip in response headers. | ||
fasthttp.ListenAndServe(":8080", yourIPRequestHandler) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package fasthttp | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
"time" | ||
) | ||
|
||
func TestByteBufferAcquireReleaseSerial(t *testing.T) { | ||
testByteBufferAcquireRelease(t) | ||
} | ||
|
||
func TestByteBufferAcquireReleaseConcurrent(t *testing.T) { | ||
concurrency := 10 | ||
ch := make(chan struct{}, concurrency) | ||
for i := 0; i < concurrency; i++ { | ||
go func() { | ||
testByteBufferAcquireRelease(t) | ||
ch <- struct{}{} | ||
}() | ||
} | ||
|
||
for i := 0; i < concurrency; i++ { | ||
select { | ||
case <-ch: | ||
case <-time.After(time.Second): | ||
t.Fatalf("timeout!") | ||
} | ||
} | ||
} | ||
|
||
func testByteBufferAcquireRelease(t *testing.T) { | ||
for i := 0; i < 10; i++ { | ||
b := AcquireByteBuffer() | ||
b.B = append(b.B, "num "...) | ||
b.B = AppendUint(b.B, i) | ||
expectedS := fmt.Sprintf("num %d", i) | ||
if string(b.B) != expectedS { | ||
t.Fatalf("unexpected result: %q. Expecting %q", b.B, expectedS) | ||
} | ||
ReleaseByteBuffer(b) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters