• 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();
        }
    }
  • 相关阅读:
    @ControllerAdvice + @ExceptionHandler 使用
    将博客搬至CSDN
    Docker pull网络错误
    Centos7.5安装Docker
    Oracle18c创建不带C##的用户
    Centos7.5静默安装Oracle18c
    nodeJs和JavaScript的异同
    maven项目引入本地包,不使用中央仓库
    java中把指数形式的数字转为正常形式显示
    validateJarFile jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class
  • 原文地址:https://www.cnblogs.com/yaowen/p/11058674.html
Copyright © 2020-2023  润新知