Files
Dmitry Verkhoturov 07c7926453 Update backend dependencies to latest
Update all Go modules in backend/ and backend/_example/memory_store/ to
their latest versions (chroma 2.27, go-redis 9.21, bbolt 1.5, slack 0.27,
golang.org/x/* and others); re-tidy and re-vendor, keep the example module
in sync.

Hold github.com/go-chi/chi/v5 at v5.2.5: v5.3.0 deprecates
middleware.RealIP (IP-spoofing advisories). Switching off RealIP changes
how the client IP is derived for rate limiting and votes, which is a
security decision better made on its own rather than inside a dependency
bump.

go test -race, go vet, golangci-lint and govulncheck all clean on both
modules.
2026-06-30 18:35:31 +01:00

77 lines
1.7 KiB
Go

package regexp2
import (
"bytes"
"slices"
"sync"
)
type pooledSliceBuffers[T any] struct {
sizes []int
pools []sync.Pool
}
func newPooledSliceBuffers[T any](sizes ...int) *pooledSliceBuffers[T] {
sizes = slices.Clone(sizes)
slices.Sort(sizes)
return &pooledSliceBuffers[T]{
sizes: sizes,
pools: make([]sync.Pool, len(sizes)),
}
}
func (p *pooledSliceBuffers[T]) poolIndex(neededSize, maxSize int) int {
if maxSize == 0 {
return -1
}
for i, classSize := range p.sizes {
if neededSize <= classSize {
if maxSize > 0 && classSize > maxSize {
return -1
}
return i
}
}
return -1
}
func (p *pooledSliceBuffers[T]) get(neededSize, maxSize int) ([]T, *[]T) {
idx := p.poolIndex(neededSize, maxSize)
if idx < 0 {
return make([]T, neededSize), nil
}
if v := p.pools[idx].Get(); v != nil {
bufp := v.(*[]T)
if cap(*bufp) >= neededSize {
return (*bufp)[:neededSize], bufp
}
}
buf := make([]T, neededSize, p.sizes[idx])
return buf, &buf
}
func (p *pooledSliceBuffers[T]) put(bufp *[]T) {
idx := p.poolIndex(cap(*bufp), -1)
if idx < 0 || cap(*bufp) != p.sizes[idx] {
return
}
*bufp = (*bufp)[:0]
p.pools[idx].Put(bufp)
}
// our specific pooled buffers
var (
pooledRuneBuffers = newPooledSliceBuffers[rune](1<<10, 4<<10, 16<<10, 64<<10, 256<<10)
pooledByteBuffers = newPooledSliceBuffers[byte](4<<10, 16<<10, 64<<10, 256<<10, 1<<20)
)
func getPooledReplaceBuffer(neededBytes, maxSize int) (*bytes.Buffer, *[]byte) {
buf, pooled := pooledByteBuffers.get(neededBytes, maxSize)
return bytes.NewBuffer(buf[:0]), pooled
}
func putPooledReplaceBuffer(buf *bytes.Buffer, pooled *[]byte) {
*pooled = buf.Bytes()
pooledByteBuffers.put(pooled)
}