# Class Optimization

Object
Optimization

public class Optimization extends Object
Description of optimizations or simplifications to attempt on filters and expressions. Optimizations can include the following changes:

- Application of some logical identities such as `NOT(NOT(A)) == A`.
- Application of logical short circuits such as `A & FALSE == FALSE`.
- Replacement of value references to non-existent properties by null literals.
- Immediate evaluation of expressions where all parameters are literal values.

The following options can enable some additional optimizations:

- The type of the `Feature` instances to be filtered.

## Usage in multi-threads context

This class is not thread-safe. A new instance shall be created for each thread applying optimizations. Example:

    Filter<R> filter = ...;
    filter = new Optimization().apply(filter);

## How optimizations are applied

Optimizations are specific to each expression and filter type. For optimizations to happen, classes must implement the `Optimization​.OnExpression` or `Optimization​.OnFilter` interface. The `apply(Filter)` and `apply(Expression)` methods in this `Optimization` class merely delegate to the methods defined in above-cited interfaces, with safety guards against infinite recursion.

## Behavioral changes

Optimized filters shall produce the same results as non-optimized filters. However side-effects may differ, in particular regarding exceptions that may be thrown. For example, if a filter tests `A & B` and if `Optimization` determines that the `B` condition will always evaluate to `false`, then the `A` condition will never be tested. If that condition had side-effects or threw an exception, those effects will disappear in the optimized filter.

