ExpressionSelectors: Add optimized selectors.#5048
Conversation
- SingleLongInputCaching selector for expressions on the __time column, using a similar optimization to SingleScanTimeDimSelector - SingleStringInputDimensionSelector for expressions on string columns that return strings, using a similar optimization to ExtractionFn based DimensionSelectors. - SingleStringInputCaching selector for expressions on string columns that return primitives. Also, in the SQL planner, prefer expressions for time operations rather than extractionFns.
| final ExprEval exprEval = baseSelector.getObject(); | ||
| return exprEval.value(); | ||
| // No need for null check on getObject() since baseSelector impls will never return null. | ||
| return baseSelector.getObject().value(); |
There was a problem hiding this comment.
Could you please add //noinspection ... comment for IntelliJ?
There was a problem hiding this comment.
Added //noinspection ConstantConditions
| } | ||
|
|
||
| @VisibleForTesting | ||
| @Nonnull |
There was a problem hiding this comment.
Better to annotate the package with @EverythingIsNonnullByDefault instead
There was a problem hiding this comment.
I started trying to do this but ran into a few too many things to change as a result (mostly to get rid of false suggestions of "remove null check, X cannot be null"). So I ended up leaving it as-is.
There was a problem hiding this comment.
You don't have to resolve them, I think
There was a problem hiding this comment.
It's true, but I didn't see much point in adding @EverythingIsNonnullByDefault without fixing the issues that causes with inspections, given that its whole point is to help with inspections in the first place.
| @Nullable | ||
| static Supplier<Object> supplierFromObjectSelector(final BaseObjectColumnValueSelector<?> selector) | ||
| { | ||
| if (selector == null) { |
There was a problem hiding this comment.
ColumnSelectorFactory.makeColumnValueSelector() always returns non-null now, I think we shouldn't accept nulls here
There was a problem hiding this comment.
Replaced this with selector instanceof NilColumnValueSelector since this seems to be how to do it now.
| final Supplier<Object> inputSupplier = ExpressionSelectors.supplierFromDimensionSelector(selector); | ||
| this.bindings = name -> inputSupplier.get(); | ||
|
|
||
| if (selector.getValueCardinality() <= CACHE_SIZE) { |
There was a problem hiding this comment.
Looks like it doesn't consider -1 which is "unknown" cardinality
There was a problem hiding this comment.
There is a check for this a couple of lines up… cardinality >= 0 is a precondition for using this optimized implementation. I moved the check to be closer to this block so they are more visually connected. I also added a note to the javadoc about the precondition.
|
|
||
| public ExprEval compute(final int id) | ||
| { | ||
| ExprEval value = m.getAndMoveToFirst(id); |
| @Override | ||
| public IndexedInts getRow() | ||
| { | ||
| // Treat any non-single-valued row as a row containing a single null value, to ensure consistency with |
There was a problem hiding this comment.
Please make this comment a javadoc comment of the method and make ExpressionSelectors.supplierFromDimensionSelector a reference.
| } else { | ||
| // Can't handle non-singly-valued rows in expressions. | ||
| // Treat them as nulls until we think of something better to do. | ||
| return new SingleIndexedInt(0); |
There was a problem hiding this comment.
Could be cached, SingleIndexedInt.of() and cache 0-127 :)
| if (nullAdjustment == 0) { | ||
| return row; | ||
| } else { | ||
| return new SingleIndexedInt(row.get(0) + nullAdjustment); |
There was a problem hiding this comment.
Could add MutableSingleIndexedInt and cache the object
There was a problem hiding this comment.
I'm not sure if this offers a measurable benefit and I'm also not sure if the return value from getRow ever needs to persist beyond the next movement of the selector. So I left this as-is.
| private final Expr expression; | ||
| private final SingleInputBindings bindings = new SingleInputBindings(); | ||
|
|
||
| // 0 if selector has null as a value; 1 if it doesn't. |
Adds optimized selectors for certain cases.
using a similar optimization to SingleScanTimeDimSelector
that return strings, using a similar optimization to ExtractionFn
based DimensionSelectors.
that return primitives.
Also, in the SQL planner, prefer expressions for time operations
rather than extractionFns.
Benchmark: