From a783b26ce6009d5a329a1a81e11012b774850f2e Mon Sep 17 00:00:00 2001 From: cheney Date: Fri, 2 Sep 2022 14:27:08 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AD=97=E8=8A=82=E9=98=9F=E5=88=97=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sunyard/sge/bytes/BytesQueue.java | 116 ++++++++++++++++++ .../com/sunyard/sge/log/SydLogFactory.java | 4 + src/test/java/test/ByteQueueTest.java | 35 ++++++ 3 files changed, 155 insertions(+) create mode 100644 src/main/java/com/sunyard/sge/bytes/BytesQueue.java create mode 100644 src/main/java/com/sunyard/sge/log/SydLogFactory.java create mode 100644 src/test/java/test/ByteQueueTest.java diff --git a/src/main/java/com/sunyard/sge/bytes/BytesQueue.java b/src/main/java/com/sunyard/sge/bytes/BytesQueue.java new file mode 100644 index 0000000..17e9f87 --- /dev/null +++ b/src/main/java/com/sunyard/sge/bytes/BytesQueue.java @@ -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 Listqueue = 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; + Iteratorit = 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 ); + } +} diff --git a/src/main/java/com/sunyard/sge/log/SydLogFactory.java b/src/main/java/com/sunyard/sge/log/SydLogFactory.java new file mode 100644 index 0000000..6aab66e --- /dev/null +++ b/src/main/java/com/sunyard/sge/log/SydLogFactory.java @@ -0,0 +1,4 @@ +package com.sunyard.sge.log; + +public class SydLogFactory { +} diff --git a/src/test/java/test/ByteQueueTest.java b/src/test/java/test/ByteQueueTest.java new file mode 100644 index 0000000..16718aa --- /dev/null +++ b/src/test/java/test/ByteQueueTest.java @@ -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; + } + } + } + +}