Skip to content

Commit

Permalink
Various simple optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
safris committed Nov 27, 2023
1 parent 2705810 commit 6b11225
Show file tree
Hide file tree
Showing 24 changed files with 201 additions and 200 deletions.
54 changes: 26 additions & 28 deletions generator/src/main/java/org/jsonx/AnyModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.RandomAccess;

Expand Down Expand Up @@ -159,7 +158,7 @@ static AnyModel reference(final Registry registry, final Referrer<?> referrer, f
};
}

private final ArrayList<Member> types;
private final Member[] types;

private AnyModel(final Registry registry, final Declarer declarer, final $Any xsb, final $FieldBinding binding) {
super(registry, declarer, xsb.getDoc$(), xsb.getNames$(), xsb.getNullable$(), xsb.getUse$(), null, binding == null ? null : binding.getField$(), null);
Expand Down Expand Up @@ -194,39 +193,38 @@ private AnyModel(final Registry registry, final Declarer declarer, final AnyElem
validateTypeBinding();
}

// FIXME: This can be converted to recursive algo
private ArrayList<Member> getTypes(final Boolean nullable, final Use use, final $AnyMember.Types$ refs, final $FieldBinding binding) {
private Member[] getTypes(final Boolean nullable, final Use use, final $AnyMember.Types$ refs, final $FieldBinding binding) {
final List<String> idrefs;
final int i$;
if (refs == null || (i$ = (idrefs = refs.text()).size()) == 0)
final int size;
if (refs == null || (size = (idrefs = refs.text()).size()) == 0)
return null;

final ArrayList<Member> types = new ArrayList<>(i$);
final Member[] types = new Member[size];
int i = 0;
if (idrefs instanceof RandomAccess) {
int i = 0;
do // [RA]
addReference(types, idrefs.get(i), nullable, use, binding);
while (++i < i$);
types[i] = addReference(idrefs.get(i), nullable, use, binding);
while (++i < size);
}
else {
final Iterator<String> i = idrefs.iterator();
final Iterator<String> it = idrefs.iterator();
do // [I]
addReference(types, i.next(), nullable, use, binding);
while (i.hasNext());
types[i] = addReference(it.next(), nullable, use, binding);
while (++i < size);
}

return types;
}

private void addReference(final ArrayList<Member> types, final String idref, final Boolean nullable, final Use use, final $FieldBinding binding) {
private Member addReference(final String idref, final Boolean nullable, final Use use, final $FieldBinding binding) {
final Id id = Id.hashed(idref);
types.add(Reference.defer(registry, this, newRnonymousReference(nullable, use), binding, () -> {
return Reference.defer(registry, this, newRnonymousReference(nullable, use), binding, () -> {
final Member model = registry.getModel(id);
if (model == null)
throw new IllegalStateException("Type id=\"" + id + "\" in <any> not found");

return (Model)registry.reference(model, this);
}));
});
}

private static Class<?> getFieldType(final t[] types) {
Expand Down Expand Up @@ -263,13 +261,14 @@ else if (AnyType.isEnabled(type.strings())) {
return gcc != Object.class ? gcc : isObjectModel ? JxObject.class : Object.class;
}

private ArrayList<Member> getMemberTypes(final t[] types) {
private Member[] getMemberTypes(final t[] types) {
final int len = types.length;
if (len == 0)
return null;

final ArrayList<Member> members = new ArrayList<>(len);
for (final t type : types) { // [A]
final Member[] members = new Member[len];
for (int i = 0; i < len; ++i) { // [A]
final t type = types[i];
Member member = null;
if (AnyType.isEnabled(type.arrays()))
member = ArrayModel.referenceOrDeclare(registry, this, type.arrays());
Expand Down Expand Up @@ -380,7 +379,7 @@ public String encode() {
if (member == null)
throw new ValidationException("@" + t.class.getName() + " does not specify a type");

members.add(member);
members[i] = member;
}

return members;
Expand Down Expand Up @@ -446,11 +445,11 @@ AttributeMap toSchemaAttributes(final Element owner, final String packageName, f
final AttributeMap attributes = super.toSchemaAttributes(owner, packageName, jsd);
if (types != null) {
final StringBuilder b = new StringBuilder();
for (int i = 0, i$ = types.size(); i < i$; ++i) { // [RA]
for (int i = 0, i$ = types.length; i < i$; ++i) { // [A]
if (i > 0)
b.append(' ');

b.append(Registry.getSubName(types.get(i).id().toString(), packageName));
b.append(Registry.getSubName(types[i].id().toString(), packageName));
}

attributes.put(jsd(jsd, "types"), b.toString());
Expand All @@ -469,8 +468,8 @@ void toAnnotationAttributes(final AttributeMap attributes, final Member owner) {
attributes.put("types", values);

StringBuilder b = null;
for (int i = 0, i$ = types.size(); i < i$; ++i) { // [RA]
final Member type = types.get(i);
for (int i = 0, i$ = types.length; i < i$; ++i) { // [A]
final Member type = types[i];
if (type instanceof ArrayModel) {
values.add("@" + t.class.getName() + "(arrays = " + ((ArrayModel)type).classType().canonicalName + ".class)");
}
Expand Down Expand Up @@ -530,16 +529,15 @@ void resolveReferences() {
if (types == null)
return;

final ListIterator<Member> iterator = types.listIterator();
while (iterator.hasNext()) {
Member member = iterator.next();
for (int i = 0, i$ = types.length; i < i$; ++i) { // [A]
Member member = types[i];
if (member instanceof Deferred)
member = ((Deferred<?>)member).resolve();

if (member instanceof Reference)
member = ((Reference)member).model;

iterator.set(member);
types[i] = member;
}
}
}
144 changes: 76 additions & 68 deletions generator/src/main/java/org/jsonx/ArrayModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.RandomAccess;
import java.util.Set;
Expand Down Expand Up @@ -243,71 +242,79 @@ private void writeElementIdsClause(final AttributeMap attributes, final int[] in
attributes.put("elementIds", indices.length == 0 ? "{}" : "{" + ArrayUtil.toString(indices, ", ") + "}");
}

private static ArrayList<Member> parseMembers(final Registry registry, final ArrayModel referrer, final $ArrayMember xsb, final IdentityHashMap<$AnyType<?>,$FieldBinding> xsbToBinding) {
final ArrayList<Member> members = new ArrayList<>();
final Iterator<? super $Member> iterator = Iterators.filter(xsb.elementIterator(), m -> m instanceof $Member);
while (iterator.hasNext()) {
final $Member member = ($Member)iterator.next();
if (member instanceof $Array.Any) {
members.add(AnyModel.reference(registry, referrer, ($Array.Any)member, xsbToBinding));
}
else if (member instanceof $Array.Array) {
members.add(ArrayModel.reference(registry, referrer, ($Array.Array)member, xsbToBinding));
}
else if (member instanceof $Array.Boolean) {
members.add(BooleanModel.reference(registry, referrer, ($Array.Boolean)member, xsbToBinding));
}
else if (member instanceof $Array.Number) {
members.add(NumberModel.reference(registry, referrer, ($Array.Number)member, xsbToBinding));
}
else if (member instanceof $Array.String) {
members.add(StringModel.reference(registry, referrer, ($Array.String)member, xsbToBinding));
}
else if (member instanceof $Array.Reference) {
final $Array.Reference reference = ($Array.Reference)member;
members.add(Reference.defer(registry, referrer, reference, () -> {
final Model model = registry.getModel(Id.named(reference.getType$()));
if (model == null)
throw new IllegalStateException("Template type=\"" + reference.getType$().text() + "\" in array not found");

return registry.reference(model, referrer);
}));
}
else {
throw new UnsupportedOperationException("Unsupported " + member.getClass().getSimpleName() + " member type: " + member.getClass().getName());
}
private static Member[] parseMembers(final Registry registry, final ArrayModel referrer, final $ArrayMember xsb, final IdentityHashMap<$AnyType<?>,$FieldBinding> xsbToBinding) {
return parseMembers(registry, referrer, xsb, xsbToBinding, Iterators.filter(xsb.elementIterator(), m -> m instanceof $Member), 0);
}

private static Member[] parseMembers(final Registry registry, final ArrayModel referrer, final $ArrayMember xsb, final IdentityHashMap<$AnyType<?>,$FieldBinding> xsbToBinding, final Iterator<? super $Member> iterator, final int depth) {
if (!iterator.hasNext())
return new Member[depth];

final $Member member$ = ($Member)iterator.next();
final Member member;
if (member$ instanceof $Array.Any) {
member = AnyModel.reference(registry, referrer, ($Array.Any)member$, xsbToBinding);
}
else if (member$ instanceof $Array.Array) {
member = ArrayModel.reference(registry, referrer, ($Array.Array)member$, xsbToBinding);
}
else if (member$ instanceof $Array.Boolean) {
member = BooleanModel.reference(registry, referrer, ($Array.Boolean)member$, xsbToBinding);
}
else if (member$ instanceof $Array.Number) {
member = NumberModel.reference(registry, referrer, ($Array.Number)member$, xsbToBinding);
}
else if (member$ instanceof $Array.String) {
member = StringModel.reference(registry, referrer, ($Array.String)member$, xsbToBinding);
}
else if (member$ instanceof $Array.Reference) {
final $Array.Reference reference = ($Array.Reference)member$;
member = Reference.defer(registry, referrer, reference, () -> {
final Model model = registry.getModel(Id.named(reference.getType$()));
if (model == null)
throw new IllegalStateException("Template type=\"" + reference.getType$().text() + "\" in array not found");

return registry.reference(model, referrer);
});
}
else {
throw new UnsupportedOperationException("Unsupported " + member$.getClass().getSimpleName() + " member type: " + member$.getClass().getName());
}

final Member[] members = parseMembers(registry, referrer, xsb, xsbToBinding, iterator, depth + 1);
members[depth] = member;
return members;
}

private static ArrayList<Member> parseMembers(final Registry registry, final ArrayModel referrer, final Annotation annotation, final int[] elementIds, final Map<Integer,Annotation> idToElement, final String declaringTypeName) {
final ArrayList<Member> members = new ArrayList<>();
for (final int elementId : elementIds) { // [A]
private static Member[] parseMembers(final Registry registry, final ArrayModel referrer, final Annotation annotation, final int[] elementIds, final Map<Integer,Annotation> idToElement, final String declaringTypeName) {
final int len = elementIds.length;
final Member[] members = new Member[len];
for (int i = 0; i < len; ++i) { // [A]
final int elementId = elementIds[i];
final Annotation element = idToElement.get(elementId);
if (element == null)
throw new AnnotationParameterException(annotation, declaringTypeName + ": @" + annotation.annotationType().getName() + " specifies non-existent element with id=" + elementId);

if (element instanceof StringElement)
members.add(StringModel.referenceOrDeclare(registry, referrer, (StringElement)element));
members[i] = StringModel.referenceOrDeclare(registry, referrer, (StringElement)element);
else if (element instanceof NumberElement)
members.add(NumberModel.referenceOrDeclare(registry, referrer, (NumberElement)element));
members[i] = NumberModel.referenceOrDeclare(registry, referrer, (NumberElement)element);
else if (element instanceof ObjectElement)
members.add(ObjectModel.referenceOrDeclare(registry, referrer, (ObjectElement)element));
members[i] = ObjectModel.referenceOrDeclare(registry, referrer, (ObjectElement)element);
else if (element instanceof BooleanElement)
members.add(BooleanModel.referenceOrDeclare(registry, referrer, (BooleanElement)element));
members[i] = BooleanModel.referenceOrDeclare(registry, referrer, (BooleanElement)element);
else if (element instanceof ArrayElement)
members.add(ArrayModel.referenceOrDeclare(registry, referrer, (ArrayElement)element, idToElement, declaringTypeName));
members[i] = ArrayModel.referenceOrDeclare(registry, referrer, (ArrayElement)element, idToElement, declaringTypeName);
else if (element instanceof AnyElement)
members.add(AnyModel.referenceOrDeclare(registry, referrer, (AnyElement)element));
members[i] = AnyModel.referenceOrDeclare(registry, referrer, (AnyElement)element);
else
throw new UnsupportedOperationException("Unsupported annotation type: " + element.annotationType().getName());
}

return members;
}

final ArrayList<Member> members;
final Member[] members;
final Integer minIterate;
final Integer maxIterate;

Expand All @@ -332,9 +339,9 @@ private ArrayModel(final Registry registry, final Declarer declarer, final Schem
private ArrayModel(final Registry registry, final Declarer declarer, final $Array xsb, final IdentityHashMap<$AnyType<?>,$FieldBinding> xsbToBinding) {
super(registry, declarer, xsb.getDoc$(), xsb.getName$(), xsb.getNullable$(), xsb.getUse$(), null, getField(xsbToBinding, xsb), null);
this.members = parseMembers(registry, this, xsb, xsbToBinding);
final MinIterate$ minIterate$ = xsb.getMinIterate$();
this.minIterate = parseIterate(minIterate$.text());
this.maxIterate = parseIterate(parseMaxCardinality(minIterate$.text(), xsb.getMaxIterate$(), "Iterate", 1));
final BigInteger minIterate = xsb.getMinIterate$().text();
this.minIterate = parseIterate(minIterate);
this.maxIterate = parseIterate(parseMaxCardinality(minIterate, xsb.getMaxIterate$(), "Iterate", 1));

validateTypeBinding();
}
Expand All @@ -345,8 +352,9 @@ private ArrayModel(final Registry registry, final Declarer declarer, final $Arra
throw new ValidationException(Bindings.getXPath(xsb, elementXPath) + ": minOccurs=\"" + this.minOccurs.get + "\" > maxOccurs=\"" + this.maxOccurs.get + "\"");

this.members = parseMembers(registry, this, xsb, xsbToBinding);
this.minIterate = parseIterate(xsb.getMinIterate$().text());
this.maxIterate = parseIterate(parseMaxCardinality(xsb.getMinIterate$().text(), xsb.getMaxIterate$(), "Iterate", 1));
final BigInteger minIterate = xsb.getMinIterate$().text();
this.minIterate = parseIterate(minIterate);
this.maxIterate = parseIterate(parseMaxCardinality(minIterate, xsb.getMaxIterate$(), "Iterate", 1));

validateTypeBinding();
}
Expand Down Expand Up @@ -477,11 +485,10 @@ void resolveReferences() {
if (referencesResolved)
return;

final ListIterator<Member> iterator = members.listIterator();
while (iterator.hasNext()) {
final Member member = iterator.next();
for (int i = 0, i$ = members.length; i < i$; ++i) { // [A]
final Member member = members[i];
if (member instanceof Deferred)
iterator.set(((Deferred<?>)member).resolve());
members[i] = ((Deferred<?>)member).resolve();
}

referencesResolved = true;
Expand All @@ -493,21 +500,21 @@ void getDeclaredTypes(final Set<? super Registry.Type> types) {
types.add(classType());

if (members != null)
for (int i = 0, i$ = members.size(); i < i$; ++i) // [RA]
members.get(i).getDeclaredTypes(types);
for (int i = 0, i$ = members.length; i < i$; ++i) // [A]
members[i].getDeclaredTypes(types);
}

@Override
@SuppressWarnings({"rawtypes", "unchecked"})
XmlElement toXml(final Element owner, final String packageName, final JsonPath.Cursor cursor, final PropertyMap<AttributeMap> pathToBinding) {
final XmlElement element = super.toXml(owner, packageName, cursor, pathToBinding);
final int size = members.size();
final int size = members.length;
if (size > 0) {
final Collection superElements = element.getElements();
final ArrayList<XmlElement> elements = new ArrayList<>(size + (superElements != null ? superElements.size() : 0));
cursor.inArray();
for (int i = 0; i < size; ++i) // [RA]
elements.add(members.get(i).toXml(this, packageName, cursor, pathToBinding));
for (int i = 0; i < size; ++i) // [A]
elements.add(members[i].toXml(this, packageName, cursor, pathToBinding));

if (superElements != null)
elements.addAll(superElements);
Expand All @@ -522,11 +529,12 @@ XmlElement toXml(final Element owner, final String packageName, final JsonPath.C
@Override
PropertyMap<Object> toJson(final Element owner, final String packageName, final JsonPath.Cursor cursor, final PropertyMap<AttributeMap> pathToBinding) {
final PropertyMap<Object> element = super.toJson(owner, packageName, cursor, pathToBinding);
if (members.size() > 0) {
final int len = members.length;
if (len > 0) {
final ArrayList<Object> elements = new ArrayList<>();
cursor.inArray();
for (int i = 0, i$ = members.size(); i < i$; ++i) // [RA]
elements.add(members.get(i).toJson(this, packageName, cursor, pathToBinding));
for (int i = 0; i < len; ++i) // [A]
elements.add(members[i].toJson(this, packageName, cursor, pathToBinding));

element.put("@elements", elements);
}
Expand All @@ -551,10 +559,10 @@ AttributeMap toSchemaAttributes(final Element owner, final String packageName, f
}

private void renderAnnotations(final AttributeMap attributes, final List<? super AnnotationType> annotations) {
final int len = members.size();
final int len = members.length;
final int[] indices = new int[len];
for (int i = 0, index = 0; i < len; ++i) // [RA]
index += writeElementAnnotations(annotations, members.get(i), indices[i] = index, this);
index += writeElementAnnotations(annotations, members[i], indices[i] = index, this);

writeElementIdsClause(attributes, indices);
}
Expand Down Expand Up @@ -595,12 +603,12 @@ private static int writeElementAnnotations(final List<? super AnnotationType> an
int offset = 1;
final ArrayList<AnnotationType> inner = new ArrayList<>();
if (arrayModel.classType() == null) {
final ArrayList<Member> members = arrayModel.members;
final int size = members.size();
final Member[] members = arrayModel.members;
final int size = members.length;
final int[] indices = new int[size];
for (int i = 0; i < size; ++i) { // [RA]
indices[i] = index + offset;
offset += writeElementAnnotations(inner, members.get(i), index + offset, owner);
offset += writeElementAnnotations(inner, members[i], index + offset, owner);
}

// FIXME: Can this be abstracted better? minOccurs, maxOccurs and nullable are rendered here and in Member#toAnnotationAttributes()
Expand Down Expand Up @@ -635,8 +643,8 @@ List<AnnotationType> toElementAnnotations() {
return null;

final ArrayList<AnnotationType> annotations = new ArrayList<>();
for (int i = 0, i$ = members.size(), index = 0; i < i$; ++i) // [RA]
index += writeElementAnnotations(annotations, members.get(i), index, this);
for (int i = 0, i$ = members.length, index = 0; i < i$; ++i) // [RA]
index += writeElementAnnotations(annotations, members[i], index, this);

return annotations;
}
Expand Down
Loading

0 comments on commit 6b11225

Please sign in to comment.