75
LMAX Disruptor 3.x Details & Advanced Patterns @mikeb2701 Friday, 20 September 13

Disruptor yow2013 v2

Embed Size (px)

Citation preview

Page 1: Disruptor yow2013 v2

LMAX Disruptor 3.xDetails & Advanced Patterns

@mikeb2701

Friday, 20 September 13

Page 2: Disruptor yow2013 v2

<Intro>

Friday, 20 September 13

Page 3: Disruptor yow2013 v2

Agenda

• Safer

• Safer

• Faster

• Faster

Friday, 20 September 13

Page 4: Disruptor yow2013 v2

<safer>

Friday, 20 September 13

Page 5: Disruptor yow2013 v2

class PlayerMove { long id; long direction; long distance;}

Friday, 20 September 13

Page 6: Disruptor yow2013 v2

class PlayerMoveFactory implements EventFactory<PlayerMove> {

public PlayerMove newInstance() { return new PlayerMove(); }}

Friday, 20 September 13

Page 7: Disruptor yow2013 v2

class PlayerMoveFactory implements EventFactory<PlayerMove> {

public PlayerMove newInstance() { return new PlayerMove(); }}

Friday, 20 September 13

Page 8: Disruptor yow2013 v2

class PlayerHandler implements EventHandler<PlayerMove> {

public void onEvent(PlayerMove event, long sequence, boolean onBatchEnd) {

Player player = findPlayer(event.id); player.move(event.direction, event.distance); }}

Friday, 20 September 13

Page 9: Disruptor yow2013 v2

class PlayerHandler implements EventHandler<PlayerMove> {

public void onEvent(PlayerMove event, long sequence, boolean onBatchEnd) {

Player player = findPlayer(event.id); player.move(event.direction, event.distance); }}

Friday, 20 September 13

Page 10: Disruptor yow2013 v2

class NetworkHandler { RingBuffer<PlayerMove> buffer;

void handle(ByteBuffer packet) {

long next = buffer.next();

PlayerMove playerMove = buffer.get(next); playerMove.id = packet.getLong(); playerMove.direction = packet.getLong(); playerMove.distance = packet.getLong();

buffer.publish(next); }}

Friday, 20 September 13

Page 11: Disruptor yow2013 v2

class NetworkHandler { RingBuffer<PlayerMove> buffer;

void handle(ByteBuffer packet) {

long next = buffer.next();

PlayerMove playerMove = buffer.get(next); playerMove.id = packet.getLong(); playerMove.direction = packet.getLong(); playerMove.distance = packet.getLong();

buffer.publish(next); }}

Friday, 20 September 13

Page 12: Disruptor yow2013 v2

class NetworkHandler { RingBuffer<PlayerMove> buffer;

void handle(ByteBuffer packet) {

long next = buffer.next();

PlayerMove playerMove = buffer.get(next); playerMove.id = packet.getLong(); playerMove.direction = packet.getLong(); playerMove.distance = packet.getLong();

buffer.publish(next); }}

Friday, 20 September 13

Page 13: Disruptor yow2013 v2

class NetworkHandler { RingBuffer<PlayerMove> buffer;

void handle(ByteBuffer packet) {

long next = buffer.next();

PlayerMove playerMove = buffer.get(next); playerMove.id = packet.getLong(); playerMove.direction = packet.getLong(); playerMove.distance = packet.getLong();

buffer.publish(next); }}

Friday, 20 September 13

Page 14: Disruptor yow2013 v2

class NetworkHandler { RingBuffer<PlayerMove> buffer;

void handle(ByteBuffer packet) {

long next = buffer.next();

PlayerMove playerMove = buffer.get(next); playerMove.id = packet.getLong(); playerMove.direction = packet.getLong(); playerMove.distance = packet.getLong();

buffer.publish(next); }}

Friday, 20 September 13

Page 15: Disruptor yow2013 v2

class NetworkHandler { RingBuffer<PlayerMove> buffer;

void handle(ByteBuffer packet) {

long next = buffer.next(); try { PlayerMove playerMove = buffer.get(next); playerMove.id = packet.getLong(); playerMove.direction = packet.getLong(); playerMove.distance = packet.getLong(); } finally { buffer.publish(next); } }}

