首页 > 其他分享 >go-buffer-pool

go-buffer-pool

时间:2024-03-26 16:36:19浏览次数:18  
标签:Get buffer length bp go uint32 pool

go-buffer-pool

go-buffer-pool

package pool

import (
  "math"
  "math/bits"
  "sync"
)

// GlobalPool is a static Pool for reusing byteslices of various sizes.
var GlobalPool = new(BufferPool)

// MaxLength is the maximum length of an element that can be added to the Pool.
const MaxLength = math.MaxInt32

// BufferPool is a pool to handle cases of reusing elements of varying sizes. It
// maintains 32 internal pools, for each power of 2 in 0-32.
//
// You should generally just call the package level Get and Put methods or use
// the GlobalPool BufferPool instead of constructing your own.
//
// You MUST NOT copy Pool after using.
type BufferPool struct {
  pools [32]sync.Pool // a list of singlePools
  ptrs  sync.Pool
}

type bufp struct {
  buf []byte
}

// Get retrieves a buffer of the appropriate length from the buffer pool or
// allocates a new one. Get may choose to ignore the pool and treat it as empty.
// Callers should not assume any relation between values passed to Put and the
// values returned by Get.
//
// If no suitable buffer exists in the pool, Get creates one.
func (p *BufferPool) Get(length int) []byte {
  if length == 0 {
    return nil
  }
  // Calling this function with a negative length is invalid.
  // make will panic if length is negative, so we don't have to.
  if length > MaxLength || length < 0 {
    return make([]byte, length)
  }
  idx := nextLogBase2(uint32(length))
  if ptr := p.pools[idx].Get(); ptr != nil {
    bp := ptr.(*bufp)
    buf := bp.buf[:uint32(length)]
    bp.buf = nil
    p.ptrs.Put(ptr)
    return buf
  }
  return make([]byte, 1<<idx)[:uint32(length)]
}

// Put adds x to the pool.
func (p *BufferPool) Put(buf []byte) {
  capacity := cap(buf)
  if capacity == 0 || capacity > MaxLength {
    return // drop it
  }
  idx := prevLogBase2(uint32(capacity))
  var bp *bufp
  if ptr := p.ptrs.Get(); ptr != nil {
    bp = ptr.(*bufp)
  } else {
    bp = new(bufp)
  }
  bp.buf = buf
  p.pools[idx].Put(bp)
}

// Get retrieves a buffer of the appropriate length from the global buffer pool
// (or allocates a new one).
func Get(length int) []byte {
  return GlobalPool.Get(length)
}

// Put returns a buffer to the global buffer pool.
func Put(slice []byte) {
  GlobalPool.Put(slice)
}

// Log of base two, round up (for v > 0).
func nextLogBase2(v uint32) uint32 {
  return uint32(bits.Len32(v - 1))
}

// Log of base two, round down (for v > 0)
func prevLogBase2(num uint32) uint32 {
  next := nextLogBase2(num)
  if num == (1 << uint32(next)) {
    return next
  }
  return next - 1
}

README

这段代码写的真的非常的漂亮

主要有这么几个地方

  1. 使用指数位数的点位进行处理
  2. 封装bufp , 与使用 *[]byte的方式相比, 减少了一次解引用时切片头的复制, 这个是很容易忽略的

标签:Get,buffer,length,bp,go,uint32,pool
From: https://www.cnblogs.com/pDJJq/p/18096984/gobufferpool-1ff09b

相关文章

  • [YU-RIS] Whirlpool社的一些观察
    [YU-RIS引擎]Whirlpool社的一些观察对于原版的yuris引擎,只需要解包后对ybn进文本的导出导入,然后把SJIS范围的检查表改成GBK的即可对于yuris来说CreateFont其实是默认依据系统判断的,一般都可以不用改。Whirlpool比较奇葩点,他们用的好像是改过的yuris引擎,ybn里不包含游戏的文本......
  • 分享一个项目:go `file_line`,在编译器得到源码行号,减少运行期runtime消耗
    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!cnblogs博客zhihuGithub公众号:一本正经的瞎扯file_linehttps://github.com/ahfuzhang/file_lineLike__FILE__/__LINE__ofC:usegogeneratetogetsourcecodelinenumberatcompiletime.像C语言里面......
  • 【IT老齐054】MongoDB介绍
    【IT老齐054】MongoDB介绍场景特点多形性:同一个集合中可以包含不同字段(类型)的文档对象动态性:线上修改数据模式,修改是应用与数据库均无须下线数据治理:支持使用JSONSchema来规范数据模式。在保证模式灵活动态的前提下,提供数据治理能力速度优势数据库引擎只需要在......
  • Django_Restful_Framework视图与路由
    视图与路由drf除了在数据序列化部分简写代码以外,还在视图中提供了简写操作。所以在django原有的django.views.View类基础上,drf封装了多个子类出来提供给我们使用。**DjangoRESTframwork**提供的视图的主要作用:控制序列化器的执行(检验、保存、转换数据)控制数据库查询的执......
  • Go 切片
    Go切片切片结构源码包src/runtime/slice.go中定义slice的结构为typeslicestruct{arrayunsafe.Pointerlenintcapint}array指针指向底层数组len表示切片长度cap表示切片容量切片扩容机制go1.18之后:growslice方法中可以得知go切片......
  • 使用go语言, 如何 只需一步调用,创建支付宝代扣
    使用go语言,如何只需一步调用,创建支付宝代扣  目标原理快速使用gitclonehttps://github.com/284851828/alilite_go.gitgomodtidygorundemo.go"#alilite_go"packagemainimport( "log" "time" c"alilite/client"//Replacewith......
  • Django_Restful_Framework
    1.Web应用模式在开发Web应用中,有两种应用模式:前后端不分离前后端分离2.api接口为了在团队内部形成共识、防止个人习惯差异引起的混乱,我们需要找到一种大家都觉得很好的接口实现规范,而且这种规范能够让后端写的接口,用途一目了然,减少双方之间的合作成本。目前市面上大部......
  • nexus 代理 go
    创建 BlobStores创建Repositoriesnginx配置server{listen19000;server_namelocalhost;#设置代理访问日志access_loglogs/yum.access.log;error_loglogs/yum.error.log;location/goproxy/{ proxy_passhtt......
  • 理解 go mod init 命令
    gomodinit命令是Go1.11中引入的Go模块系统的基本组成部分。它用于创建或初始化Go模块,是管理Go项目中依赖关系和版本的一种方法。下面是关于gomodinit的全部内容:1.初始化Go模块gomodinit命令的主要用途是初始化项目中的Go模块。Go模块是指与版本相关......
  • 使用Go语言开发一个短链接服务:一、基本原理
    章节 使用Go语言开发一个短链接服务:一、基本原理 使用Go语言开发一个短链接服务:二、架构设计 使用Go语言开发一个短链接服务:三、项目目录结构设计 使用Go语言开发一个短链接服务:四、生成code算法 使用Go语言开发一个短链接服务:五、添加和获取短链接 使用Go语言开......