/* * 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.keyarray; import com.github.geophile.erdo.AbstractRecord; import com.github.geophile.erdo.RecordFactory; import com.github.geophile.erdo.TestFactory; import com.github.geophile.erdo.TestKey; import org.junit.After; import org.junit.BeforeClass; import org.junit.Test; import static junit.framework.Assert.*; public class KeyArrayTest { @BeforeClass public static void beforeClass() { FACTORY = new TestFactory(); FACTORY.recordFactory(1, RecordFactory.simpleRecordFactory(TestKey1.class, null)); FACTORY.recordFactory(2, RecordFactory.simpleRecordFactory(TestKey2.class, null)); } @After public void after() { FACTORY.reset(); } @Test public void testEmpty() { KeyArray a = new KeyArray(FACTORY, 1000); a.close(); TestKey1 key = new TestKey1(); // size assertEquals(0, a.size()); // scan forward assertNull(a.cursor(null).next()); // scan backward assertNull(a.cursor(null).next()); // binary search assertEquals(-1, a.binarySearch(key)); // subscript try { a.key(0, key); fail(); } catch (IndexOutOfBoundsException e) { // expected } } @Test public void testNonEmpty() { final int MAX_N = 100; for (int n = 1; n <= MAX_N; n++) { // debug("n: %s", n); KeyArray a; KeyArrayCursor cursor; AbstractRecord record; int expected; TestKey1 key; // load { a = new KeyArray(FACTORY, 1000); for (int i = 1; i <= n; i++) { key = key1(i * 10); a.append(key); // debug(" %s", key); } a.close(); // check size assertEquals(n, a.size()); } // scan forward { cursor = a.cursor(null); expected = 0; while ((record = cursor.next()) != null) { expected += 10; assertEquals(expected, ((TestKey1)record.key()).key()); } assertEquals(n * 10, expected); } // scan backward { cursor = a.cursor(null); expected = n * 10; while ((record = cursor.previous()) != null) { assertEquals(expected, ((TestKey1)record.key()).key()); expected -= 10; } assertEquals(0, expected); } // binary search - search key present { for (int i = 1; i <= n; i++) { key = key1(i * 10); // forward cursor = a.cursor(key); record = cursor.next(); assertNotNull(record); assertEquals(i * 10, ((TestKey1)record.key()).key()); // backward cursor = a.cursor(key); record = cursor.previous(); assertNotNull(record); assertEquals(i * 10, ((TestKey1)record.key()).key()); } } // binary search - search key missing { for (int i = 1; i <= n + 1; i++) { key = key1(i * 10 - 5); // debug("binary search - missing key: %s", key); TestKey1 above = i <= n ? key1(i * 10) : null; TestKey1 below = i > 1 ? key1((i - 1) * 10) : null; // debug(" above: %s", above); // debug(" below: %s", below); // forward cursor = a.cursor(key); record = cursor.next(); if (above == null) { assertNull(record); } else { assertNotNull(record); assertEquals(above, record.key()); } // backward cursor = a.cursor(key); record = cursor.previous(); if (below == null) { assertNull(record); } else { assertNotNull(record); assertEquals(below, record.key()); } } } } } @Test public void testMixed() { final int N = 100; for (int n1 = 1; n1 < N; n1++) { int n2 = N - n1; KeyArray a = new KeyArray(FACTORY, 1000); for (int i = 0; i < n1; i++) { a.append(key1(i)); } for (int i = 0; i < n2; i++) { a.append(key2(i)); } a.close(); // size assertEquals(N, a.size()); // scan forward KeyArrayCursor cursor = a.cursor(null); AbstractRecord record; int expected = 0; while ((record = cursor.next()) != null) { if (expected < n1) { assertEquals(expected, ((TestKey)record.key()).key()); } else { assertEquals(expected - n1, ((TestKey)record.key()).key()); } expected++; } // binary search for (int i = 0; i < n1; i++) { assertEquals(i, a.binarySearch(key1(i))); } for (int i = 0; i < n2; i++) { assertEquals(n1 + i, a.binarySearch(key2(i))); } // subscript int i = 0; TestKey1 key1 = key1(-1); while (i < n1) { a.key(i, key1); assertEquals(1, key1.erdoId()); assertEquals(i, key1.key()); i++; } TestKey2 key2 = key2(-1); while (i < N) { a.key(i, key2); assertEquals(2, key2.erdoId()); assertEquals(i - n1, key2.key()); i++; } } } private TestKey1 key1(int k) { TestKey1 key = new TestKey1(); key.key(k); key.erdoId(1); key.transactionTimestamp(100); return key; } private TestKey2 key2(int k) { TestKey2 key = new TestKey2(); key.key(k); key.erdoId(2); key.transactionTimestamp(200); return key; } private void debug(String template, Object ... args) { System.out.println(String.format(template, args)); } private static TestFactory FACTORY; public static class TestKey1 extends TestKey { public TestKey1() { erdoId(1); } } public static class TestKey2 extends TestKey { public TestKey2() { erdoId(2); } } }