Home / Class/ PoolChunkList Class — netty Architecture

PoolChunkList Class — netty Architecture

Architecture documentation for the PoolChunkList class in PoolChunkList.java from the netty codebase.

Entity Profile

Dependency Diagram

graph TD
  ad035c77_35f5_72ad_c059_f20a84e5fef2["PoolChunkList"]
  cecd6147_5415_6c1a_967a_c780e6afb43a["PoolChunkList.java"]
  ad035c77_35f5_72ad_c059_f20a84e5fef2 -->|defined in| cecd6147_5415_6c1a_967a_c780e6afb43a
  e6307482_2181_2668_7240_5899f12f023b["PoolChunkList()"]
  ad035c77_35f5_72ad_c059_f20a84e5fef2 -->|method| e6307482_2181_2668_7240_5899f12f023b
  3c6adea5_3b63_3b6c_a0b5_fba34459afae["calculateMaxCapacity()"]
  ad035c77_35f5_72ad_c059_f20a84e5fef2 -->|method| 3c6adea5_3b63_3b6c_a0b5_fba34459afae
  f33d4982_b707_d8bc_2926_af0840f30db4["prevList()"]
  ad035c77_35f5_72ad_c059_f20a84e5fef2 -->|method| f33d4982_b707_d8bc_2926_af0840f30db4
  18042f3d_b641_22b7_d7b2_aba6c8edf02c["allocate()"]
  ad035c77_35f5_72ad_c059_f20a84e5fef2 -->|method| 18042f3d_b641_22b7_d7b2_aba6c8edf02c
  19eddafa_2b2a_04f8_fed6_1389610a1b08["free()"]
  ad035c77_35f5_72ad_c059_f20a84e5fef2 -->|method| 19eddafa_2b2a_04f8_fed6_1389610a1b08
  ab82259c_2fab_fc43_d5d6_285810df3808["move()"]
  ad035c77_35f5_72ad_c059_f20a84e5fef2 -->|method| ab82259c_2fab_fc43_d5d6_285810df3808
  d1999192_ee28_91ce_aaeb_bd7dac88882a["move0()"]
  ad035c77_35f5_72ad_c059_f20a84e5fef2 -->|method| d1999192_ee28_91ce_aaeb_bd7dac88882a
  91139286_a1fc_610b_22e4_6610a6b11791["add()"]
  ad035c77_35f5_72ad_c059_f20a84e5fef2 -->|method| 91139286_a1fc_610b_22e4_6610a6b11791
  01ec12e0_052d_217e_a5d8_c8040b24bf97["add0()"]
  ad035c77_35f5_72ad_c059_f20a84e5fef2 -->|method| 01ec12e0_052d_217e_a5d8_c8040b24bf97
  82c98989_ce91_11bf_56b1_649038858a55["remove()"]
  ad035c77_35f5_72ad_c059_f20a84e5fef2 -->|method| 82c98989_ce91_11bf_56b1_649038858a55
  35ba0200_852a_861d_b3e6_48d2f1bbdc7f["minUsage()"]
  ad035c77_35f5_72ad_c059_f20a84e5fef2 -->|method| 35ba0200_852a_861d_b3e6_48d2f1bbdc7f
  bb49bd12_aca1_5247_7ef3_54c18494b231["maxUsage()"]
  ad035c77_35f5_72ad_c059_f20a84e5fef2 -->|method| bb49bd12_aca1_5247_7ef3_54c18494b231
  2bbfa269_5720_69c0_8f58_2f93fc2ae4aa["minUsage0()"]
  ad035c77_35f5_72ad_c059_f20a84e5fef2 -->|method| 2bbfa269_5720_69c0_8f58_2f93fc2ae4aa

Relationship Graph

Source Code

buffer/src/main/java/io/netty/buffer/PoolChunkList.java lines 30–262

final class PoolChunkList<T> implements PoolChunkListMetric {
    private static final Iterator<PoolChunkMetric> EMPTY_METRICS = Collections.emptyIterator();
    private final PoolArena<T> arena;
    private final PoolChunkList<T> nextList;
    private final int minUsage;
    private final int maxUsage;
    private final int maxCapacity;
    private PoolChunk<T> head;
    private final int freeMinThreshold;
    private final int freeMaxThreshold;

