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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+