forked from lightningnetwork/lnd
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
lnpeer/write_buffer_pool: adds write buffer pool
- Loading branch information
1 parent
0118120
commit 0670db2
Showing
1 changed file
with
79 additions
and
0 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,79 @@ | ||
package lnpeer | ||
|
||
import ( | ||
"time" | ||
|
||
"github.com/lightningnetwork/lnd/lnwire" | ||
"github.com/lightningnetwork/lnd/queue" | ||
) | ||
|
||
const ( | ||
// DefaultGCInterval is the default interval that the WriteBufferPool | ||
// will perform a sweep to see which expired buffers can be released to | ||
// the runtime. | ||
DefaultGCInterval = 15 * time.Second | ||
|
||
// DefaultExpiryInterval is the default, minimum interval that must | ||
// elapse before a WriteBuffer will be released. The maximum time before | ||
// the buffer can be released is equal to the expiry interval plus the | ||
// gc interval. | ||
DefaultExpiryInterval = 30 * time.Second | ||
) | ||
|
||
// WriteBuffer is static byte array occupying to maximum-allowed | ||
// plaintext-message size. | ||
type WriteBuffer [lnwire.MaxMessagePayload]byte | ||
|
||
// Recycle zeroes the WriteBuffer, making it fresh for another use. | ||
// Zeroing the buffer using a logarithmic number of calls to the optimized copy | ||
// method. Benchmarking shows this to be ~30 times faster than a for loop that | ||
// sets each index to 0 for this buffer size. Inspired by: | ||
// https://stackoverflow.com/questions/30614165/is-there-analog-of-memset-in-go | ||
// | ||
// This is part of the queue.Recycler interface. | ||
func (b *WriteBuffer) Recycle() { | ||
b[0] = 0 | ||
for i := 1; i < lnwire.MaxMessagePayload; i *= 2 { | ||
copy(b[i:], b[:i]) | ||
} | ||
} | ||
|
||
// newRecyclableWriteBuffer is a constructor that returns a WriteBuffer typed as | ||
// a queue.Recycler. | ||
func newRecyclableWriteBuffer() queue.Recycler { | ||
return new(WriteBuffer) | ||
} | ||
|
||
// A compile-time constraint to ensure that *WriteBuffer implements the | ||
// queue.Recycler interface. | ||
var _ queue.Recycler = (*WriteBuffer)(nil) | ||
|
||
// WriteBufferPool acts a global pool of WriteBuffers, that dynamically | ||
// allocates and reclaims buffers in response to load. | ||
type WriteBufferPool struct { | ||
pool *queue.GCQueue | ||
} | ||
|
||
// NewWriteBufferPool returns a freshly instantiated WriteBufferPool, using the | ||
// given gcInterval and expiryIntervals. | ||
func NewWriteBufferPool( | ||
gcInterval, expiryInterval time.Duration) *WriteBufferPool { | ||
|
||
return &WriteBufferPool{ | ||
pool: queue.NewGCQueue( | ||
newRecyclableWriteBuffer, 100, | ||
gcInterval, expiryInterval, | ||
), | ||
} | ||
} | ||
|
||
// Take returns a fresh WriteBuffer to the caller. | ||
func (p *WriteBufferPool) Take() *WriteBuffer { | ||
return p.pool.Take().(*WriteBuffer) | ||
} | ||
|
||
// Return returns the WriteBuffer to the pool, so that it can be recycled or | ||
// released. | ||
func (p *WriteBufferPool) Return(buf *WriteBuffer) { | ||
p.pool.Return(buf) | ||
} |