blob: e62a43ebefef8faa8ba7c6a02b223511d73d6a19 [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.uniffle.common.util;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class BlockIdLayoutTest {
@Test
public void testFromLengths() {
BlockIdLayout layout = BlockIdLayout.from(20, 21, 22);
assertEquals(20, layout.sequenceNoBits);
assertEquals(21, layout.partitionIdBits);
assertEquals(22, layout.taskAttemptIdBits);
assertEquals(43, layout.sequenceNoOffset);
assertEquals(22, layout.partitionIdOffset);
assertEquals(0, layout.taskAttemptIdOffset);
assertEquals(1048575, layout.maxSequenceNo);
assertEquals(2097151, layout.maxPartitionId);
assertEquals(4194303, layout.maxTaskAttemptId);
assertEquals(2097152, layout.maxNumPartitions);
assertEquals(1048575L << (21 + 22), layout.sequenceNoMask);
assertEquals(2097151L << 22, layout.partitionIdMask);
assertEquals(4194303L, layout.taskAttemptIdMask);
assertEquals("blockIdLayout[seq: 20 bits, part: 21 bits, task: 22 bits]", layout.toString());
}
@Test
public void testFromLengthsErrors() {
final Throwable e1 =
assertThrows(IllegalArgumentException.class, () -> BlockIdLayout.from(21, 21, 20));
assertEquals(
"Don't support given lengths, sum must be exactly 63: 21 + 21 + 20 = 62", e1.getMessage());
final Throwable e2 =
assertThrows(IllegalArgumentException.class, () -> BlockIdLayout.from(21, 21, 22));
assertEquals(
"Don't support given lengths, sum must be exactly 63: 21 + 21 + 22 = 64", e2.getMessage());
final Throwable e3 =
assertThrows(IllegalArgumentException.class, () -> BlockIdLayout.from(32, 16, 16));
assertEquals(
"Don't support given lengths, individual lengths must be less that 32: "
+ "given sequenceNoBits=32, partitionIdBits=16, taskAttemptIdBits=16",
e3.getMessage());
final Throwable e4 =
assertThrows(IllegalArgumentException.class, () -> BlockIdLayout.from(16, 32, 16));
assertEquals(
"Don't support given lengths, individual lengths must be less that 32: "
+ "given sequenceNoBits=16, partitionIdBits=32, taskAttemptIdBits=16",
e4.getMessage());
final Throwable e5 =
assertThrows(IllegalArgumentException.class, () -> BlockIdLayout.from(16, 16, 32));
assertEquals(
"Don't support given lengths, individual lengths must be less that 32: "
+ "given sequenceNoBits=16, partitionIdBits=16, taskAttemptIdBits=32",
e5.getMessage());
final Throwable e6 =
assertThrows(IllegalArgumentException.class, () -> BlockIdLayout.from(22, 21, 21));
assertEquals(
"Don't support given lengths, sum must be exactly 63: 22 + 21 + 21 = 64", e6.getMessage());
final Throwable e7 =
assertThrows(IllegalArgumentException.class, () -> BlockIdLayout.from(21, 22, 21));
assertEquals(
"Don't support given lengths, sum must be exactly 63: 21 + 22 + 21 = 64", e7.getMessage());
final Throwable e8 =
assertThrows(IllegalArgumentException.class, () -> BlockIdLayout.from(21, 21, 22));
assertEquals(
"Don't support given lengths, sum must be exactly 63: 21 + 21 + 22 = 64", e8.getMessage());
}
public static Stream<Arguments> testBlockIdLayouts() {
return Stream.of(
Arguments.of(BlockIdLayout.DEFAULT),
Arguments.of(BlockIdLayout.from(21, 21, 21)),
Arguments.of(BlockIdLayout.from(12, 24, 27)),
Arguments.of(BlockIdLayout.from(1, 31, 31)),
Arguments.of(BlockIdLayout.from(31, 1, 31)),
Arguments.of(BlockIdLayout.from(31, 31, 1)));
}
@ParameterizedTest
@MethodSource("testBlockIdLayouts")
public void testLayoutGetBlockId(BlockIdLayout layout) {
// max value of blockId
assertEquals(
(long) layout.maxSequenceNo << layout.sequenceNoOffset
| (long) layout.maxPartitionId << layout.partitionIdOffset
| (long) layout.maxTaskAttemptId << layout.taskAttemptIdOffset,
layout.getBlockId(layout.maxSequenceNo, layout.maxPartitionId, layout.maxTaskAttemptId));
// min value of blockId
assertEquals(0L, layout.getBlockId(0, 0, 0));
// just a random test
if (layout.sequenceNoBits > 7 && layout.partitionIdBits > 6 && layout.taskAttemptIdBits > 7) {
long blockId = layout.getBlockId(123, 45, 67);
assertEquals(
123L << layout.sequenceNoOffset
| 45L << layout.partitionIdOffset
| 67L << layout.taskAttemptIdOffset,
blockId);
assertEquals(123, layout.getSequenceNo(blockId));
assertEquals(45, layout.getPartitionId(blockId));
assertEquals(67, layout.getTaskAttemptId(blockId));
assertEquals(blockId, layout.asBlockId(blockId).blockId);
assertEquals(123, layout.asBlockId(blockId).sequenceNo);
assertEquals(45, layout.asBlockId(blockId).partitionId);
assertEquals(67, layout.asBlockId(blockId).taskAttemptId);
assertEquals(layout, layout.asBlockId(blockId).layout);
}
final Throwable e1 =
assertThrows(
IllegalArgumentException.class,
() -> layout.getBlockId(layout.maxSequenceNo + 1, 0, 0));
assertEquals(
"Don't support sequenceNo["
+ (layout.maxSequenceNo + 1)
+ "], "
+ "the max value should be "
+ layout.maxSequenceNo,
e1.getMessage());
final Throwable e2 =
assertThrows(
IllegalArgumentException.class,
() -> layout.getBlockId(0, layout.maxPartitionId + 1, 0));
assertEquals(
"Don't support partitionId["
+ (layout.maxPartitionId + 1)
+ "], "
+ "the max value should be "
+ layout.maxPartitionId,
e2.getMessage());
final Throwable e3 =
assertThrows(
IllegalArgumentException.class,
() -> layout.getBlockId(0, 0, layout.maxTaskAttemptId + 1));
assertEquals(
"Don't support taskAttemptId["
+ (layout.maxTaskAttemptId + 1)
+ "], "
+ "the max value should be "
+ layout.maxTaskAttemptId,
e3.getMessage());
}
@Test
public void testEquals() {
BlockIdLayout layout1 = BlockIdLayout.from(20, 21, 22);
BlockIdLayout layout2 = BlockIdLayout.from(20, 21, 22);
BlockIdLayout layout3 = BlockIdLayout.from(18, 22, 23);
assertEquals(layout1, layout1);
assertEquals(layout1, layout2);
assertNotEquals(layout1, layout3);
BlockIdLayout layout4 = BlockIdLayout.from(18, 24, 21);
assertNotEquals(layout1, layout4);
assertEquals(layout4, BlockIdLayout.DEFAULT);
}
}