package com.mildom.decodedemo;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* author : tanliang
* date : 2020/12/17 16:00
* description :
*/
public class RingByteBuffer {
int capacity;
volatile int readSequence;//最后读到的一位
volatile int writeSequence;//最后写到的一位
volatile int remainBytes;
volatile int usedBytes;
volatile byte[]data;
Locklock =new ReentrantLock();
public RingByteBuffer(int capacity) {
this.capacity = capacity;
this.data =new byte[capacity];
this.readSequence = -1;
this.writeSequence = -1;
this.remainBytes = capacity;
this.usedBytes =0;
}
public synchronized boolean putBytes(byte[] bytes) {
lock.lock();
if(bytes ==null || bytes.length ==0 ||remainBytes < bytes.length) {
lock.unlock();
return false;
}
if(readSequence <=writeSequence) {
int rightRemain =capacity -writeSequence-1;
if (bytes.length <= rightRemain) {
System.arraycopy(bytes,0,data,writeSequence+1,bytes.length);
writeSequence =writeSequence + bytes.length;
}else {
System.arraycopy(bytes,0,data,writeSequence+1,rightRemain);
System.arraycopy(bytes,rightRemain-1+1,data,0,bytes.length -rightRemain);
writeSequence = bytes.length -rightRemain -1;
}
}else {
System.arraycopy(bytes,0,data,writeSequence+1,bytes.length);
writeSequence =writeSequence + bytes.length;
}
//加入成功则剩余的减少
remainBytes =remainBytes - bytes.length;
usedBytes =usedBytes + bytes.length;
lock.unlock();
return true;
}
public synchronized byte[]pollBytes(int length) {
lock.lock();
if(usedBytes < length) {
lock.unlock();
return null;
}
byte[] temp =new byte[length];
if(readSequence
System.arraycopy(data,readSequence+1,temp,0,length);
readSequence =readSequence + length;
}else {
int rightWrited =capacity -readSequence -1;
if (length <= rightWrited) {
System.arraycopy(data,readSequence+1,temp,0,length);
readSequence =readSequence + length;
}else {
System.arraycopy(data,readSequence+1,temp,0,rightWrited);
System.arraycopy(data,0,temp,rightWrited-1+1,length - rightWrited);
readSequence = length - rightWrited -1;
}
}
//弹出成功则减少长度
usedBytes =usedBytes - length;
remainBytes =remainBytes + length;
lock.unlock();
return temp;
}
public void clear(){
usedBytes =0;
remainBytes =capacity;
readSequence = -1;
writeSequence = -1;
}
public synchronized int getUsedBytes() {
return usedBytes;
}
public synchronized int getRemainBytes() {
return remainBytes;
}
}