Skip to content

短路求值单元测试

单元测试代码

/*
 * 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.tsfile.read.filter;

import java.util.Arrays;
import java.util.Optional;
import org.apache.tsfile.block.column.Column;
import org.apache.tsfile.common.conf.TSFileConfig;
import org.apache.tsfile.read.common.block.TsBlock;
import org.apache.tsfile.read.common.block.column.BinaryColumn;
import org.apache.tsfile.read.common.block.column.TimeColumn;
import org.apache.tsfile.read.filter.basic.Filter;
import org.apache.tsfile.read.filter.factory.FilterFactory;
import org.apache.tsfile.read.filter.factory.ValueFilterApi;
import org.apache.tsfile.utils.Binary;
import org.junit.Test;

/**
 * @Author yuyong @Date 2024/7/16-下午5:08
 */
public class LikeOptimizerTest {

  private static TsBlock tsBlock;
  private static final int ROW_NUM = 2;
  private static final int COL_NUM = 10000;
  private static final int COUNT = 8000;

  public void createTsBlock() {
    long[] timeValues = new long[COL_NUM];
    Binary[] firstValues = new Binary[COL_NUM];
    Binary[] sencondValues = new Binary[COL_NUM];

    for (int i = 0; i < COL_NUM; i++) {
      timeValues[i] = i;
      if (i < COUNT) {
        firstValues[i] = new Binary("10000481".getBytes());
      } else {
        firstValues[i] = new Binary("10000482".getBytes());
      }
      sencondValues[i] = new Binary(String.format("xxZ6%dxx", i % 100).getBytes());
    }
    // print the selection rate
    System.out.printf("选择率为%.2f%n", (float) COUNT / 10000);

    // build tsBlock
    TimeColumn timeColumn = new TimeColumn(COL_NUM, timeValues);
    BinaryColumn firstColumn = new BinaryColumn(COL_NUM, Optional.empty(), firstValues);
    BinaryColumn sencondColumn = new BinaryColumn(COL_NUM, Optional.empty(), sencondValues);
    Column[] valueColumn = new Column[ROW_NUM];
    valueColumn[0] = firstColumn;
    valueColumn[1] = sencondColumn;
    tsBlock = new TsBlock(COL_NUM, timeColumn, valueColumn);
  }

  @Test
  public void testOrNodeShortCircuitEvaluation() {
    // init tsBlock
    createTsBlock();

    Filter leftFilter = ValueFilterApi.eq(0, new Binary("10000481", TSFileConfig.STRING_CHARSET));
    Filter rightFilter = ValueFilterApi.like(1, "%50%");
    Filter filter = FilterFactory.and(leftFilter, rightFilter);

    // create an all true array
    boolean[] selection = new boolean[COL_NUM];
    Arrays.fill(selection, true);

    long preOptimizationTime = 0;
    long optimizedTime = 0;

    // test the performance of the filter without optimization
    for (int i = 0; i < 1100; i++) {
      long startTime = System.nanoTime();
      boolean[] result = filter.satisfyTsBlock(tsBlock);
      long endTime = System.nanoTime();
      double duration = endTime - startTime;
      if (i > 100) {
        preOptimizationTime += duration;
      }
    }
    System.out.printf("优化前:本次查询 1000轮的平均耗时为:%d%n", preOptimizationTime / 1000);

    // test the performance of the filter with optimization
    for (int i = 0; i < 1100; i++) {
      long startTime = System.nanoTime();
      boolean[] result = filter.satisfyTsBlock(selection, tsBlock);
      long endTime = System.nanoTime();
      double duration = endTime - startTime;
      if (i > 100) {
        optimizedTime += duration;
      }
    }
    System.out.printf("优化后:本次查询 1000轮的平均耗时为:%d%n", optimizedTime / 1000);

    long temp = preOptimizationTime - optimizedTime;

    System.out.printf("优化率为%.2f%n", (float) temp / preOptimizationTime * 100);
  }
}