org.janusgraph.graphdb.idmanagement.VariableLongTest.java Source code

Java tutorial

Introduction

Here is the source code for org.janusgraph.graphdb.idmanagement.VariableLongTest.java

Source

// 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;
    }

}