package org.ObjectLayout.examples;/* * Written by Gil Tene, Martin Thompson, and Michael Barker, and released to the public domain, * as explained at http://creativecommons.org/publicdomain/zero/1.0/ */ import java.util.Iterator; import org.ObjectLayout.*; public class MassOrder extends StructuredArray<SimpleOrder> { private final long accountId; private final String instructionId; private final SimpleOrder.OrderType orderType; private final long instrumentId; private final int askOrderIndex; MassOrder(final Builder builder) { this.accountId = builder.accountId; this.instructionId = builder.instructionId; this.orderType = builder.orderType; this.instrumentId = builder.instrumentId; this.askOrderIndex = builder.bidIndex; } public long getAccountId() { return accountId; } public String getInstructionId() { return instructionId; } public SimpleOrder.OrderType getOrderType() { return orderType; } public long getInstrumentId() { return instrumentId; } public int getBidOrderIndex() { return 0; } public int getBidOrderCount() { return askOrderIndex; } private final Iterable<SimpleOrder> bidIterable = new Iterable<SimpleOrder>() { @Override public Iterator<SimpleOrder> iterator() { return new ElementIterator(getBidOrderIndex(), getBidOrderCount()); } }; public Iterable<SimpleOrder> getBids() { return bidIterable; } public int getAskOrderCount() { return (int) (getLength() - askOrderIndex); } public int getAskOrderIndex() { return askOrderIndex; } private final Iterable<SimpleOrder> askIterable = new Iterable<SimpleOrder>() { @Override public Iterator<SimpleOrder> iterator() { return new ElementIterator(getAskOrderIndex(), getAskOrderCount()); } }; public Iterable<SimpleOrder> getAsks() { return askIterable; } @Override public String toString() { return "MassOrderWithBuilder [accountId=" + this.accountId + ", instructionId=" + this.instructionId + ", orderType=" + this.orderType + ", instrumentId=" + this.instrumentId + ", askOrderIndex=" + this.askOrderIndex + "]"; } private static final ThreadLocal<Builder> BUILDER = new ThreadLocal<MassOrder.Builder>() { protected Builder initialValue() { try { return new Builder(); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } } }; public static Builder builder() { return BUILDER.get().reset(); } public static final class Builder implements CtorAndArgsProvider<SimpleOrder> { private static CtorAndArgs<MassOrder> massOrderCtorAndArgs() { try { final Class[] argTypes = { Builder.class }; return new CtorAndArgs<MassOrder>(MassOrder.class, argTypes, (Object) null); } catch (Exception e) { throw new RuntimeException(e); } } private static CtorAndArgs<SimpleOrder> simpleOrderCtorAndArgs() { try { final Class[] argTypes = { Builder.class, SimpleOrder.Side.class, long.class, long.class }; return new CtorAndArgs<SimpleOrder>(SimpleOrder.class, argTypes, null, null, 0L, 0L); } catch (Exception e) { throw new RuntimeException(e); } } private static final int MAX_ORDERS_PER_SIDE = 6; long accountId; long instrumentId; String instructionId; SimpleOrder.OrderType orderType; private int bidIndex; private long[] bidPrices = new long[MAX_ORDERS_PER_SIDE]; private long[] bidQuantities = new long[MAX_ORDERS_PER_SIDE]; private int askIndex; private long[] askPrices = new long[MAX_ORDERS_PER_SIDE]; private long[] askQuantities = new long[MAX_ORDERS_PER_SIDE]; // We use final ctorAndArgs per builder instance, since each builder is expect to be used // in a linear way with a thread (is likely to be thread local in common use). private final CtorAndArgs<MassOrder> massOrderCtorAndArgs = massOrderCtorAndArgs(); private final CtorAndArgs<SimpleOrder> simpleOrderCtorAndArgs = simpleOrderCtorAndArgs(); public Builder() throws NoSuchMethodException { massOrderCtorAndArgs.setArgs(this); reset(); } public Builder reset() { accountId = 0; instrumentId = 0; instructionId = null; orderType = null; bidIndex = 0; askIndex = 0; return this; } public Builder accountId(long accountId) { this.accountId = accountId; return this; } public Builder instrumentId(long instrumentId) { this.instrumentId = instrumentId; return this; } public Builder instructionId(String instructionId) { this.instructionId = instructionId; return this; } public Builder orderType(SimpleOrder.OrderType orderType) { this.orderType = orderType; return this; } public Builder addBid(long price, long quantity) { bidPrices[bidIndex] = price; bidQuantities[bidIndex] = quantity; bidIndex++; return this; } public Builder addAsk(long price, long quantity) { askPrices[askIndex] = price; askQuantities[askIndex] = quantity; askIndex++; return this; } @Override public CtorAndArgs<SimpleOrder> getForContext( ConstructionContext<SimpleOrder> context) throws NoSuchMethodException { long index = context.getIndex(); CtorAndArgs<SimpleOrder> ctorAndArgs = simpleOrderCtorAndArgs; if (index > bidIndex + askIndex) { throw new IllegalArgumentException(); } int i = (int) index; if (i < bidIndex) { ctorAndArgs.setArgs(this, SimpleOrder.Side.BID, bidPrices[i], bidQuantities[i]); } else { i = i - bidIndex; ctorAndArgs.setArgs(this, SimpleOrder.Side.BID, askPrices[i], askQuantities[i]); } return ctorAndArgs; } public MassOrder newInstance() { // TODO: Order validation and sorting by price. long length = bidIndex + askIndex; return (MassOrder) StructuredArray.newInstance( massOrderCtorAndArgs, SimpleOrder.class, length, this); } } }