Java tutorial
/* * * 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.cassandra.db.clock; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.*; import org.apache.commons.lang.ArrayUtils; import org.junit.Test; import org.apache.cassandra.Util; import org.apache.cassandra.db.IClock.ClockRelationship; import org.apache.cassandra.db.clock.IContext; import org.apache.cassandra.db.clock.IncrementCounterContext; import org.apache.cassandra.utils.FBUtilities; /** * Note: these tests assume IPv4 (4 bytes) is used for id. * if IPv6 (16 bytes) is used, tests will fail (but the code will work). * however, it might be pragmatic to modify the code to just use * the IPv4 portion of the IPv6 address-space. */ public class IncrementCounterContextTest { private static final IncrementCounterContext icc = new IncrementCounterContext(); private static final int HEADER_LENGTH; private static final InetAddress idAddress; private static final byte[] id; private static final int idLength; private static final int countLength; private static final int stepLength; private static final int defaultEntries; static { HEADER_LENGTH = IncrementCounterContext.HEADER_LENGTH; // 2x size of long + size of int idAddress = FBUtilities.getLocalAddress(); id = idAddress.getAddress(); idLength = 4; // size of int countLength = 8; // size of long stepLength = idLength + countLength; defaultEntries = 10; } @Test public void testCreate() { long start = System.currentTimeMillis(); byte[] context = icc.create(); assert context.length == HEADER_LENGTH; long created = FBUtilities.byteArrayToLong(context, 0); assert (start <= created); assert (created <= System.currentTimeMillis()); } @Test public void testUpdatePresentReorder() throws UnknownHostException { byte[] context; context = new byte[HEADER_LENGTH + (stepLength * defaultEntries)]; for (int i = 0; i < defaultEntries - 1; i++) { icc.writeElementAtStepOffset(context, i, FBUtilities.toByteArray(i), 1L); } icc.writeElementAtStepOffset(context, (defaultEntries - 1), id, 1L); context = icc.update(context, idAddress, 10L); assert context.length == (HEADER_LENGTH + (stepLength * defaultEntries)); assert 11L == FBUtilities.byteArrayToLong(context, HEADER_LENGTH + idLength); for (int i = 1; i < defaultEntries; i++) { int offset = HEADER_LENGTH + (i * stepLength); assert i - 1 == FBUtilities.byteArrayToInt(context, offset); } } @Test public void testUpdateNotPresent() { byte[] context = new byte[HEADER_LENGTH + (stepLength * 2)]; for (int i = 0; i < 2; i++) { icc.writeElementAtStepOffset(context, i, FBUtilities.toByteArray(i), 1L); } context = icc.update(context, idAddress, 328L); assert context.length == (HEADER_LENGTH + (stepLength * 3)); assert 328L == FBUtilities.byteArrayToLong(context, HEADER_LENGTH + idLength); for (int i = 1; i < 3; i++) { int offset = HEADER_LENGTH + (i * stepLength); assert i - 1 == FBUtilities.byteArrayToInt(context, offset); assert 1L == FBUtilities.byteArrayToLong(context, offset + idLength); } } @Test public void testSwapElement() { byte[] context = new byte[HEADER_LENGTH + (stepLength * 3)]; for (int i = 0; i < 3; i++) { icc.writeElementAtStepOffset(context, i, FBUtilities.toByteArray(i), 1L); } icc.swapElement(context, HEADER_LENGTH, HEADER_LENGTH + (2 * stepLength)); assert 2 == FBUtilities.byteArrayToInt(context, HEADER_LENGTH); assert 0 == FBUtilities.byteArrayToInt(context, HEADER_LENGTH + (2 * stepLength)); icc.swapElement(context, HEADER_LENGTH, HEADER_LENGTH + (1 * stepLength)); assert 1 == FBUtilities.byteArrayToInt(context, HEADER_LENGTH); assert 2 == FBUtilities.byteArrayToInt(context, HEADER_LENGTH + (1 * stepLength)); } @Test public void testPartitionElements() { byte[] context = new byte[HEADER_LENGTH + stepLength * 10]; icc.writeElementAtStepOffset(context, 0, FBUtilities.toByteArray(5), 1L); icc.writeElementAtStepOffset(context, 1, FBUtilities.toByteArray(3), 1L); icc.writeElementAtStepOffset(context, 2, FBUtilities.toByteArray(6), 1L); icc.writeElementAtStepOffset(context, 3, FBUtilities.toByteArray(7), 1L); icc.writeElementAtStepOffset(context, 4, FBUtilities.toByteArray(8), 1L); icc.writeElementAtStepOffset(context, 5, FBUtilities.toByteArray(9), 1L); icc.writeElementAtStepOffset(context, 6, FBUtilities.toByteArray(2), 1L); icc.writeElementAtStepOffset(context, 7, FBUtilities.toByteArray(4), 1L); icc.writeElementAtStepOffset(context, 8, FBUtilities.toByteArray(1), 1L); icc.writeElementAtStepOffset(context, 9, FBUtilities.toByteArray(3), 1L); icc.partitionElements(context, 0, // left 9, // right (inclusive) 2 // pivot ); assert 5 == FBUtilities.byteArrayToInt(context, HEADER_LENGTH + 0 * stepLength); assert 3 == FBUtilities.byteArrayToInt(context, HEADER_LENGTH + 1 * stepLength); assert 3 == FBUtilities.byteArrayToInt(context, HEADER_LENGTH + 2 * stepLength); assert 2 == FBUtilities.byteArrayToInt(context, HEADER_LENGTH + 3 * stepLength); assert 4 == FBUtilities.byteArrayToInt(context, HEADER_LENGTH + 4 * stepLength); assert 1 == FBUtilities.byteArrayToInt(context, HEADER_LENGTH + 5 * stepLength); assert 6 == FBUtilities.byteArrayToInt(context, HEADER_LENGTH + 6 * stepLength); assert 8 == FBUtilities.byteArrayToInt(context, HEADER_LENGTH + 7 * stepLength); assert 9 == FBUtilities.byteArrayToInt(context, HEADER_LENGTH + 8 * stepLength); assert 7 == FBUtilities.byteArrayToInt(context, HEADER_LENGTH + 9 * stepLength); } @Test public void testSortElementsById() { byte[] context = new byte[HEADER_LENGTH + (stepLength * 10)]; icc.writeElementAtStepOffset(context, 0, FBUtilities.toByteArray(5), 1L); icc.writeElementAtStepOffset(context, 1, FBUtilities.toByteArray(3), 1L); icc.writeElementAtStepOffset(context, 2, FBUtilities.toByteArray(6), 1L); icc.writeElementAtStepOffset(context, 3, FBUtilities.toByteArray(7), 1L); icc.writeElementAtStepOffset(context, 4, FBUtilities.toByteArray(8), 1L); icc.writeElementAtStepOffset(context, 5, FBUtilities.toByteArray(9), 1L); icc.writeElementAtStepOffset(context, 6, FBUtilities.toByteArray(2), 1L); icc.writeElementAtStepOffset(context, 7, FBUtilities.toByteArray(4), 1L); icc.writeElementAtStepOffset(context, 8, FBUtilities.toByteArray(1), 1L); icc.writeElementAtStepOffset(context, 9, FBUtilities.toByteArray(3), 1L); byte[] sorted = icc.sortElementsById(context); assert 1 == FBUtilities.byteArrayToInt(sorted, HEADER_LENGTH + 0 * stepLength); assert 2 == FBUtilities.byteArrayToInt(sorted, HEADER_LENGTH + 1 * stepLength); assert 3 == FBUtilities.byteArrayToInt(sorted, HEADER_LENGTH + 2 * stepLength); assert 3 == FBUtilities.byteArrayToInt(sorted, HEADER_LENGTH + 3 * stepLength); assert 4 == FBUtilities.byteArrayToInt(sorted, HEADER_LENGTH + 4 * stepLength); assert 5 == FBUtilities.byteArrayToInt(sorted, HEADER_LENGTH + 5 * stepLength); assert 6 == FBUtilities.byteArrayToInt(sorted, HEADER_LENGTH + 6 * stepLength); assert 7 == FBUtilities.byteArrayToInt(sorted, HEADER_LENGTH + 7 * stepLength); assert 8 == FBUtilities.byteArrayToInt(sorted, HEADER_LENGTH + 8 * stepLength); assert 9 == FBUtilities.byteArrayToInt(sorted, HEADER_LENGTH + 9 * stepLength); } @Test public void testCompare() { byte[] left; byte[] right; // equality: // left: no local timestamp // right: no local timestamp left = Util.concatByteArrays(FBUtilities.toByteArray(1L), FBUtilities.toByteArray(0L)); right = Util.concatByteArrays(FBUtilities.toByteArray(1L), FBUtilities.toByteArray(0L)); assert ClockRelationship.EQUAL == icc.compare(left, right); // equality: // left, right: local timestamps equal left = Util.concatByteArrays(FBUtilities.toByteArray(9L), FBUtilities.toByteArray(0L), FBUtilities.getLocalAddress().getAddress(), FBUtilities.toByteArray(32L), FBUtilities.toByteArray(1), FBUtilities.toByteArray(4L), FBUtilities.toByteArray(3), FBUtilities.toByteArray(2L)); right = Util.concatByteArrays(FBUtilities.toByteArray(9L), FBUtilities.toByteArray(0L), FBUtilities.getLocalAddress().getAddress(), FBUtilities.toByteArray(2L), FBUtilities.toByteArray(3), FBUtilities.toByteArray(9L), FBUtilities.toByteArray(2), FBUtilities.toByteArray(1L)); assert ClockRelationship.EQUAL == icc.compare(left, right); // greater than: // left: local timestamp // right: no local timestamp left = Util.concatByteArrays(FBUtilities.toByteArray(9L), FBUtilities.toByteArray(0L), FBUtilities.getLocalAddress().getAddress(), FBUtilities.toByteArray(32L), FBUtilities.toByteArray(1), FBUtilities.toByteArray(4L), FBUtilities.toByteArray(3), FBUtilities.toByteArray(2L)); right = Util.concatByteArrays(FBUtilities.toByteArray(4L), FBUtilities.toByteArray(0L), FBUtilities.toByteArray(3), FBUtilities.toByteArray(9L), FBUtilities.toByteArray(2), FBUtilities.toByteArray(1L)); assert ClockRelationship.GREATER_THAN == icc.compare(left, right); // greater than: // left's local timestamp > right's local timestamp left = Util.concatByteArrays(FBUtilities.toByteArray(11L), FBUtilities.toByteArray(0L), FBUtilities.getLocalAddress().getAddress(), FBUtilities.toByteArray(32L), FBUtilities.toByteArray(1), FBUtilities.toByteArray(4L), FBUtilities.toByteArray(3), FBUtilities.toByteArray(2L)); right = Util.concatByteArrays(FBUtilities.toByteArray(9L), FBUtilities.toByteArray(0L), FBUtilities.getLocalAddress().getAddress(), FBUtilities.toByteArray(2L), FBUtilities.toByteArray(3), FBUtilities.toByteArray(9L), FBUtilities.toByteArray(2), FBUtilities.toByteArray(1L)); assert ClockRelationship.GREATER_THAN == icc.compare(left, right); // less than: // left: no local timestamp // right: local timestamp left = Util.concatByteArrays(FBUtilities.toByteArray(7L), FBUtilities.toByteArray(0L), FBUtilities.toByteArray(1), FBUtilities.toByteArray(4L), FBUtilities.toByteArray(3), FBUtilities.toByteArray(2L)); right = Util.concatByteArrays(FBUtilities.toByteArray(9L), FBUtilities.toByteArray(0L), FBUtilities.getLocalAddress().getAddress(), FBUtilities.toByteArray(2L), FBUtilities.toByteArray(3), FBUtilities.toByteArray(9L), FBUtilities.toByteArray(2), FBUtilities.toByteArray(1L)); assert ClockRelationship.LESS_THAN == icc.compare(left, right); // less than: // left's local timestamp < right's local timestamp left = Util.concatByteArrays(FBUtilities.toByteArray(9L), FBUtilities.toByteArray(0L), FBUtilities.getLocalAddress().getAddress(), FBUtilities.toByteArray(32L), FBUtilities.toByteArray(1), FBUtilities.toByteArray(4L), FBUtilities.toByteArray(3), FBUtilities.toByteArray(2L)); right = Util.concatByteArrays(FBUtilities.toByteArray(122L), FBUtilities.toByteArray(0L), FBUtilities.getLocalAddress().getAddress(), FBUtilities.toByteArray(2L), FBUtilities.toByteArray(3), FBUtilities.toByteArray(9L), FBUtilities.toByteArray(2), FBUtilities.toByteArray(1L)); assert ClockRelationship.LESS_THAN == icc.compare(left, right); } @Test public void testDiff() { byte[] left = new byte[HEADER_LENGTH + (3 * stepLength)]; byte[] right; // equality: equal nodes, all counts same icc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 3L); icc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(6), 2L); icc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 1L); right = ArrayUtils.clone(left); assert ClockRelationship.EQUAL == icc.diff(left, right); // greater than: left has superset of nodes (counts equal) left = new byte[HEADER_LENGTH + (4 * stepLength)]; icc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 3L); icc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(6), 2L); icc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 1L); icc.writeElementAtStepOffset(left, 3, FBUtilities.toByteArray(12), 0L); right = new byte[HEADER_LENGTH + (3 * stepLength)]; icc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(3), 3L); icc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 2L); icc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(9), 1L); assert ClockRelationship.GREATER_THAN == icc.diff(left, right); // less than: left has subset of nodes (counts equal) left = new byte[HEADER_LENGTH + (3 * stepLength)]; icc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 3L); icc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(6), 2L); icc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 1L); right = new byte[HEADER_LENGTH + (4 * stepLength)]; icc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(3), 3L); icc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 2L); icc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(9), 1L); icc.writeElementAtStepOffset(right, 3, FBUtilities.toByteArray(12), 0L); assert ClockRelationship.LESS_THAN == icc.diff(left, right); // greater than: equal nodes, but left has higher counts left = new byte[HEADER_LENGTH + (3 * stepLength)]; icc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 3L); icc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(6), 2L); icc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 3L); right = new byte[HEADER_LENGTH + (3 * stepLength)]; icc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(3), 3L); icc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 2L); icc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(9), 1L); assert ClockRelationship.GREATER_THAN == icc.diff(left, right); // less than: equal nodes, but right has higher counts left = new byte[HEADER_LENGTH + (3 * stepLength)]; icc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 3L); icc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(6), 2L); icc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 3L); right = new byte[HEADER_LENGTH + (3 * stepLength)]; icc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(3), 3L); icc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 9L); icc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(9), 3L); assert ClockRelationship.LESS_THAN == icc.diff(left, right); // disjoint: right and left have disjoint node sets left = new byte[HEADER_LENGTH + (3 * stepLength)]; icc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 1L); icc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(4), 1L); icc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 1L); right = new byte[HEADER_LENGTH + (3 * stepLength)]; icc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(3), 1L); icc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 1L); icc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(9), 1L); assert ClockRelationship.DISJOINT == icc.diff(left, right); left = new byte[HEADER_LENGTH + (3 * stepLength)]; icc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 1L); icc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(4), 1L); icc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 1L); right = new byte[HEADER_LENGTH + (3 * stepLength)]; icc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(2), 1L); icc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 1L); icc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(12), 1L); assert ClockRelationship.DISJOINT == icc.diff(left, right); // disjoint: equal nodes, but right and left have higher counts in differing nodes left = new byte[HEADER_LENGTH + (3 * stepLength)]; icc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 1L); icc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(6), 3L); icc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 1L); right = new byte[HEADER_LENGTH + (3 * stepLength)]; icc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(3), 1L); icc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 1L); icc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(9), 5L); assert ClockRelationship.DISJOINT == icc.diff(left, right); left = new byte[HEADER_LENGTH + (3 * stepLength)]; icc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 2L); icc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(6), 3L); icc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 1L); right = new byte[HEADER_LENGTH + (3 * stepLength)]; icc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(3), 1L); icc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 9L); icc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(9), 5L); assert ClockRelationship.DISJOINT == icc.diff(left, right); // disjoint: left has more nodes, but lower counts left = new byte[HEADER_LENGTH + (4 * stepLength)]; icc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 2L); icc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(6), 3L); icc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 1L); icc.writeElementAtStepOffset(left, 3, FBUtilities.toByteArray(12), 1L); right = new byte[HEADER_LENGTH + (3 * stepLength)]; icc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(3), 4L); icc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 9L); icc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(9), 5L); assert ClockRelationship.DISJOINT == icc.diff(left, right); // disjoint: left has less nodes, but higher counts left = new byte[HEADER_LENGTH + (3 * stepLength)]; icc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 5L); icc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(6), 3L); icc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 2L); right = new byte[HEADER_LENGTH + (4 * stepLength)]; icc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(3), 4L); icc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 3L); icc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(9), 2L); icc.writeElementAtStepOffset(right, 3, FBUtilities.toByteArray(12), 1L); assert ClockRelationship.DISJOINT == icc.diff(left, right); // disjoint: mixed nodes and counts left = new byte[HEADER_LENGTH + (3 * stepLength)]; icc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 5L); icc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(6), 2L); icc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 2L); right = new byte[HEADER_LENGTH + (4 * stepLength)]; icc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(3), 4L); icc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 3L); icc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(9), 2L); icc.writeElementAtStepOffset(right, 3, FBUtilities.toByteArray(12), 1L); assert ClockRelationship.DISJOINT == icc.diff(left, right); left = new byte[HEADER_LENGTH + (4 * stepLength)]; icc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 5L); icc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(6), 2L); icc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(7), 2L); icc.writeElementAtStepOffset(left, 3, FBUtilities.toByteArray(9), 2L); right = new byte[HEADER_LENGTH + (3 * stepLength)]; icc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(3), 4L); icc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 3L); icc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(9), 2L); assert ClockRelationship.DISJOINT == icc.diff(left, right); } @Test public void testMerge() { // note: local counts aggregated; remote counts are reconciled (i.e. take max) List<byte[]> contexts = new ArrayList<byte[]>(); byte[] bytes = new byte[HEADER_LENGTH + (4 * stepLength)]; icc.writeElementAtStepOffset(bytes, 0, FBUtilities.toByteArray(1), 1L); icc.writeElementAtStepOffset(bytes, 1, FBUtilities.toByteArray(2), 2L); icc.writeElementAtStepOffset(bytes, 2, FBUtilities.toByteArray(4), 3L); icc.writeElementAtStepOffset(bytes, 3, FBUtilities.getLocalAddress().getAddress(), 3L); contexts.add(bytes); bytes = new byte[HEADER_LENGTH + (3 * stepLength)]; icc.writeElementAtStepOffset(bytes, 2, FBUtilities.toByteArray(5), 5L); icc.writeElementAtStepOffset(bytes, 1, FBUtilities.toByteArray(4), 4L); icc.writeElementAtStepOffset(bytes, 0, FBUtilities.getLocalAddress().getAddress(), 9L); contexts.add(bytes); byte[] merged = icc.merge(contexts); // local node id's counts are aggregated assert 0 == FBUtilities.compareByteSubArrays(FBUtilities.getLocalAddress().getAddress(), 0, merged, HEADER_LENGTH + 0 * stepLength, 4); assert 12L == FBUtilities.byteArrayToLong(merged, HEADER_LENGTH + 0 * stepLength + idLength); // remote node id counts are reconciled (i.e. take max) assert 5 == FBUtilities.byteArrayToInt(merged, HEADER_LENGTH + 1 * stepLength); assert 5L == FBUtilities.byteArrayToLong(merged, HEADER_LENGTH + 1 * stepLength + idLength); assert 4 == FBUtilities.byteArrayToInt(merged, HEADER_LENGTH + 2 * stepLength); assert 4L == FBUtilities.byteArrayToLong(merged, HEADER_LENGTH + 2 * stepLength + idLength); assert 2 == FBUtilities.byteArrayToInt(merged, HEADER_LENGTH + 3 * stepLength); assert 2L == FBUtilities.byteArrayToLong(merged, HEADER_LENGTH + 3 * stepLength + idLength); assert 1 == FBUtilities.byteArrayToInt(merged, HEADER_LENGTH + 4 * stepLength); assert 1L == FBUtilities.byteArrayToLong(merged, HEADER_LENGTH + 4 * stepLength + idLength); } @Test public void testTotal() { List<byte[]> contexts = new ArrayList<byte[]>(); byte[] bytes = new byte[HEADER_LENGTH + (4 * stepLength)]; icc.writeElementAtStepOffset(bytes, 0, FBUtilities.toByteArray(1), 1L); icc.writeElementAtStepOffset(bytes, 1, FBUtilities.toByteArray(2), 2L); icc.writeElementAtStepOffset(bytes, 2, FBUtilities.toByteArray(4), 3L); icc.writeElementAtStepOffset(bytes, 3, FBUtilities.getLocalAddress().getAddress(), 3L); contexts.add(bytes); bytes = new byte[HEADER_LENGTH + (3 * stepLength)]; icc.writeElementAtStepOffset(bytes, 2, FBUtilities.toByteArray(5), 5L); icc.writeElementAtStepOffset(bytes, 1, FBUtilities.toByteArray(4), 4L); icc.writeElementAtStepOffset(bytes, 0, FBUtilities.getLocalAddress().getAddress(), 9L); contexts.add(bytes); byte[] merged = icc.merge(contexts); // 127.0.0.1: 12 (3+9) // 0.0.0.1: 1 // 0.0.0.2: 2 // 0.0.0.4: 4 // 0.0.0.5: 5 assert 24L == FBUtilities.byteArrayToLong(icc.total(merged)); } @Test public void testCleanNodeCounts() throws UnknownHostException { byte[] bytes = new byte[HEADER_LENGTH + (4 * stepLength)]; icc.writeElementAtStepOffset(bytes, 0, FBUtilities.toByteArray(1), 1L); icc.writeElementAtStepOffset(bytes, 1, FBUtilities.toByteArray(2), 2L); icc.writeElementAtStepOffset(bytes, 2, FBUtilities.toByteArray(4), 3L); icc.writeElementAtStepOffset(bytes, 3, FBUtilities.toByteArray(8), 4L); assert 4 == FBUtilities.byteArrayToInt(bytes, HEADER_LENGTH + 2 * stepLength); assert 3L == FBUtilities.byteArrayToLong(bytes, HEADER_LENGTH + 2 * stepLength + idLength); bytes = icc.cleanNodeCounts(bytes, InetAddress.getByAddress(FBUtilities.toByteArray(4))); // node: 0.0.0.4 should be removed assert (HEADER_LENGTH + (3 * stepLength)) == bytes.length; // other nodes should be unaffected assert 1 == FBUtilities.byteArrayToInt(bytes, HEADER_LENGTH + 0 * stepLength); assert 1L == FBUtilities.byteArrayToLong(bytes, HEADER_LENGTH + 0 * stepLength + idLength); assert 2 == FBUtilities.byteArrayToInt(bytes, HEADER_LENGTH + 1 * stepLength); assert 2L == FBUtilities.byteArrayToLong(bytes, HEADER_LENGTH + 1 * stepLength + idLength); assert 8 == FBUtilities.byteArrayToInt(bytes, HEADER_LENGTH + 2 * stepLength); assert 4L == FBUtilities.byteArrayToLong(bytes, HEADER_LENGTH + 2 * stepLength + idLength); } }