slot_pool.go 877 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. package mem
  2. import (
  3. "sync"
  4. )
  5. var pools []*sync.Pool
  6. const (
  7. min_size = 1024
  8. )
  9. func bitCount(size int) (count int) {
  10. for ; size > min_size; count++ {
  11. size = (size + 1) >> 1
  12. }
  13. return
  14. }
  15. func init() {
  16. // 1KB ~ 256MB
  17. pools = make([]*sync.Pool, bitCount(1024*1024*256))
  18. for i := 0; i < len(pools); i++ {
  19. slotSize := 1024 << i
  20. pools[i] = &sync.Pool{
  21. New: func() interface{} {
  22. buffer := make([]byte, slotSize)
  23. return &buffer
  24. },
  25. }
  26. }
  27. }
  28. func getSlotPool(size int) (*sync.Pool, bool) {
  29. index := bitCount(size)
  30. if index >= len(pools) {
  31. return nil, false
  32. }
  33. return pools[index], true
  34. }
  35. func Allocate(size int) []byte {
  36. if pool, found := getSlotPool(size); found {
  37. slab := *pool.Get().(*[]byte)
  38. return slab[:size]
  39. }
  40. return make([]byte, size)
  41. }
  42. func Free(buf []byte) {
  43. if pool, found := getSlotPool(cap(buf)); found {
  44. pool.Put(&buf)
  45. }
  46. }