Friday, 20 September 13

Page 16: Disruptor yow2013 v2

class PlayerMoveTranslator implements EventTranslatorOneArg<PlayerMove, ByteBuffer> { public static final PlayerMoveTranslator INSTANCE = new PlayerMoveTranslator(); public void translateTo(PlayerMove playerMove, long sequence, ByteBuffer packet) { playerMove.id = packet.getLong(); playerMove.direction = packet.getLong(); playerMove.distance = packet.getLong(); }}

class NetworkHandler2 { RingBuffer<PlayerMove> buffer; void handle(final ByteBuffer packet) { buffer.publishEvent(PlayerMoveTranslator.INSTANCE, packet); } }

Friday, 20 September 13

Page 17: Disruptor yow2013 v2

class PlayerMoveTranslator implements EventTranslatorOneArg<PlayerMove, ByteBuffer> { public static final PlayerMoveTranslator INSTANCE = new PlayerMoveTranslator(); public void translateTo(PlayerMove playerMove, long sequence, ByteBuffer packet) { playerMove.id = packet.getLong(); playerMove.direction = packet.getLong(); playerMove.distance = packet.getLong(); }}

class NetworkHandler2 { RingBuffer<PlayerMove> buffer; void handle(final ByteBuffer packet) { buffer.publishEvent(PlayerMoveTranslator.INSTANCE, packet); } }

Friday, 20 September 13

Page 18: Disruptor yow2013 v2

class PlayerMoveTranslator implements EventTranslatorOneArg<PlayerMove, ByteBuffer> { public static final PlayerMoveTranslator INSTANCE = new PlayerMoveTranslator(); public void translateTo(PlayerMove playerMove, long sequence, ByteBuffer packet) { playerMove.id = packet.getLong(); playerMove.direction = packet.getLong(); playerMove.distance = packet.getLong(); }}

class NetworkHandler2 { RingBuffer<PlayerMove> buffer; void handle(final ByteBuffer packet) { buffer.publishEvent(PlayerMoveTranslator.INSTANCE, packet); } }

Friday, 20 September 13

Page 19: Disruptor yow2013 v2

class PlayerMoveTranslator implements EventTranslatorOneArg<PlayerMove, ByteBuffer> { public static final PlayerMoveTranslator INSTANCE = new PlayerMoveTranslator(); public void translateTo(PlayerMove playerMove, long sequence, ByteBuffer packet) { playerMove.id = packet.getLong(); playerMove.direction = packet.getLong(); playerMove.distance = packet.getLong(); }}

class NetworkHandler2 { RingBuffer<PlayerMove> buffer; void handle(final ByteBuffer packet) { buffer.publishEvent(PlayerMoveTranslator.INSTANCE, packet); } }

Friday, 20 September 13

Page 20: Disruptor yow2013 v2

<safer>

Friday, 20 September 13

Page 21: Disruptor yow2013 v2

public abstract class BaseMessage { public boolean isValid;}

Friday, 20 September 13

Page 22: Disruptor yow2013 v2

class SafeTranslator<T extends BaseMessage, A> implements EventTranslatorOneArg<T, A> { private EventTranslatorOneArg<T, A> delegate;

public SafeTranslator(EventTranslatorOneArg<T, A> delegate) { this.delegate = delegate; }

public void translateTo(T t, long sequence, A arg0) { t.isValid = false; delegate.translateTo(t, sequence, arg0); t.isValid = true; }}

Friday, 20 September 13

Page 23: Disruptor yow2013 v2

class SafeTranslator<T extends BaseMessage, A> implements EventTranslatorOneArg<T, A> { private EventTranslatorOneArg<T, A> delegate;

public SafeTranslator(EventTranslatorOneArg<T, A> delegate) { this.delegate = delegate; }

public void translateTo(T t, long sequence, A arg0) { t.isValid = false; delegate.translateTo(t, sequence, arg0); t.isValid = true; }}

Friday, 20 September 13

Page 24: Disruptor yow2013 v2

