-
Notifications
You must be signed in to change notification settings - Fork 20
Specialize macro list folds #929
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,15 +28,18 @@ | |
| import static org.projectnessie.cel.interpreter.Coster.Cost.estimateCost; | ||
| import static org.projectnessie.cel.interpreter.Coster.costOf; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.Arrays; | ||
| import java.util.HashMap; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.Objects; | ||
| import java.util.Set; | ||
| import org.projectnessie.cel.common.operators.Operator; | ||
| import org.projectnessie.cel.common.types.Err; | ||
| import org.projectnessie.cel.common.types.IterableT; | ||
| import org.projectnessie.cel.common.types.IteratorT; | ||
| import org.projectnessie.cel.common.types.ListT; | ||
| import org.projectnessie.cel.common.types.MapT; | ||
| import org.projectnessie.cel.common.types.Overloads; | ||
| import org.projectnessie.cel.common.types.StringT; | ||
|
|
@@ -49,6 +52,7 @@ | |
| import org.projectnessie.cel.common.types.traits.FieldTester; | ||
| import org.projectnessie.cel.common.types.traits.Negater; | ||
| import org.projectnessie.cel.common.types.traits.Receiver; | ||
| import org.projectnessie.cel.common.types.traits.Sizer; | ||
| import org.projectnessie.cel.common.types.traits.Trait; | ||
| import org.projectnessie.cel.interpreter.Activation.VarActivation; | ||
| import org.projectnessie.cel.interpreter.AttributeFactory.Attribute; | ||
|
|
@@ -1108,6 +1112,111 @@ public String toString() { | |
| } | ||
| } | ||
|
|
||
| final class EvalListFold extends AbstractEval implements Coster { | ||
| final String iterVar; | ||
| final Interpretable iterRange; | ||
| final Interpretable filter; | ||
| final Interpretable transform; | ||
| private final TypeAdapter adapter; | ||
|
|
||
| EvalListFold( | ||
| long id, | ||
| String iterVar, | ||
| Interpretable iterRange, | ||
| Interpretable filter, | ||
| Interpretable transform, | ||
| TypeAdapter adapter) { | ||
| super(id); | ||
| this.iterVar = iterVar; | ||
| this.iterRange = iterRange; | ||
| this.filter = filter; | ||
| this.transform = transform; | ||
| this.adapter = adapter; | ||
| } | ||
|
|
||
| @Override | ||
| public Val eval(org.projectnessie.cel.interpreter.Activation ctx) { | ||
| Val foldRange = iterRange.eval(ctx); | ||
| if (!foldRange.type().hasTrait(Trait.IterableType)) { | ||
| return valOrErr( | ||
| foldRange, "got '%s', expected iterable type", foldRange.getClass().getName()); | ||
| } | ||
|
|
||
| VarActivation iterCtx = new VarActivation(); | ||
| iterCtx.parent = ctx; | ||
| iterCtx.name = iterVar; | ||
| List<Val> values = new ArrayList<>(listCapacity(foldRange)); | ||
| IteratorT it = ((IterableT) foldRange).iterator(); | ||
| while (it.hasNext() == True) { | ||
| iterCtx.val = it.next(); | ||
|
|
||
| if (filter != null) { | ||
| Val include = filter.eval(iterCtx); | ||
| if (include == False) { | ||
| continue; | ||
| } | ||
| if (include != True) { | ||
| return noSuchOverload(null, Operator.Conditional.id, include); | ||
| } | ||
| } | ||
|
|
||
| Val value = transform.eval(iterCtx); | ||
| if (isUnknownOrError(value)) { | ||
| return value; | ||
| } | ||
| values.add(value); | ||
| } | ||
| return ListT.newValArrayList(adapter, values.toArray(new Val[0])); | ||
| } | ||
|
|
||
| private int listCapacity(Val foldRange) { | ||
| if (foldRange.type().hasTrait(Trait.SizerType)) { | ||
| long size = ((Sizer) foldRange).size().intValue(); | ||
| if (size > 0 && size <= Integer.MAX_VALUE) { | ||
| return (int) size; | ||
| } | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| @Override | ||
| public Cost cost() { | ||
| Cost range = estimateCost(iterRange); | ||
| Cost result = estimateCost(transform); | ||
| if (filter != null) { | ||
| result = result.add(estimateCost(filter)); | ||
| } | ||
| Val foldRange = iterRange.eval(emptyActivation()); | ||
| if (!foldRange.type().hasTrait(Trait.IterableType)) { | ||
| return Cost.Unknown; | ||
| } | ||
| long rangeCnt = 0L; | ||
| IteratorT it = ((IterableT) foldRange).iterator(); | ||
| while (it.hasNext() == True) { | ||
| it.next(); | ||
| rangeCnt++; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this try to use
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice catch! I already have a follow-up for that. |
||
| } | ||
| return range.add(result.multiply(rangeCnt)); | ||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| return "EvalListFold{" | ||
| + "id=" | ||
| + id | ||
| + ", iterVar='" | ||
| + iterVar | ||
| + '\'' | ||
| + ", iterRange=" | ||
| + iterRange | ||
| + ", filter=" | ||
| + filter | ||
| + ", transform=" | ||
| + transform | ||
| + '}'; | ||
| } | ||
| } | ||
|
|
||
| // Optional Intepretable implementations that specialize, subsume, or extend the core evaluation | ||
| // plan via decorators. | ||
|
|
||
|
|
@@ -1677,6 +1786,65 @@ public String toString() { | |
| } | ||
| } | ||
|
|
||
| /** EvalExhaustiveListFold evaluates every filter and transform without short-circuiting. */ | ||
| final class EvalExhaustiveListFold extends AbstractEval implements Coster { | ||
| private final EvalListFold fold; | ||
|
|
||
| EvalExhaustiveListFold(EvalListFold fold) { | ||
| super(fold.id); | ||
| this.fold = fold; | ||
| } | ||
|
|
||
| @Override | ||
| public Val eval(org.projectnessie.cel.interpreter.Activation ctx) { | ||
| Val foldRange = fold.iterRange.eval(ctx); | ||
| if (!foldRange.type().hasTrait(Trait.IterableType)) { | ||
| return valOrErr( | ||
| foldRange, "got '%s', expected iterable type", foldRange.getClass().getName()); | ||
| } | ||
|
|
||
| VarActivation iterCtx = new VarActivation(); | ||
| iterCtx.parent = ctx; | ||
| iterCtx.name = fold.iterVar; | ||
| List<Val> values = new ArrayList<>(fold.listCapacity(foldRange)); | ||
| Val result = null; | ||
| IteratorT it = ((IterableT) foldRange).iterator(); | ||
| while (it.hasNext() == True) { | ||
| iterCtx.val = it.next(); | ||
|
|
||
| Val include = fold.filter != null ? fold.filter.eval(iterCtx) : True; | ||
| Val value = fold.transform.eval(iterCtx); | ||
| if (include == False) { | ||
| continue; | ||
| } | ||
| if (include != True) { | ||
| result = noSuchOverload(null, Operator.Conditional.id, include); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. minor sonnet finding:
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch! I'll keep it in mind! |
||
| continue; | ||
| } | ||
| if (result == null) { | ||
| if (isUnknownOrError(value)) { | ||
| result = value; | ||
| } else { | ||
| values.add(value); | ||
| } | ||
| } | ||
| } | ||
| return result != null | ||
| ? result | ||
| : ListT.newValArrayList(fold.adapter, values.toArray(new Val[0])); | ||
| } | ||
|
|
||
| @Override | ||
| public Cost cost() { | ||
| return fold.cost(); | ||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| return "EvalExhaustiveListFold{" + fold + '}'; | ||
| } | ||
| } | ||
|
|
||
| /** evalAttr evaluates an Attribute value. */ | ||
| final class EvalAttr extends AbstractEval | ||
| implements InterpretableAttribute, Coster, Qualifier, Attribute { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.