菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
318
0

nio.buffer

原创
05/13 14:22
阅读数 80282

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

 

发表评论

0/200
318 点赞
0 评论
收藏