class SafeTranslator<T extends BaseMessage, A> implements EventTranslatorOneArg<T, A> { private EventTranslatorOneArg<T, A> delegate;

public SafeTranslator(EventTranslatorOneArg<T, A> delegate) { this.delegate = delegate; }

public void translateTo(T t, long sequence, A arg0) { t.isValid = false; delegate.translateTo(t, sequence, arg0); t.isValid = true; }}

Friday, 20 September 13

Page 25: Disruptor yow2013 v2

class SafeTranslator<T extends BaseMessage, A> implements EventTranslatorOneArg<T, A> { private EventTranslatorOneArg<T, A> delegate;

public SafeTranslator(EventTranslatorOneArg<T, A> delegate) { this.delegate = delegate; }

public void translateTo(T t, long sequence, A arg0) { t.isValid = false; delegate.translateTo(t, sequence, arg0); t.isValid = true; }}

Friday, 20 September 13

Page 26: Disruptor yow2013 v2

class SafeTranslator<T extends BaseMessage, A> implements EventTranslatorOneArg<T, A> { private EventTranslatorOneArg<T, A> delegate;

public SafeTranslator(EventTranslatorOneArg<T, A> delegate) { this.delegate = delegate; }

public void translateTo(T t, long sequence, A arg0) { t.isValid = false; delegate.translateTo(t, sequence, arg0); t.isValid = true; }}

Friday, 20 September 13

Page 27: Disruptor yow2013 v2

class SafeTranslator<T extends BaseMessage, A> implements EventTranslatorOneArg<T, A> { private EventTranslatorOneArg<T, A> delegate;

public SafeTranslator(EventTranslatorOneArg<T, A> delegate) { this.delegate = delegate; }

public void translateTo(T t, long sequence, A arg0) { t.isValid = false; delegate.translateTo(t, sequence, arg0); t.isValid = true; }}

Friday, 20 September 13

Page 28: Disruptor yow2013 v2

class SafeHandler<T extends BaseMessage>implements EventHandler<T> { private EventHandler<T> delegate;

public SafeHandler(EventHandler<T> handler) { this.delegate = handler; }

public void onEvent(T t, long sequence, boolean endOfBatch) { if (!t.isValid) { return; } delegate.onEvent(t, sequence, endOfBatch); }}

Friday, 20 September 13

Page 29: Disruptor yow2013 v2

class SafeHandler<T extends BaseMessage>implements EventHandler<T> { private EventHandler<T> delegate;

public SafeHandler(EventHandler<T> handler) { this.delegate = handler; }

public void onEvent(T t, long sequence, boolean endOfBatch) { if (!t.isValid) { return; } delegate.onEvent(t, sequence, endOfBatch); }}

Friday, 20 September 13

Page 30: Disruptor yow2013 v2

class SafeHandler<T extends BaseMessage>implements EventHandler<T> { private EventHandler<T> delegate;

public SafeHandler(EventHandler<T> handler) { this.delegate = handler; }

public void onEvent(T t, long sequence, boolean endOfBatch) { if (!t.isValid) { return; } delegate.onEvent(t, sequence, endOfBatch); }}

Friday, 20 September 13

Page 31: Disruptor yow2013 v2

class SafeHandler<T extends BaseMessage>implements EventHandler<T> { private EventHandler<T> delegate;

public SafeHandler(EventHandler<T> handler) { this.delegate = handler; }

public void onEvent(T t, long sequence, boolean endOfBatch) { if (!t.isValid) { return; } delegate.onEvent(t, sequence, endOfBatch); }}

Friday, 20 September 13

Page 32: Disruptor yow2013 v2

class SafeHandler<T extends BaseMessage>implements EventHandler<T> { private EventHandler<T> delegate;

public SafeHandler(EventHandler<T> handler) { this.delegate = handler; }

public void onEvent(T t, long sequence, boolean endOfBatch) { if (!t.isValid) { return; } delegate.onEvent(t, sequence, endOfBatch); }}

Friday, 20 September 13

Page 33: Disruptor yow2013 v2

<faster>

Friday, 20 September 13

Page 34: Disruptor yow2013 v2

