forked from bradfitz/gomemcache
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow result memory to be allocated from per-call Allocator (#8)
Remove the existing Client.Pool for pooling memory used by cache results and replace it with an optional per-call Allocator. The per-call allocator allows callers to determine the correct lifecycle for anything allocated. Signed-off-by: Nick Pillitteri <nick.pillitteri@grafana.com>
- Loading branch information
1 parent
8ab22a7
commit c1cca81
Showing
4 changed files
with
106 additions
and
51 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
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
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
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,59 @@ | ||
package memcache | ||
|
||
var nopAllocator = &defaultAllocator{} | ||
|
||
func newOptions(opts ...Option) *Options { | ||
o := &Options{ | ||
Alloc: nopAllocator, | ||
} | ||
|
||
for _, opt := range opts { | ||
opt(o) | ||
} | ||
|
||
return o | ||
} | ||
|
||
// Options are used to modify the behavior of an individual Get or GetMulti | ||
// call made by the Client. They are constructed by applying Option callbacks | ||
// passed to a Client method to a default Options instance. | ||
type Options struct { | ||
Alloc Allocator | ||
} | ||
|
||
// Option is a callback used to modify the Options that a particular Client | ||
// method uses. | ||
type Option func(opts *Options) | ||
|
||
// WithAllocator creates a new Option that makes use of a specific memory Allocator | ||
// for result values (Item.Value) loaded from memcached. | ||
func WithAllocator(alloc Allocator) Option { | ||
return func(opts *Options) { | ||
opts.Alloc = alloc | ||
} | ||
} | ||
|
||
// Allocator allows memory for memcached result values (Item.Value) to managed by | ||
// callers of the Client instead of by the Client itself. For example, this can be | ||
// used by callers to implement arena-style memory management. The default implementation | ||
// used, when not otherwise overridden, uses `make` and relies on GC for cleanup. | ||
type Allocator interface { | ||
// Get returns a byte slice with at least sz capacity. Length of the slice is | ||
// not guaranteed and so must be asserted by callers (the Client). | ||
Get(sz int) *[]byte | ||
// Put returns the byte slice to the underlying allocator. The Client will | ||
// only call this method during error handling when allocated values are not | ||
// returned to the caller as cache results. | ||
Put(b *[]byte) | ||
} | ||
|
||
type defaultAllocator struct{} | ||
|
||
func (d defaultAllocator) Get(sz int) *[]byte { | ||
b := make([]byte, sz) | ||
return &b | ||
} | ||
|
||
func (d defaultAllocator) Put(_ *[]byte) { | ||
// no-op | ||
} |