    // This is only update once when create the linked like list of PoolChunkList in PoolArena constructor.
    private PoolChunkList<T> prevList;

    // TODO: Test if adding padding helps under contention
    //private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7;

    PoolChunkList(PoolArena<T> arena, PoolChunkList<T> nextList, int minUsage, int maxUsage, int chunkSize) {
        assert minUsage <= maxUsage;
        this.arena = arena;
        this.nextList = nextList;
        this.minUsage = minUsage;
        this.maxUsage = maxUsage;
        maxCapacity = calculateMaxCapacity(minUsage, chunkSize);

        // the thresholds are aligned with PoolChunk.usage() logic:
        // 1) basic logic: usage() = 100 - freeBytes * 100L / chunkSize
        //    so, for example: (usage() >= maxUsage) condition can be transformed in the following way:
        //      100 - freeBytes * 100L / chunkSize >= maxUsage
        //      freeBytes <= chunkSize * (100 - maxUsage) / 100
        //      let freeMinThreshold = chunkSize * (100 - maxUsage) / 100, then freeBytes <= freeMinThreshold
        //
        //  2) usage() returns an int value and has a floor rounding during a calculation,
        //     to be aligned absolute thresholds should be shifted for "the rounding step":
        //       freeBytes * 100 / chunkSize < 1
        //       the condition can be converted to: freeBytes < 1 * chunkSize / 100
        //     this is why we have + 0.99999999 shifts. A example why just +1 shift cannot be used:
        //       freeBytes = 16777216 == freeMaxThreshold: 16777216, usage = 0 < minUsage: 1, chunkSize: 16777216
        //     At the same time we want to have zero thresholds in case of (maxUsage == 100) and (minUsage == 100).
        //
        freeMinThreshold = (maxUsage == 100) ? 0 : (int) (chunkSize * (100.0 - maxUsage + 0.99999999) / 100L);
        freeMaxThreshold = (minUsage == 100) ? 0 : (int) (chunkSize * (100.0 - minUsage + 0.99999999) / 100L);
    }

    /**
     * Calculates the maximum capacity of a buffer that will ever be possible to allocate out of the {@link PoolChunk}s
     * that belong to the {@link PoolChunkList} with the given {@code minUsage} and {@code maxUsage} settings.
     */
    private static int calculateMaxCapacity(int minUsage, int chunkSize) {
        minUsage = minUsage0(minUsage);

        if (minUsage == 100) {
            // If the minUsage is 100 we can not allocate anything out of this list.
            return 0;
        }

        // Calculate the maximum amount of bytes that can be allocated from a PoolChunk in this PoolChunkList.
        //
        // As an example:
        // - If a PoolChunkList has minUsage == 25 we are allowed to allocate at most 75% of the chunkSize because
        //   this is the maximum amount available in any PoolChunk in this PoolChunkList.
        return  (int) (chunkSize * (100L - minUsage) / 100L);
    }

    void prevList(PoolChunkList<T> prevList) {
        assert this.prevList == null;
        this.prevList = prevList;
    }

    boolean allocate(PooledByteBuf<T> buf, int reqCapacity, int sizeIdx, PoolThreadCache threadCache) {
        int normCapacity = arena.sizeClass.sizeIdx2size(sizeIdx);
        if (normCapacity > maxCapacity) {
            // Either this PoolChunkList is empty or the requested capacity is larger then the capacity which can
            // be handled by the PoolChunks that are contained in this PoolChunkList.
            return false;
        }

        for (PoolChunk<T> cur = head; cur != null; cur = cur.next) {
            if (cur.allocate(buf, reqCapacity, sizeIdx, threadCache)) {
                if (cur.freeBytes <= freeMinThreshold) {
                    remove(cur);

Frequently Asked Questions

What is the PoolChunkList class?
PoolChunkList is a class in the netty codebase, defined in buffer/src/main/java/io/netty/buffer/PoolChunkList.java.
Where is PoolChunkList defined?
PoolChunkList is defined in buffer/src/main/java/io/netty/buffer/PoolChunkList.java at line 30.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free