public class SimpleEvent { private final long id; private final long v1; private final long v2; private final long v3;

public SimpleEvent(long id, long v1, long v2, long v3) { this.id = id; this.v1 = v1; this.v2 = v2; this.v3 = v3; }}

public class EventHolder { public SimpleEvent event;}

Friday, 20 September 13

Page 35: Disruptor yow2013 v2

public class SimpleEvent { private final long id; private final long v1; private final long v2; private final long v3;

public SimpleEvent(long id, long v1, long v2, long v3) { this.id = id; this.v1 = v1; this.v2 = v2; this.v3 = v3; }}

public class EventHolder { public SimpleEvent event;}

Friday, 20 September 13

Page 36: Disruptor yow2013 v2

EventTranslatorOneArg<EventHolder, SimpleEvent> TRANSLATOR = new EventTranslatorOneArg<>() { public void translateTo(EventHolder holder, long sequence, SimpleEvent event) { holder.event = event; }};

Friday, 20 September 13

Page 37: Disruptor yow2013 v2

<GC>

Friday, 20 September 13

Page 38: Disruptor yow2013 v2

next() : longget(long) : Tpublish(long) : void

RingBuffer<T>

next() : longpublish(long) : void

Sequencer

WaitStrategy

SingleProducerSequencer

MultiProducerSequencer

get(long) : T

DataProvider<T>

run() : void

BatchEventProcessor<T>

onEvent(T, long, boolean) : void

EventHandler<T>

Friday, 20 September 13

Page 39: Disruptor yow2013 v2

next() : longget(long) : Tpublish(long) : void

RingBuffer<T>

next() : longpublish(long) : void

Sequencer

WaitStrategy

SingleProducerSequencer

MultiProducerSequencer

get(long) : T

DataProvider<T>

run() : void

BatchEventProcessor<T>

onEvent(T, long, boolean) : void

EventHandler<T>

Friday, 20 September 13

Page 40: Disruptor yow2013 v2

public interface EventAccessor<T> { T take(long sequence);}

