Java tutorial
// Copyright 2017 JanusGraph Authors // // 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 org.janusgraph.graphdb.idmanagement; import com.google.common.base.Preconditions; import org.janusgraph.diskstorage.ReadBuffer; import org.janusgraph.diskstorage.StaticBuffer; import org.janusgraph.diskstorage.WriteBuffer; import org.janusgraph.diskstorage.util.WriteByteBuffer; import org.janusgraph.graphdb.database.idhandling.VariableLong; import org.janusgraph.testutil.RandomGenerator; import org.apache.commons.lang.time.StopWatch; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Random; import static org.junit.Assert.assertEquals; /** * @author Matthias Broecheler (me@matthiasb.com) */ public class VariableLongTest { private static final Logger log = LoggerFactory.getLogger(VariableLongTest.class); private void readWriteTest(final ReadWriteLong impl, long maxValue, long jump, boolean negative, boolean backward) { Preconditions.checkArgument(maxValue % jump == 0); long allocate = maxValue / jump * 8 * (negative ? 2 : 1); Preconditions.checkArgument(allocate < (1 << 28)); WriteBuffer wb = new WriteByteBuffer((int) allocate); int num = 0; StopWatch w = new StopWatch(); w.start(); for (long i = (negative ? -maxValue : 0); i <= maxValue; i += jump) { impl.write(wb, i); num++; } //for (int i=0;i<b.remaining();i++) System.out.print(b.get(i)+"|"); w.stop(); ReadBuffer rb = wb.getStaticBuffer().asReadBuffer(); log.info("Writing " + num + " longs in " + rb.length() + " bytes. in time: " + w.getTime()); final ReadVerify read = new ReadVerify() { @Override public void next(ReadBuffer rb, long expected) { int beforePos = rb.getPosition(); long value = impl.read(rb); assertEquals(expected, value); int length = Math.abs(rb.getPosition() - beforePos); assertEquals("On: " + expected, length, impl.length(expected)); } }; if (backward) { rb.movePositionTo(rb.length()); for (long i = maxValue; i != (negative ? -maxValue : 0); i -= jump) { read.next(rb, i); } } else { for (long i = (negative ? -maxValue : 0); i <= maxValue; i += jump) { read.next(rb, i); } } //Test boundaries wb = new WriteByteBuffer(512); impl.write(wb, 0); impl.write(wb, Long.MAX_VALUE); if (negative) impl.write(wb, -Long.MAX_VALUE); rb = wb.getStaticBuffer().asReadBuffer(); if (backward) { rb.movePositionTo(rb.length()); if (negative) assertEquals(-Long.MAX_VALUE, impl.read(rb)); assertEquals(Long.MAX_VALUE, impl.read(rb)); assertEquals(0, impl.read(rb)); } else { assertEquals(0, impl.read(rb)); assertEquals(Long.MAX_VALUE, impl.read(rb)); if (negative) assertEquals(-Long.MAX_VALUE, impl.read(rb)); } } private interface ReadVerify { public void next(ReadBuffer rb, long expected); } public void positiveReadWriteTest(ReadWriteLong impl, long maxValue, long jump) { readWriteTest(impl, maxValue, jump, false, false); } public void negativeReadWriteTest(ReadWriteLong impl, long maxValue, long jump) { readWriteTest(impl, maxValue, jump, true, false); } @Test public void testPositiveWriteBig() { positiveReadWriteTest(new PositiveReadWrite(), 10000000000000L, 1000000L); } @Test public void testPositiveWriteSmall() { positiveReadWriteTest(new PositiveReadWrite(), 1000000, 1); } @Test public void testNegativeWriteBig() { negativeReadWriteTest(new NegativeReadWrite(), 1000000000000L, 1000000L); } @Test public void testNegativeWriteSmall() { negativeReadWriteTest(new NegativeReadWrite(), 1000000, 1); } @Test public void testPosBackwardWriteBig() { readWriteTest(new PosBackwardReadWrite(), 10000000000000L, 1000000L, false, true); } @Test public void testPosBackwardWriteSmall() { readWriteTest(new PosBackwardReadWrite(), 1000000, 1, false, true); } @Test public void testBackwardWriteBig() { readWriteTest(new BackwardReadWrite(), 10000000000000L, 10000000L, true, true); } @Test public void testBackwardWriteSmall() { readWriteTest(new BackwardReadWrite(), 1000000, 1, true, true); } @Test public void testPrefix1WriteBig() { positiveReadWriteTest(new PrefixReadWrite(3, 4), 1000000000000L, 1000000L); } @Test public void testPrefix2WriteTiny() { positiveReadWriteTest(new PrefixReadWrite(2, 1), 130, 1); } @Test public void testPrefix2WriteSmall() { positiveReadWriteTest(new PrefixReadWrite(2, 1), 100000, 1); } @Test public void testPrefix3WriteSmall() { positiveReadWriteTest(new PrefixReadWrite(2, 0), 100000, 1); } public interface ReadWriteLong { public void write(WriteBuffer out, long value); public int length(long value); public long read(ReadBuffer in); } public static class PositiveReadWrite implements ReadWriteLong { @Override public void write(WriteBuffer out, long value) { VariableLong.writePositive(out, value); } @Override public int length(long value) { return VariableLong.positiveLength(value); } @Override public long read(ReadBuffer in) { return VariableLong.readPositive(in); } } public static class NegativeReadWrite implements ReadWriteLong { @Override public void write(WriteBuffer out, long value) { VariableLong.write(out, value); } @Override public int length(long value) { return VariableLong.length(value); } @Override public long read(ReadBuffer in) { return VariableLong.read(in); } } public static class PosBackwardReadWrite implements ReadWriteLong { @Override public void write(WriteBuffer out, long value) { VariableLong.writePositiveBackward(out, value); } @Override public int length(long value) { return VariableLong.positiveBackwardLength(value); } @Override public long read(ReadBuffer in) { return VariableLong.readPositiveBackward(in); } } public static class BackwardReadWrite implements ReadWriteLong { @Override public void write(WriteBuffer out, long value) { VariableLong.writeBackward(out, value); } @Override public int length(long value) { return VariableLong.backwardLength(value); } @Override public long read(ReadBuffer in) { return VariableLong.readBackward(in); } } public static class PrefixReadWrite implements ReadWriteLong { private final int prefixLen; private final int prefix; public PrefixReadWrite(int prefixLen, int prefix) { Preconditions.checkArgument(prefixLen > 0); Preconditions.checkArgument(prefix >= 0 && prefix < (1 << prefixLen)); this.prefixLen = prefixLen; this.prefix = prefix; } @Override public void write(WriteBuffer out, long value) { VariableLong.writePositiveWithPrefix(out, value, prefix, prefixLen); } @Override public int length(long value) { return VariableLong.positiveWithPrefixLength(value, prefixLen); } @Override public long read(ReadBuffer in) { long[] result = VariableLong.readPositiveWithPrefix(in, prefixLen); assertEquals(prefix, result[1]); return result[0]; } } @Test public void byteOrderPreservingPositiveBackward() { long[] scalingFactors = { Long.MAX_VALUE, 1000, 1000000000l }; for (int t = 0; t < 10000000; t++) { StaticBuffer[] b = new StaticBuffer[2]; long[] l = new long[2]; for (int i = 0; i < 2; i++) { l[i] = randomPosLong(scalingFactors[random.nextInt(scalingFactors.length)]); WriteBuffer out = new WriteByteBuffer(11); VariableLong.writePositiveBackward(out, l[i]); b[i] = out.getStaticBuffer(); ReadBuffer res = b[i].asReadBuffer(); res.movePositionTo(res.length()); assertEquals(l[i], VariableLong.readPositiveBackward(res)); } // System.out.println(l[0] + " vs " + l[1]); assertEquals(Math.signum(Long.compare(l[0], l[1])), Math.signum(b[0].compareTo(b[1])), 0.01); } } private static final Random random = new Random(); public static long randomPosLong(long scaling) { long l = Math.round(random.nextGaussian() / 3 * scaling); if (l < 0) l = Math.abs(l + 1); assert l >= 0; return l; } }