All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.druid.sql.calcite.aggregation.Aggregation Maven / Gradle / Ivy

There is a newer version: 0.12.3
Show newest version
/*
 * Licensed to Metamarkets Group Inc. (Metamarkets) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. Metamarkets licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package io.druid.sql.calcite.aggregation;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import io.druid.java.util.common.IAE;
import io.druid.java.util.common.ISE;
import io.druid.query.aggregation.AggregatorFactory;
import io.druid.query.aggregation.FilteredAggregatorFactory;
import io.druid.query.aggregation.PostAggregator;
import io.druid.query.filter.DimFilter;

import java.util.List;
import java.util.Set;

public class Aggregation
{
  private final List aggregatorFactories;
  private final PostAggregator postAggregator;
  private final PostAggregatorFactory finalizingPostAggregatorFactory;

  private Aggregation(
      final List aggregatorFactories,
      final PostAggregator postAggregator,
      final PostAggregatorFactory finalizingPostAggregatorFactory
  )
  {
    this.aggregatorFactories = Preconditions.checkNotNull(aggregatorFactories, "aggregatorFactories");
    this.postAggregator = postAggregator;
    this.finalizingPostAggregatorFactory = finalizingPostAggregatorFactory;

    if (postAggregator == null) {
      Preconditions.checkArgument(aggregatorFactories.size() == 1, "aggregatorFactories.size == 1");
    } else {
      // Verify that there are no "useless" fields in the aggregatorFactories.
      // Don't verify that the PostAggregator inputs are all present; they might not be.
      final Set dependentFields = postAggregator.getDependentFields();
      for (AggregatorFactory aggregatorFactory : aggregatorFactories) {
        if (!dependentFields.contains(aggregatorFactory.getName())) {
          throw new IAE("Unused field[%s] in Aggregation", aggregatorFactory.getName());
        }
      }
    }
  }

  public static Aggregation create(final AggregatorFactory aggregatorFactory)
  {
    return new Aggregation(ImmutableList.of(aggregatorFactory), null, null);
  }

  public static Aggregation create(final PostAggregator postAggregator)
  {
    return new Aggregation(ImmutableList.of(), postAggregator, null);
  }

  public static Aggregation create(
      final List aggregatorFactories,
      final PostAggregator postAggregator
  )
  {
    return new Aggregation(aggregatorFactories, postAggregator, null);
  }

  public static Aggregation createFinalizable(
      final List aggregatorFactories,
      final PostAggregator postAggregator,
      final PostAggregatorFactory finalizingPostAggregatorFactory
  )
  {
    return new Aggregation(
        aggregatorFactories,
        postAggregator,
        Preconditions.checkNotNull(finalizingPostAggregatorFactory, "finalizingPostAggregatorFactory")
    );
  }

  public List getAggregatorFactories()
  {
    return aggregatorFactories;
  }

  public PostAggregator getPostAggregator()
  {
    return postAggregator;
  }

  public PostAggregatorFactory getFinalizingPostAggregatorFactory()
  {
    return finalizingPostAggregatorFactory;
  }

  public String getOutputName()
  {
    return postAggregator != null
           ? postAggregator.getName()
           : Iterables.getOnlyElement(aggregatorFactories).getName();
  }

  public Aggregation filter(final DimFilter filter)
  {
    if (filter == null) {
      return this;
    }

    if (postAggregator != null) {
      // Verify that this Aggregation contains all inputs. If not, this "filter" call won't work right.
      final Set dependentFields = postAggregator.getDependentFields();
      final Set aggregatorNames = Sets.newHashSet();
      for (AggregatorFactory aggregatorFactory : aggregatorFactories) {
        aggregatorNames.add(aggregatorFactory.getName());
      }
      for (String field : dependentFields) {
        if (!aggregatorNames.contains(field)) {
          throw new ISE("Cannot filter an Aggregation that does not contain its inputs: %s", this);
        }
      }
    }

    final List newAggregators = Lists.newArrayList();

    for (AggregatorFactory agg : aggregatorFactories) {
      newAggregators.add(new FilteredAggregatorFactory(agg, filter));
    }

    return new Aggregation(
        newAggregators,
        postAggregator,
        finalizingPostAggregatorFactory
    );
  }

  @Override
  public boolean equals(Object o)
  {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }

    Aggregation that = (Aggregation) o;

    if (aggregatorFactories != null
        ? !aggregatorFactories.equals(that.aggregatorFactories)
        : that.aggregatorFactories != null) {
      return false;
    }
    if (postAggregator != null ? !postAggregator.equals(that.postAggregator) : that.postAggregator != null) {
      return false;
    }
    return finalizingPostAggregatorFactory != null
           ? finalizingPostAggregatorFactory.equals(that.finalizingPostAggregatorFactory)
           : that.finalizingPostAggregatorFactory == null;
  }

  @Override
  public int hashCode()
  {
    int result = aggregatorFactories != null ? aggregatorFactories.hashCode() : 0;
    result = 31 * result + (postAggregator != null ? postAggregator.hashCode() : 0);
    result = 31 * result + (finalizingPostAggregatorFactory != null ? finalizingPostAggregatorFactory.hashCode() : 0);
    return result;
  }

  @Override
  public String toString()
  {
    return "Aggregation{" +
           "aggregatorFactories=" + aggregatorFactories +
           ", postAggregator=" + postAggregator +
           ", finalizingPostAggregatorFactory=" + finalizingPostAggregatorFactory +
           '}';
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy