blob: c7b5c66d7cc3eb315a7e3b18e5af652b800beffd [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 org.apache.doris.planner;
import org.apache.doris.analysis.Expr;
import org.apache.doris.analysis.InPredicate;
import org.apache.doris.analysis.SlotRef;
import org.apache.doris.analysis.StringLiteral;
import org.apache.doris.catalog.Column;
import org.apache.doris.catalog.PartitionKey;
import org.apache.doris.catalog.PrimitiveType;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.junit.Assert;
import org.junit.Test;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class HashDistributionPrunerTest {
@Test
public void test() {
List<Long> tabletIds = Lists.newArrayListWithExpectedSize(300);
for (long i = 0; i < 300; i++) {
tabletIds.add(i);
}
// distribution columns
Column dealDate = new Column("dealDate", PrimitiveType.DATE, false);
Column mainBrandId = new Column("main_brand_id", PrimitiveType.CHAR, false);
Column itemThirdCateId = new Column("item_third_cate_id", PrimitiveType.CHAR, false);
Column channel = new Column("channel", PrimitiveType.CHAR, false);
Column shopType = new Column("shop_type", PrimitiveType.CHAR, false);
List<Column> columns = Lists.newArrayList(dealDate, mainBrandId, itemThirdCateId, channel, shopType);
// filters
PartitionColumnFilter dealDatefilter = new PartitionColumnFilter();
dealDatefilter.setLowerBound(new StringLiteral("2019-08-22"), true);
dealDatefilter.setUpperBound(new StringLiteral("2019-08-22"), true);
PartitionColumnFilter mainBrandFilter = new PartitionColumnFilter();
List<Expr> inList = Lists.newArrayList();
inList.add(new StringLiteral("1323"));
inList.add(new StringLiteral("2528"));
inList.add(new StringLiteral("9610"));
inList.add(new StringLiteral("3893"));
inList.add(new StringLiteral("6121"));
mainBrandFilter.setInPredicate(new InPredicate(new SlotRef(null, "main_brand_id"), inList, false));
PartitionColumnFilter itemThirdFilter = new PartitionColumnFilter();
List<Expr> inList2 = Lists.newArrayList();
inList2.add(new StringLiteral("9719"));
inList2.add(new StringLiteral("11163"));
itemThirdFilter.setInPredicate(new InPredicate(new SlotRef(null, "item_third_cate_id"), inList2, false));
PartitionColumnFilter channelFilter = new PartitionColumnFilter();
List<Expr> inList3 = Lists.newArrayList();
inList3.add(new StringLiteral("1"));
inList3.add(new StringLiteral("3"));
channelFilter.setInPredicate(new InPredicate(new SlotRef(null, "channel"), inList3, false));
PartitionColumnFilter shopTypeFilter = new PartitionColumnFilter();
List<Expr> inList4 = Lists.newArrayList();
inList4.add(new StringLiteral("2"));
shopTypeFilter.setInPredicate(new InPredicate(new SlotRef(null, "shop_type"), inList4, false));
Map<String, PartitionColumnFilter> filters = Maps.newHashMap();
filters.put("dealDate", dealDatefilter);
filters.put("main_brand_id", mainBrandFilter);
filters.put("item_third_cate_id", itemThirdFilter);
filters.put("channel", channelFilter);
filters.put("shop_type", shopTypeFilter);
HashDistributionPruner pruner = new HashDistributionPruner(tabletIds, columns, filters, tabletIds.size());
Collection<Long> results = pruner.prune();
// 20 = 1 * 5 * 2 * 2 * 1 (element num of each filter)
Assert.assertEquals(20, results.size());
filters.get("shop_type").getInPredicate().addChild(new StringLiteral("4"));
results = pruner.prune();
// 40 = 1 * 5 * 2 * 2 * 2 (element num of each filter)
// 39 is because these is hash conflict
Assert.assertEquals(39, results.size());
filters.get("shop_type").getInPredicate().addChild(new StringLiteral("5"));
filters.get("shop_type").getInPredicate().addChild(new StringLiteral("6"));
filters.get("shop_type").getInPredicate().addChild(new StringLiteral("7"));
filters.get("shop_type").getInPredicate().addChild(new StringLiteral("8"));
results = pruner.prune();
// 120 = 1 * 5 * 2 * 2 * 6 (element num of each filter) > 100
Assert.assertEquals(300, results.size());
// check hash conflict
inList4.add(new StringLiteral("4"));
PartitionKey hashKey = new PartitionKey();
Set<Long> tablets = Sets.newHashSet();
hashKey.pushColumn(new StringLiteral("2019-08-22"), PrimitiveType.DATE);
for (Expr inLiteral : inList) {
hashKey.pushColumn((StringLiteral) inLiteral, PrimitiveType.CHAR);
for (Expr inLiteral2 : inList2) {
hashKey.pushColumn((StringLiteral) inLiteral2, PrimitiveType.CHAR);
for (Expr inLiteral3 : inList3) {
hashKey.pushColumn((StringLiteral) inLiteral3, PrimitiveType.CHAR);
for (Expr inLiteral4 : inList4) {
hashKey.pushColumn((StringLiteral) inLiteral4, PrimitiveType.CHAR);
long hashValue = hashKey.getHashValue();
tablets.add(tabletIds.get((int) ((hashValue & 0xffffffff) % tabletIds.size())));
hashKey.popColumn();
}
hashKey.popColumn();
}
hashKey.popColumn();
}
hashKey.popColumn();
}
Assert.assertEquals(39, tablets.size());
}
}