Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1480)

Unified Diff: common/sync/bufferpool/buffer_pool.go

Issue 2596633002: Add bufferpool, a sync.Pool-backed pool of buffers (Closed)
Patch Set: Move to "common/sync" Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | common/sync/bufferpool/buffer_pool_test.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: common/sync/bufferpool/buffer_pool.go
diff --git a/common/sync/bufferpool/buffer_pool.go b/common/sync/bufferpool/buffer_pool.go
new file mode 100644
index 0000000000000000000000000000000000000000..96695b63864f4fb626e972386c07b1e30df1dcf3
--- /dev/null
+++ b/common/sync/bufferpool/buffer_pool.go
@@ -0,0 +1,70 @@
+// Copyright 2016 The LUCI Authors. All rights reserved.
+// Use of this source code is governed under the Apache License, Version 2.0
+// that can be found in the LICENSE file.
+
+// Package bufferpool implements a pool of bytes.Buffer instances backed by
+// a sync.Pool. The goal of using a buffer pool is that, in exchange for some
+// locking overhead, the user can avoid iteratively reallocating buffers for
+// frequently used purposes.
+//
+// Ideal usage of bufferpool is with like-purposed buffers in order to encourage
+// the pool to contain buffers sized to that specific purpose. If this is
+// correctly implemented, the buffers in the pool should generally come into
+// existence, grow to the purpose's size need, and then remain there without
+// further allocation.
+//
+// An overly-broad-purposed pool, on the other hand, will have its buffers grow
+// to max(purpose...) size and consequently contain more large buffers than
+// necessary.
+package bufferpool
+
+import (
+ "bytes"
+ "sync"
+)
+
+// P is a pool of buffers. The zero value is an initialized but empty pool.
+//
+// P must be passed around as reference, not value.
+type P struct {
+ pool sync.Pool
+}
+
+// Get returns a Buffer. When the caller is finished with the Buffer, they
+// should call Release to return it to its pool.
+func (p *P) Get() *Buffer {
+ buf, ok := p.pool.Get().(*Buffer)
+ if !ok {
+ buf = &Buffer{
+ Buffer: &bytes.Buffer{},
+ p: p,
+ }
+ }
+ return buf
+}
+
+// Buffer is a bytes.Buffer that is bound to a pool. It should not be used
+// directly, but rather obtained through calling Get on a P instance.
+type Buffer struct {
+ *bytes.Buffer
+
+ p *P
+}
+
+// Clone clones the contents of the buffer's Bytes, returning an indepdent
+// duplicate []byte.
+func (b *Buffer) Clone() []byte {
+ return append([]byte(nil), b.Bytes()...)
+}
+
+// Release returns this Buffer to its pool.
+//
+// After calling Release, no accesses may be made to b or its internal data.
Vadim Sh. 2016/12/20 23:11:51 you can ensure this by setting b.p and b.Buffer to
Vadim Sh. 2016/12/20 23:13:51 Hm... For that, sync.Pool must hold referenced to
dnj 2016/12/21 00:54:38 Done.
+// If its data is to be retained, it must be cloned prior to Release (see
+// Clone).
+func (b *Buffer) Release() {
+ if b.p != nil {
+ b.Reset()
+ b.p.pool.Put(b)
+ }
+}
« no previous file with comments | « no previous file | common/sync/bufferpool/buffer_pool_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698