ResultSetMergeContext.java 5.5 KB
Newer Older
T
terrymanu 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * Copyright 1999-2015 dangdang.com.
 * <p>
 * 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.
 * </p>
 */

package com.dangdang.ddframe.rdb.sharding.merger;

import com.dangdang.ddframe.rdb.sharding.jdbc.adapter.AbstractResultSetAdapter;
T
terrymanu 已提交
21 22 23 24 25
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.AggregationSelectItemContext;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.GroupByContext;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.IndexColumn;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.OrderByContext;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.SQLContext;
T
terrymanu 已提交
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import lombok.Getter;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * 结果集归并上下文.
 *
 * @author zhangliang
 */
@Getter
public final class ResultSetMergeContext {
    
    private final ShardingResultSets shardingResultSets;
    
T
terrymanu 已提交
45
    private final SQLContext sqlContext;
T
terrymanu 已提交
46
    
47
    private final List<OrderByContext> currentOrderByKeys;
T
terrymanu 已提交
48
    
T
terrymanu 已提交
49
    public ResultSetMergeContext(final ShardingResultSets shardingResultSets, final SQLContext sqlContext) {
T
terrymanu 已提交
50
        this.shardingResultSets = shardingResultSets;
T
terrymanu 已提交
51
        this.sqlContext = sqlContext;
T
terrymanu 已提交
52 53 54 55
        currentOrderByKeys = new LinkedList<>();
        init();
    }
    
T
terrymanu 已提交
56
    private void init() {
T
terrymanu 已提交
57
        setColumnIndex(((AbstractResultSetAdapter) shardingResultSets.getResultSets().get(0)).getColumnLabelIndexMap());
T
terrymanu 已提交
58
        currentOrderByKeys.addAll(sqlContext.getOrderByContexts());
T
terrymanu 已提交
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
    }
    
    private void setColumnIndex(final Map<String, Integer> columnLabelIndexMap) {
        for (IndexColumn each : getAllFocusedColumns()) {
            if (each.getColumnIndex() > 0) {
                continue;
            }
            Preconditions.checkState(
                    columnLabelIndexMap.containsKey(each.getColumnLabel().orNull()) || columnLabelIndexMap.containsKey(each.getColumnName().orNull()), String.format("%s has not index", each));
            if (each.getColumnLabel().isPresent() && columnLabelIndexMap.containsKey(each.getColumnLabel().get())) {
                each.setColumnIndex(columnLabelIndexMap.get(each.getColumnLabel().get()));
            } else if (each.getColumnName().isPresent() && columnLabelIndexMap.containsKey(each.getColumnName().get())) {
                each.setColumnIndex(columnLabelIndexMap.get(each.getColumnName().get()));
            }
        }
    }
    
    private List<IndexColumn> getAllFocusedColumns() {
        List<IndexColumn> result = new LinkedList<>();
T
terrymanu 已提交
78 79 80
        result.addAll(sqlContext.getGroupByContexts());
        result.addAll(sqlContext.getOrderByContexts());
        LinkedList<AggregationSelectItemContext> allAggregationColumns = Lists.newLinkedList(sqlContext.getAggregationSelectItemContexts());
T
terrymanu 已提交
81
        while (!allAggregationColumns.isEmpty()) {
82
            AggregationSelectItemContext firstElement = allAggregationColumns.poll();
T
terrymanu 已提交
83
            result.add(firstElement);
84 85
            if (!firstElement.getDerivedAggregationSelectItemContexts().isEmpty()) {
                allAggregationColumns.addAll(firstElement.getDerivedAggregationSelectItemContexts());
T
terrymanu 已提交
86 87 88 89 90 91 92 93 94 95 96
            }
        }
        return result;
    }
    
    /**
     * 判断分组归并是否需要内存排序.
     *
     * @return 分组归并是否需要内存排序
     */
    public boolean isNeedMemorySortForGroupBy() {
T
terrymanu 已提交
97
        return !sqlContext.getGroupByContexts().isEmpty() && !currentOrderByKeys.equals(transformGroupByColumnsToOrderByColumns());
T
terrymanu 已提交
98 99 100 101 102 103 104 105 106 107
    }
    
    /**
     * 将分组顺序设置为排序序列.
     */
    public void setGroupByKeysToCurrentOrderByKeys() {
        currentOrderByKeys.clear();
        currentOrderByKeys.addAll(transformGroupByColumnsToOrderByColumns());
    }
    
108
    private List<OrderByContext> transformGroupByColumnsToOrderByColumns() {
T
terrymanu 已提交
109
        return Lists.transform(sqlContext.getGroupByContexts(), new Function<GroupByContext, OrderByContext>() {
T
terrymanu 已提交
110 111
            
            @Override
112 113 114
            public OrderByContext apply(final GroupByContext input) {
                OrderByContext result = input.getOwner().isPresent() ? new OrderByContext(input.getOwner().get(), input.getName(), input.getOrderByType(), input.getAlias())
                        : new OrderByContext(input.getName(), input.getOrderByType(), input.getAlias());
T
terrymanu 已提交
115 116 117 118 119 120 121 122 123 124 125 126
                result.setColumnIndex(input.getColumnIndex());
                return result;
            }
        });
    }
    
    /**
     * 判断排序归并是否需要内存排序.
     *
     * @return 排序归并是否需要内存排序
     */
    public boolean isNeedMemorySortForOrderBy() {
T
terrymanu 已提交
127
        return !sqlContext.getOrderByContexts().isEmpty() && !currentOrderByKeys.equals(sqlContext.getOrderByContexts());
T
terrymanu 已提交
128 129 130 131 132 133 134
    }
    
    /**
     * 将排序顺序设置为排序序列.
     */
    public void setOrderByKeysToCurrentOrderByKeys() {
        currentOrderByKeys.clear();
T
terrymanu 已提交
135
        currentOrderByKeys.addAll(sqlContext.getOrderByContexts());
T
terrymanu 已提交
136 137
    }
}