/** * Circular chained byte array * * @author bbwang8088@126.com */ public class CircularChainedBuffer { enum ACTION { WAIT, READ, WRITE } private ACTION lastAction = ACTION.WAIT; // current write position private int wPos = 0; // current read position private int rPos = 0; // byte array private byte[] buffer = null; // byte array length private int length = 0; public CircularChainedBuffer(int size) { this.length = size; init(); } /** * initialize method */ private void init() { this.buffer = new byte[this.length]; this.wPos = 0; this.rPos = 0; this.lastAction = ACTION.WAIT; } /** * reset method */ public void reset() { init(); } /** * Get current writable data size. * * @return */ public int getWritableSize() { int ret = 0; // if initialize, return length of buffer array. if (this.wPos == 0 && this.rPos == 0) { return this.length; } ret = this.wPos - this.rPos; // normal case. if (ret > 0) { ret = this.length - ret; } // same position of read and write. else if (ret == 0) { // write to same position,then cann't write any more. if (this.lastAction == ACTION.WRITE) { ret = 0; } // read to same position,then cann't read any more, array is empty. else if (this.lastAction == ACTION.READ) { ret = this.length; } } // if read position before write position, then calculate against. else { ret = this.rPos - this.wPos; } return ret; } /** * Get current readable data size. * * @return */ public int getReadableSize() { return this.length - this.getWritableSize(); } /** * Try to write some data, if cann't write all, then write a part, if buffer * is filled, then return 0. * * @param data * @return return size of wrote data */ public synchronized int tryWrite(byte[] data) { int retValue = 0; int tmpWritableSize = this.getWritableSize(); // if current writable size is 0, then return 0. if (tmpWritableSize == 0) { return 0; } int copyLength = 0; if (data.length > tmpWritableSize) { copyLength = tmpWritableSize; } else { copyLength = data.length; } // write position after read position. if (this.wPos >= this.rPos) { // all data can write from current write position to end of array, // no need to write data back to head of buffer array. if ((this.wPos + copyLength) <= this.length) { // copy all data of parameter array to buffer array. System.arraycopy(data, 0, this.buffer, this.wPos, copyLength); // move write position. this.wPos += copyLength; } // copy part of parameter array full fill buffer array from write // position, // then copy left part of parameter array from head of buffer array. else { int partA = (this.length - this.wPos); int partB = copyLength - partA; // copy part of parameter array full fill buffer array from // write position System.arraycopy(data, 0, this.buffer, this.wPos, partA); // copy left part of parameter array from head of buffer array System.arraycopy(data, partA, this.buffer, 0, partB); // move write position this.wPos = partB; } } // read position after write position else { // can only write data between write position and read position System.arraycopy(data, 0, this.buffer, this.wPos, copyLength); // move write position this.wPos += copyLength; } retValue = copyLength; this.lastAction = ACTION.WRITE; return retValue; } /** * Try to read size of data,return real read data, if no data can read then * return null. * * @param size * @return return byte array of read data */ public synchronized byte[] tryRead(int size) { byte[] ret = null; int tmpReadableSize = this.getReadableSize(); if (tmpReadableSize == 0 || size <= 0) { return new byte[0]; } int realReadLength = 0; if (size > tmpReadableSize) { realReadLength = tmpReadableSize; } else { realReadLength = size; } ret = new byte[realReadLength]; // write position after read position. if (this.rPos < this.wPos) { System.arraycopy(this.buffer, this.rPos, ret, 0, realReadLength); this.rPos += realReadLength; } // read position after write position else { if( (this.rPos +realReadLength ) <= this.length){ System.arraycopy(this.buffer, this.rPos, ret, 0, realReadLength); this.rPos += realReadLength; }else{ int partA = (this.length - this.rPos); int partB = realReadLength - partA; //Log.d(this.getClass().getSimpleName(),"size:"+size+" realReadLength"+realReadLength+" this.length:"+this.length+" this.rPos:"+this.rPos+" this.wPos:"+this.wPos+" partA:"+partA+" partB:"+partB); // copy part of parameter array full fill buffer array from write // position System.arraycopy(this.buffer, this.rPos, ret, 0, partA); // copy left part of parameter array from head of buffer array System.arraycopy(this.buffer, 0, ret, partA, partB); // move write position this.rPos = partB; } } this.lastAction = ACTION.READ; return ret; } /** * Attation: this method will not move read position. Try to read size of * data,return real read data, if no data can read then return null. * * @param size * @return return byte array of read data */ public synchronized byte[] pretendRead(int size) { byte[] ret = null; int tmpReadableSize = this.getReadableSize(); if (tmpReadableSize == 0) { return new byte[0]; } int realReadLength = 0; if (size > tmpReadableSize) { realReadLength = tmpReadableSize; } else { realReadLength = size; } ret = new byte[realReadLength]; // write position after read position. if (this.rPos < this.wPos) { System.arraycopy(this.buffer, this.rPos, ret, 0, realReadLength); // this.rPos += realReadLength; } // read position after write position else { int partA = (this.length - this.rPos); int partB = realReadLength - partA; // copy part of parameter array full fill buffer array from write // position System.arraycopy(this.buffer, this.rPos, ret, 0, partA); // copy left part of parameter array from head of buffer array System.arraycopy(this.buffer, 0, ret, partA, partB); // move write position // this.rPos = partB; } // this.lastAction = ACTION.READ; return ret; } public synchronized byte[] pretendReadAll() { return this.pretendRead(this.getReadableSize()); } /** * Attation: this method will not move read position. Try to read size of * data,return real read data, if no data can read then return null. * * @param size * @return return byte array of read data */ public synchronized byte[] pretendRead(int offset, int size) { byte[] data = new byte[size]; System.arraycopy(pretendReadAll(), offset, data, 0, size); return data; } public synchronized byte[] readAll() { return this.tryRead(this.getReadableSize()); } public String toString() { StringBuffer sb = new StringBuffer(); for (byte b : this.buffer) { sb.append(" " + Integer.toHexString(b & 0xFF)); } return sb.toString(); } }
import static org.junit.Assert.*; import org.junit.Test; /** * Tester for Circular chained byte array * * @author bbwang8088@126.com */ public class TestCycleByteArray { @Test public void TestGetWritableSize() { int size = 4096; CircularChainedBuffer buffer = new CircularChainedBuffer(size); assertEquals(buffer.getWritableSize(), size); byte[] data1_size10 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a }; byte[] data2_size10 = { (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa }; // byte[] data3_size10 = { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, // (byte) 0xff }; buffer.tryWrite(data1_size10); assertEquals(size - data1_size10.length, buffer.getWritableSize()); assertEquals(size, buffer.getWritableSize() + buffer.getReadableSize()); // System.out.println(buffer.toString()); buffer.tryWrite(data2_size10); assertEquals(size - data2_size10.length * 2, buffer.getWritableSize()); assertEquals(size, buffer.getWritableSize() + buffer.getReadableSize()); // System.out.println(buffer.toString()); byte[] data = buffer.tryRead(data2_size10.length * 2); // System.out.println(new String(data)); assertEquals(size, buffer.getWritableSize()); assertEquals(size, buffer.getWritableSize() + buffer.getReadableSize()); // System.out.println(buffer.toString()); data = buffer.tryRead(data2_size10.length * 2); assertEquals(0, data.length); // System.out.println(new String(data)); // System.out.println(buffer.toString()); for (int i = 0; i < (size / data1_size10.length); i++) { assertEquals(data1_size10.length, buffer.tryWrite(data1_size10));// 1 // System.out.println(buffer.toString()); } assertEquals(size % data1_size10.length, buffer.getWritableSize()); assertEquals(size, buffer.getWritableSize() + buffer.getReadableSize()); data = buffer.tryRead(size*2); assertEquals(size-size%data1_size10.length, data.length); assertEquals(size, buffer.getWritableSize()); assertEquals(0, buffer.getReadableSize()); assertEquals(size, buffer.getWritableSize() + buffer.getReadableSize()); assertEquals(data1_size10.length, buffer.tryWrite(data1_size10)); assertEquals(data2_size10.length, buffer.tryWrite(data2_size10)); assertEquals(size - data1_size10.length * 2, buffer.getWritableSize()); assertEquals(size, buffer.getWritableSize() + buffer.getReadableSize()); data = buffer.tryRead(data1_size10.length*2); assertEquals(data1_size10.length*2, data.length); assertEquals(size, buffer.getWritableSize()); assertEquals(0, buffer.getReadableSize()); assertEquals(size, buffer.getWritableSize() + buffer.getReadableSize()); for (int i = 0; i < (size / data1_size10.length); i++) { assertEquals(data1_size10.length, buffer.tryWrite(data1_size10));// 1 } assertEquals(size % data1_size10.length, buffer.getWritableSize()); assertEquals(size-size % data1_size10.length, buffer.getReadableSize()); assertEquals(size, buffer.getWritableSize() + buffer.getReadableSize()); assertEquals(size % data1_size10.length, buffer.tryWrite(data1_size10));// 1 data = buffer.readAll(); assertEquals(size, buffer.getWritableSize()); assertEquals(0, buffer.getReadableSize()); } }
相关推荐
循环链表 实现约瑟夫环 java 自己写的 测试通过 有注释
用Java定义一个循环链表,实现链表的基本操作: 初始化*、获取头结点、添加新元素*、删除链表元素 、获取链表元素*、查找链表元素*、更新链表中某个元素、 判断链表是否为空、求链表元素个数、输出链表元素、清空...
使用java语言编译循环双链表,有三个类,分别是一个接口类,一个循环双链表继承接口的实现类,一个循环双链表的测试类
由于在项目中需要用到循环链表,然而在JDK没有其实现,所以用Java语言实现了循环链表,供大家学习和参考。若有任何问题请发送E-Mail:wn_lut@126.com,以交流及改进。 Package:com.utilities.structs 打开方式:...
java双向循环链表实现程序_.docx
java双向循环链表实现程序__1.docx
这个循环链表是基于引用的,现实的算法比较简单,但是可以作为参考之用。
NULL 博文链接:https://128kj.iteye.com/blog/1744646
JAVA实现链表_双向链表
类似约瑟夫环问题。有一群人组成一个圈。从头开始按照顺时针方向从1开始依次报数。报到到9的人就离开圈子。其左手边的人接着从1开始报数。依此进行,直到剩最后一个人为止。
约瑟夫环,用循环链表实现,语言为Java。假设数到三的数出列。程序输出1到10的出列顺序。
用java语言将双向链表和循环链表结合起来,数据结构吧课程设计的题目
Java 有序 非循环 双向 链表 算法 实例
循环链表源码,分别用C、C++、JAVA实现,仅供参考
介绍了java双向循环链表的实现代码,有需要的朋友可以参考一下
05.循环链表仿真链表以及循环链表应用
JAVA 循环链表, 模板类. 后续将提交JavaScript版本, C语言版本及C++版本