Skip to content

Commit

Permalink
[Java] Extend arbitrary varData encodings.
Browse files Browse the repository at this point in the history
We now explore more of the "schema space", as we generate lengths of
different encodings.

It surfaces an issue, reported in real-logic#955, which was fixed in another
outstanding PR's commit: 3885a63.
  • Loading branch information
ZachBray committed May 15, 2024
1 parent ead428c commit a207daf
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,18 @@ private static Arbitrary<EnumTypeSchema> enumTypeSchema()
private static Arbitrary<SetSchema> setTypeSchema()
{
return Arbitraries.oneOf(
Arbitraries.integers().between(0, 7).set().map(choices -> new SetSchema("uint8", choices)),
Arbitraries.integers().between(0, 15).set().map(choices -> new SetSchema("uint16", choices)),
Arbitraries.integers().between(0, 31).set().map(choices -> new SetSchema("uint32", choices)),
Arbitraries.integers().between(0, 63).set().map(choices -> new SetSchema("uint64", choices))
Arbitraries.integers().between(0, 7).set()
.ofMaxSize(8)
.map(choices -> new SetSchema("uint8", choices)),
Arbitraries.integers().between(0, 15).set()
.ofMaxSize(16)
.map(choices -> new SetSchema("uint16", choices)),
Arbitraries.integers().between(0, 31).set()
.ofMaxSize(32)
.map(choices -> new SetSchema("uint32", choices)),
Arbitraries.integers().between(0, 63).set()
.ofMaxSize(64)
.map(choices -> new SetSchema("uint64", choices))
);
}

Expand Down Expand Up @@ -213,14 +221,19 @@ private static Arbitrary<Encoding.Presence> presence()

private static Arbitrary<VarDataSchema> varDataSchema()
{
return Arbitraries.of(VarDataSchema.Encoding.values())
.map(VarDataSchema::new);
return Combinators.combine(
Arbitraries.of(VarDataSchema.Encoding.values()),
Arbitraries.of(
PrimitiveType.UINT8,
PrimitiveType.UINT16,
PrimitiveType.UINT32
)
).as(VarDataSchema::new);
}

