Documentation
¶
Overview ¶
Example ¶
package main import ( "bytes" "encoding/gob" "fmt" "log" "github.com/weiwenchen2022/freelist" ) type P struct { X, Y, Z int Name string } type Q struct { X, Y *int32 Name string next *Q // for free list } var freeQ = &freelist.FreeList[Q]{ New: func() *Q { return new(Q) }, Reset: func(q *Q) { *q = Q{} }, } func main() { // Initialize the encoder and decoder. Normally enc and dec would be // bound to network connections and the encoder and decoder would // run in different processes. var network bytes.Buffer // Stand-in for a network connection enc := gob.NewEncoder(&network) // Will write to network. dec := gob.NewDecoder(&network) // Will read from network. // Encode (send) some values. if err := enc.Encode(P{3, 4, 5, "Pythagoras"}); err != nil { log.Fatal("encode error:", err) } if err := enc.Encode(P{1782, 1841, 1922, "Treehouse"}); err != nil { log.Fatal("encode error:", err) } // Decode (receive) and print the values. var q = freeQ.Get() defer freeQ.Put(q) if err := dec.Decode(q); err != nil { log.Fatal("decode error 1:", err) } fmt.Printf("%q: {%d, %d}\n", q.Name, *q.X, *q.Y) q = freeQ.Get() defer freeQ.Put(q) if err := dec.Decode(q); err != nil { log.Fatal("decode error 2:", err) } fmt.Printf("%q: {%d, %d}\n", q.Name, *q.X, *q.Y) }
Output: "Pythagoras": {3, 4} "Treehouse": {1782, 1841}
Example (Wrapper) ¶
package main import ( "bytes" "io" "os" "time" "github.com/weiwenchen2022/freelist" ) type Buf struct { *bytes.Buffer next *Buf // for free list } var freeBuf = freelist.FreeList[Buf]{ New: func() *Buf { return &Buf{Buffer: new(bytes.Buffer)} }, Reset: (*Buf).Reset, } // timeNow is a fake version of time.Now for tests. func timeNow() time.Time { return time.Unix(1136214245, 0) } func Log(w io.Writer, key, val string) { b := freeBuf.Get() defer freeBuf.Put(b) // Replace this with time.Now() in a real logger. b.WriteString(timeNow().UTC().Format(time.RFC3339)) b.WriteByte(' ') b.WriteString(key) b.WriteByte('=') b.WriteString(val) _, _ = io.Copy(w, b) } func main() { Log(os.Stdout, "path", "/search?q=flowers") }
Output: 2006-01-02T15:04:05Z path=/search?q=flowers
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type FreeList ¶
type FreeList[E any] struct { // New optionally specifies a function to generate // a value when Get would otherwise return nil. // It may not be changed concurrently with calls to Get. New func() *E // Reset optionally specifies a function to reset // a value when Get would return a cached value. // It may not be changed concurrently with calls to Get. Reset func(*E) // contains filtered or unexported fields }
A FreeList is a set of temporary objects that may be individually saved and retrieved.
Any item stored in the FreeList must be a struct look schematically like
type T struct { ... next *T ... }
A FreeList is safe for use by multiple goroutines simultaneously.
FreeList's purpose is to cache allocated but unused items for later reuse, relieving pressure on the garbage collector. That is, it makes it easy to build efficient, thread-safe free lists.
An appropriate use of a FreeList is to manage a group of temporary items silently shared among and potentially reused by concurrent independent clients of a package. FreeList provides a way to amortize allocation overhead across many clients.
On the other hand, a free list maintained as part of a short-lived object is not a suitable use for a FreeList, since the overhead does not amortize well in that scenario. It is more efficient to have such objects implement their own free list.
A FreeList must not be copied after first use.
In the terminology of the Go memory model, a call to Put(x) “synchronizes before” a call to Get returning that same value x. Similarly, a call to New returning x “synchronizes before” a call to Get returning that same value x.
func (*FreeList[E]) Get ¶
func (l *FreeList[E]) Get() *E
Get selects a last put back item from the FreeList, removes it from the FreeList, if l.Reset is non-nil calling l.Reset with it, and returns it to the caller.
If Get would otherwise return nil and l.New is non-nil, Get returns the result of calling l.New.