MyCATApache/Mycat-Server · error · IllegalArgumentException

bufferSize must be a power of 2

Error message

bufferSize must be a power of 2

What it means

AbstractSequencer requires the ring buffer size to be a power of 2 (Integer.bitCount(bufferSize) == 1). Powers of two let the sequencer replace modulo with a cheap mask (index = sequence & (bufferSize-1)). Any non-power-of-two size fails fast with IllegalArgumentException at construction.

Solutions

  1. Use the nearest power of two: 1024, 2048, 4096, etc.
  2. If capacity must be derived, round down with Integer.highestOneBit(requested) (min 1)
  3. Log/normalize the configured size before constructing the sequencer

Example fix

// before
int size = 1000;
RingBuffer<Event> rb = RingBuffer.createSingleProducer(factory, size);
// after
int size = Math.max(1, Integer.highestOneBit(1000)); // 512
RingBuffer<Event> rb = RingBuffer.createSingleProducer(factory, size);
Defensive patterns

Strategy: validation

Validate before calling

if (Integer.bitCount(bufferSize) != 1) throw new IllegalArgumentException("bufferSize must be a power of 2, got " + bufferSize);

Type guard

boolean isPowerOfTwo(int n) { return n > 0 && (n & (n - 1)) == 0; }

Prevention

When it happens

Trigger: Constructing any AbstractSequencer subclass or RingBuffer via its factories with bufferSize such as 3, 1000, 1023, 1500 — anything whose binary representation has more than one set bit.

Common situations: Developers picking 'round' decimal sizes like 1000 or 10000 instead of 1024/16384; computing capacity from a quota that isn't rounded down to a power of 2.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11). Data as JSON: /api/errors/2e4a9bfb9113d497. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/io/mycat/memory/unsafe/ringbuffer/producer/AbstractSequencer.java:35

public abstract class AbstractSequencer implements Sequencer {

    private static final AtomicReferenceFieldUpdater<AbstractSequencer, Sequence[]> SEQUENCE_UPDATER =
            AtomicReferenceFieldUpdater.newUpdater(AbstractSequencer.class, Sequence[].class, "gatingSequences");

    protected final int bufferSize;
    protected final WaitStrategy waitStrategy;
    protected final Sequence cursor = new Sequence(Sequencer.INITIAL_CURSOR_VALUE);
    protected volatile Sequence[] gatingSequences = new Sequence[0];

    public AbstractSequencer(int bufferSize, WaitStrategy waitStrategy)
    {
        if (bufferSize < 1)
        {
            throw new IllegalArgumentException("bufferSize must not be less than 1");
        }
        if (Integer.bitCount(bufferSize) != 1)
        {
            throw new IllegalArgumentException("bufferSize must be a power of 2");
        }

        this.bufferSize = bufferSize;
        this.waitStrategy = waitStrategy;
    }

    @Override
    public final long getCursor()
    {
        return cursor.get();
    }


    @Override
    public final int getBufferSize()
    {
        return bufferSize;
    }

View on GitHub (pinned to 65f8d8beb7)