com.unister.semweb.drums.api.DRUMSTest.java Source code

Java tutorial

Introduction

Here is the source code for com.unister.semweb.drums.api.DRUMSTest.java

Source

/*
 * Copyright (C) 2012-2013 Unister GmbH
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
package com.unister.semweb.drums.api;

import static org.junit.Assert.assertEquals;

import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.unister.semweb.drums.TestUtils;
import com.unister.semweb.drums.bucket.hashfunction.AbstractHashFunction;
import com.unister.semweb.drums.bucket.hashfunction.RangeHashFunction;
import com.unister.semweb.drums.storable.DummyKVStorable;
import com.unister.semweb.drums.util.AbstractKVStorableComparator;
import com.unister.semweb.drums.util.Bytes;
import com.unister.semweb.drums.util.KeyUtils;

/** Tests the DRUMS API. */
public class DRUMSTest {
    private static final Logger log = LoggerFactory.getLogger(DRUMSTest.class);
    private AbstractHashFunction hashFunction;

    @Before
    public void initialise() throws Exception {
        System.gc(); // needed, that files are deletable under windows
        long[] ranges = new long[] { 0, 10, 20, 30 };
        byte[][] bRanges = KeyUtils.toByteArray(ranges);
        String[] filenames = new String[] { "1.db", "2.db", "3.db", "4.db" };
        FileUtils.deleteQuietly(new File(TestUtils.gp.DATABASE_DIRECTORY));
        hashFunction = new RangeHashFunction(bRanges, filenames, "/tmp/hash.hs");
        System.gc();
    }

    /**
     * This method is for testing the binary search in DRUMS.findElementInReadBuffer()
     * 
     * @throws IOException
     * @throws ClassNotFoundException
     */
    @Test
    public void findElementInReadBufferTest() throws IOException, ClassNotFoundException {
        log.info("Test Binary search. findElementInReadBufferTest()");
        DRUMS<DummyKVStorable> table = DRUMSInstantiator.createOrOpenTable(hashFunction, TestUtils.gp);
        // create data
        DummyKVStorable d1 = DummyKVStorable.getInstance();
        d1.setKey(new byte[] { 0, 0, 0, 0, 0, 0, 0, 1 });
        DummyKVStorable d2 = DummyKVStorable.getInstance();
        d2.setKey(new byte[] { 0, 0, 0, 0, 0, 0, 0, 2 });
        DummyKVStorable d3 = DummyKVStorable.getInstance();
        d3.setKey(new byte[] { 0, 0, 0, 0, 0, 0, 0, 3 });
        ByteBuffer bb = ByteBuffer.allocate(3 * TestUtils.gp.getElementSize());
        bb.put(d1.toByteBuffer().array());
        bb.put(d2.toByteBuffer().array());
        bb.put(d3.toByteBuffer().array());

        Assert.assertEquals(-1, table.findElementInReadBuffer(bb, new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, 0));
        Assert.assertEquals(0, table.findElementInReadBuffer(bb, new byte[] { 0, 0, 0, 0, 0, 0, 0, 1 }, 0));
        Assert.assertEquals(1 * TestUtils.gp.getElementSize(),
                table.findElementInReadBuffer(bb, new byte[] { 0, 0, 0, 0, 0, 0, 0, 2 }, 0));
        Assert.assertEquals(2 * TestUtils.gp.getElementSize(),
                table.findElementInReadBuffer(bb, new byte[] { 0, 0, 0, 0, 0, 0, 0, 3 }, 0));
        Assert.assertEquals(2 * TestUtils.gp.getElementSize(), table.findElementInReadBuffer(bb,
                new byte[] { 0, 0, 0, 0, 0, 0, 0, 3 }, 1 * TestUtils.gp.getElementSize()));
        Assert.assertEquals(2 * TestUtils.gp.getElementSize(), table.findElementInReadBuffer(bb,
                new byte[] { 0, 0, 0, 0, 0, 0, 0, 3 }, 2 * TestUtils.gp.getElementSize()));
        Assert.assertEquals(-1, table.findElementInReadBuffer(bb, new byte[] { 0, 0, 0, 0, 0, 0, 0, 3 },
                3 * TestUtils.gp.getElementSize()));
    }

