Class PoolChunk<T>

  • All Implemented Interfaces:
    PoolChunkMetric

    final class PoolChunk<T>
    extends java.lang.Object
    implements PoolChunkMetric
    Description of algorithm for PageRun/PoolSubpage allocation from PoolChunk Notation: The following terms are important to understand the code > page - a page is the smallest unit of memory chunk that can be allocated > run - a run is a collection of pages > chunk - a chunk is a collection of runs > in this code chunkSize = maxPages * pageSize To begin we allocate a byte array of size = chunkSize Whenever a ByteBuf of given size needs to be created we search for the first position in the byte array that has enough empty space to accommodate the requested size and return a (long) handle that encodes this offset information, (this memory segment is then marked as reserved so it is always used by exactly one ByteBuf and no more) For simplicity all sizes are normalized according to SizeClasses.size2SizeIdx(int) method. This ensures that when we request for memory segments of size > pageSize the normalizedCapacity equals the next nearest size in SizeClasses. A chunk has the following layout: /-----------------\ | run | | | | | |-----------------| | run | | | |-----------------| | unalloctated | | (freed) | | | |-----------------| | subpage | |-----------------| | unallocated | | (freed) | | ... | | ... | | ... | | | | | | | \-----------------/ handle: ------- a handle is a long number, the bit layout of a run looks like: oooooooo ooooooos ssssssss ssssssue bbbbbbbb bbbbbbbb bbbbbbbb bbbbbbbb o: runOffset (page offset in the chunk), 15bit s: size (number of pages) of this run, 15bit u: isUsed?, 1bit e: isSubpage?, 1bit b: bitmapIdx of subpage, zero if it's not subpage, 32bit runsAvailMap: ------ a map which manages all runs (used and not in used). For each run, the first runOffset and last runOffset are stored in runsAvailMap. key: runOffset value: handle runsAvail: ---------- an array of PriorityQueue. Each queue manages same size of runs. Runs are sorted by offset, so that we always allocate runs with smaller offset. Algorithm: ---------- As we allocate runs, we update values stored in runsAvailMap and runsAvail so that the property is maintained. Initialization - In the beginning we store the initial run which is the whole chunk. The initial run: runOffset = 0 size = chunkSize isUsed = no isSubpage = no bitmapIdx = 0 Algorithm: [allocateRun(size)] ---------- 1) find the first avail run using in runsAvails according to size 2) if pages of run is larger than request pages then split it, and save the tailing run for later using Algorithm: [allocateSubpage(size)] ---------- 1) find a not full subpage according to size. if it already exists just return, otherwise allocate a new PoolSubpage and call init() note that this subpage object is added to subpagesPool in the PoolArena when we init() it 2) call subpage.allocate() Algorithm: [free(handle, length, nioBuffer)] ---------- 1) if it is a subpage, return the slab back into this subpage 2) if the subpage is not used or it is a run, then start free this run 3) merge continuous avail runs 4) save the merged run
    • Field Detail

      • base

        final java.lang.Object base
      • memory

        final T memory
      • unpooled

        final boolean unpooled
      • runsAvailMap

        private final LongLongHashMap runsAvailMap
        store the first page and last page of each avail run
      • runsAvailLock

        private final java.util.concurrent.locks.ReentrantLock runsAvailLock
      • subpages

        private final PoolSubpage<T>[] subpages
        manage all subpages in this chunk
      • pinnedBytes

        private final LongCounter pinnedBytes
        Accounting of pinned memory – memory that is currently in use by ByteBuf instances.
      • pageSize

        private final int pageSize
      • pageShifts

        private final int pageShifts
      • chunkSize

        private final int chunkSize
      • cachedNioBuffers

        private final java.util.Deque<java.nio.ByteBuffer> cachedNioBuffers
      • freeBytes

        int freeBytes
    • Constructor Detail

      • PoolChunk

        PoolChunk​(PoolArena<T> arena,
                  java.lang.Object base,
                  T memory,
                  int pageSize,
                  int pageShifts,
                  int chunkSize,
                  int maxPageIdx)
      • PoolChunk

        PoolChunk​(PoolArena<T> arena,
                  java.lang.Object base,
                  T memory,
                  int size)
        Creates a special chunk that is not pooled.
    • Method Detail

      • newRunsAvailqueueArray

        private static LongPriorityQueue[] newRunsAvailqueueArray​(int size)
      • insertAvailRun

        private void insertAvailRun​(int runOffset,
                                    int pages,
                                    long handle)
      • insertAvailRun0

        private void insertAvailRun0​(int runOffset,
                                     long handle)
      • removeAvailRun

        private void removeAvailRun​(long handle)
      • removeAvailRun0

        private void removeAvailRun0​(long handle)
      • lastPage

        private static int lastPage​(int runOffset,
                                    int pages)
      • getAvailRunByOffset

        private long getAvailRunByOffset​(int runOffset)
      • usage

        public int usage()
        Description copied from interface: PoolChunkMetric
        Return the percentage of the current usage of the chunk.
        Specified by:
        usage in interface PoolChunkMetric
      • usage

        private int usage​(int freeBytes)
      • allocateRun

        private long allocateRun​(int runSize)
      • calculateRunSize

        private int calculateRunSize​(int sizeIdx)
      • runFirstBestFit

        private int runFirstBestFit​(int pageIdx)
      • splitLargeRun

        private long splitLargeRun​(long handle,
                                   int needPages)
      • allocateSubpage

        private long allocateSubpage​(int sizeIdx)
        Create / initialize a new PoolSubpage of normCapacity. Any PoolSubpage created / initialized here is added to subpage pool in the PoolArena that owns this PoolChunk
        Parameters:
        sizeIdx - sizeIdx of normalized size
        Returns:
        index in memoryMap
      • free

        void free​(long handle,
                  int normCapacity,
                  java.nio.ByteBuffer nioBuffer)
        Free a subpage or a run of pages When a subpage is freed from PoolSubpage, it might be added back to subpage pool of the owning PoolArena. If the subpage pool in PoolArena has at least one other PoolSubpage of given elemSize, we can completely free the owning Page so it is available for subsequent allocations
        Parameters:
        handle - handle to free
      • collapseRuns

        private long collapseRuns​(long handle)
      • collapsePast

        private long collapsePast​(long handle)
      • collapseNext

        private long collapseNext​(long handle)
      • toRunHandle

        private static long toRunHandle​(int runOffset,
                                        int runPages,
                                        int inUsed)
      • initBufWithSubpage

        void initBufWithSubpage​(PooledByteBuf<T> buf,
                                java.nio.ByteBuffer nioBuffer,
                                long handle,
                                int reqCapacity,
                                PoolArenasCache threadCache)
      • incrementPinnedMemory

        void incrementPinnedMemory​(int delta)
      • decrementPinnedMemory

        void decrementPinnedMemory​(int delta)
      • chunkSize

        public int chunkSize()
        Description copied from interface: PoolChunkMetric
        Return the size of the chunk in bytes, this is the maximum of bytes that can be served out of the chunk.
        Specified by:
        chunkSize in interface PoolChunkMetric
      • pinnedBytes

        public int pinnedBytes()
      • toString

        public java.lang.String toString()
        Overrides:
        toString in class java.lang.Object
      • destroy

        void destroy()
      • runOffset

        static int runOffset​(long handle)
      • runSize

        static int runSize​(int pageShifts,
                           long handle)
      • runPages

        static int runPages​(long handle)
      • isUsed

        static boolean isUsed​(long handle)
      • isRun

        static boolean isRun​(long handle)
      • isSubpage

        static boolean isSubpage​(long handle)
      • bitmapIdx

        static int bitmapIdx​(long handle)