<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    上善若水
    In general the OO style is to use a lot of little objects with a lot of little methods that give us a lot of plug points for overriding and variation. To do is to be -Nietzsche, To bei is to do -Kant, Do be do be do -Sinatra
    posts - 146,comments - 147,trackbacks - 0

    概述

    在Jetty中Buffer是對Java中Stream IO中的buffer和NIO中的buffer的抽象表示,它主要用于緩存連接中讀取和寫入的數(shù)據(jù)。在Jetty中,對每個連接使用Buffer從其InputStream中讀取字節(jié)數(shù)據(jù),或?qū)⑻幚砗蟮捻憫止?jié)寫入OutputStream中,從而Jetty其他模塊在處理請求和響應數(shù)據(jù)時直接和Buffer打交道,而不需要關注底層IO流。

    Buffer接口定義

    Jetty中Buffer接口定義如下:
    public interface Buffer extends Cloneable {
        // 基于Buffer主要用于向當前連接讀寫數(shù)據(jù),因而它定義了兩個核心的方法:readFrom和writeTo。其中readFrom方法從InputStream中讀取字節(jié)數(shù)據(jù),writeTo方法將響應字節(jié)寫入OutputStream中,即向Connection中讀取和寫入數(shù)據(jù),寫完后清理當前Buffer。
        int readFrom(InputStream in, int max) throws IOException;
        void writeTo(OutputStream out) throws IOException;

        // 在Buffer從InputStream(Connection)中讀取數(shù)據(jù)后,Buffer接口還提供了很多不同的方法用于從Buffer中讀取或?qū)懭胱止?jié)數(shù)據(jù)。

        
    // Jetty中的Buffer是一個FIFO的字節(jié)隊列,它的設計類似NIO中Buffer的設計:每次get操作都從getIndex開始,并且getIndex會向前移動讀取的字節(jié)數(shù)的長度;每次的peek操作也getIndex開始,但是peek操作不會使getIndex向前移動;每次put操作都從putIndex開始,并且putIndex會向前移動寫入的字節(jié)數(shù)的長度;每次poke操作也會從putIndex開始,但是poke操作不會使putIndex向前移動;mark操作會以getIndex作為基準設置markIndex的值,從而在reset時會將getIndex重置到之前mark過的位置;capacity表示該Buffer最多可存儲的字節(jié)數(shù),而length表示從getIndex到putIndex還存在的字節(jié)數(shù)。并且Buffer永遠保證以下關系總是成立:markIndex<=getIndex<=putIndex<=capacity

        byte get();
        int get(byte[] b, int offset, int length);
        Buffer get(int length);
        int getIndex();

        void mark();
        void mark(int offset);
        int markIndex();

        byte peek();
        byte peek(int index);
        Buffer peek(int index, int length);
        int peek(int index, byte[] b, int offset, int length);

        int poke(int index, Buffer src);
        void poke(int index, byte b);
        int poke(int index, byte b[], int offset, int length);

        int put(Buffer src);
        void put(byte b);
        int put(byte[] b,int offset, int length);
        int put(byte[] b);
        int putIndex();

        int length();
        void clear();
        void reset();
        void setGetIndex(int newStart);
        void setMarkIndex(int newMark);
        void setPutIndex(int newLimit);

        // 一個Buffer還有獨立的兩種狀態(tài):access級別和volatile。
    access級別有:IMMUTABLE,表示當前Buffer所有的Index和內(nèi)容都不能被改變;READONLY,表示當前Buffer是只讀的,即getIndex和markIndex可以被改變,而putIndex以及Buffer內(nèi)容不可以;READWRITE,表示所有的Index以及Buffer的內(nèi)容可以被改變。
    volatile狀態(tài)表示當前Buffer是否會通過其他路徑被修改,默認情況下,ByteArrayBuffer、DirectNIOBuffer等是NON_VOLATILE狀態(tài),而View是VOLATILE狀態(tài)(除非View內(nèi)部的Buffer是IMMUTABLE)。VOLATILE的狀態(tài)感覺不是一個比較嚴謹?shù)母拍睿热鐚σ粋€View它是VOLATILE的,但是在這種情況下,它內(nèi)部包裝的Buffer應該也變成VOLATILE狀態(tài),并且在所有的View被回收后,其內(nèi)部包裝的Buffer應該重新變成NON_VOLATILE狀態(tài)。要實現(xiàn)這種嚴謹邏輯應該是可以做的到的,只是會比較麻煩,而且貌似也沒必要,因而Jetty并沒有嘗試著去這樣做。

        // 返回包含當前Buffer從getIndex到putIndex內(nèi)容的Buffer,并且返回的Buffer不可以被其他路徑修改。如果當前Buffer是NON_VOLATILE,則直接返回當前Buffer(這個實現(xiàn)是不嚴謹?shù)模驗樵谶@種情況下,其實有兩個Buffer實例可以修改同一份數(shù)據(jù)),否則,克隆一個新的Buffer,這樣對新的Buffer的修改不會影響原Buffer的內(nèi)容。
        Buffer asNonVolatileBuffer();
        // 返回一個只讀的Buffer(View),該只讀的Buffer的讀取不會影響原來Buffer的Index。
        Buffer asReadOnlyBuffer();
        // 拷貝一個不可修改的ByteBuffer。
        Buffer asImmutableBuffer();
        // 返回一個可修改的Buffer,并且對返回的Buffer的內(nèi)容修改會影響原有的Buffer。
        Buffer asMutableBuffer();

        // 當前Buffer是否不可被修改,即Buffer內(nèi)容和所有Index都不能被修改。
        boolean isImmutable();
        // 當前Buffer是否是只讀的。
        boolean isReadOnly();
        // 是否當前Buffer內(nèi)容可以通過其他路徑被修改,比如View一般情況下是VOLATILE狀態(tài)(除非View內(nèi)部的Buffer是IMMUTABLE)。
       boolean isVolatile();
        
        // 除了以上的操作,Buffer還提供了一些其他用于操作Buffer內(nèi)部字節(jié)的方法:

        
    //如果內(nèi)部使用字節(jié)數(shù)組表示,返回該字節(jié)數(shù)組,否則,返回null。
        byte[] array();
        // 獲取從getIndex到putIndex的字節(jié)數(shù)組,其長度為length。
        byte[] asArray();
        // 如果當前Buffer是對另一個Buffer的包裝,則返回內(nèi)部被包裝的Buffer實例,否則返回當前Buffer本身。
        Buffer buffer();

        int capacity();
        // 返回當前Buffer剩余的空間,即capacity-putIndex。
        int space();
        // 清除Buffer內(nèi)容,即設置getIndex和putIndex為0,以及markIndex為-1。
        
    // 整理Buffer內(nèi)容,即將markIndex >= 0 ? min(getIndex, markIndex) : getIndex到putIndex的內(nèi)容移動到Buffer的起始位置,同時修改相應的getIndex、markIndex、putIndex。
        void compact();
        // 當前Buffer是否有可用字節(jié),即是否putIndex>getIndex。
        boolean hasContent();

        // 跳過n個字節(jié),即getIndex增加min(remaining(), n)的值。
        int skip(int n);

        // 切割出當前Buffer從getIndex到putIndex的View,一般來說它是volatile的(除非它是immutable類型的Buffer)。
        Buffer slice();
        // 切割出當前Buffer從markIndex到putIndex的View,一般來說它是volatile的(除非它是immutable類型的Buffer)。
        Buffer sliceFromMark();
        Buffer sliceFromMark(int length);

        // 返回包含當前Buffer狀態(tài)和內(nèi)容的字符串。
        String toDetailString();
        boolean equalsIgnoreCase(Buffer buffer);
     }

    類圖


    主要實現(xiàn)類

    AbstractBuffer:
    所有Buffer的基類,是對Buffer接口的基本實現(xiàn)。
    ByteBuffer:
    它繼承自AbstractBuffer主要的非NIO的Buffer實現(xiàn),內(nèi)部使用字節(jié)數(shù)組做緩存,直接讀InputStream和寫OutputStream。
    DirectNIOBuffer:
    它實現(xiàn)了NIOBuffer接口,繼承自AbstractBuffer,內(nèi)部使用Direct的ByteBuffer做緩存,使用ReadableByteChannel和WritableByteChannel分別對InputStream(readFrom傳入)和OutputStream(writeTo傳入)包裝,并在這兩個方法中使用包裝后的Channel讀寫數(shù)據(jù)。
    IndirectNIOBuffer:
    它繼承自ByteBuffer,內(nèi)部使用非direct的ByteBuffer做緩存,并且它也直接對InputStream和OutputStream讀寫。
    RandomAccessFileBuffer:
    它繼承自AbstractBuffer,內(nèi)部使用RandomAccessFile做緩存。
    View:
    它繼承自AbstractBuffer,內(nèi)部使用另一個Buffer作為緩存,并且對非IMMUTABLE的Buffer,很多時候,它是VOLATILE。View如其名,它是對內(nèi)部Buffer的視圖,對View內(nèi)容以及Index的修改會影響內(nèi)部Buffer中相應的值。

    Buffers

    Buffers是Buffer的抽象工廠,它用于創(chuàng)建Header的Buffer和Body的Buffer,并且可以根據(jù)給定的size獲得相應的Buffer實例,在Buffer使用完成后,還可以通過returnBuffer方法將它歸還個Buffers以復用。在創(chuàng)建Buffers子類時,可以將指定Header和Body各自Buffer的類型,從而在內(nèi)部創(chuàng)建相應Buffer時會創(chuàng)建相應類型的Buffer,支持的Buffer類型有:BYTE_ARRAY、DIRECT、INDIRECT。

    Jetty中有兩個Buffers的實現(xiàn):PooledBuffers和ThreadLocalBuffers。

    PooledBuffers使用ConcurrentLinkedQueue構建各自的Header、Body、Other類型的Buffer池,它有一個maxSize值用于控制該Buffers中包含的所有類型的Buffer的總數(shù)。 ThreadLocalBuffers將Header、Body、Other類型的Buffer保存在ThreadLocal中。

    Jetty還提供了BuffersFactory用于創(chuàng)建不同類型的Buffers:通過在參數(shù)中maxSize是否大于等于0以決定是使用PooledBuffers還是ThreadLocalBuffers。

    BufferCache/BufferDateCache

    Jetty還為Buffer提供了兩個特殊的類:BufferCache和BufferDateCache。

    BufferCache
    用于存儲一個可以使用存儲的String值、索引值等獲取相應的Buffer實例,主要用于HttpHeaders、HttpMethods等一些預定義的值。
    BufferDateCache
    繼承自DateCache,它存儲了上一次使用一個long類型的date值格式化出的Buffer實例,從而實現(xiàn)部分復用(復用在同一秒得到的Request請求時創(chuàng)建的Buffer,因為時間也只能在這種情況下被復用,因而才會有這樣的實現(xiàn)),在Request類中使用。
    posted on 2014-03-29 13:30 DLevin 閱讀(1551) 評論(0)  編輯  收藏 所屬分類: Jetty
    主站蜘蛛池模板: 好猛好深好爽好硬免费视频| 91老湿机福利免费体验| 亚洲国产成人一区二区精品区| 99re在线精品视频免费| 亚洲国产成人综合精品| 亚洲精品中文字幕无码蜜桃| 97在线观免费视频观看| 一级做a爰黑人又硬又粗免费看51社区国产精品视 | 亚洲日韩一中文字暮| 在线亚洲精品福利网址导航| 国产1000部成人免费视频| 男女猛烈激情xx00免费视频| 亚洲自偷精品视频自拍| 亚洲第一网站男人都懂| 在线看片v免费观看视频777| 九九九精品视频免费| 亚洲冬月枫中文字幕在线看| 国产亚洲美日韩AV中文字幕无码成人 | 亚洲色欲久久久综合网东京热| 99久久国产热无码精品免费| GOGOGO高清免费看韩国| 亚洲日本中文字幕天天更新| 亚洲AV无码久久| 一本色道久久88亚洲综合| 国内精自视频品线六区免费| 最近免费中文字幕中文高清 | 亚洲国产综合第一精品小说| 国产亚洲精品成人a v小说| 毛片免费在线观看网站| 一区二区免费视频| 成人福利在线观看免费视频| 亚洲精品免费网站| 亚洲a一级免费视频| 亚洲午夜无码片在线观看影院猛| 性做久久久久久久免费看| 中文字幕天天躁日日躁狠狠躁免费| 男人j进女人p免费视频| 久久亚洲色WWW成人欧美| 亚洲成人一级电影| 亚洲a在线视频视频| 亚洲国产综合无码一区|