/* * Copyright 2011 LMAX Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.lmax.disruptor; /** * Ring based store of reusable entries containing the data representing an event being exchanged between event publisher and {@link EventProcessor}s. * * @param <T> implementation storing the data for sharing during exchange or parallel coordination of an event. */ public final class RingBuffer<T> extends Sequencer { private final int indexMask; private final Object[] entries; /** * Construct a RingBuffer with the full option set. * * @param eventFactory to newInstance entries for filling the RingBuffer * @param claimStrategy threading strategy for publisher claiming entries in the ring. * @param waitStrategy waiting strategy employed by processorsToTrack waiting on entries becoming available. * * @throws IllegalArgumentException if bufferSize is not a power of 2 */ public RingBuffer(final EventFactory<T> eventFactory, final ClaimStrategy claimStrategy, final WaitStrategy waitStrategy) { super(claimStrategy, waitStrategy); if (Integer.bitCount(claimStrategy.getBufferSize()) != 1) { throw new IllegalArgumentException("bufferSize must be a power of 2"); } indexMask = claimStrategy.getBufferSize() - 1; entries = new Object[claimStrategy.getBufferSize()]; fill(eventFactory); } /** * Construct a RingBuffer with default strategies of: * {@link MultiThreadedClaimStrategy} and {@link BlockingWaitStrategy} * * @param eventFactory to newInstance entries for filling the RingBuffer * @param bufferSize of the RingBuffer that will be rounded up to the next power of 2 */ public RingBuffer(final EventFactory<T> eventFactory, final int bufferSize) { this(eventFactory, new MultiThreadedClaimStrategy(bufferSize), new BlockingWaitStrategy()); } /** * Get the event for a given sequence in the RingBuffer. * * @param sequence for the event * @return event for the sequence */ @SuppressWarnings("unchecked") public T get(final long sequence) { return (T)entries[(int)sequence & indexMask]; } private void fill(final EventFactory<T> eventFactory) { for (int i = 0; i < entries.length; i++) { entries[i] = eventFactory.newInstance(); } } }