{"record":{"id":"1659d6c62d0f4947","repo":"MyCATApache/Mycat-Server","slug":"buffersize-must-be-a-power-of-2","errorCode":null,"errorMessage":"bufferSize must be a power of 2","messagePattern":"bufferSize must be a power of 2","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/memory/unsafe/ringbuffer/RingBuffer.java","lineNumber":51,"sourceCode":"        BUFFER_PAD = 128 / scale;\n        REF_ARRAY_BASE = Platform.arrayBaseOffset(Object[].class) + (BUFFER_PAD << REF_ELEMENT_SHIFT);\n    }\n\n    private final long indexMask;\n    private final Object[] entries;\n    protected final int bufferSize;\n    protected final Sequencer sequencer;\n\n    public RingBuffer(EventFactory<E> eventFactory, Sequencer sequencer) {\n        this.sequencer = sequencer;\n        this.bufferSize = sequencer.getBufferSize();\n        //保证buffer大小不小于1\n        if (bufferSize < 1) {\n            throw new IllegalArgumentException(\"bufferSize must not be less than 1\");\n        }\n        //保证buffer大小为2的n次方\n        if (Integer.bitCount(bufferSize) != 1) {\n            throw new IllegalArgumentException(\"bufferSize must be a power of 2\");\n        }\n        //m % 2^n  <=>  m & (2^n - 1)\n        this.indexMask = bufferSize - 1;\n        /**\n         * 结构：缓存行填充，避免频繁访问的任一entry与另一被修改的无关变量写入同一缓存行\n         * --------------\n         * *   数组头   * BASE\n         * *   Padding  * 128字节\n         * * reference1 * SCALE\n         * * reference2 * SCALE\n         * * reference3 * SCALE\n         * ..........\n         * *   Padding  * 128字节\n         * --------------\n         */\n        this.entries = new Object[sequencer.getBufferSize() + 2 * BUFFER_PAD];\n        //利用eventFactory初始化RingBuffer的每个槽\n        fill(eventFactory);","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/memory/unsafe/ringbuffer/RingBuffer.java#L33-L69","documentation":"RingBuffer's constructor validates that the buffer size is at least 1 and exactly a power of 2. The power-of-2 requirement lets the buffer compute ring indices with a cheap bitmask (indexMask = bufferSize - 1) instead of a modulo operation. Any size that is not 2^n fails this check and the constructor throws IllegalArgumentException.","triggerScenarios":"Calling the RingBuffer constructor with bufferSize values such as 0, 3, 100, 1000, or any integer where Integer.bitCount(bufferSize) != 1 (e.g. RingBuffer ring = new RingBuffer(1000);).","commonSituations":"Developers pick a 'nice round' buffer size like 1000 or 5000 for throughput tuning, or pass a user-supplied config value without validating it, or pass 0/negative values derived from a misconfigured property.","solutions":["Round the requested size up to the next power of 2 before constructing (e.g. Integer.highestOneBit(size - 1) << 1).","Use a known-good size like 1024, 4096, or 8192 in your configuration.","Validate/normalize user-supplied buffer-size config at startup with a clear message.","Ensure the size is at least 1 to avoid the related 'must not be less than 1' error."],"exampleFix":"// before\nRingBuffer ring = new RingBuffer(1000);\n// after\nint size = 1000;\nint pow2 = Integer.highestOneBit(Math.max(1, size - 1)) << 1;\nRingBuffer ring = new RingBuffer(pow2); // 1024","handlingStrategy":"validation","validationCode":"public static int toPow2(int size) {\n    if (size < 1) throw new IllegalArgumentException(\"bufferSize must be >= 1\");\n    return Integer.bitCount(size) == 1 ? size : Integer.highestOneBit(size - 1) << 1;\n}\n// call: new RingBuffer(toPow2(requestedSize));","typeGuard":"public static boolean isPowerOfTwo(int n) {\n    return n > 0 && (n & (n - 1)) == 0;\n}","tryCatchPattern":"try {\n    ring = new RingBuffer(configuredSize);\n} catch (IllegalArgumentException e) {\n    ring = new RingBuffer(Integer.highestOneBit(Math.max(1, configuredSize - 1)) << 1);\n}","preventionTips":["Always derive capacity via Integer.highestOneBit/next power of 2 helpers","Use standard sizes (1024, 4096, 8192) in configs","Validate buffer-size config at startup, before constructing the buffer"],"tags":["java","ringbuffer","illegal-argument","configuration"],"backgroundTag":"invalid-argument-value","analyzedSha":"65f8d8beb752f935752f2a0eec0ab017facab9ef","analyzedAt":"2026-09-11T00:12:21.696Z","contentChangedAt":"2026-09-11T00:12:21.696Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}