/*
* 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;
import com.github.geophile.erdo.TestKey;
import com.github.geophile.erdo.TestRecord;
import org.junit.Test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static junit.framework.Assert.*;
public class SealedMapTest extends MapBehaviorTestBase
{
@Test
public void testCursor() throws IOException, InterruptedException
{
// LOG.log(Level.SEVERE, "Re-enable all of SealedMapTest");
for (int n = 0; n <= N_MAX; n++) {
testCursor(arrayMap(testRecords(n)), n);
testCursor(privateMap(testRecords(n)), n);
testCursor(diskMap(testRecords(n)), n);
/* Operating on a ForestMap outside the context of a TransactionalMap doesn't
work so well due to new work on transactions & consolidation.
testCursor(forest(testRecords(n)), n);
*/
}
}
private void testCursor(SealedMap map, int n) throws IOException, InterruptedException
{
try {
FACTORY.reset();
MapCursor cursor;
int expectedKey;
int expectedLastKey;
boolean expectedEmpty;
LazyRecord record;
// Full scan
{
cursor = map.cursor(null, false);
expectedKey = 0;
// debug("n: %s", n);
while ((record = cursor.next()) != null) {
// debug(" %s", record.materializeRecord());
assertEquals(expectedKey, key(record));
expectedKey += GAP;
}
assertEquals(n * GAP, expectedKey);
}
// Try scans starting at, before, and after each key and ending at, before and after each key.
{
for (int i = 0; i < n; i++) {
int startBase = GAP * i;
int endBase = GAP * (n - 1 - i);
for (int start = startBase - 1; start <= startBase + 1; start++) {
for (int end = endBase - 1; end <= endBase + 1; end++) {
// debug("n: %s, start: %s, end: %s", n, start, end);
if (start <= end) {
cursor = map.cursor(key(start), false);
TestKey endKey = key(end);
expectedKey = start <= startBase ? startBase : startBase + GAP;
expectedLastKey = end >= endBase ? endBase : endBase - GAP;
expectedEmpty = start > end || start <= end && (end >= startBase || start <= endBase);
boolean empty = true;
while ((record = cursor.next()) != null &&
record.key() .compareTo(endKey) <= 0) {
// debug(" %s", record.materializeRecord());
assertEquals(expectedKey, key(record));
expectedKey += GAP;
empty = false;
}
if (empty) {
assertTrue(expectedEmpty);
} else {
assertEquals(expectedLastKey + GAP, expectedKey);
}
}
}
}
}
}
// Alternating next and previous
{
// System.out.println(n);
cursor = map.cursor(null, false);
expectedKey = 0;
record = cursor.next();
if (record != null) {
// debug("expected: %s, start: %s", expectedKey, record);
expectedKey += GAP;
}
while ((record = cursor.next()) != null) {
// debug("expected: %s, next: %s", expectedKey, record);
assertEquals(expectedKey, key(record));
expectedKey += GAP;
if (expectedKey != n * GAP) {
record = cursor.next();
// debug("expected: %s, next: %s", expectedKey, record);
assertNotNull(record);
assertEquals(expectedKey, key(record));
expectedKey -= GAP;
record = cursor.previous();
// debug("expected: %s, previous: %s", expectedKey, record);
assertEquals(expectedKey, key(record));
expectedKey += GAP; // About to go to next
}
}
assertEquals(n * GAP, expectedKey);
}
// Alternating previous and next
{
// debug("n: %s", n);
cursor = map.cursor(null, false);
expectedKey = (n - 1) * GAP;
record = cursor.previous();
if (record != null) {
// debug("expected: %s, start: %s", expectedKey, record.key());
expectedKey -= GAP;
}
while ((record = cursor.previous()) != null) {
// debug("expected: %s, previous: %s", expectedKey, record.key());
assertEquals(expectedKey, key(record));
expectedKey -= GAP;
if (expectedKey >= 0) {
record = cursor.previous();
// debug("expected: %s, previous: %s", expectedKey, record.key());
assertNotNull(record);
assertEquals(expectedKey, key(record));
expectedKey += GAP;
record = cursor.next();
// debug("expected: %s, next: %s", expectedKey, record.key());
assertEquals(expectedKey, key(record));
expectedKey -= GAP; // About to go to next
}
}
assertEquals(-GAP, expectedKey);
}
// goTo
if (n > 0) {
cursor = map.cursor(null, false);
int match;
int before;
for (int i = 0; i <= n; i++) {
// debug("n: %s, i: %s", n, i);
match = i * GAP;
if (i < n) {
// Match, next
cursor.goTo(key(match));
assertEquals(key(match), cursor.next().key());
// Match, previous
cursor.goTo(key(match));
assertEquals(key(match), cursor.previous().key());
}
// Before, next
before = match - GAP / 2;
cursor.goTo(key(before));
if (i == n) {
assertNull(cursor.next());
} else {
assertEquals(key(match), cursor.next().key());
}
// Before, previous
cursor.goTo(key(before));
if (i == 0) {
assertNull(cursor.previous());
} else {
assertEquals(key(match - GAP), cursor.previous().key());
}
}
}
} finally {
if (db != null) {
db.close();
}
}
}
private List<TestRecord> testRecords(int n) throws IOException
{
List<TestRecord> testRecords = new ArrayList<>();
assertTrue(GAP > 1);
// Populate map with keys 0, GAP, ..., GAP * (n - 1)
// System.out.println("Records:");
for (int i = 0; i < n; i++) {
int key = GAP * i;
TestRecord record = newRecord(key, value(key));
// debug(" %s", record);
testRecords.add(record);
}
return testRecords;
}
private String value(int key)
{
return Integer.toString(key) + FILLER;
}
private void debug(String template, Object ... args)
{
System.out.println(String.format(template, args));
}
private static final String FILLER = "xxxxxxxxxxxxxxxxxxxx" +
"xxxxxxxxxxxxxxxxxxxx" +
"xxxxxxxxxxxxxxxxxxxx" +
"xxxxxxxxxxxxxxxxxxxx" +
"xxxxxxxxxxxxxxxxxxxx" +
"xxxxxxxxxxxxxxxxxxxx" +
"xxxxxxxxxxxxxxxxxxxx" +
"xxxxxxxxxxxxxxxxxxxx" +
"xxxxxxxxxxxxxxxxxxxx" +
"xxxxxxxxxxxxxxxxxxxx";
private static final int N_MAX = 100;
private static final int GAP = 10;
}