/*
* Copyright 2012, Facebook, Inc.
*
* 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.
*/
package com.facebook.LinkBench;
import java.util.Arrays;
import org.junit.Test;
import junit.framework.TestCase;
/**
* Check that the shuffler obeys expected invariants
*/
public class InvertibleShufflerTest extends TestCase {
@Test
public void testShuffleSmallRange() {
long seed = 1234;
testShuffle(0, 10, true, seed, 1);
testShuffle(0, 4, true, seed, 2);
testShuffle(0, 10, true, seed, 5);
testShuffle(0, 7, true, seed, 3);
testShuffle(0, 10, true, seed, 7);
testShuffle(0, 10, true, seed, 11);
testShuffle(0, 10, true, seed, 15);
testShuffle(0, 100, true, seed, 11);
}
@Test
public void testShuffleMedRange() {
testShuffle(512, 10543, false, 13, 7);
testShuffle(512, 10543, false, 13, 7, 27, 140);
}
@Test
public void testShuffleLargeRange() {
testShuffle(12345, 123456, false, 13, 7, 27, 140);
}
/**
* Check that result is a valid permutation (i.e. a 1->1 mapping)
* @param minId
* @param maxId
* @param params
*/
public static void testShuffle(int minId, int maxId, boolean print,
long... params) {
String shuffleDesc = String.format(
"Permuting range [%d,%d) with params %s", minId, maxId,
Arrays.toString(params));
if (print) {
System.err.println(shuffleDesc);
}
int n = maxId - minId;
//ProbDistShuffler shuf = new ProbDistShuffler(params[0], (int)params[1], n);
InvertibleShuffler shuf = new InvertibleShuffler(params[0], (int)params[1], n);
long reverse[] = new long[n]; // Store the reverse permutation
// Store if ID has appeared (inited to false)
boolean exists[] = new boolean[n];
for (int i = minId; i < maxId; i++) {
//long lj = Shuffler.getPermutationValue(i, minId, maxId, params);
long lj = minId + shuf.permute(i - minId);
assertEquals(i, minId + shuf.invertPermute(lj - minId));
if (lj < minId || lj >= maxId) {
fail(String.format("Error with test %s, permutation result p(%d) = %d"
+ " out of range [%d, %d)", shuffleDesc, i, lj, minId, maxId));
}
assertTrue(lj >= minId);
assertTrue(lj < maxId);
int j = (int)lj; // Must be in integer range
if (exists[j - minId]) {
fail(String.format(
"Error with test %s: collision. p(%d) = p(%d) = %d",
shuffleDesc, i, reverse[j - minId], j));
}
reverse[j - minId] = i;
exists[j - minId] = true;
if (print) {
System.err.print(" " + j);
}
}
if (print) {
System.err.println();
}
/* If we made it to here there were no collisions and we know all
* n ids appeared in the permutation */
}
}