    /**
     * Creates a table and inserts 10 elements. After that the file in which the data should be written are read and the
     * data is compared with the generated data.
     */
    @Test
    public void createTableAndInsertTest() throws Exception {
        log.info("Test simple write to one Bucket. createTableAndInsertTest()");
        // Adding elements to the drum.
        DummyKVStorable[] test = TestUtils.createDummyData(10);
        DRUMS<DummyKVStorable> table = DRUMSInstantiator.createTable(hashFunction, TestUtils.gp);
        table.insertOrMerge(test);
        table.close();
        List<DummyKVStorable> readData = TestUtils.readFrom(TestUtils.gp.DATABASE_DIRECTORY + "/2.db", 10);
        Assert.assertArrayEquals(test, readData.toArray(new DummyKVStorable[readData.size()]));
    }

    /**
     * Adds {@link DummyKVStorable}s to different Buckets.
     * 
     * @throws Exception
     */
    @Test
    public void insertDifferentRanges() throws Exception {
        log.info("Test extended write to different Buckets. createTableAndInsertTest()");
        DummyKVStorable bucket2_el1 = TestUtils.createDummyData(Bytes.toBytes(5l), 1, 0.5);
        DummyKVStorable bucket2_el2 = TestUtils.createDummyData(Bytes.toBytes(10l), 12, 0.3);
        DummyKVStorable bucket4_el1 = TestUtils.createDummyData(Bytes.toBytes(29l), 9, 0.23);
        DummyKVStorable bucket4_el2 = TestUtils.createDummyData(Bytes.toBytes(30l), 9, 0.23);

        DummyKVStorable[] toAdd = new DummyKVStorable[] { bucket2_el1, bucket2_el2, bucket4_el1, bucket4_el2 };

        DRUMS<DummyKVStorable> table = DRUMSInstantiator.createTable(hashFunction, TestUtils.gp);
        table.insertOrMerge(toAdd);
        table.close();

        List<DummyKVStorable> db2 = TestUtils.readFrom(TestUtils.gp.DATABASE_DIRECTORY + "/2.db", 1000);
        List<DummyKVStorable> db4 = TestUtils.readFrom(TestUtils.gp.DATABASE_DIRECTORY + "/4.db", 1000);

        assertEquals(2, db2.size());
        assertEquals(bucket2_el1, db2.get(0));
        assertEquals(bucket2_el2, db2.get(1));
        assertEquals(2, db4.size());
        assertEquals(bucket4_el1, db4.get(0));
        assertEquals(bucket4_el2, db4.get(1));
    }

    /**
     * Adds one element to the DRUM and select this element.
     * 
     * @throws Exception
     */
    @Test
    public void selectTestSingleElement() throws Exception {
        DummyKVStorable data = TestUtils.createDummyData(Bytes.toBytes(1l), 1, 0.23);
        DummyKVStorable[] toAdd = new DummyKVStorable[] { data };

        DRUMS<DummyKVStorable> table = DRUMSInstantiator.createTable(hashFunction, TestUtils.gp);
        table.insertOrMerge(toAdd);
        table.close();

        List<DummyKVStorable> selectedData = table.select(Bytes.toBytes(1l));

        Assert.assertEquals(1, selectedData.size());
        Assert.assertEquals(data, selectedData.get(0));
    }

    /**
     * Add elements from different ranges to the DRUMS and select these elements.
     * 
     * @throws Exception
     */
    @Test
    public void selectTestSeveralRanges() throws Exception {
        DummyKVStorable firstRange = TestUtils.createDummyData(Bytes.toBytes(2l), 2, 0.24);
        DummyKVStorable secondRange = TestUtils.createDummyData(Bytes.toBytes(10l), 10, 0.23);
        DummyKVStorable thirdRange = TestUtils.createDummyData(Bytes.toBytes(12l), 19, 0.29);
        DummyKVStorable[] toAdd = new DummyKVStorable[] { firstRange, secondRange, thirdRange };

        DRUMS<DummyKVStorable> table = DRUMSInstantiator.createTable(hashFunction, TestUtils.gp);
        table.insertOrMerge(toAdd);
        table.close();

        List<DummyKVStorable> selectedData = table.select(Bytes.toBytes(12l), Bytes.toBytes(10l),
                Bytes.toBytes(2l));

        DummyKVStorable[] result = selectedData.toArray(new DummyKVStorable[selectedData.size()]);
        Arrays.sort(toAdd, new AbstractKVStorableComparator());
        Arrays.sort(result, new AbstractKVStorableComparator());
        Assert.assertArrayEquals(toAdd, result);
    }

