From 35060d0d39b136a70f8d5bd288a55c2727a70b1a Mon Sep 17 00:00:00 2001 From: Shaun L <534336+eleventy7@users.noreply.github.com> Date: Wed, 24 Jan 2024 07:28:28 -0500 Subject: [PATCH] Check --- agrona/build.gradle.kts | 35 +- .../agrona/ringbuffer/ReceiveAgent.java | 11 +- .../agrona/ringbuffer/SendAgent1.java | 12 +- .../agrona/ringbuffer/SendAgent2.java | 9 +- .../agrona/ringbuffer/StartHere.java | 2 +- agrona/src/main/resources/messages.xml | 56 +++ agrona/src/main/resources/sbe/sbe.xsd | 404 ++++++++++++++++++ 7 files changed, 521 insertions(+), 8 deletions(-) create mode 100644 agrona/src/main/resources/messages.xml create mode 100644 agrona/src/main/resources/sbe/sbe.xsd diff --git a/agrona/build.gradle.kts b/agrona/build.gradle.kts index 724ba1f3..34556cfa 100644 --- a/agrona/build.gradle.kts +++ b/agrona/build.gradle.kts @@ -1,10 +1,15 @@ - plugins { application checkstyle } + +@Suppress("DEPRECATION") +val generatedDir = file("${buildDir}/generated/src/main/java") +val codecGeneration = configurations.create("codecGeneration") + dependencies { + "codecGeneration"(libs.sbe) checkstyle(libs.checkstyle) implementation(libs.agrona) implementation(libs.slf4j) @@ -12,6 +17,12 @@ dependencies { testImplementation(libs.bundles.testing) } +sourceSets { + main { + java.srcDir(generatedDir) + } +} + testing { suites { // Configure the built-in test suite @@ -22,3 +33,25 @@ testing { } } } + +tasks { + task("generateCodecs", JavaExec::class) { + group = "sbe" + val codecsFile = "src/main/resources/messages.xml" + val sbeFile = "src/main/resources/sbe/sbe.xsd" + inputs.files(codecsFile, sbeFile) + outputs.dir(generatedDir) + classpath = codecGeneration + mainClass.set("uk.co.real_logic.sbe.SbeTool") + args = listOf(codecsFile) + systemProperties["sbe.output.dir"] = generatedDir + systemProperties["sbe.target.language"] = "Java" + systemProperties["sbe.validation.xsd"] = sbeFile + systemProperties["sbe.validation.stop.on.error"] = "true" + outputs.dir(generatedDir) + } + + compileJava { + dependsOn("generateCodecs") + } +} diff --git a/agrona/src/main/java/com/aeroncookbook/agrona/ringbuffer/ReceiveAgent.java b/agrona/src/main/java/com/aeroncookbook/agrona/ringbuffer/ReceiveAgent.java index bed28881..e2d11eff 100644 --- a/agrona/src/main/java/com/aeroncookbook/agrona/ringbuffer/ReceiveAgent.java +++ b/agrona/src/main/java/com/aeroncookbook/agrona/ringbuffer/ReceiveAgent.java @@ -16,6 +16,8 @@ package com.aeroncookbook.agrona.ringbuffer; +import com.aeroncookbook.sbe.MessageHeaderDecoder; +import com.aeroncookbook.sbe.SampleSimpleDecoder; import org.agrona.DirectBuffer; import org.agrona.concurrent.Agent; import org.agrona.concurrent.ShutdownSignalBarrier; @@ -29,6 +31,8 @@ public class ReceiveAgent implements Agent private final ManyToOneRingBuffer ringBuffer; private final int sendCount; private final Logger logger = LoggerFactory.getLogger(ReceiveAgent.class); + private final MessageHeaderDecoder headerDecoder = new MessageHeaderDecoder(); + private final SampleSimpleDecoder sampleSimpleDecoder = new SampleSimpleDecoder(); public ReceiveAgent(final ManyToOneRingBuffer ringBuffer, final ShutdownSignalBarrier barrier, final int sendCount) { @@ -46,11 +50,12 @@ public int doWork() throws Exception private void handler(final int messageType, final DirectBuffer buffer, final int offset, final int length) { - final int lastValue = buffer.getInt(offset); + sampleSimpleDecoder.wrapAndApplyHeader(buffer, offset, headerDecoder); + final long count = sampleSimpleDecoder.sequence(); - if (lastValue == sendCount) + if (count == sendCount) { - logger.info("received: {}", lastValue); + logger.info("received: {}", count); barrier.signal(); } } diff --git a/agrona/src/main/java/com/aeroncookbook/agrona/ringbuffer/SendAgent1.java b/agrona/src/main/java/com/aeroncookbook/agrona/ringbuffer/SendAgent1.java index 2d3e8d54..773e4a91 100644 --- a/agrona/src/main/java/com/aeroncookbook/agrona/ringbuffer/SendAgent1.java +++ b/agrona/src/main/java/com/aeroncookbook/agrona/ringbuffer/SendAgent1.java @@ -16,6 +16,9 @@ package com.aeroncookbook.agrona.ringbuffer; +import com.aeroncookbook.sbe.MessageHeaderEncoder; +import com.aeroncookbook.sbe.SampleEnum; +import com.aeroncookbook.sbe.SampleSimpleEncoder; import org.agrona.concurrent.Agent; import org.agrona.concurrent.AtomicBuffer; import org.agrona.concurrent.ringbuffer.ManyToOneRingBuffer; @@ -24,6 +27,8 @@ public class SendAgent1 implements Agent { private final int sendCount; private final ManyToOneRingBuffer ringBuffer; + private final MessageHeaderEncoder messageHeaderEncoder = new MessageHeaderEncoder(); + private final SampleSimpleEncoder sampleSimpleEncoder = new SampleSimpleEncoder(); private int currentCountItem = 1; public SendAgent1(final ManyToOneRingBuffer ringBuffer, final int sendCount) @@ -40,12 +45,15 @@ public int doWork() return 0; } - final int claimIndex = ringBuffer.tryClaim(1, Integer.BYTES); + final int claimIndex = ringBuffer.tryClaim(1, sampleSimpleEncoder.encodedLength() + + MessageHeaderEncoder.ENCODED_LENGTH); if (claimIndex > 0) { currentCountItem += 1; final AtomicBuffer buffer = ringBuffer.buffer(); - buffer.putInt(claimIndex, currentCountItem); + sampleSimpleEncoder.wrapAndApplyHeader(buffer, claimIndex, messageHeaderEncoder); + sampleSimpleEncoder.sequence(currentCountItem); + sampleSimpleEncoder.enumField(SampleEnum.VALUE_1); ringBuffer.commit(claimIndex); } return 0; diff --git a/agrona/src/main/java/com/aeroncookbook/agrona/ringbuffer/SendAgent2.java b/agrona/src/main/java/com/aeroncookbook/agrona/ringbuffer/SendAgent2.java index 1804f83f..d7b125c0 100644 --- a/agrona/src/main/java/com/aeroncookbook/agrona/ringbuffer/SendAgent2.java +++ b/agrona/src/main/java/com/aeroncookbook/agrona/ringbuffer/SendAgent2.java @@ -16,6 +16,9 @@ package com.aeroncookbook.agrona.ringbuffer; +import com.aeroncookbook.sbe.MessageHeaderEncoder; +import com.aeroncookbook.sbe.SampleEnum; +import com.aeroncookbook.sbe.SampleSimpleEncoder; import org.agrona.concurrent.Agent; import org.agrona.concurrent.AtomicBuffer; import org.agrona.concurrent.ringbuffer.ManyToOneRingBuffer; @@ -25,6 +28,8 @@ public class SendAgent2 implements Agent private final int sendCount; private final ManyToOneRingBuffer ringBuffer; private int currentCountItem; + private final MessageHeaderEncoder messageHeaderEncoder = new MessageHeaderEncoder(); + private final SampleSimpleEncoder sampleSimpleEncoder = new SampleSimpleEncoder(); public SendAgent2(final ManyToOneRingBuffer ringBuffer, final int sendCount) { @@ -46,7 +51,9 @@ public int doWork() { currentCountItem -= 1; final AtomicBuffer buffer = ringBuffer.buffer(); - buffer.putInt(claimIndex, currentCountItem); + sampleSimpleEncoder.wrapAndApplyHeader(buffer, claimIndex, messageHeaderEncoder); + sampleSimpleEncoder.sequence(currentCountItem); + sampleSimpleEncoder.enumField(SampleEnum.VALUE_1); ringBuffer.commit(claimIndex); } return 0; diff --git a/agrona/src/main/java/com/aeroncookbook/agrona/ringbuffer/StartHere.java b/agrona/src/main/java/com/aeroncookbook/agrona/ringbuffer/StartHere.java index f548d6ea..5cd7c003 100644 --- a/agrona/src/main/java/com/aeroncookbook/agrona/ringbuffer/StartHere.java +++ b/agrona/src/main/java/com/aeroncookbook/agrona/ringbuffer/StartHere.java @@ -34,7 +34,7 @@ public class StartHere public static void main(final String[] args) { - final int sendCount = 10_000_000; + final int sendCount = 20_000_000; final int bufferLength = 16384 + RingBufferDescriptor.TRAILER_LENGTH; final UnsafeBuffer unsafeBuffer = new UnsafeBuffer(ByteBuffer.allocateDirect(bufferLength)); final IdleStrategy idleStrategySend1 = new BusySpinIdleStrategy(); diff --git a/agrona/src/main/resources/messages.xml b/agrona/src/main/resources/messages.xml new file mode 100644 index 00000000..45215adf --- /dev/null +++ b/agrona/src/main/resources/messages.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + 1 + 2 + 3 + + + + + + + + + + + + + diff --git a/agrona/src/main/resources/sbe/sbe.xsd b/agrona/src/main/resources/sbe/sbe.xsd new file mode 100644 index 00000000..f0f05033 --- /dev/null +++ b/agrona/src/main/resources/sbe/sbe.xsd @@ -0,0 +1,404 @@ + + + + + + + Message schema for FIX Simple Binary Encoding + Version: 1.0 Draft Standard + © Copyright 2014-2016 FIX Protocol Limited + License: Creative Commons Attribution-NoDerivatives 4.0 International Public License + + + + + + Root of XML document, holds all message templates + and their elements + + + + + + + + More than one set of types may be provided. + Names must be unique across all encoding + types. + Encoding types may appear in any order. + + + + + + + + + + + + + + + + + Unique ID of a message schema + + + + + + The version of a message schema. Initial version + is 0. + + + + + + Application layer specification version, such as + FIX version 'FIX.5.0SP2' + + + + + + + + + + + + + + + + Name of the encoding type of the message header, + which is the same for all messages in a schema. The name has a + default, but an encoding of that name must be present under a + 'types' element. + + + + + + + + + A message type, also known as a message template + + + + + + Base type of message and repeating group entry + + + + + + Fixed-length fields + + + + + + Variable-length fields + + + + + + + Unique ID of a message template + + + + + + Space reserved for root level of message, not + include groups or variable-length + data elements. + + + + + + + + + + A repeating group contains an array of entries + + + + + + + + + + + + Simple wire encoding consisting of a primitive type + or array of primitives + + + + + + + + Override of default null indicator for the data + type in SBE specification, + as a string. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A wire encoding composed of multiple parts + + + + + + + + + + + + + + + + + + An enumeration of valid values + + + + + + + + + + + + + + + Valid value as a string + + + + + + + + + + + + + + A reference to any existing encoding type (simple type, enum or set) + to reuse as a member of a composite type + + + + + + + + + + + A multi value choice (encoded as a bitset) + + + + + + + + + + + + + + + A choice within a multi value set. Value is the + position within a bitset (zero-based index). + + + + + + + + + + + + + + A field of a message of a specified dataType + + + + + + + Must match the name of an encoding contained by + 'types' element + + + + + + + Deprecated - only for back compatibility with RC2 + + + + + + + + + + + + + Application layer class. Maps a field or encoding + to a FIX data type. + + + + + + + + + Schema versioning supports message extension + + + + + + The schema version in which an element was added + + + + + + + The version of the schema in which an element was + deprecated. It is retained for back compatibility but should no + longer be used by updated applications. + + + + + + + + Offset from start of a composite type or block + as a zero-based index. + + + + + + + + + + + The value must always be populated + + + + + + Value may be set to nullValue for its data type + + + + + + Value does not vary so it need not be + serialized on the wire + + + + + + + + + A constant value as valid value of an enum + in the form enum-name.valid-value-name + + + + + + + + + + + + + + + + +