字节队列类

This commit is contained in:
cheney 2022-09-02 14:27:08 +08:00
parent 18843fc99b
commit a783b26ce6
3 changed files with 155 additions and 0 deletions

View File

@ -0,0 +1,116 @@
package com.sunyard.sge.bytes;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
* 字节流先入先出队列
* **非线程安全**
*/
public class BytesQueue {
// 字节队列
private List<byte[]>queue = new LinkedList<>();
// 有效字节起始位置指针
private int index = 0;
// 维护实时长度
private int length = 0;
/**
* 尾部添加
* @param datas
*/
public void push(byte[] datas){
if ( null == datas ) {
return;
}
if ( datas.length == 0 ) {
return;
}
if ( datas.length > Integer.MAX_VALUE - length ){
throw new IllegalArgumentException("too big");
}
queue.add( datas );
length += datas.length;
}
/**
* 获取字节
* @param multiple 整倍数
* @param reserve 保留
* @return 所有字节
*/
public byte[] pop(int multiple, int reserve){
if ( length <= reserve ) {
return new byte[0];
}
int len = length - reserve;
int raminder = len % multiple;
len -= raminder;
if ( 0 == len ) {
return new byte[0];
}
byte[] data = null;
int dataIndex = 0;
int needLen = len;
boolean isFirst = true;
Iterator<byte[]>it = queue.iterator();
while ( it.hasNext() ){
byte[] q = it.next();
// 首轮加速
if ( isFirst ) {
isFirst = false;
if ( 0 == index && q.length == needLen ) {
queue.remove(0);
index = 0;
length -= needLen;
return q;
}
data = new byte[ needLen ];
}
int hasLen = q.length - index;
System.out.println(String.format("-> %d %d %d", dataIndex, needLen, hasLen));
if ( hasLen == needLen ) {
System.arraycopy( q, index , data, dataIndex, needLen );
it.remove();
index = 0;
length -= needLen;
return data;
} else if ( hasLen > needLen ) {
System.arraycopy( q, index , data, dataIndex, needLen );
index += needLen;
length -= needLen;
return data;
} else {
System.arraycopy( q, index , data, dataIndex, hasLen );
it.remove();
index = 0;
length -= hasLen;
dataIndex += hasLen;
needLen = len - dataIndex;
if ( 0 == needLen ) {
return data;
}
}
}
throw new RuntimeException("pop error");
}
public byte[] pop(int reserve){
return pop( 1, reserve );
}
public byte[] pop(){
return pop( 1, 0 );
}
}

View File

@ -0,0 +1,4 @@
package com.sunyard.sge.log;
public class SydLogFactory {
}

View File

@ -0,0 +1,35 @@
package test;
import com.sunyard.sge.bytes.BytesQueue;
import org.junit.Assert;
import org.junit.Test;
import java.util.Random;
public class ByteQueueTest {
@Test
public void case1() {
BytesQueue queue = new BytesQueue();
int max = 1000;
for (int i = 0; i < max; i++) {
int r = new Random().nextInt(4096);
queue.push(new byte[r]);
}
while (true) {
byte[] data = queue.pop(16, 16);
Assert.assertEquals(data.length % 16, 0);
if (0 == data.length) {
data = queue.pop();
Assert.assertTrue( data.length >= 16 );
data = queue.pop();
Assert.assertEquals(0, data.length);
return;
}
}
}
}