> groupingSources) {
+ sc = SharedContext.makeSharedContext();
+ bidTimeChunk = WritableObjectChunk.makeWritableChunk(CHUNK_SIZE);
+ askTimeChunk = WritableObjectChunk.makeWritableChunk(CHUNK_SIZE);
+ bidSizeChunk = WritableObjectChunk.makeWritableChunk(CHUNK_SIZE);
+ askSizeChunk = WritableObjectChunk.makeWritableChunk(CHUNK_SIZE);
+ bidPriceChunk = WritableObjectChunk.makeWritableChunk(CHUNK_SIZE);
+ askPriceChunk = WritableObjectChunk.makeWritableChunk(CHUNK_SIZE);
+ bidOrdIdChunk = WritableObjectChunk.makeWritableChunk(CHUNK_SIZE);
+ askOrdIdChunk = WritableObjectChunk.makeWritableChunk(CHUNK_SIZE);
+
+ groupingChunks = new ArrayList<>();
+ for (int i = 0; i < groupingSources.size(); i++) {
+ groupingChunks.add(WritableObjectChunk.makeWritableChunk(CHUNK_SIZE));
+ }
+ }
+
+ /**
+ * At the end of an update cycle this must be invoked to close and release any shared resources that were claimed
+ *
+ * during the update cycle.
+ */
+ @Override
+ public void close() {
+ sc.close();
+ fillContexts.forEach(ChunkSource.FillContext::close);
+ bidTimeChunk.close();
+ askTimeChunk.close();
+ bidSizeChunk.close();
+ askSizeChunk.close();
+ bidPriceChunk.close();
+ askPriceChunk.close();
+ bidOrdIdChunk.close();
+ askOrdIdChunk.close();
+
+ for (final WritableChunk> chunk : groupingChunks) {
+ chunk.close();
+ }
+ }
+
+ /**
+ * Just a helper method to create fill contexts and save them so they can be cleaned up neatly on close.
+ *
+ * @param cs the column source
+ * @return a new fill context for that source.
+ */
+ ChunkSource.FillContext makeFillContext(ChunkSource> cs) {
+ final ChunkSource.FillContext fc = cs.makeFillContext(CHUNK_SIZE, sc);
+ fillContexts.add(fc);
+ return fc;
+ }
+ }
+
/**
* This class listens for updates from the source table and pushes each row through the BookState for the symbol
* indicated for the row, emitting a new row into the output table for each input row which results in a book
@@ -659,7 +1013,7 @@ public void process() {
}
// First process all of the new rows
- final long rowsAdded = processAdded(upstream.added(), false);
+ final long rowsAdded = processAdded(upstream.added(), false, null);
// Handle the case where the input rows generate no book state changes, we don't want to accidentally
// try to inject a -1 into the row set.
@@ -680,11 +1034,13 @@ public void process() {
}
}
+
/**
* Build a book of bid and ask prices with the specified number of levels from the requested table, grouping input rows by the
* specified set of grouping columns. Levels will be represented as a set of columns (Price, Time, Size) for each level.
*
* @param source the table with the source data
+ * @param snapshot the table with the book
* @param depth the desired book depth
* @param batchTimestamps set to true to batch input rows with identical timestamps into the a single output row.
* @param timestampColumnName the name of the source timestamp column
@@ -692,12 +1048,14 @@ public void process() {
* @param sideColumnName the name of the source side column
* @param opColumnName the name of the source book-op column
* @param priceColumnName the name of the price column
+ * @param ordIdColumnName the name of the Order ID column
* @param groupingCols the columns to group the source table by
*
* @return a new table representing the current state of the book. This table will update as the source table updates.
*/
@SuppressWarnings("unused")
public static QueryTable build(@NotNull Table source,
+ Table snapshot,
int depth,
boolean batchTimestamps,
@NotNull String timestampColumnName,
@@ -705,8 +1063,10 @@ public static QueryTable build(@NotNull Table source,
@NotNull String sideColumnName,
@NotNull String opColumnName,
@NotNull String priceColumnName,
+ @NotNull String ordIdColumnName,
@NotNull String... groupingCols) {
final PriceBook book = new PriceBook(source,
+ snapshot,
depth,
batchTimestamps,
timestampColumnName,
@@ -714,6 +1074,7 @@ public static QueryTable build(@NotNull Table source,
sideColumnName,
opColumnName,
priceColumnName,
+ ordIdColumnName,
groupingCols);
return book.resultTable;