Skip to content

Commit

Permalink
Qute: optimize iteration metadata access in loops
Browse files Browse the repository at this point in the history
Co-authored-by: Francesco Nigro <nigro.fra@gmail.com>
  • Loading branch information
mkouba and franz1981 committed Sep 4, 2024
1 parent c4c9c1a commit a86499c
Showing 1 changed file with 54 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ public class LoopSectionHelper implements SectionHelper {
private static final String ITERABLE = "iterable";

private final String alias;
private final String metadataPrefix;
private final Expression iterable;
private final SectionBlock elseBlock;
private final Engine engine;

private final String metadataPrefix;

LoopSectionHelper(SectionInitContext context, String metadataPrefix) {
this.alias = context.getParameterOrDefault(ALIAS, DEFAULT_ALIAS);
this.metadataPrefix = LoopSectionHelper.Factory.prefixValue(alias, metadataPrefix);
Expand Down Expand Up @@ -142,7 +143,7 @@ private Iterator<?> extractIterator(Object it) {

CompletionStage<ResultNode> nextElement(Object element, int index, boolean hasNext, SectionResolutionContext context) {
ResolutionContext child = context.resolutionContext().createChild(
new IterationElement(alias, metadataPrefix, element, index, hasNext),
new IterationElement(element, index, hasNext),
null);
return context.execute(child);
}
Expand Down Expand Up @@ -266,20 +267,16 @@ static String prefixValue(String alias, String metadataPrefix) {
}
}

static class IterationElement implements Mapper {
class IterationElement implements Mapper {

static final CompletedStage<Object> EVEN = CompletedStage.of("even");
static final CompletedStage<Object> ODD = CompletedStage.of("odd");

final String alias;
final String metadataPrefix;
final CompletedStage<Object> element;
final int index;
final boolean hasNext;

public IterationElement(String alias, String metadataPrefix, Object element, int index, boolean hasNext) {
this.alias = alias;
this.metadataPrefix = metadataPrefix;
public IterationElement(Object element, int index, boolean hasNext) {
this.element = CompletedStage.of(element);
this.index = index;
this.hasNext = hasNext;
Expand All @@ -290,26 +287,57 @@ public CompletionStage<Object> getAsync(String key) {
if (alias.equals(key)) {
return element;
}
if (metadataPrefix != null) {
if (key.startsWith(metadataPrefix)) {
key = key.substring(metadataPrefix.length(), key.length());
} else {
return Results.notFound(key);
}
if (metadataPrefix != null && !key.startsWith(metadataPrefix)) {
return Results.notFound(key);
}
int keyStartIndex = metadataPrefix == null ? 0 : metadataPrefix.length();
// Iteration metadata
final int count = index + 1;
return switch (key) {
case "count" -> CompletedStage.of(count);
case "index" -> CompletedStage.of(index);
case "indexParity" -> count % 2 == 0 ? EVEN : ODD;
case "hasNext" -> hasNext ? Results.TRUE : Results.FALSE;
case "isLast" -> hasNext ? Results.FALSE : Results.TRUE;
case "isFirst" -> index == 0 ? Results.TRUE : Results.FALSE;
case "isOdd", "odd" -> count % 2 != 0 ? Results.TRUE : Results.FALSE;
case "isEven", "even" -> count % 2 == 0 ? Results.TRUE : Results.FALSE;
default -> Results.notFound(key);
};
switch (key.length() - keyStartIndex) {
case 3:
if (key.indexOf("odd", keyStartIndex) == keyStartIndex) {
return (index + 1) % 2 != 0 ? Results.TRUE : Results.FALSE;
}
return Results.notFound(key);
case 4:
if (key.indexOf("even", keyStartIndex) == keyStartIndex) {
return (index + 1) % 2 == 0 ? Results.TRUE : Results.FALSE;
}
return Results.notFound(key);
case 5:
if (key.indexOf("count", keyStartIndex) == keyStartIndex) {
return CompletedStage.of(index + 1);
}
if (key.indexOf("index", keyStartIndex) == keyStartIndex) {
return CompletedStage.of(index);
}
if (key.indexOf("isOdd", keyStartIndex) == keyStartIndex) {
return (index + 1) % 2 != 0 ? Results.TRUE : Results.FALSE;
}
return Results.notFound(key);
case 6:
if (key.indexOf("isEven", keyStartIndex) == keyStartIndex) {
return (index + 1) % 2 == 0 ? Results.TRUE : Results.FALSE;
}
if (key.indexOf("isLast", keyStartIndex) == keyStartIndex) {
return hasNext ? Results.FALSE : Results.TRUE;
}
return Results.notFound(key);
case 7:
if (key.indexOf("hasNext", keyStartIndex) == keyStartIndex) {
return hasNext ? Results.TRUE : Results.FALSE;
}
if (key.indexOf("isFirst", keyStartIndex) == keyStartIndex) {
return index == 0 ? Results.TRUE : Results.FALSE;
}
return Results.notFound(key);
case 11:
if (key.indexOf("indexParity", keyStartIndex) == keyStartIndex) {
return (index + 1) % 2 == 0 ? EVEN : ODD;
}
return Results.notFound(key);
default:
return Results.notFound(key);
}
}

@Override
Expand Down

0 comments on commit a86499c

Please sign in to comment.