public static Arbitrary<MessageSchema> messageSchema()
{
return Combinators.combine(

withDuplicates(
3,
Combinators.combine(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.agrona.collections.MutableInteger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import java.io.File;
import java.io.StringWriter;
Expand Down Expand Up @@ -74,7 +75,7 @@ private static void writeTo(
final Element topLevelTypes = createTypesElement(document);
root.appendChild(topLevelTypes);

final HashMap<TypeSchema, String> typeToName = new HashMap<>();
final HashMap<Object, String> typeToName = new HashMap<>();

final TypeSchemaConverter typeSchemaConverter = new TypeSchemaConverter(
document,
Expand All @@ -88,7 +89,8 @@ private static void writeTo(
topLevelTypes,
typeSchemaConverter,
schema.blockFields().stream().map(FieldSchema::type).collect(Collectors.toList()),
schema.groups());
schema.groups(),
schema.varData());

final Element message = document.createElement("sbe:message");
message.setAttribute("name", "TestMessage");
Expand Down Expand Up @@ -129,7 +131,7 @@ private static void writeTo(

private static void appendMembers(
final Document document,
final HashMap<TypeSchema, String> typeToName,
final HashMap<Object, String> typeToName,
final List<FieldSchema> blockFields,
final List<GroupSchema> groups,
final List<VarDataSchema> varData,
Expand Down Expand Up @@ -174,21 +176,10 @@ private static void appendMembers(
for (final VarDataSchema data : varData)
{
final int id = nextMemberId.getAndIncrement();

final Element element = document.createElement("data");
element.setAttribute("id", Integer.toString(id));
element.setAttribute("name", "member" + id);
switch (data.encoding())
{
case ASCII:
element.setAttribute("type", "varStringEncoding");
break;
case BYTES:
element.setAttribute("type", "varDataEncoding");
break;
default:
throw new IllegalStateException("Unknown encoding: " + data.encoding());
}
element.setAttribute("type", requireNonNull(typeToName.get(data)));
parent.appendChild(element);
}
}
Expand All @@ -213,27 +204,6 @@ private static Element createTypesElement(final Document document)
createTypeElement(document, "numInGroup", "uint16")
));

final Element varString = createTypeElement(document, "varData", "uint8");
varString.setAttribute("length", "0");
varString.setAttribute("characterEncoding", "US-ASCII");
types.appendChild(createCompositeElement(
document,
"varStringEncoding",
createTypeElement(document, "length", "uint16"),
varString
));

final Element varData = createTypeElement(document, "varData", "uint8");
final Element varDataLength = createTypeElement(document, "length", "uint32");
varDataLength.setAttribute("maxValue", "1000000");
varData.setAttribute("length", "0");
types.appendChild(createCompositeElement(
document,
"varDataEncoding",
varDataLength,
varData
));

return types;
}

Expand Down Expand Up @@ -359,7 +329,8 @@ private static void appendTypes(
final Element topLevelTypes,
final TypeSchemaConverter typeSchemaConverter,
final List<TypeSchema> blockFields,
final List<GroupSchema> groups)
final List<GroupSchema> groups,
final List<VarDataSchema> varDataFields)
{
for (final TypeSchema field : blockFields)
{
Expand All @@ -376,23 +347,29 @@ private static void appendTypes(
topLevelTypes,
typeSchemaConverter,
group.blockFields().stream().map(FieldSchema::type).collect(Collectors.toList()),
group.groups()
);
group.groups(),
group.varData());
}

for (final VarDataSchema varData : varDataFields)
{
topLevelTypes.appendChild(typeSchemaConverter.convert(varData));
}
}

@SuppressWarnings("EnhancedSwitchMigration")
private static final class TypeSchemaConverter implements TypeSchemaVisitor
{
private final Document document;
private final Element topLevelTypes;
private final Map<TypeSchema, String> typeToName;
private final Function<TypeSchema, String> nextName;
private final Map<Object, String> typeToName;
private final Function<Object, String> nextName;
private Element result;

private TypeSchemaConverter(
final Document document,
final Element topLevelTypes,
final Map<TypeSchema, String> typeToName)
final Map<Object, String> typeToName)
{
this.document = document;
this.topLevelTypes = topLevelTypes;
Expand Down Expand Up @@ -481,5 +458,31 @@ public Element convert(final TypeSchema type)
type.accept(this);
return requireNonNull(result);
}

public Node convert(final VarDataSchema varData)
{
final Element lengthElement = createTypeElement(document, "length",
varData.lengthEncoding().primitiveName());

if (varData.lengthEncoding().size() >= 4)
{
lengthElement.setAttribute("maxValue", Integer.toString(1_000_000));
}

final Element varDataElement = createTypeElement(document, "varData", "uint8");
varDataElement.setAttribute("length", "0");

if (varData.dataEncoding().equals(VarDataSchema.Encoding.ASCII))
{
varDataElement.setAttribute("characterEncoding", "US-ASCII");
}

return createCompositeElement(
document,
typeToName.computeIfAbsent(varData, nextName),
lengthElement,
varDataElement
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,29 @@

package uk.co.real_logic.sbe.properties.schema;

import uk.co.real_logic.sbe.PrimitiveType;

public final class VarDataSchema
{
private final Encoding encoding;
private final Encoding dataEncoding;
private final PrimitiveType lengthEncoding;

public VarDataSchema(
final Encoding dataEncoding,
final PrimitiveType lengthEncoding)
{
this.dataEncoding = dataEncoding;
this.lengthEncoding = lengthEncoding;
}

public VarDataSchema(final Encoding encoding)
public Encoding dataEncoding()
{
this.encoding = encoding;
return dataEncoding;
}

public Encoding encoding()
public PrimitiveType lengthEncoding()
{
return encoding;
return lengthEncoding;
}

public enum Encoding
Expand Down

0 comments on commit a207daf

Please sign in to comment.