![]()
![]()
![]()
![]()
![]()
/*
capacity是不会改变的。
limit是最后一个元素位置。
position是第一个元素位置。
mark是标识,reset()方法调用。
0<=mark<=position<=limit<=capacity
不可变buffer是内容不可变,但是mark、position、limit、capacity是可以变化的。
不是线程安全的,要想安全就要加同步。
链式调用: b.flip(); b.position(23); b.limit(42);
b.flip().position(23).limit(42);
*/
public abstract class Buffer1 {
//遍历或者切割元素的特征值
static final int SPLITERATOR_CHARACTERISTICS = Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED;
private int mark = -1;
private int position = 0;//下一个要放的位置
private int limit;
private int capacity;
long address;//直接地址,GetDirectBufferAddress
public Buffer1(int mark, int pos, int lim, int cap) {//包私有
if (cap < 0)
throw new IllegalArgumentException("Negative capacity: " + cap);
this.capacity = cap;
limit(lim);//limit大于capacity抛异常,limit小于0抛异常,limit小于position:position等于limit,makr大于limit:markt等于-1。
position(pos);//position大于limit抛异常,positon小于0抛异常,mark大于position:mark等于-1。
if (mark >= 0) {
if (mark > pos)
throw new IllegalArgumentException("mark > position: (" + mark + " > " + pos + ")");
this.mark = mark;
}
}
public final int capacity() {
return capacity;
}
public final int position() {
return position;
}
//position大于limit抛异常,positon小于0抛异常,mark大于position:mark等于-1。
public final Buffer1 position(int newPosition) {
if ((newPosition > limit) || (newPosition < 0))
throw new IllegalArgumentException();
position = newPosition;
if (mark > position) mark = -1;
return this;
}
public final int limit() {
return limit;
}
//limit大于capacity抛异常,limit小于0抛异常,limit小于position:position等于limit,makr大于limit:markt等于-1。
public final Buffer1 limit(int newLimit) {
if ((newLimit > capacity) || (newLimit < 0))
throw new IllegalArgumentException();
limit = newLimit;
if (position > limit) position = limit;
if (mark > limit) mark = -1;
return this;
}
//设置mark为position的值
public final Buffer1 mark() {
mark = position;
return this;
}
//position回指到mark
public final Buffer1 reset() {
int m = mark;
if (m < 0)
throw new InvalidMarkException();
position = m;
return this;
}
//不清除数组的元素
public final Buffer1 clear() {
position = 0;
limit = capacity;
mark = -1;
return this;
}
//读进来之后,写出去时候要反转
public final Buffer1 flip() {//position是下一个要放的位置,下一个要读的位置。limit是读进去的时候最后一个元素下一个位置。limit读出去时候是最后一个元素下一个位置。
limit = position;//读进去的时候,position是下一个要放的位置,limit是等于capacity的,limit是没有用的。
//反转时候,limit=position,是读出来时候,最后一个元素的后一个位置,也就是放进去时候最后一个元素的后一个位置。position是下一个要读的位置。
position = 0;
mark = -1;
return this;
}
public final Buffer1 rewind() {
position = 0;
mark = -1;
return this;
}
public final int remaining() {//剩余可以读出去的元素
return limit - position;//(limit+1) - (position+1)。不包括前面包括后面的元素个数。
}
public final boolean hasRemaining() {
return position < limit;
}
public abstract boolean isReadOnly();
public abstract boolean hasArray();
public abstract Object array();
public abstract int arrayOffset();
//是否直接内存
public abstract boolean isDirect();
public final int nextGetIndex() { //包私有方法
if (position >= limit)
throw new BufferUnderflowException();
return position++;
}
public final int nextGetIndex(int nb) {//包私有方法
if (limit - position < nb)
throw new BufferUnderflowException();
int p = position;
position += nb;
return p;
}
public final int nextPutIndex() {//包私有方法,position++
if (position >= limit)
throw new BufferOverflowException();
return position++;
}
public final int nextPutIndex(int nb) {//包私有方法
if (limit - position < nb)
throw new BufferOverflowException();
int p = position;
position += nb;
return p;
}
public final int checkIndex(int i) { // package-private
if ((i < 0) || (i >= limit))
throw new IndexOutOfBoundsException();
return i;
}
public final int checkIndex(int i, int nb) { // package-private
if ((i < 0) || (nb > limit - i))
throw new IndexOutOfBoundsException();
return i;
}
public final int markValue() { // package-private
return mark;
}
public final void truncate() { // package-private
mark = -1;
position = 0;
limit = 0;
capacity = 0;
}
public final void discardMark() { // package-private
mark = -1;
}
public static void checkBounds(int off, int len, int size) { // package-private
if ((off | len | (off + len) | (size - (off + len))) < 0)
throw new IndexOutOfBoundsException();
}
}
//get,put,分为直接和非直接内存,wrap()是非直接的,view()方法是直接的,
public abstract class LongBuffer1 extends Buffer1 implements Comparable<LongBuffer1>{
final long[] hb; // 堆内存才有值,是一个数组,
final int offset;
boolean isReadOnly;
LongBuffer1(int mark, int pos, int lim, int cap,long[] hb, int offset){
super(mark, pos, lim, cap);
this.hb = hb;
this.offset = offset;
}
LongBuffer1(int mark, int pos, int lim, int cap) { // package-private
this(mark, pos, lim, cap, null, 0);
}
public static LongBuffer1 allocate(int capacity) {
if (capacity < 0)
throw new IllegalArgumentException();
//limit=capacity,new long[cap],mark=-1,position=0,offset=0,
return new HeapLongBuffer1(capacity, capacity);
}
//将Long数组包装到LongBuffer。 Long数组的改变会引起buffer的改变,反之亦然。
public static LongBuffer1 wrap(long[] array,int offset, int length){
try {
//mark=-1,position=offset,limit=offset+length,capacity=array.length,hb=array,offset=0,
return new HeapLongBuffer1(array, offset, length);
} catch (IllegalArgumentException x) {
throw new IndexOutOfBoundsException();
}
}
public static LongBuffer1 wrap(long[] array) {
return wrap(array, 0, array.length);
}
//切割,原数组是直接内存切割后就是直接内存,原数组只读切割后就只读。
public abstract LongBuffer1 slice();
//复制,原数组是直接内存切割后就是直接内存,原数组只读切割后就只读。
public abstract LongBuffer1 duplicate();
public abstract LongBuffer1 asReadOnlyBuffer();
public abstract long get();
public abstract LongBuffer1 put(long l);
public abstract long get(int index);
public abstract LongBuffer1 put(int index, long l);
public LongBuffer1 get(long[] dst, int offset, int length) {
checkBounds(offset, length, dst.length);
if (length > remaining())
throw new BufferUnderflowException();
int end = offset + length;//offset是下标,end就是下标。
for (int i = offset; i < end; i++)
dst[i] = get();//拷贝到dst
return this;
}
public LongBuffer1 get(long[] dst) {
return get(dst, 0, dst.length);
}
public LongBuffer1 put(LongBuffer1 src) {
if (src == this)
throw new IllegalArgumentException();
if (isReadOnly())
throw new ReadOnlyBufferException();
int n = src.remaining();//不包括position包括limit的元素个数,也是包括position不包括limit的元素的个数。
if (n > remaining())
throw new BufferOverflowException();
for (int i = 0; i < n; i++)
put(src.get());//把src剩余的元素放进this中
return this;
}
public LongBuffer1 put(long[] src, int offset, int length) {
checkBounds(offset, length, src.length);
if (length > remaining())
throw new BufferOverflowException();
int end = offset + length;
for (int i = offset; i < end; i++)
this.put(src[i]);
return this;
}
public final LongBuffer1 put(long[] src) {
return put(src, 0, src.length);
}
public final boolean hasArray() {
return (hb != null) && !isReadOnly;
}
public final long[] array() {
if (hb == null)
throw new UnsupportedOperationException();
if (isReadOnly)
throw new ReadOnlyBufferException();
return hb;
}
public final int arrayOffset() {
if (hb == null)
throw new UnsupportedOperationException();
if (isReadOnly)
throw new ReadOnlyBufferException();
return offset;
}
public abstract LongBuffer1 compact();
public abstract boolean isDirect();
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(getClass().getName());
sb.append("[pos=");
sb.append(position());
sb.append(" lim=");
sb.append(limit());
sb.append(" cap=");
sb.append(capacity());
sb.append("]");
return sb.toString();
}
public int hashCode() {
int h = 1;
int p = position();
for (int i = limit() - 1; i >= p; i--)
h = 31 * h + (int)get(i);
return h;
}
public boolean equals(Object ob) {
if (this == ob)
return true;
if (!(ob instanceof LongBuffer1))//快速失败
return false;
LongBuffer1 that = (LongBuffer1)ob;
if (this.remaining() != that.remaining())//快速失败
return false;
int p = this.position();
for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)//从各自的limit开始
if (!equals(this.get(i), that.get(j)))
return false;
return true;
}
private static boolean equals(long x, long y) {
return x == y;
}
public int compareTo(LongBuffer1 that) {
int n = this.position() + Math.min(this.remaining(), that.remaining());
//position到n的位置this都是可以取到的,that从that.position到n不一定取的到。
for (int i = this.position(), j = that.position(); i < n; i++, j++) {
int cmp = compare(this.get(i), that.get(j));
if (cmp != 0)
return cmp;
}
return this.remaining() - that.remaining();
}
private static int compare(long x, long y) {
return Long.compare(x, y);
}
// 字节顺序。
public abstract ByteOrder order();
}
class HeapLongBuffer1 extends LongBuffer1{
HeapLongBuffer1(int cap, int lim) {
super(-1, 0, lim, cap, new long[cap], 0);
}
HeapLongBuffer1(long[] buf, int off, int len) {
super(-1, off, off + len, buf.length, buf, 0);//mark, pos, lim, cap, hb, off
}
protected HeapLongBuffer1(long[] buf,int mark, int pos, int lim, int cap,int off){
super(mark, pos, lim, cap, buf, off);
}
public LongBuffer1 slice() { //mark, pos, lim, cap, off,截断之后只保留position到limit之间的元素,包括position不包括limit,切割之后元素的个数位remaining=limit-position。
//切割之后是一个新的数组,开始元素必须从0开始,结束位置是remaining=limit-position。还是用的hb,相对于原来数组的偏移是offset=position,
//新数组元素值还是原来从position到limit的元素。
return new HeapLongBuffer1(hb,-1,0,this.remaining(),this.remaining(),this.position() + offset);
}
public LongBuffer1 duplicate() { //mark, pos, lim, cap, off
return new HeapLongBuffer1(hb,this.markValue(),this.position(),this.limit(),this.capacity(),offset);
}
public LongBuffer1 asReadOnlyBuffer() { //mark, pos, lim, cap, off
return new HeapLongBufferR1(hb,this.markValue(),this.position(),this.limit(),this.capacity(),offset);
}
protected int ix(int i) {
return i + offset;
}
//get和put都是position++,然后取或者放元素,
public long get() {
return hb[ix(nextGetIndex())];
}
public LongBuffer1 put(long x) {//position加一,放在pposition位置。
hb[ix(nextPutIndex())] = x;//nextPutIndex():position++, ix():position + offset
return this;
}
public LongBuffer1 put(int i, long x) {
hb[ix(checkIndex(i))] = x;
return this;
}
public long get(int i) {
return hb[ix(checkIndex(i))];
}
public LongBuffer1 get(long[] dst, int offset, int length) {
checkBounds(offset, length, dst.length);
if (length > remaining())
throw new BufferUnderflowException();
System.arraycopy(hb, ix(position()), dst, offset, length);//把hb复制到dest,position是下一个读取地方,
position(position() + length);//position加length,position继续指向下一个读取位置,
return this;
}
public boolean isDirect() {
return false;
}
public boolean isReadOnly() {
return false;
}
public LongBuffer1 put(long[] src, int offset, int length) {
checkBounds(offset, length, src.length);
if (length > remaining())
throw new BufferOverflowException();
System.arraycopy(src, offset, hb, ix(position()), length);//把src复制到hb,position是下一个放置地方,
position(position() + length);//position继续指向下一个放置位置,
return this;
}
public LongBuffer1 put(LongBuffer1 src) {
if (src instanceof HeapLongBuffer1) {
if (src == this)
throw new IllegalArgumentException();
HeapLongBuffer1 sb = (HeapLongBuffer1)src;
int n = sb.remaining();
if (n > remaining())
throw new BufferOverflowException();
System.arraycopy(sb.hb, sb.ix(sb.position()),hb, ix(position()), n);
sb.position(sb.position() + n);//position继续指向下一个放置位置,
position(position() + n);//position继续指向下一个放置位置,
} else if (src.isDirect()) {
int n = src.remaining();
if (n > remaining())
throw new BufferOverflowException();
src.get(hb, ix(position()), n);
position(position() + n);//position继续指向下一个放置位置,
} else {
super.put(src);
}
return this;
}
public LongBuffer1 compact() {
System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
position(remaining());
limit(capacity());
discardMark();
return this;
}
public ByteOrder order() {
return ByteOrder.nativeOrder();
}
class HeapLongBufferR1 extends HeapLongBuffer1{//只读的longbuffer
HeapLongBufferR1(int cap, int lim) { // package-private
super(cap, lim);
this.isReadOnly = true;
}
HeapLongBufferR1(long[] buf, int off, int len) { // package-private
super(buf, off, len);
this.isReadOnly = true;
}
protected HeapLongBufferR1(long[] buf,int mark, int pos, int lim, int cap,int off){
super(buf, mark, pos, lim, cap, off);
this.isReadOnly = true;
}
public LongBuffer1 slice() {
return new HeapLongBufferR1(hb,-1,0,this.remaining(),this.remaining(),this.position() + offset);
}
public LongBuffer1 duplicate() {
return new HeapLongBufferR1(hb,this.markValue(),this.position(),this.limit(),this.capacity(),offset);
}
public LongBuffer1 asReadOnlyBuffer() {
return duplicate();
}
public boolean isReadOnly() {
return true;
}
public LongBuffer1 put(long x) {
throw new ReadOnlyBufferException();
}
public LongBuffer1 put(int i, long x) {
throw new ReadOnlyBufferException();
}
public LongBuffer1 put(long[] src, int offset, int length) {
throw new ReadOnlyBufferException();
}
public LongBuffer1 put(LongBuffer1 src) {
throw new ReadOnlyBufferException();
}
public LongBuffer1 compact() {
throw new ReadOnlyBufferException();
}
public ByteOrder order() {
return ByteOrder.nativeOrder();
}
}