golang实现Ringbuf

Ring buffer算法优点:高内存使用率,在缓冲buffer内存模型中,不太容易发生内存越界、悬空指针等 bug ,出了问题也容易在内存级别分析调试。做出来的系统容易保持健壮。

package main

import (
	"bytes"
	"fmt"
)

type Ringbuf struct {
	buf         []byte
	start, size int
}

func New(size int) *Ringbuf {
	return &Ringbuf{make([]byte, size), 0, 0}
}

func (r *Ringbuf) Write(b []byte) {
	for len(b) > 0 {
		start := (r.start + r.size) % len(r.buf)
		n := copy(r.buf[start:], b)
		b = b[n:] //golang就是要好好运用切片

		if r.size >= len(r.buf) {
			if n <= len(r.buf) {
				r.start += n
				if r.start >= len(r.buf) {
					r.start = 0
				}
			} else {
				r.start = 0
			}
		}
		r.size += n
		// Size can‘t exceed the capacity
		if r.size > cap(r.buf) {
			r.size = cap(r.buf)
		}
	}
}

func (r *Ringbuf) Read(b []byte) int {
	read := 0
	size := r.size
	start := r.start
	for len(b) > 0 && size > 0 {
		end := start + size
		if end > len(r.buf) {
			end = len(r.buf)
		}
		n := copy(b, r.buf[start:end])
		size -= n
		read += n
		b = b[n:]

		start = (start + n) % len(r.buf)
	}
	return read
}

func (r *Ringbuf) Size() int {
	return r.size
}
时间: 2024-12-25 01:56:03

golang实现Ringbuf的相关文章

golang []byte转string

golang中,字符切片[]byte转换成string最简单的方式是 package main import ( "fmt" _ "unsafe" ) func main() { bytes := []byte("I am byte array !") str := string(bytes) bytes[0] = 'i'//注意这一行,bytes在这里修改了数据,但是str打印出来的依然没变化, fmt.Println(str) } 打印信息:

Golang Hash MD4

//Go标准包中只有MD5的实现 //还好,github上有MD4实现. package main import (     "golang.org/x/crypto/md4"     "encoding/hex"     "fmt" ) func get_md4(buf []byte) ([] byte) { ctx := md4.New() ctx.Write(buf) return ctx.Sum(nil) } func main() {

Java程序员的Golang入门指南(上)

Java程序员的Golang入门指南 1.序言 Golang作为一门出身名门望族的编程语言新星,像豆瓣的Redis平台Codis.类Evernote的云笔记leanote等. 1.1 为什么要学习 如果有人说X语言比Y语言好,两方的支持者经常会激烈地争吵.如果你是某种语言老手,你就是那门语言的"传道者",下意识地会保护它.无论承认与否,你都已被困在一个隧道里,你看到的完全是局限的.<肖申克的救赎>对此有很好的注脚: [Red] These walls are funny.

golang学习笔记:golang 语法篇(二)

在语法篇(一)中学习了go中基本的数据类型.变量.常量等组成语言的基本要素,在这一节中将会学习如何将这些元素组织起来,最终写成可以执行的代码. 在这一部分包括: go中的流程控制语句: go中函数的用法: go特殊的错误处理方式: Golang中的流程控制语句 在具体编程的时候免不了需要使用一些特殊的语句实现某些功能,比如使用循环语句来进行迭代,使用选择语句控制程序的执行方式等.这些语句在任何一门程序设计语言 中都会有支持,golang中除了支持常用的循环,条件选择语句以外,还支持跳转语句,下面

Golang关键字—— if/else

Golang中,if/else 关键字用于条件判断,如果满足条件就做某事,否则做另一件事: if age >= 18 { fmt.Println("成年人") } else { fmt.Println("未成年") } 多重判断: if score >= 90 { fmt.Println("优秀") } else if score >= 70 { fmt.Println("良好") } else if sco

golang控制channel的出入口

golang控制channel的出入口 我们常常使用channel来在多个goroutine之间做数据通讯,但是chan作为函数的入参我们应该怎么写呢?也许有人觉得这个问题比较傻,不过这个还真的是我今天才知道的. 首先我们看看下面的代码: func main() { c := make(chan int) go in(c) go out(c) time.Sleep(time.Second) } func in(c chan int) { for i := 0; i < 10; i++ { c <

golang winForm开发

最近一直在看rust,语法挺头疼的,正好趁着1.0发布前的一段时间,回来玩玩golang. golang的语法很简单,liteIde又变得越来越好用,因此学习golang不会花费您多少时间,还能够清醒被rust晃晕的头脑,哈哈. winform开发虽然已经不再流行,但是用来练手却非常合适,写小工具也很爽,废话少说,golang的UI库就是大名鼎鼎的 andlabs ui, 在github的star数已达到1946,相当可观.这是一个跨平台的UI库,可以运行在 windows/linux/mac上

golang性能监控初探

最近在用golang写一个server.压力测试过程发现反应比较慢,但是由于中间的操作都是串行的,无法知道在哪个操作消耗了比较多时间. 一开始想到的是打log.但是单个请求又是很快的,于是想到如下方案 在调用每个函数的时候,统计该函数的时耗,然后利用channel把同一个函数调用发送到同一个地方,利用map进行累计统计(这里可以更近一步,比如统计每个worker甚至每个services的状态,包括最长请求时间,最短请求时间,平均消耗等等,如果加上runtime还可以记录其他的运行相关信息). 一

GoLang入门-安装-配置

Go的三种安装方式 Go有多种安装方式,你可以选择自己喜欢的.这里我们介绍三种最常见的安装方式: Go源码安装:这是一种标准的软件安装方式.对于经常使用Unix类系统的用户,尤其对于开发者来说,从源码安装是最方便而熟悉的.Go标准包安装:Go提供了方便的安装包,支持Windows.Linux.Mac等系统.这种方式适合初学者,可根据自己的系统位数下载好相应的安装包,一路next就可以轻松安装了.第三方工具安装:目前有很多方便的第三方软件包工具,例如Ubuntu的apt-get.Mac的homeb