Home / Class/ MagazineGroup Class — netty Architecture

MagazineGroup Class — netty Architecture

Architecture documentation for the MagazineGroup class in AdaptivePoolingAllocator.java from the netty codebase.

Entity Profile

Dependency Diagram

graph TD
  5c7d3ca5_8d2c_76d2_0628_1864f492365d["MagazineGroup"]
  fee3fa6d_a7fb_30d6_ea34_49602c633a2c["AdaptivePoolingAllocator.java"]
  5c7d3ca5_8d2c_76d2_0628_1864f492365d -->|defined in| fee3fa6d_a7fb_30d6_ea34_49602c633a2c
  02a76ead_33d8_cfe3_4978_8b372c856ad7["MagazineGroup()"]
  5c7d3ca5_8d2c_76d2_0628_1864f492365d -->|method| 02a76ead_33d8_cfe3_4978_8b372c856ad7
  080309e4_d57c_ce66_6f51_f105cc6f6710["AdaptiveByteBuf()"]
  5c7d3ca5_8d2c_76d2_0628_1864f492365d -->|method| 080309e4_d57c_ce66_6f51_f105cc6f6710
  7d98a725_7e43_8a22_908d_604424cb35a1["tryExpandMagazines()"]
  5c7d3ca5_8d2c_76d2_0628_1864f492365d -->|method| 7d98a725_7e43_8a22_908d_604424cb35a1
  653ce3aa_e303_1e3b_325f_51c631cec2f4["Chunk()"]
  5c7d3ca5_8d2c_76d2_0628_1864f492365d -->|method| 653ce3aa_e303_1e3b_325f_51c631cec2f4
  8b849fa9_e590_a1c7_94f9_6de2bdddf91a["offerChunk()"]
  5c7d3ca5_8d2c_76d2_0628_1864f492365d -->|method| 8b849fa9_e590_a1c7_94f9_6de2bdddf91a
  65823112_6744_318f_eee4_bb0a2804a97f["free()"]
  5c7d3ca5_8d2c_76d2_0628_1864f492365d -->|method| 65823112_6744_318f_eee4_bb0a2804a97f
  fd186d64_9da5_df36_66cb_2167df031bd3["freeChunkReuseQueue()"]
  5c7d3ca5_8d2c_76d2_0628_1864f492365d -->|method| fd186d64_9da5_df36_66cb_2167df031bd3

Relationship Graph

Source Code

buffer/src/main/java/io/netty/buffer/AdaptivePoolingAllocator.java lines 358–517

    private static final class MagazineGroup {
        private final AdaptivePoolingAllocator allocator;
        private final ChunkAllocator chunkAllocator;
        private final ChunkManagementStrategy chunkManagementStrategy;
        private final ChunkCache chunkCache;
        private final StampedLock magazineExpandLock;
        private final Magazine threadLocalMagazine;
        private Thread ownerThread;
        private volatile Magazine[] magazines;
        private volatile boolean freed;

        MagazineGroup(AdaptivePoolingAllocator allocator,
                      ChunkAllocator chunkAllocator,
                      ChunkManagementStrategy chunkManagementStrategy,
                      boolean isThreadLocal) {
            this.allocator = allocator;
            this.chunkAllocator = chunkAllocator;
            this.chunkManagementStrategy = chunkManagementStrategy;
            chunkCache = chunkManagementStrategy.createChunkCache(isThreadLocal);
            if (isThreadLocal) {
                ownerThread = Thread.currentThread();
                magazineExpandLock = null;
                threadLocalMagazine = new Magazine(this, false, chunkManagementStrategy.createController(this));
            } else {
                ownerThread = null;
                magazineExpandLock = new StampedLock();
                threadLocalMagazine = null;
                Magazine[] mags = new Magazine[INITIAL_MAGAZINES];
                for (int i = 0; i < mags.length; i++) {
                    mags[i] = new Magazine(this, true, chunkManagementStrategy.createController(this));
                }
                magazines = mags;
            }
        }

        public AdaptiveByteBuf allocate(int size, int maxCapacity, Thread currentThread, AdaptiveByteBuf buf) {
            boolean reallocate = buf != null;

            // Path for thread-local allocation.
            Magazine tlMag = threadLocalMagazine;
            if (tlMag != null) {
                if (buf == null) {
                    buf = tlMag.newBuffer();
                }
                boolean allocated = tlMag.tryAllocate(size, maxCapacity, buf, reallocate);
                assert allocated : "Allocation of threadLocalMagazine must always succeed";
                return buf;
            }

            // Path for concurrent allocation.
            long threadId = currentThread.getId();
            Magazine[] mags;
            int expansions = 0;
            do {
                mags = magazines;
                int mask = mags.length - 1;
                int index = (int) (threadId & mask);
                for (int i = 0, m = mags.length << 1; i < m; i++) {
                    Magazine mag = mags[index + i & mask];
                    if (buf == null) {
                        buf = mag.newBuffer();
                    }
                    if (mag.tryAllocate(size, maxCapacity, buf, reallocate)) {
                        // Was able to allocate.
                        return buf;
                    }
                }
                expansions++;
            } while (expansions <= EXPANSION_ATTEMPTS && tryExpandMagazines(mags.length));

            // The magazines failed us; contention too high and we don't want to spend more effort expanding the array.
            if (!reallocate && buf != null) {
                buf.release(); // Release the previously claimed buffer before we return.
            }
            return null;
        }

        private boolean tryExpandMagazines(int currentLength) {
            if (currentLength >= MAX_STRIPES) {
                return true;
            }

Frequently Asked Questions

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

Analyze Your Own Codebase

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

Try Supermodel Free