com.unister.semweb.drums.file.EnlargeFileTest.java Source code

Java tutorial

Introduction

Here is the source code for com.unister.semweb.drums.file.EnlargeFileTest.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.file;

import java.io.File;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import com.unister.semweb.drums.DRUMSParameterSet;
import com.unister.semweb.drums.file.AbstractHeaderFile.AccessMode;
import com.unister.semweb.drums.storable.TestStorable;

/**
 * Tests the enlargement of the {@link HeaderIndexFile}.
 * 
 * @author Nils Thieme
 * 
 */
public class EnlargeFileTest {
    private static final String testFilename = "/tmp/headerIndexFile.db";

    /** Deletes the test file. */
    @Before
    public void initialise() throws Exception {
        FileUtils.deleteQuietly(new File(testFilename));
    }

    /** The test data fit into the begin file size and no enlargement takes place. */
    @Test
    public void noEnlargment() throws Exception {
        DRUMSParameterSet<TestStorable> globalParameters = new DRUMSParameterSet<TestStorable>(new TestStorable());
        globalParameters.INITIAL_FILE_SIZE = HeaderIndexFile.HEADER_SIZE;

        List<TestStorable> testdata = generateTestdata(10);

        List<Long> filePositions = writeData(testdata, globalParameters);

        List<TestStorable> readData = readFile(filePositions, globalParameters);

        Assert.assertTrue(testdata.equals(readData));
    }

    /**
     * The test data don't fit into the increment so a the file must be enlarged. After writing a bunch of test data
     * that are greater in size that the increment size another huge bunch will be written. This simulates a problem
     * that we have encountered when the enlargement is not done correctly.
     */
    @Test
    public void bigEnlargment() throws Exception {
        DRUMSParameterSet<TestStorable> globalParameters = new DRUMSParameterSet<TestStorable>(new TestStorable());
        globalParameters.INITIAL_INCREMENT_SIZE = 1000;
        globalParameters.INITIAL_FILE_SIZE = HeaderIndexFile.HEADER_SIZE;
        List<TestStorable> testdata = generateTestdata(50000);
        List<TestStorable> testdata2 = generateTestdata(20000);

        List<TestStorable> overallTestdata = new ArrayList<TestStorable>(testdata);
        overallTestdata.addAll(testdata2);

        List<Long> filePositions = writeData(testdata, globalParameters);
        List<Long> secondFilePositions = writeData(testdata2, globalParameters);

        List<Long> overallFilePositions = new ArrayList<Long>(filePositions);
        overallFilePositions.addAll(secondFilePositions);

        List<TestStorable> readData = readFile(overallFilePositions, globalParameters);
        Assert.assertTrue(overallTestdata.equals(readData));
    }

    @Test
    public void specialTest() throws Exception {
        DRUMSParameterSet<TestStorable> globalParameters = new DRUMSParameterSet<TestStorable>(new TestStorable());
        globalParameters.INITIAL_INCREMENT_SIZE = 50;
        globalParameters.INITIAL_FILE_SIZE = (int) (HeaderIndexFile.HEADER_SIZE
                + HeaderIndexFile.MAX_INDEX_SIZE_IN_BYTES);
        List<TestStorable> testdata = generateTestdata(3);
        List<TestStorable> testdata2 = generateTestdata(200);

        List<TestStorable> overallTestdata = new ArrayList<TestStorable>(testdata);
        overallTestdata.addAll(testdata2);

        List<Long> filePositions = writeData(testdata, globalParameters);
        List<Long> secondFilePositions = writeData(testdata2, globalParameters);

        List<Long> overallFilePositions = new ArrayList<Long>(filePositions);
        overallFilePositions.addAll(secondFilePositions);

        List<TestStorable> readData = readFile(overallFilePositions, globalParameters);
        Assert.assertTrue(overallTestdata.equals(readData));
    }

    /**
     * Writes the given test data to the test file. The <code>globalParameters</code> are used to control the increment
     * and the initial file size.
     */
    private List<Long> writeData(List<TestStorable> toWrite, DRUMSParameterSet<TestStorable> globalParameters)
            throws Exception {
        HeaderIndexFile<TestStorable> file = new HeaderIndexFile<TestStorable>(testFilename, AccessMode.READ_WRITE,
                1, globalParameters);
        List<Long> filePositions = new ArrayList<Long>();
        ByteBuffer overallBuffer = ByteBuffer.allocate(globalParameters.getPrototype().getSize() * toWrite.size());
        long currentFilePosition = file.getFilledUpFromContentStart();
        for (TestStorable currentTestObject : toWrite) {
            ByteBuffer buffer = currentTestObject.toByteBuffer();
            overallBuffer.put(buffer);
            filePositions.add(currentFilePosition);
            currentFilePosition += globalParameters.getPrototype().getSize();
        }
        overallBuffer.flip();
        file.append(overallBuffer);
        file.close();
        return filePositions;
    }

    /** Reads the data given by the <code>filePositions</code>. */
    private List<TestStorable> readFile(List<Long> filePositions, DRUMSParameterSet<TestStorable> globalParameters)
            throws Exception {
        HeaderIndexFile<TestStorable> file = new HeaderIndexFile<TestStorable>(testFilename, AccessMode.READ_ONLY,
                1, globalParameters);
        List<TestStorable> readData = new ArrayList<TestStorable>();
        for (long currentFilePosition : filePositions) {
            byte[] buffer = new byte[globalParameters.getPrototype().getSize()];
            file.read(currentFilePosition, buffer);

            TestStorable oneReadTestStorable = new TestStorable(buffer);
            readData.add(oneReadTestStorable);
        }
        file.close();
        return readData;
    }

    /** Generates the given number of test data. */
    private List<TestStorable> generateTestdata(int numberOfTestdata) throws Exception {
        List<TestStorable> result = new ArrayList<TestStorable>();
        byte[] keyPrefix = new byte[4];
        for (int i = 0; i < numberOfTestdata; i++) {
            TestStorable newTestObject = new TestStorable();
            byte[] runningNumberAsArray = ByteBuffer.allocate(4).putInt(i).array();
            byte[] key = ArrayUtils.addAll(keyPrefix, runningNumberAsArray);

            newTestObject.setKey(key);
            newTestObject.setFirstValue(i);
            newTestObject.setSecondValue(i);
            result.add(newTestObject);
        }
        return result;
    }
}