Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
*
* Copyright (c) 2006-2019, Speedment, Inc. All Rights Reserved.
*
* Licensed 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 com.speedment.runtime.core.internal.component.sql.optimizer;
import com.speedment.runtime.config.identifier.ColumnIdentifier;
import com.speedment.runtime.core.component.sql.Metrics;
import com.speedment.runtime.core.component.sql.SqlStreamOptimizer;
import com.speedment.runtime.core.component.sql.SqlStreamOptimizerInfo;
import com.speedment.runtime.core.db.AsynchronousQueryResult;
import com.speedment.runtime.core.db.DbmsType;
import com.speedment.runtime.core.internal.stream.builder.action.reference.FilterAction;
import com.speedment.runtime.core.internal.stream.builder.action.reference.LimitAction;
import com.speedment.runtime.core.internal.stream.builder.action.reference.SkipAction;
import com.speedment.runtime.core.internal.stream.builder.action.reference.SortedComparatorAction;
import com.speedment.runtime.core.internal.stream.builder.streamterminator.StreamTerminatorUtil;
import com.speedment.runtime.core.internal.stream.builder.streamterminator.StreamTerminatorUtil.RenderResult;
import com.speedment.runtime.core.stream.Pipeline;
import com.speedment.runtime.core.stream.action.Action;
import com.speedment.runtime.field.EnumField;
import com.speedment.runtime.field.comparator.CombinedComparator;
import com.speedment.runtime.field.comparator.FieldComparator;
import com.speedment.runtime.field.comparator.NullOrder;
import com.speedment.runtime.field.comparator.ReferenceFieldComparator;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Predicate;
import static com.speedment.runtime.core.db.DbmsType.SkipLimitSupport.NONE;
import static com.speedment.runtime.core.db.DbmsType.SkipLimitSupport.ONLY_AFTER_SORTED;
import static com.speedment.runtime.core.internal.stream.builder.streamterminator.StreamTerminatorUtil.isContainingOnlyFieldPredicate;
import static com.speedment.runtime.core.internal.stream.builder.streamterminator.StreamTerminatorUtil.isSortedActionWithFieldPredicate;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toList;
/**
* This Optimizer takes care of the following case:
*
*
a) Zero or more filter() operations
*
b) Zero or more sorted() operations
*
c) Zero or more skip() operations
*
d) Zero or more limit() operations
*
*
* No other operations must be in the sequence a-d or within the
* individual items a-d. All parameters in a and b must be obtained via
* fields. Failure to any of these rules will make the Optimizer reject
* optimization. Steps a) and b) may swap places.
*
* Thus, this optimizer can handle a (FILTER*, SORTED*, SKIP*, LIMIT*) or
* (SORTED*, LIMIT*, SKIP*, LIMIT*) pattern where all non-primitive parameters
* are all Field derived
*
* @author Per Minborg
* @param entity type
*/
public final class FilterSortedSkipOptimizer implements SqlStreamOptimizer {
private final FilterOperation FILTER_OPERATION = new FilterOperation();
private final SortedOperation SORTED_OPERATION = new SortedOperation();
private final SkipOperation SKIP_OPERATION = new SkipOperation();
private final LimitOperation LIMIT_OPERATION = new LimitOperation();
private final List> FILTER_SORTED_SKIP_LIMIT_PATH = Arrays.asList(
FILTER_OPERATION,
SORTED_OPERATION,
SKIP_OPERATION,
LIMIT_OPERATION
);
private final List> SORTED_FILTER_SKIP_LIMIT_PATH = Arrays.asList(
SORTED_OPERATION,
FILTER_OPERATION,
SKIP_OPERATION,
LIMIT_OPERATION
);
// FILTER <-> SORTED
// This optimizer can handle a (FILTER*,SORTED*,SKIP*, LIMIT*) pattern where filter and sorted parameters are all Field derived
@Override
public Metrics metrics(Pipeline initialPipeline, DbmsType dbmsType) {
requireNonNull(initialPipeline);
requireNonNull(dbmsType);
final DbmsType.SkipLimitSupport skipLimitSupport = dbmsType.getSkipLimitSupport();
final AtomicInteger filterCounter = new AtomicInteger();
final AtomicInteger orderCounter = new AtomicInteger();
final AtomicInteger skipCounter = new AtomicInteger();
final AtomicInteger limitCounter = new AtomicInteger();
traverse(initialPipeline,
$ -> filterCounter.incrementAndGet(),
$ -> orderCounter.incrementAndGet(),
$ -> skipCounter.incrementAndGet(),
$ -> limitCounter.incrementAndGet()
);
if (skipLimitSupport == ONLY_AFTER_SORTED && orderCounter.get() == 0) {
// Just decline. There are other optimizer that handles just filtering better
return Metrics.empty();
}
if (skipLimitSupport == NONE) {
return Metrics.of(filterCounter.get() + orderCounter.get(), filterCounter.get(), orderCounter.get(), 0, 0);
}
return Metrics.of(
filterCounter.get() + orderCounter.get() + skipCounter.get() + limitCounter.get(),
filterCounter.get(),
orderCounter.get(),
skipCounter.get() > 0 ? 1 : 0,
limitCounter.get() > 0 ? 1 : 0
);
}
@Override
@SuppressWarnings("unchecked")
public
P optimize(
final P initialPipeline,
final SqlStreamOptimizerInfo info,
final AsynchronousQueryResult query
) {
requireNonNull(initialPipeline);
requireNonNull(info);
requireNonNull(query);
final DbmsType dbmsType = info.getDbmsType();
final DbmsType.SkipLimitSupport skipLimitSupport = dbmsType.getSkipLimitSupport();
final List> filters = new ArrayList<>();
final List> sorteds = new ArrayList<>();
final List> skips = new ArrayList<>();
final List> limits = new ArrayList<>();
traverse(initialPipeline, filters::add, sorteds::add, skips::add, limits::add);
final List