golang 링 버퍼 구현 (길이 부정)
packet_size:uint16 | packet_ctx:byte[ ]
전체 링 버퍼 의 구조:
----------
packet1
----------
packet2
--------
……
type Ringbuffer struct{
start,use int
buf []byte
}
ringbuffer 에서 buf 는 데이터 내용 을 저장 하고 start 는 읽 는 위치의 index 이 며 use 는 ringbuffer 에서 읽 지 않 은 패 킷 의 바이트 수, start + 입 니 다.
use 는 바로 쓴 위치 입 니 다.
실현 요점 1: 돌아 가기
ringbuffer 는 링 입 니 다. 끝 에 기록 한 후에 끝 부분 으로 돌아 가 야 합 니 다. 패 킷 의 크기 가 정 해 지지 않 기 때문에 끝 부분 에 도착 하면 숫자 가 나타 날 수 있 습 니 다.
가방 의 반 은 끝 에 있 고 반 은 시작 에 있 으 며 읽 을 때 패 킷 의 반 은 끝 에 있 고 반 은 시작 에 합 쳐 야 합 니 다.
구현 요점 2: 기록 이 너무 빠 르 고 덮어 쓰기 해제
쓰기 속도 가 읽 기 속도 보다 클 때 새 쓰기 데 이 터 는 읽 지 않 은 데이터 와 겹 쳐 집 니 다. 그러면 두 가지 결정 이 있 습 니 다. 읽 지 않 은 데 이 터 를 덮어 쓰 고 새 데 이 터 를 버 리 는 것 입 니 다.
데 이 터 를 기록 하 다.
구현 요점 3: 중복 읽 기 방지
ringbuffer 는 덮어 쓰기 데 이 터 를 통 해 읽 지 않 은 데 이 터 를 삭제 하지 않 기 때문에 ringbuffer 의 use 를 통 해 읽 지 않 은 데 이 터 를 판단 합 니 다.
데이터
package ringbuffer
import(
"fmt"
)
type Ringbuffer struct{
start,use int
buf []byte
}
func IntToByte(n int) []byte{
buf:=make([]byte,4)
buf[3] = (byte)((n>>24) & 0xFF)
buf[2] = (byte)((n>>16) & 0xFF)
buf[1] = (byte)((n>>8) & 0xFF)
buf[0] = (byte)(n & 0xFF);
return buf
}
func ByteToInt(buf []byte) int{
var value int
value = (int)((buf[0] & 0xFF)|((buf[1] & 0xFF)<<8)|((buf[2] & 0xFF)<<16)|((buf[3] & 0xFF)<<24))
return value;
}
func NewRingbuffer(size int) *Ringbuffer{
return &Ringbuffer{0,0,make([]byte,size)}
}//
func (r *Ringbuffer) WriteCover(b []byte) bool {
block_size:=len(b)
if block_size > 0 {
size:=len(r.buf)
start:=(r.start+r.use)%size
size_byte:= IntToByte(block_size)
/* block,
, r.start */
flag:=block_size+len(size_byte)
for flag > (r.start-start+size)%size &&r.use!=0 {
rblock_size:= ByteToInt(r.buf[r.start:r.start+4])
r.start = (r.start + rblock_size + 4)%size
}
// block
n:=copy(r.buf[start:],size_byte)
if start+len(size_byte) > len(r.buf){
copy(r.buf,size_byte[n:])//
}
start = (start+len(size_byte))%size
// block
n =copy(r.buf[start:],b)
if start+len(b) > len(r.buf){
copy(r.buf,b[n:])//
}
start = (start+block_size)%size
// ringbuffer
r.use = (start+size-r.start)%size
return true
}
return false
}//
func (r *Ringbuffer) Write(b []byte) bool {
block_size:=len(b)
if block_size > 0 {
size:=len(r.buf)
start:=(r.start+r.use)%size
size_byte:= IntToByte(block_size)
// ringbuffer block
end:=(start+len(b)+len(size_byte))
flag:=end-len(r.buf)
if flag>0 && flag > r.start {
return false
}
// block
n:=copy(r.buf[start:],size_byte)
if start+len(size_byte) > len(r.buf){
copy(r.buf,size_byte[n:])
}
start = (start+len(size_byte))%size
// block
n =copy(r.buf[start:],b)
if start+len(b) > len(r.buf){
copy(r.buf,b[n:])
}
start = (start+block_size)%size
// ringbuffer
r.use = (start+size-r.start)%size
return true
}
return false
}
func (r *Ringbuffer) Read(b []byte) int{
if r.use > 0 {//
// block
size_byte:=make([]byte,4)
t:=copy(size_byte,r.buf[r.start:])
if t!=4 {//
copy(size_byte[t:4],r.buf[:])
}
rblock_size:= ByteToInt(size_byte)
// block
start:=(r.start+4)%len(r.buf)
nread:=0
if start+rblock_size >= len(r.buf) {
n:= copy(b,r.buf[start:])//
nread = copy(b[n:],r.buf[:])
nread = nread + n
}else{
nread = copy(b,r.buf[start:start+rblock_size])
}
if nread == rblock_size {
r.start = (r.start + rblock_size + 4)%len(r.buf)
r.use = r.use - rblock_size - 4
return nread
}else{
return -1
}
}
return 0
}
func (r *Ringbuffer) GetUse() int{
return r.use
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
set containerThere is no built-in set container in Go How to implement Set struct{} => type struct{}{} => 0bytes How to create set :=...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.