Skip to content

Instantly share code, notes, and snippets.

@gobwas
Created May 27, 2018 19:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gobwas/89ab3ecd1dd007bd4ec92a17b537d07d to your computer and use it in GitHub Desktop.
Save gobwas/89ab3ecd1dd007bd4ec92a17b537d07d to your computer and use it in GitHub Desktop.
var cowPool sync.Pool
func acquireCow(r io.Reader) *cow {
if c, ok := cowPool.Get().(*cow); ok {
c.r = r
return c
}
return &cow{r: r}
}
func releaseCow(c *cow) {
cowPool.Put(c)
}
type cow struct {
r io.Reader
n int
sz int
ps [1]uintptr
}
func (r *cow) Read(p []byte) (int, error) {
if r.sz > 0 {
r.move()
}
return r.r.Read(p)
}
func (r *cow) move() {
cp := make([]byte, r.sz)
for i, ptr := range r.ps {
p := (*[]byte)(unsafe.Pointer(ptr))
n := copy(cp, *p)
*p = cp[:n]
cp = cp[n:]
r.ps[i] = 0
}
r.n = 0
r.sz = 0
}
func (r *cow) add(p uintptr, n int) {
r.ps[r.n] = p
r.n++
r.sz += n
}
func (r *cow) del(p uintptr, n int) {
for i := 0; i < r.n; i++ {
if r.ps[i] == p {
r.n--
r.sz -= n
r.ps[i] = r.ps[r.n]
r.ps[r.n] = 0
return
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment