/* * 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.tree; import com.github.geophile.erdo.*; import com.github.geophile.erdo.TestFactory; import com.github.geophile.erdo.TestKey; import com.github.geophile.erdo.TestRecord; import com.github.geophile.erdo.RecordFactory; import com.github.geophile.erdo.TransactionCallback; import com.github.geophile.erdo.map.LazyRecord; import com.github.geophile.erdo.map.MapCursor; import com.github.geophile.erdo.map.diskmap.DBStructure; import com.github.geophile.erdo.transaction.Transaction; import com.github.geophile.erdo.util.FileUtil; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import java.io.File; import java.io.IOException; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNull; public class TreeTest { @BeforeClass public static void beforeClass() throws IOException { TestKey.testErdoId(ERDO_ID); DB_STRUCTURE = new DBStructure(new File(FileUtil.tempDirectory(), "erdo")); Transaction.initialize(FACTORY); } @Before public void before() throws IOException { FACTORY.recordFactory(ERDO_ID, RecordFactory.simpleRecordFactory(TestKey.class, TestRecord.class)); FileUtil.deleteDirectory(DB_STRUCTURE.dbDirectory()); FileUtil.ensureDirectoryExists(DB_STRUCTURE.dbDirectory()); FileUtil.ensureDirectoryExists(DB_STRUCTURE.forestDirectory()); FileUtil.ensureDirectoryExists(DB_STRUCTURE.segmentsDirectory()); FileUtil.ensureDirectoryExists(DB_STRUCTURE.summariesDirectory()); } @After public void after() { FACTORY.reset(); } @Test public void testScanEmpty() throws Exception { WriteableTree writeableTree = Tree.create(FACTORY, DB_STRUCTURE, TREE_ID); Tree tree = writeableTree.close(); startTransaction(); MapCursor cursor = tree.cursor(null); assertNull(cursor.next()); } // This test checks tree scanning. Tree random access is tested indirectly, in SealedMapTest, // operating on a DiskMap. @Test public void testScanRecords() throws Exception { final int N = 1000; // Load tree Tree tree; { WriteableTree writeableTree = Tree.create(FACTORY, DB_STRUCTURE, TREE_ID); for (int i = 0; i < N; i++) { startTransaction(); TestRecord record = TestRecord.createRecord(i, VALUES[i % 10]); record.key().transaction(FACTORY.transactionManager().currentTransaction()); commitTransaction(); writeableTree.append(record); } tree = writeableTree.close(); } // Scan forward { startTransaction(); MapCursor cursor = tree.cursor(null); int expected = 0; LazyRecord lazyRecord; while ((lazyRecord = cursor.next()) != null) { TestRecord record = (TestRecord) lazyRecord.materializeRecord(); int key = record.key().key(); assertEquals(expected, key); assertEquals(VALUES[key % 10], record.stringValue()); expected++; } commitTransaction(); assertEquals(N, expected); } // Scan backward { startTransaction(); MapCursor cursor = tree.cursor(null); int expected = N; LazyRecord lazyRecord; while ((lazyRecord = cursor.previous()) != null) { expected--; TestRecord record = (TestRecord) lazyRecord.materializeRecord(); int key = record.key().key(); assertEquals(expected, key); assertEquals(VALUES[key % 10], record.stringValue()); } commitTransaction(); assertEquals(0, expected); } } private void startTransaction() { FACTORY.transactionManager().currentTransaction(); } private void commitTransaction() throws IOException, InterruptedException { FACTORY.transactionManager().commitTransaction(TransactionCallback.DO_NOTHING, null); } private static final int ERDO_ID = 1; private static DBStructure DB_STRUCTURE; private static final int TREE_ID = 0; private static final String[] VALUES = { "", "a", "ab", "abc", "abcd", "abcde", "abcdef", "abcdefg", "abcdefgh", "abcdefghi" }; private static TestFactory FACTORY = new TestFactory(); }