public class CustomRingBuffer<T> implements DataProvider<EventAccessor<T>>, EventAccessor<T> { private final Sequencer sequencer; private final Object[] buffer; private final int mask;

public CustomRingBuffer(Sequencer sequencer) { this.sequencer = sequencer; buffer = new Object[sequencer.getBufferSize()]; mask = sequencer.getBufferSize() - 1; }

Friday, 20 September 13

Page 41: Disruptor yow2013 v2

public interface EventAccessor<T> { T take(long sequence);}

public class CustomRingBuffer<T> implements DataProvider<EventAccessor<T>>, EventAccessor<T> { private final Sequencer sequencer; private final Object[] buffer; private final int mask;

public CustomRingBuffer(Sequencer sequencer) { this.sequencer = sequencer; buffer = new Object[sequencer.getBufferSize()]; mask = sequencer.getBufferSize() - 1; }

Friday, 20 September 13

Page 42: Disruptor yow2013 v2

public interface EventAccessor<T> { T take(long sequence);}

public class CustomRingBuffer<T> implements DataProvider<EventAccessor<T>>, EventAccessor<T> { private final Sequencer sequencer; private final Object[] buffer; private final int mask;

public CustomRingBuffer(Sequencer sequencer) { this.sequencer = sequencer; buffer = new Object[sequencer.getBufferSize()]; mask = sequencer.getBufferSize() - 1; }

Friday, 20 September 13

Page 43: Disruptor yow2013 v2

public interface EventAccessor<T> { T take(long sequence);}

public class CustomRingBuffer<T> implements DataProvider<EventAccessor<T>>, EventAccessor<T> { private final Sequencer sequencer; private final Object[] buffer; private final int mask;

public CustomRingBuffer(Sequencer sequencer) { this.sequencer = sequencer; buffer = new Object[sequencer.getBufferSize()]; mask = sequencer.getBufferSize() - 1; }

Friday, 20 September 13

Page 44: Disruptor yow2013 v2

public void put(T t) { long next = sequencer.next(); buffer[index(next)] = t; sequencer.publish(next); }

public T take(long sequence) { T t = (T) buffer[index(sequence)]; buffer[index(sequence)] = null; return t; }

public EventAccessor<T> get(long sequence) { return this; }

Friday, 20 September 13

Page 45: Disruptor yow2013 v2

public void put(T t) { long next = sequencer.next(); buffer[index(next)] = t; sequencer.publish(next); }

public T take(long sequence) { T t = (T) buffer[index(sequence)]; buffer[index(sequence)] = null; return t; }

public EventAccessor<T> get(long sequence) { return this; }

Friday, 20 September 13

Page 46: Disruptor yow2013 v2

public void put(T t) { long next = sequencer.next(); buffer[index(next)] = t; sequencer.publish(next); }

public T take(long sequence) { T t = (T) buffer[index(sequence)]; buffer[index(sequence)] = null; return t; }

public EventAccessor<T> get(long sequence) { return this; }

Friday, 20 September 13

Page 47: Disruptor yow2013 v2

public void put(T t) { long next = sequencer.next(); buffer[index(next)] = t; sequencer.publish(next); }

public T take(long sequence) { T t = (T) buffer[index(sequence)]; buffer[index(sequence)] = null; return t; }

public EventAccessor<T> get(long sequence) { return this; }

Friday, 20 September 13

Page 48: Disruptor yow2013 v2

public void put(T t) { long next = sequencer.next(); buffer[index(next)] = t; sequencer.publish(next); }

public T take(long sequence) { T t = (T) buffer[index(sequence)]; buffer[index(sequence)] = null; return t; }

public EventAccessor<T> get(long sequence) { return this; }

Friday, 20 September 13

Page 49: Disruptor yow2013 v2

public void put(T t) { long next = sequencer.next(); buffer[index(next)] = t; sequencer.publish(next); }

public T take(long sequence) { T t = (T) buffer[index(sequence)]; buffer[index(sequence)] = null; return t; }

public EventAccessor<T> get(long sequence) { return this; }

Friday, 20 September 13

Page 50: Disruptor yow2013 v2

public void put(T t) { long next = sequencer.next(); buffer[index(next)] = t; sequencer.publish(next); }

public T take(long sequence) { T t = (T) buffer[index(sequence)]; buffer[index(sequence)] = null; return t; }

public EventAccessor<T> get(long sequence) { return this; }

Friday, 20 September 13

Page 51: Disruptor yow2013 v2

public void put(T t) { long next = sequencer.next(); buffer[index(next)] = t; sequencer.publish(next); }

public T take(long sequence) { T t = (T) buffer[index(sequence)]; buffer[index(sequence)] = null; return t; }

public EventAccessor<T> get(long sequence) { return this; }

Friday, 20 September 13

Page 52: Disruptor yow2013 v2

public void put(T t) { long next = sequencer.next(); buffer[index(next)] = t; sequencer.publish(next); }

public T take(long sequence) { T t = (T) buffer[index(sequence)]; buffer[index(sequence)] = null; return t; }

public EventAccessor<T> get(long sequence) { return this; }

Friday, 20 September 13

Page 53: Disruptor yow2013 v2

public BatchEventProcessor<EventAccessor<T>> createHandler(final EventHandler<T> handler) { BatchEventProcessor<EventAccessor<T>> processor = new BatchEventProcessor<>(this, sequencer.newBarrier(), new EventHandler<EventAccessor<T>>() { public void onEvent(EventAccessor<T> accessor, long sequence, boolean endOfBatch) { handler.onEvent(accessor.take(sequence), sequence, endOfBatch); } });

sequencer.addGatingSequences(processor.getSequence());

return processor;}

Friday, 20 September 13

Page 54: Disruptor yow2013 v2

public BatchEventProcessor<EventAccessor<T>> createHandler(final EventHandler<T> handler) { BatchEventProcessor<EventAccessor<T>> processor = new BatchEventProcessor<>(this, sequencer.newBarrier(), new EventHandler<EventAccessor<T>>() { public void onEvent(EventAccessor<T> accessor, long sequence, boolean endOfBatch) { handler.onEvent(accessor.take(sequence), sequence, endOfBatch); } });

sequencer.addGatingSequences(processor.getSequence());

return processor;}

Friday, 20 September 13

Page 55: Disruptor yow2013 v2

public BatchEventProcessor<EventAccessor<T>> createHandler(final EventHandler<T> handler) { BatchEventProcessor<EventAccessor<T>> processor = new BatchEventProcessor<>(this, sequencer.newBarrier(), new EventHandler<EventAccessor<T>>() { public void onEvent(EventAccessor<T> accessor, long sequence, boolean endOfBatch) { handler.onEvent(accessor.take(sequence), sequence, endOfBatch); } });

sequencer.addGatingSequences(processor.getSequence());

return processor;}

Friday, 20 September 13

Page 56: Disruptor yow2013 v2

public BatchEventProcessor<EventAccessor<T>> createHandler(final EventHandler<T> handler) { BatchEventProcessor<EventAccessor<T>> processor = new BatchEventProcessor<>(this, sequencer.newBarrier(), new EventHandler<EventAccessor<T>>() { public void onEvent(EventAccessor<T> accessor, long sequence, boolean endOfBatch) { handler.onEvent(accessor.take(sequence), sequence, endOfBatch); } });

sequencer.addGatingSequences(processor.getSequence());

return processor;}

Friday, 20 September 13

Page 57: Disruptor yow2013 v2

public BatchEventProcessor<EventAccessor<T>> createHandler(final EventHandler<T> handler) { BatchEventProcessor<EventAccessor<T>> processor = new BatchEventProcessor<>(this, sequencer.newBarrier(), new EventHandler<EventAccessor<T>>() { public void onEvent(EventAccessor<T> accessor, long sequence, boolean endOfBatch) { handler.onEvent(accessor.take(sequence), sequence, endOfBatch); } });

sequencer.addGatingSequences(processor.getSequence());

return processor;}

Friday, 20 September 13

Page 58: Disruptor yow2013 v2

Simple Custom

Mean 0.032 0.002

Median 0.021 0.002

Mode 0.020 0.002

Performance - It’s my laptop, YMMV!!!

Friday, 20 September 13

Page 59: Disruptor yow2013 v2

<faster>

Friday, 20 September 13

Page 60: Disruptor yow2013 v2

public class OffHeapRingBufferimplements DataProvider<ByteBuffer> { private final Sequencer sequencer; private final int entrySize; private final ByteBuffer buffer; private final int mask; ThreadLocal<ByteBuffer> perThreadBuffer = new ThreadLocal<ByteBuffer>() { protected ByteBuffer initialValue() { return buffer.duplicate(); } };

public OffHeapRingBuffer(Sequencer sequencer, int entrySize) { this.sequencer = sequencer; this.entrySize = entrySize; this.mask = sequencer.getBufferSize() - 1; buffer = ByteBuffer.allocateDirect( sequencer.getBufferSize() * entrySize); }

Friday, 20 September 13

Page 61: Disruptor yow2013 v2

public class OffHeapRingBufferimplements DataProvider<ByteBuffer> { private final Sequencer sequencer; private final int entrySize; private final ByteBuffer buffer; private final int mask; ThreadLocal<ByteBuffer> perThreadBuffer = new ThreadLocal<ByteBuffer>() { protected ByteBuffer initialValue() { return buffer.duplicate(); } };

public OffHeapRingBuffer(Sequencer sequencer, int entrySize) { this.sequencer = sequencer; this.entrySize = entrySize; this.mask = sequencer.getBufferSize() - 1; buffer = ByteBuffer.allocateDirect( sequencer.getBufferSize() * entrySize); }

Friday, 20 September 13

Page 62: Disruptor yow2013 v2

public class OffHeapRingBufferimplements DataProvider<ByteBuffer> { private final Sequencer sequencer; private final int entrySize; private final ByteBuffer buffer; private final int mask; ThreadLocal<ByteBuffer> perThreadBuffer = new ThreadLocal<ByteBuffer>() { protected ByteBuffer initialValue() { return buffer.duplicate(); } };

public OffHeapRingBuffer(Sequencer sequencer, int entrySize) { this.sequencer = sequencer; this.entrySize = entrySize; this.mask = sequencer.getBufferSize() - 1; buffer = ByteBuffer.allocateDirect( sequencer.getBufferSize() * entrySize); }

Friday, 20 September 13

Page 63: Disruptor yow2013 v2

public class OffHeapRingBufferimplements DataProvider<ByteBuffer> { private final Sequencer sequencer; private final int entrySize; private final ByteBuffer buffer; private final int mask; ThreadLocal<ByteBuffer> perThreadBuffer = new ThreadLocal<ByteBuffer>() { protected ByteBuffer initialValue() { return buffer.duplicate(); } };

public OffHeapRingBuffer(Sequencer sequencer, int entrySize) { this.sequencer = sequencer; this.entrySize = entrySize; this.mask = sequencer.getBufferSize() - 1; buffer = ByteBuffer.allocateDirect( sequencer.getBufferSize() * entrySize); }

Friday, 20 September 13

Page 64: Disruptor yow2013 v2

public class OffHeapRingBufferimplements DataProvider<ByteBuffer> { private final Sequencer sequencer; private final int entrySize; private final ByteBuffer buffer; private final int mask; ThreadLocal<ByteBuffer> perThreadBuffer = new ThreadLocal<ByteBuffer>() { protected ByteBuffer initialValue() { return buffer.duplicate(); } };

public OffHeapRingBuffer(Sequencer sequencer, int entrySize) { this.sequencer = sequencer; this.entrySize = entrySize; this.mask = sequencer.getBufferSize() - 1; buffer = ByteBuffer.allocateDirect( sequencer.getBufferSize() * entrySize); }

Friday, 20 September 13

Page 65: Disruptor yow2013 v2

public ByteBuffer get(long sequence) { int index = index(sequence); int position = index * entrySize; int limit = position + entrySize; ByteBuffer byteBuffer = perThreadBuffer.get(); byteBuffer.position(position).limit(limit); return byteBuffer; }

Friday, 20 September 13

Page 66: Disruptor yow2013 v2

public ByteBuffer get(long sequence) { int index = index(sequence); int position = index * entrySize; int limit = position + entrySize; ByteBuffer byteBuffer = perThreadBuffer.get(); byteBuffer.position(position).limit(limit); return byteBuffer; }

Friday, 20 September 13

Page 67: Disruptor yow2013 v2

public ByteBuffer get(long sequence) { int index = index(sequence); int position = index * entrySize; int limit = position + entrySize; ByteBuffer byteBuffer = perThreadBuffer.get(); byteBuffer.position(position).limit(limit); return byteBuffer; }

Friday, 20 September 13

Page 68: Disruptor yow2013 v2

public ByteBuffer get(long sequence) { int index = index(sequence); int position = index * entrySize; int limit = position + entrySize; ByteBuffer byteBuffer = perThreadBuffer.get(); byteBuffer.position(position).limit(limit); return byteBuffer; }

Friday, 20 September 13

Page 69: Disruptor yow2013 v2

public ByteBuffer get(long sequence) { int index = index(sequence); int position = index * entrySize; int limit = position + entrySize; ByteBuffer byteBuffer = perThreadBuffer.get(); byteBuffer.position(position).limit(limit); return byteBuffer; }

Friday, 20 September 13

Page 70: Disruptor yow2013 v2

public void put(byte[] data) { long next = sequencer.next(); try { get(next).put(data); } finally { sequencer.publish(next); } }

Friday, 20 September 13

Page 71: Disruptor yow2013 v2

public void put(byte[] data) { long next = sequencer.next(); try { get(next).put(data); } finally { sequencer.publish(next); } }

Friday, 20 September 13

Page 72: Disruptor yow2013 v2

public void put(byte[] data) { long next = sequencer.next(); try { get(next).put(data); } finally { sequencer.publish(next); } }

Friday, 20 September 13

Page 73: Disruptor yow2013 v2

public void put(byte[] data) { long next = sequencer.next(); try { get(next).put(data); } finally { sequencer.publish(next); } }

Friday, 20 September 13

Page 74: Disruptor yow2013 v2

public class BufferEventHandler implements EventHandler<ByteBuffer> {

public void onEvent(ByteBuffer buffer, long sequence, boolean endOfBatch) { // Do stuff... }}

Friday, 20 September 13