/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package com.github.geophile.erdo.map.diskmap; import com.github.geophile.erdo.util.Transferrable; import org.junit.Test; import java.nio.BufferOverflowException; import java.nio.ByteBuffer; import static junit.framework.Assert.assertEquals; import static org.junit.Assert.fail; public class DiskPageSectionVariableLengthRecordTest { @Test public void testEmpty() { DiskPageSection s = DiskPageSectionVariableLengthRecords.forWrite(0, newDiskPageSectionBuffer()); s.metadataClose(); try { s.metadataAppendUInt(0); fail(); } catch (AssertionError e) { } assertEquals(0, s.count()); assertEquals(8, s.size()); s.close(); assertEquals(0, s.count()); assertEquals(8, s.size()); try { s.append(new TestValue(0)); fail(); } catch (AssertionError e) { } } @Test public void testMetadataOnly() { DiskPageSection s = DiskPageSectionVariableLengthRecords.forWrite(6, newDiskPageSectionBuffer()); s.metadataAppendUInt(123); s.metadataAppendUShort(456); assertEquals(0, s.count()); assertEquals(14, s.size()); try { s.metadataUInt(0); fail(); } catch (AssertionError e) { } s.metadataClose(); assertEquals(0, s.count()); assertEquals(14, s.size()); try { s.metadataUInt(0); fail(); } catch (AssertionError e) { } s.close(); assertEquals(123, s.metadataUInt(0)); assertEquals(456, s.metadataUShort(4)); assertEquals(0, s.count()); assertEquals(14, s.size()); } @Test public void testUnsignedMetadata() { DiskPageSection s = DiskPageSectionVariableLengthRecords.forWrite(6, newDiskPageSectionBuffer()); s.metadataAppendUInt(0xffffffffL); s.metadataAppendUShort(0xffff); s.metadataClose(); s.close(); assertEquals(0xffffffffL, s.metadataUInt(0)); assertEquals(0xffff, s.metadataUShort(4)); } @Test public void testMetadataOverflow() { DiskPageSection s = DiskPageSectionVariableLengthRecords.forWrite(6, newDiskPageSectionBuffer()); s.metadataAppendUInt(123); try { s.metadataAppendUInt(456); fail(); } catch (AssertionError e) { } } @Test public void testData() { // Write records of size 1, 2, .... buffer size is 4k, metadata size is 0. There should be // room for 87 records with 88 bytes unused. final int N = 87; DiskPageSection s = DiskPageSectionVariableLengthRecords.forWrite(0, newDiskPageSectionBuffer()); assertEquals(0, s.count()); assertEquals(8, s.size()); for (int size = 1; size <= N; size++) { s.append(new TestValue(size)); assertEquals(size, s.count()); assertEquals(8 + size * (size + 1) / 2 + 2 * size, s.size()); } try { s.append(new TestValue(N + 1)); fail(); } catch (BufferOverflowException e) { } assertEquals(N, s.count()); assertEquals(8 + N * (N + 1) / 2 + N * 2, s.size()); s.close(); assertEquals(N, s.count()); assertEquals(8 + N * (N + 1) / 2 + N * 2, s.size()); ByteBuffer buffer = s.accessBuffer(); for (int position = 0; position < 87; position++) { s.setBoundariesInBuffer(position, buffer); int size = position + 1; new TestValue(size).readFrom(buffer); } try { s.setBoundariesInBuffer(-1, buffer); fail(); } catch (AssertionError e) { } } @Test public void testEmptyRecords() { // Write 3 0-length records, a record of size 10 and then 3 more 0-length. DiskPageSection s = DiskPageSectionVariableLengthRecords.forWrite(0, newDiskPageSectionBuffer()); TestValue v0 = new TestValue(0); TestValue v10 = new TestValue(10); s.append(v0); s.append(v0); s.append(v0); s.append(v10); s.append(v0); s.append(v0); s.append(v0); s.close(); assertEquals(7, s.count()); assertEquals(8 + 10 + 7 * 2, s.size()); ByteBuffer buffer = s.accessBuffer(); s.setBoundariesInBuffer(0, buffer); v0.readFrom(buffer); s.setBoundariesInBuffer(1, buffer); v0.readFrom(buffer); s.setBoundariesInBuffer(2, buffer); v0.readFrom(buffer); s.setBoundariesInBuffer(3, buffer); v10.readFrom(buffer); s.setBoundariesInBuffer(4, buffer); v0.readFrom(buffer); s.setBoundariesInBuffer(5, buffer); v0.readFrom(buffer); s.setBoundariesInBuffer(6, buffer); v0.readFrom(buffer); } @Test public void testMarkReset() { DiskPageSection s = DiskPageSectionVariableLengthRecords.forWrite(0, newDiskPageSectionBuffer()); s.append(new TestValue(1)); s.append(new TestValue(2)); assertEquals(2, s.count()); assertEquals(8 + 3 + 4, s.size()); s.mark(); s.append(new TestValue(3)); s.append(new TestValue(4)); assertEquals(4, s.count()); assertEquals(8 + 10 + 8, s.size()); s.resetToMark(); assertEquals(2, s.count()); assertEquals(8 + 3 + 4, s.size()); s.append(new TestValue(5)); s.append(new TestValue(6)); assertEquals(4, s.count()); assertEquals(8 + 14 + 8, s.size()); s.close(); assertEquals(4, s.count()); assertEquals(8 + 14 + 8, s.size()); assertEquals(4, s.count()); ByteBuffer buffer = s.accessBuffer(); s.setBoundariesInBuffer(0, buffer); new TestValue(1).readFrom(buffer); s.setBoundariesInBuffer(1, buffer); new TestValue(2).readFrom(buffer); s.setBoundariesInBuffer(2, buffer); new TestValue(5).readFrom(buffer); s.setBoundariesInBuffer(3, buffer); new TestValue(6).readFrom(buffer); } private ByteBuffer newDiskPageSectionBuffer() { return ByteBuffer.allocate(BUFFER_SIZE); } private static final int BUFFER_SIZE = 4096; private static class TestValue implements Transferrable { public void writeTo(ByteBuffer buffer) throws BufferOverflowException { for (int i = 0; i < size; i++) { buffer.put((byte)(i % 10)); } } public void readFrom(ByteBuffer buffer) { for (int i = 0; i < size; i++) { assertEquals(i % 10, buffer.get()); } assertEquals(0, buffer.remaining()); } public int recordCount() { return 1; } public TestValue(int size) { this.size = size; } private final int size; } }