    /**
     * Adds an element to the drum and read it from the right bucket.
     * 
     * @throws Exception
     */
    @Test
    public void readTestSingleElement() throws Exception {
        DummyKVStorable testElement = TestUtils.createDummyData(Bytes.toBytes(1l), 2, 0.23);
        DummyKVStorable[] toAdd = new DummyKVStorable[] { testElement };

        DRUMS<DummyKVStorable> table = DRUMSInstantiator.createTable(hashFunction, TestUtils.gp);
        table.insertOrMerge(toAdd);
        table.close();

        List<DummyKVStorable> selectedData = table.read(1, 0, 10);

        DummyKVStorable[] result = selectedData.toArray(new DummyKVStorable[selectedData.size()]);
        Arrays.sort(toAdd, new AbstractKVStorableComparator());
        Arrays.sort(result, new AbstractKVStorableComparator());
        Assert.assertArrayEquals(toAdd, result);
    }

    /**
     * Writes several elements of the same range to the drum and reads the drum.
     * 
     * @throws Exception
     */
    @Test
    public void readTestSeveralElements() throws Exception {
        DummyKVStorable[] testdata = TestUtils.createDummyData(10);

        DRUMS<DummyKVStorable> table = DRUMSInstantiator.createTable(hashFunction, TestUtils.gp);
        table.insertOrMerge(testdata);
        table.close();

        List<DummyKVStorable> selectedData = table.read(1, 0, 10);

        DummyKVStorable[] result = selectedData.toArray(new DummyKVStorable[selectedData.size()]);
        Arrays.sort(testdata, new AbstractKVStorableComparator());
        Assert.assertArrayEquals(testdata, result);

        List<DummyKVStorable> selectedData2 = table.read(1, 5, 10);
        DummyKVStorable[] result2 = selectedData2.toArray(new DummyKVStorable[selectedData2.size()]);
        Arrays.sort(testdata, new AbstractKVStorableComparator());
        Assert.assertArrayEquals(Arrays.copyOfRange(testdata, 5, 10), result2);
    }

    /** Add test data of different ranges to the DRUM and read the corresponding buckets. */
    @Test
    public void readTestDifferentRanges() throws Exception {
        DummyKVStorable[] testdata = TestUtils.createDummyData(1, 5);
        DummyKVStorable[] secondRange = TestUtils.createDummyData(11, 19);
        DummyKVStorable[] thirdRange = TestUtils.createDummyData(21, 29);

        DummyKVStorable[] completeTestdata = TestUtils.merge(testdata, secondRange, thirdRange);

        DRUMS<DummyKVStorable> table = DRUMSInstantiator.createTable(hashFunction, TestUtils.gp);
        table.insertOrMerge(completeTestdata);
        table.close();

        List<DummyKVStorable> readSecondBucket = table.read(1, 0, 7);
        List<DummyKVStorable> readThirdBucket = table.read(2, 0, 10);
        List<DummyKVStorable> readFourthBucket = table.read(3, 0, 10);

        Assert.assertArrayEquals(testdata, readSecondBucket.toArray(new DummyKVStorable[readSecondBucket.size()]));
        Assert.assertArrayEquals(secondRange, readThirdBucket.toArray(new DummyKVStorable[readThirdBucket.size()]));
        Assert.assertArrayEquals(thirdRange,
                readFourthBucket.toArray(new DummyKVStorable[readFourthBucket.size()]));
    }

    /** Add test data of different ranges to the DRUM and read the corresponding buckets. */
    @Test
    public void testMergeOfOneElement() throws Exception {
        DummyKVStorable date1 = TestUtils.createDummyData(Bytes.toBytes(5l), 1, 0.5);
        DummyKVStorable[] completeTestdata = new DummyKVStorable[] { date1 };

        DRUMS<DummyKVStorable> table = DRUMSInstantiator.createTable(hashFunction, TestUtils.gp);
        table.insertOrMerge(completeTestdata);
        table.close();

        table = DRUMSInstantiator.createOrOpenTable(hashFunction, TestUtils.gp);
        table.insertOrMerge(completeTestdata);
        table.close();
        List<DummyKVStorable> readSecondBucket = table.read(1, 0, 7);

        assertEquals(1, readSecondBucket.size());
        assertEquals(2, readSecondBucket.get(0).getValueAsInt("parentCount"));
    }
}