Since:
  1.1

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static interface`
  `Optimization​.OnExpression<R,V>`
  Expression that can be optimized.
  `static interface`
  `Optimization​.OnFilter<R>`
  Filter that can be optimized.

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `Optimization()`
  Creates a new instance.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `<R,V> Expression<R, ? extends V>`
  `apply(Expression<R, ? extends V> expression)`
  Optimizes or simplifies the given expression.
  `<R> Filter<R>`
  `apply(Filter<R> filter)`
  Optimizes or simplifies the given filter.
  `<R> List<Filter<R>>`
  `applyAndDecompose(Filter<R> filter)`
  Optimizes or simplifies the given filter and returns it as a list of `AND` operands.
  `Optional<CoordinateReferenceSystem>`
  `findExpectedCRS(Expression<?,?> parameter)`
  If the specified parameter should always use the same Coordinate Reference System, returns that CRS.
  `DefaultFeatureType`
  `getFeatureType()`
  Deprecated, for removal: This API element is subject to removal in a future version.
  Replaced by `getFinalFeatureTypes()`.
  `Set<DefaultFeatureType>`
  `getFinalFeatureTypes()`
  Returns the exhaustive set of the types of all feature instances that the filters and expressions may see.
  `static <R,V> Expression<R,V>`
  `literal(V value)`
  Creates a constant, literal value that can be used in expressions.
  `static Set<FunctionProperty>`
  `properties(Expression<?,?> expression)`
  Returns the manner in which values are computed from resources given to the specified expression.
  `static Set<FunctionProperty>`
  `properties(Filter<?> filter)`
  Returns the manner in which values are computed from resources given to the specified filter.
  `void`
  `setFeatureType(DefaultFeatureType type)`
  Deprecated, for removal: This API element is subject to removal in a future version.
  Replaced by `setFinalFeatureTypes(Collection)`.
  `final void`
  `setFinalFeatureType(DefaultFeatureType type)`
  Specifies the single type of all feature instances that the filters and expressions may see.
  `void`
  `setFinalFeatureTypes(Collection<? extends DefaultFeatureType> types)`
  Specifies the exhaustive set of the types of all feature instances that the filters and expressions may see.
  `void`
  `warning(Exception exception, boolean resolvable)`
  Reports that a warning occurred during the execution of an `apply(…)` method.

  ### Methods inherited from class Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Constructor Details

  - ### Optimization

    public Optimization()
    Creates a new instance.

- ## Method Details

  - ### getFeatureType

    @Deprecated(since="1.6", forRemoval=true) public DefaultFeatureType getFeatureType()
    Deprecated, for removal: This API element is subject to removal in a future version.
    Replaced by `getFinalFeatureTypes()`.
    Returns the type of feature instances to be filtered, or `null` if unknown. This is the last value specified by a call to `setFeatureType(DefaultFeatureType)`. The default value is `null`.
    Returns:
      the type of feature instances to be filtered, or `null` if unknown.

  - ### setFeatureType

    @Deprecated(since="1.6", forRemoval=true) public void setFeatureType(DefaultFeatureType type)
    Deprecated, for removal: This API element is subject to removal in a future version.
    Replaced by `setFinalFeatureTypes(Collection)`.
    Sets the type of feature instances to be filtered. If this type is known in advance, specifying it may allow to compute more specific `ObjectConverter`s or to apply some geometry reprojection in advance.
    Parameters:
      `type` - the type of feature instances to be filtered, or `null` if unknown.

  - ### getFinalFeatureTypes

    public Set<DefaultFeatureType> getFinalFeatureTypes()
    Returns the exhaustive set of the types of all feature instances that the filters and expressions may see. The super-types should not be included in the set, unless some features may be instances of these specific super-types rather than instances of a some sub-type. If the set of feature types is unknown or irrelevant for the type of resources to be filtered, then this method returns an empty set.

    #### Purpose

    A `DataStore` may contain a hierarchy of feature types instead of a single type. A property may be absent in the parent type but present in some sub-types, or may be overridden in sub-types. If an optimization wants to evaluate once and for all an expression with literal parameters, the optimization needs to verify that the parameters are really literals in all possible sub-types.
    Returns:
      exhaustive set of types of all feature instances that the filters and expressions may see.
    Since:
      1.6

  - ### setFinalFeatureTypes

    public void setFinalFeatureTypes(Collection<? extends DefaultFeatureType> types)
    Specifies the exhaustive set of the types of all feature instances that the filters and expressions may see. The given collection should not include super-types, unless some features may be instances of these specific super-types rather than instances of a some sub-type. An empty collection means that feature types are unknown or irrelevant for the type of resources to be filtered.
    Parameters:
      `types` - exhaustive set of types of all feature instances that the filters and expressions may see.
    Since:
      1.6

  - ### setFinalFeatureType

    public final void setFinalFeatureType(DefaultFeatureType type)
    Specifies the single type of all feature instances that the filters and expressions may see. This is a convenience method delegating to `setFinalFeatureTypes(Collection)` with a singleton or empty set.

    Note that the given type should be effectively final, i.e. no subtype should exist. If the feature instances may be of some subtypes, then all subtypes should be enumerated in a call to `setFinalFeatureTypes(Collection)`.

    Parameters:
      `type` - the type of feature instances to be filtered, or `null` if unknown.
    Since:
      1.6

  - ### findExpectedCRS

    public Optional<CoordinateReferenceSystem> findExpectedCRS(Expression<?,?> parameter) throws IllegalArgumentException
    If the specified parameter should always use the same Coordinate Reference System, returns that CRS. The `parameter` argument is usually one of the elements returned by `Expression​.getParameters()` or `Filter​.getExpressions()`, and the CRS used by that parameter may depend on the feature types declared by `getFinalFeatureTypes()`. The returned value is empty if the CRS is unknown or not the same for all feature types.
    Parameters:
      `parameter` - a parameter of a filter or expression.
    Returns:
      the CRS expected for the specified parameter, or empty if unknown of not unique.
    Throws:
      `IllegalArgumentException` - if the parameter is a `ValueReference` and the referenced property has not been found in at least one feature type.
    Since:
      1.6

  - ### apply

    public <R> Filter<R> apply(Filter<R> filter)
    Optimizes or simplifies the given filter. If the given instance implements the `Optimization​.OnFilter` interface, then its `optimize(this)` method is invoked. Otherwise this method returns the given filter as-is.
    Type Parameters:
      `R` - the type of resources (e.g. `Feature`) used as inputs.
    Parameters:
      `filter` - the filter to optimize, or `null`.
    Returns:
      the optimized filter, or `null` if the given filter was null. May be `filter` if no optimization or simplification has been applied.
    Throws:
      `IllegalArgumentException` - if the given filter is already in process of being optimized (i.e. there is a recursive call to `apply(…)` for the same filter).

  - ### apply

    public <R,V> Expression<R, ? extends V> apply(Expression<R, ? extends V> expression)
    Optimizes or simplifies the given expression. If the given instance implements the `Optimization​.OnExpression` interface, then its `optimize(this)` method is invoked. Otherwise this method returns the given expression as-is.
    Type Parameters:
      `R` - the type of resources (e.g. `Feature`) used as inputs.
      `V` - the type of values computed by the expression.
    Parameters:
      `expression` - the expression to optimize, or `null`.
    Returns:
      the optimized expression, or `null` if the given expression was null. May be `expression` if no optimization or simplification has been applied.
    Throws:
      `IllegalArgumentException` - if the given expression is already in process of being optimized (i.e. there is a recursive call to `apply(…)` for the same expression).

  - ### applyAndDecompose

    public <R> List<Filter<R>> applyAndDecompose(Filter<R> filter)
    Optimizes or simplifies the given filter and returns it as a list of `AND` operands. If such list cannot be built, then this method returns the optimized filter in a singleton list.

    #### Use case

    This method tries to transform a filter into a `F₀ AND F₁ AND F₂ AND F₃ AND ...` sequence. This transformation is useful when some operands can be handled by the storage engine (for example a SQL database) and other operands cannot. For example, when reading features from a relational database, the implementation may choose to express the F₁ and F₃ operands as SQL statements and apply the other operands in Java code.
    Type Parameters:
      `R` - the type of resources (e.g. `Feature`) used as inputs.
    Parameters:
      `filter` - the filter to decompose.
    Returns:
      a sequence of `AND` operands, or an empty list if the given filter was null.
    Throws:
      `ClassCastException` - if a filter declares the `AND`, `OR` or `NOT` type without implementing the `LogicalOperator` interface.

  - ### warning

    public void warning(Exception exception, boolean resolvable)
    Reports that a warning occurred during the execution of an `apply(…)` method. This method can be invoked by implementations of `Optimization​.OnFilter` or `Optimization​.OnExpression` interfaces. The exception if often a `IllegalArgumentException`, which is not necessarily an error because a property may not exist in a base feature type but exists in some sub-types.

    If the `resolvable` flag is `true`, it will be taken as a hint to retry the optimization later if more information about the `final feature types` become available. This flag should be `false` if more information would not have a direct impact on the optimization done by the caller. Callers do not need to care about indirect impacts in the parameters of the filter or expression.

    Parameters:
      `exception` - the recoverable exception that occurred.
      `resolvable` - whether an optimization with more information may avoid this warning.
    Since:
      1.6

  - ### properties

    public static Set<FunctionProperty> properties(Filter<?> filter)
    Returns the manner in which values are computed from resources given to the specified filter. This set of properties may determine which optimizations are allowed. The values of particular interest are:
    - `FunctionProperty​.VOLATILE` if the computed value changes each time that the filter is evaluated, even if the resource to evaluate stay the same immutable instance.
    Parameters:
      `filter` - the filter for which to query function properties.
    Returns:
      the manners in which values are computed from resources.
    Since:
      1.4

  - ### properties

    public static Set<FunctionProperty> properties(Expression<?,?> expression)
    Returns the manner in which values are computed from resources given to the specified expression. This set of properties may determine which optimizations are allowed. The values of particular interest are:
    - `FunctionProperty​.INJECTIVE` if the computed value is unique for each resource instance (e.g. identifiers).
    - `FunctionProperty​.VOLATILE` if the computed value changes each time that the expression is evaluated, even if the resource to evaluate stay the same immutable instance.
    - `FunctionProperty​.isConstant(Set)` if the expression returns a constant value.
    Parameters:
      `expression` - the expression for which to query function properties.
    Returns:
      the manners in which values are computed from resources.
    Since:
      1.4

  - ### literal

    public static <R,V> Expression<R,V> literal(V value)
    Creates a constant, literal value that can be used in expressions. This is a helper methods for optimizations which simplified an expression to a constant value.
    Type Parameters:
      `R` - the type of resources used as inputs.
      `V` - the type of the value of the literal.
    Parameters:
      `value` - the literal value. May be `null`.
    Returns:
      a literal for the given value.
    See Also:
      - `DefaultFilterFactory​.literal(Object)`