nio.buffer
/* 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(); } }