/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 2002-2005
* Sleepycat Software. All rights reserved.
*
* $Id: DatabaseTest.java,v 1.90 2005/08/16 03:48:50 mark Exp $
*/
package com.sleepycat.je;
import java.io.File;
import java.io.IOException;
import junit.framework.TestCase;
import com.sleepycat.je.config.EnvironmentParams;
import com.sleepycat.je.dbi.INList;
import com.sleepycat.je.dbi.MemoryBudget;
import com.sleepycat.je.junit.JUnitThread;
import com.sleepycat.je.tree.Key;
import com.sleepycat.je.util.TestUtils;
/**
* Basic database operations, excluding configuration testing.
*/
public class DatabaseTest extends TestCase {
private static final boolean DEBUG = false;
private static final int NUM_RECS = 257;
private File envHome;
private Environment env;
public DatabaseTest() {
envHome = new File(System.getProperty(TestUtils.DEST_DIR));
}
public void setUp()
throws IOException {
TestUtils.removeLogFiles("Setup", envHome, false);
}
public void tearDown()
throws Exception {
try {
/* Close in case we hit an exception and didn't close */
if (env != null) {
env.close();
}
} catch (DatabaseException e) {
/* Ok if already closed */
}
env = null; // for JUNIT, to reduce memory usage when run in a suite.
TestUtils.removeLogFiles("TearDown", envHome, false);
}
/**
* Make sure we can't create a transactional cursor on a non-transactional
* database.
*/
public void testCursor()
throws Exception {
Environment txnalEnv = null;
Database nonTxnalDb = null;
Cursor txnalCursor = null;
Transaction txn = null;
try {
EnvironmentConfig envConfig = TestUtils.initEnvConfig();
envConfig.setTransactional(true);
envConfig.setAllowCreate(true);
txnalEnv = new Environment(envHome, envConfig);
// Make a db and open it
DatabaseConfig dbConfig = new DatabaseConfig();
dbConfig.setAllowCreate(true);
dbConfig.setTransactional(false);
nonTxnalDb = txnalEnv.openDatabase(null, "testDB", dbConfig);
// We should not be able to open a txnal cursor.
txn = txnalEnv.beginTransaction(null, null);
try {
txnalCursor = nonTxnalDb.openCursor(txn, null);
fail("Openin a txnal cursor on a nontxnal db is invalid.");
} catch (DatabaseException e) {
// expected
}
} finally {
if (txn != null) {
txn.abort();
}
if (txnalCursor != null) {
txnalCursor.close();
}
if (nonTxnalDb != null) {
nonTxnalDb.close();
}
if (txnalEnv != null) {
txnalEnv.close();
}
}
}
public void testPutExisting()
throws Throwable {
try {
Database myDb = initEnvAndDb(true, false, true, null);
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
DatabaseEntry getData = new DatabaseEntry();
Transaction txn = env.beginTransaction(null, null);
for (int i = NUM_RECS; i > 0; i--) {
key.setData(TestUtils.getTestArray(i));
data.setData(TestUtils.getTestArray(i));
assertEquals(OperationStatus.SUCCESS,
myDb.put(txn, key, data));
assertEquals(OperationStatus.SUCCESS,
myDb.get(txn, key, getData, LockMode.DEFAULT));
assertEquals(0, Key.compareKeys(data.getData(),
getData.getData()));
assertEquals(OperationStatus.SUCCESS,
myDb.put(txn, key, data));
assertEquals(OperationStatus.SUCCESS, myDb.getSearchBoth
(txn, key, getData, LockMode.DEFAULT));
assertEquals(0, Key.compareKeys(data.getData(),
getData.getData()));
}
txn.commit();
myDb.close();
env.close();
} catch (Throwable t) {
t.printStackTrace();
throw t;
}
}
public void testDeleteNonDup()
throws Throwable {
try {
Database myDb = initEnvAndDb(true, false, true, null);
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
DatabaseEntry getData = new DatabaseEntry();
Transaction txn = env.beginTransaction(null, null);
for (int i = NUM_RECS; i > 0; i--) {
key.setData(TestUtils.getTestArray(i));
data.setData(TestUtils.getTestArray(i));
assertEquals(OperationStatus.SUCCESS,
myDb.put(txn, key, data));
}
for (int i = NUM_RECS; i > 0; i--) {
key.setData(TestUtils.getTestArray(i));
data.setData(TestUtils.getTestArray(i));
assertEquals(OperationStatus.SUCCESS,
myDb.delete(txn, key));
OperationStatus status =
myDb.get(txn, key, getData, LockMode.DEFAULT);
if (status != OperationStatus.KEYEMPTY &&
status != OperationStatus.NOTFOUND) {
fail("invalid Database.get return: " + status);
}
assertEquals(OperationStatus.NOTFOUND,
myDb.delete(txn, key));
}
txn.commit();
myDb.close();
env.close();
} catch (Throwable t) {
t.printStackTrace();
throw t;
}
}
public void testDeleteDup()
throws Throwable {
try {
Database myDb = initEnvAndDb(true, false, true, null);
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
DatabaseEntry getData = new DatabaseEntry();
Transaction txn = env.beginTransaction(null, null);
for (int i = NUM_RECS; i > 0; i--) {
key.setData(TestUtils.getTestArray(i));
data.setData(TestUtils.getTestArray(i));
assertEquals(OperationStatus.SUCCESS,
myDb.put(txn, key, data));
for (int j = 0; j < NUM_RECS; j++) {
data.setData(TestUtils.getTestArray(i + j));
assertEquals(OperationStatus.SUCCESS,
myDb.put(txn, key, data));
}
}
txn.commit();
txn = env.beginTransaction(null, null);
for (int i = NUM_RECS; i > 0; i--) {
key.setData(TestUtils.getTestArray(i));
data.setData(TestUtils.getTestArray(i));
assertEquals(OperationStatus.SUCCESS,
myDb.delete(txn, key));
OperationStatus status =
myDb.get(txn, key, getData, LockMode.DEFAULT);
if (status != OperationStatus.KEYEMPTY &&
status != OperationStatus.NOTFOUND) {
fail("invalid Database.get return");
}
assertEquals(OperationStatus.NOTFOUND,
myDb.delete(txn, key));
}
txn.commit();
myDb.close();
env.close();
} catch (Throwable t) {
t.printStackTrace();
throw t;
}
}
public void testPutDuplicate()
throws Throwable {
try {
Database myDb = initEnvAndDb(true, true, true, null);
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
Transaction txn = env.beginTransaction(null, null);
for (int i = NUM_RECS; i > 0; i--) {
key.setData(TestUtils.getTestArray(i));
data.setData(TestUtils.getTestArray(i));
assertEquals(OperationStatus.SUCCESS,
myDb.put(txn, key, data));
data.setData(TestUtils.getTestArray(i * 2));
assertEquals(OperationStatus.SUCCESS,
myDb.put(txn, key, data));
}
txn.commit();
myDb.close();
env.close();
} catch (Throwable t) {
t.printStackTrace();
throw t;
}
}
public void testPutNoDupData()
throws Throwable {
try {
Database myDb = initEnvAndDb(true, true, true, null);
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
Transaction txn = env.beginTransaction(null, null);
for (int i = NUM_RECS; i > 0; i--) {
key.setData(TestUtils.getTestArray(i));
data.setData(TestUtils.getTestArray(i));
assertEquals(OperationStatus.SUCCESS,
myDb.putNoDupData(txn, key, data));
assertEquals(OperationStatus.KEYEXIST,
myDb.putNoDupData(txn, key, data));
data.setData(TestUtils.getTestArray(i+1));
assertEquals(OperationStatus.SUCCESS,
myDb.putNoDupData(txn, key, data));
}
txn.commit();
myDb.close();
env.close();
} catch (Throwable t) {
t.printStackTrace();
throw t;
}
}
public void testPutNoOverwriteInANoDupDb()
throws Throwable {
try {
Database myDb = initEnvAndDb(true, false, true, null);
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
Transaction txn = env.beginTransaction(null, null);
for (int i = NUM_RECS; i > 0; i--) {
key.setData(TestUtils.getTestArray(i));
data.setData(TestUtils.getTestArray(i));
assertEquals(OperationStatus.SUCCESS,
myDb.putNoOverwrite(txn, key, data));
assertEquals(OperationStatus.KEYEXIST,
myDb.putNoOverwrite(txn, key, data));
}
txn.commit();
myDb.close();
env.close();
} catch (Throwable t) {
t.printStackTrace();
throw t;
}
}
public void testPutNoOverwriteInADupDbTxn()
throws Throwable {
try {
Database myDb = initEnvAndDb(true, true, true, null);
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
for (int i = NUM_RECS; i > 0; i--) {
Transaction txn1 = env.beginTransaction(null, null);
key.setData(TestUtils.getTestArray(i));
data.setData(TestUtils.getTestArray(i));
assertEquals(OperationStatus.SUCCESS,
myDb.putNoOverwrite(txn1, key, data));
assertEquals(OperationStatus.KEYEXIST,
myDb.putNoOverwrite(txn1, key, data));
data.setData(TestUtils.getTestArray(i << 1));
assertEquals(OperationStatus.SUCCESS,
myDb.put(txn1, key, data));
data.setData(TestUtils.getTestArray(i << 2));
assertEquals(OperationStatus.KEYEXIST,
myDb.putNoOverwrite(txn1, key, data));
assertEquals(OperationStatus.SUCCESS,
myDb.delete(txn1, key));
assertEquals(OperationStatus.SUCCESS,
myDb.putNoOverwrite(txn1, key, data));
txn1.commit();
}
myDb.close();
env.close();
} catch (Throwable t) {
t.printStackTrace();
throw t;
}
}
public void testPutNoOverwriteInADupDbNoTxn()
throws Throwable {
try {
Database myDb = initEnvAndDb(true, true, false, null);
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
for (int i = NUM_RECS; i > 0; i--) {
key.setData(TestUtils.getTestArray(i));
data.setData(TestUtils.getTestArray(i));
assertEquals(OperationStatus.SUCCESS,
myDb.putNoOverwrite(null, key, data));
assertEquals(OperationStatus.KEYEXIST,
myDb.putNoOverwrite(null, key, data));
data.setData(TestUtils.getTestArray(i << 1));
assertEquals(OperationStatus.SUCCESS,
myDb.put(null, key, data));
data.setData(TestUtils.getTestArray(i << 2));
assertEquals(OperationStatus.KEYEXIST,
myDb.putNoOverwrite(null, key, data));
assertEquals(OperationStatus.SUCCESS,
myDb.delete(null, key));
assertEquals(OperationStatus.SUCCESS,
myDb.putNoOverwrite(null, key, data));
}
myDb.close();
env.close();
} catch (Throwable t) {
t.printStackTrace();
throw t;
}
}
public void testStat()
throws Throwable {
try {
Database myDb = initEnvAndDb(true, false, true, null);
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
Transaction txn = env.beginTransaction(null, null);
for (int i = NUM_RECS; i > 0; i--) {
key.setData(TestUtils.getTestArray(i));
data.setData(TestUtils.getTestArray(i));
assertEquals(OperationStatus.SUCCESS,
myDb.put(txn, key, data));
}
BtreeStats stat = (BtreeStats)
myDb.getStats(TestUtils.FAST_STATS);
assertEquals(0, stat.getInternalNodeCount());
assertEquals(0, stat.getDuplicateInternalNodeCount());
assertEquals(0, stat.getBottomInternalNodeCount());
assertEquals(0, stat.getDuplicateBottomInternalNodeCount());
assertEquals(0, stat.getLeafNodeCount());
assertEquals(0, stat.getDeletedLeafNodeCount());
assertEquals(0, stat.getDupCountLeafNodeCount());
assertEquals(0, stat.getMainTreeMaxDepth());
assertEquals(0, stat.getDuplicateTreeMaxDepth());
stat = (BtreeStats) myDb.getStats(null);
assertEquals(15, stat.getInternalNodeCount());
assertEquals(0, stat.getDuplicateInternalNodeCount());
assertEquals(52, stat.getBottomInternalNodeCount());
assertEquals(0, stat.getDuplicateBottomInternalNodeCount());
assertEquals(257, stat.getLeafNodeCount());
assertEquals(0, stat.getDeletedLeafNodeCount());
assertEquals(0, stat.getDupCountLeafNodeCount());
assertEquals(4, stat.getMainTreeMaxDepth());
assertEquals(0, stat.getDuplicateTreeMaxDepth());
stat = (BtreeStats) myDb.getStats(TestUtils.FAST_STATS);
assertEquals(15, stat.getInternalNodeCount());
assertEquals(52, stat.getBottomInternalNodeCount());
assertEquals(257, stat.getLeafNodeCount());
assertEquals(0, stat.getDeletedLeafNodeCount());
assertEquals(0, stat.getDupCountLeafNodeCount());
assertEquals(4, stat.getMainTreeMaxDepth());
assertEquals(0, stat.getDuplicateTreeMaxDepth());
txn.commit();
myDb.close();
env.close();
} catch (Throwable t) {
t.printStackTrace();
throw t;
}
}
public void testStatDupes()
throws Throwable {
try {
Database myDb = initEnvAndDb(true, true, true, null);
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
Transaction txn = env.beginTransaction(null, null);
for (int i = NUM_RECS; i > 0; i--) {
key.setData(TestUtils.getTestArray(i));
data.setData(TestUtils.getTestArray(i));
assertEquals(OperationStatus.SUCCESS,
myDb.put(txn, key, data));
for (int j = 0; j < 10; j++) {
data.setData(TestUtils.getTestArray(i + j));
assertEquals(OperationStatus.SUCCESS,
myDb.put(txn, key, data));
}
}
BtreeStats stat = (BtreeStats)
myDb.getStats(TestUtils.FAST_STATS);
assertEquals(0, stat.getInternalNodeCount());
assertEquals(0, stat.getDuplicateInternalNodeCount());
assertEquals(0, stat.getBottomInternalNodeCount());
assertEquals(0, stat.getDuplicateBottomInternalNodeCount());
assertEquals(0, stat.getLeafNodeCount());
assertEquals(0, stat.getDeletedLeafNodeCount());
assertEquals(0, stat.getDupCountLeafNodeCount());
assertEquals(0, stat.getMainTreeMaxDepth());
assertEquals(0, stat.getDuplicateTreeMaxDepth());
stat = (BtreeStats) myDb.getStats(null);
assertEquals(23, stat.getInternalNodeCount());
assertEquals(257, stat.getDuplicateInternalNodeCount());
assertEquals(85, stat.getBottomInternalNodeCount());
assertEquals(771, stat.getDuplicateBottomInternalNodeCount());
assertEquals(2570, stat.getLeafNodeCount());
assertEquals(0, stat.getDeletedLeafNodeCount());
assertEquals(257, stat.getDupCountLeafNodeCount());
assertEquals(4, stat.getMainTreeMaxDepth());
assertEquals(2, stat.getDuplicateTreeMaxDepth());
stat = (BtreeStats) myDb.getStats(TestUtils.FAST_STATS);
assertEquals(23, stat.getInternalNodeCount());
assertEquals(257, stat.getDuplicateInternalNodeCount());
assertEquals(85, stat.getBottomInternalNodeCount());
assertEquals(771, stat.getDuplicateBottomInternalNodeCount());
assertEquals(2570, stat.getLeafNodeCount());
assertEquals(0, stat.getDeletedLeafNodeCount());
assertEquals(257, stat.getDupCountLeafNodeCount());
assertEquals(4, stat.getMainTreeMaxDepth());
assertEquals(2, stat.getDuplicateTreeMaxDepth());
txn.commit();
myDb.close();
env.close();
} catch (Throwable t) {
t.printStackTrace();
throw t;
}
}
public void testStatDeletes()
throws Throwable {
deleteTestInternal(1, 2, 0, 2);
deleteTestInternal(2, 2, 2, 2);
deleteTestInternal(10, 2, 10, 10);
deleteTestInternal(11, 2, 10, 12);
}
private void deleteTestInternal(int numRecs,
int numDupRecs,
int expectedLNs,
int expectedDeletedLNs)
throws Throwable {
try {
TestUtils.removeLogFiles("Setup", envHome, false);
Database myDb = initEnvAndDb(true, true, true, null);
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
Transaction txn = env.beginTransaction(null, null);
for (int i = numRecs; i > 0; i--) {
key.setData(TestUtils.getTestArray(i));
for (int j = 0; j < numDupRecs; j++) {
data.setData(TestUtils.getTestArray(i + j));
assertEquals(OperationStatus.SUCCESS,
myDb.put(txn, key, data));
}
}
for (int i = numRecs; i > 0; i -= 2) {
key.setData(TestUtils.getTestArray(i));
assertEquals(OperationStatus.SUCCESS,
myDb.delete(txn, key));
}
BtreeStats stat = (BtreeStats) myDb.getStats(null);
assertEquals(expectedLNs, stat.getLeafNodeCount());
assertEquals(expectedDeletedLNs, stat.getDeletedLeafNodeCount());
assertEquals(numRecs, stat.getDupCountLeafNodeCount());
txn.commit();
myDb.close();
env.close();
} catch (Throwable t) {
t.printStackTrace();
throw t;
}
}
/**
* Exercise the preload method, which warms up the cache.
*/
public void testPreloadByteLimit()
throws Throwable {
/* Set up a test db */
Database myDb = initEnvAndDb(false, false, true, null);
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
Transaction txn = env.beginTransaction(null, null);
for (int i = 2500; i > 0; i--) {
key.setData(TestUtils.getTestArray(i));
data.setData(TestUtils.getTestArray(i));
assertEquals(OperationStatus.SUCCESS,
myDb.put(txn, key, data));
}
/* Recover the database, restart w/no evictor. */
long postCreateMemUsage = env.getMemoryUsage();
INList inlist = env.getEnvironmentImpl().getInMemoryINs();
long postCreateResidentNodes = inlist.getSize();
txn.commit();
myDb.close();
env.close();
myDb = initEnvAndDb
(true, false, true, MemoryBudget.MIN_MAX_MEMORY_SIZE_STRING);
/*
* Do two evictions, because the first eviction will only strip
* LNs. We need to actually evict BINS because preload only pulls in
* IN/BINs
*/
env.evictMemory(); // first eviction strips LNS.
env.evictMemory(); // second one will evict BINS
long postEvictMemUsage = env.getMemoryUsage();
inlist = env.getEnvironmentImpl().getInMemoryINs(); // re-get inList
long postEvictResidentNodes = inlist.getSize();
/* Now preload, but not up to the full size of the db */
myDb.preload(100000, 0);
long postPreloadMemUsage = env.getMemoryUsage();
long postPreloadResidentNodes = inlist.getSize();
/* Now iterate to get everything back into memory */
Cursor cursor = myDb.openCursor(null, null);
int count = 0;
OperationStatus status = cursor.getFirst(key, data, LockMode.DEFAULT);
while (status == OperationStatus.SUCCESS) {
count++;
status = cursor.getNext(key, data, LockMode.DEFAULT);
}
cursor.close();
long postIterationMemUsage = env.getMemoryUsage();
long postIterationResidentNodes = inlist.getSize();
if (DEBUG) {
System.out.println("postCreateMemUsage: " + postCreateMemUsage);
System.out.println("postEvictMemUsage: " + postEvictMemUsage);
System.out.println("postPreloadMemUsage: " + postPreloadMemUsage);
System.out.println("postIterationMemUsage: " +
postIterationMemUsage);
System.out.println("postEvictResidentNodes: " +
postEvictResidentNodes);
System.out.println("postPreloadResidentNodes: " +
postPreloadResidentNodes);
System.out.println("postIterationResidentNodes: " +
postIterationResidentNodes);
System.out.println("postCreateResidentNodes: " +
postCreateResidentNodes);
}
assertTrue(postEvictMemUsage < postCreateMemUsage);
assertTrue(postEvictMemUsage < postPreloadMemUsage);
assertTrue("postPreloadMemUsage=" + postPreloadMemUsage +
" postIterationMemUsage=" + postIterationMemUsage,
postPreloadMemUsage < postIterationMemUsage);
assertTrue(postIterationMemUsage <= postCreateMemUsage);
assertTrue(postEvictResidentNodes < postPreloadResidentNodes);
//assertEquals(postCreateResidentNodes, postIterationResidentNodes);
assertTrue(postCreateResidentNodes >= postIterationResidentNodes);
myDb.close();
env.close();
}
public void testPreloadTimeLimit()
throws Throwable {
/* Set up a test db */
Database myDb = initEnvAndDb(false, false, true, null);
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
Transaction txn = env.beginTransaction(null, null);
for (int i = 25000; i > 0; i--) {
key.setData(TestUtils.getTestArray(i));
data.setData(new byte[1]);
assertEquals(OperationStatus.SUCCESS,
myDb.put(txn, key, data));
}
/* Recover the database, restart w/no evictor. */
long postCreateMemUsage = env.getMemoryUsage();
INList inlist = env.getEnvironmentImpl().getInMemoryINs();
long postCreateResidentNodes = inlist.getSize();
txn.commit();
myDb.close();
env.close();
myDb = initEnvAndDb(true, false, true, null);
/*
* Do two evictions, because the first eviction will only strip
* LNs. We need to actually evict BINS because preload only pulls in
* IN/BINs
*/
env.evictMemory(); // first eviction strips LNS.
env.evictMemory(); // second one will evict BINS
long postEvictMemUsage = env.getMemoryUsage();
inlist = env.getEnvironmentImpl().getInMemoryINs(); // re-get inList
long postEvictResidentNodes = inlist.getSize();
/* Now preload, but not up to the full size of the db */
long startTime = System.currentTimeMillis();
myDb.preload(0, 50);
long postPreloadMemUsage = env.getMemoryUsage();
long postPreloadResidentNodes = inlist.getSize();
/* Now iterate to get everything back into memory */
Cursor cursor = myDb.openCursor(null, null);
int count = 0;
OperationStatus status = cursor.getFirst(key, data, LockMode.DEFAULT);
while (status == OperationStatus.SUCCESS) {
count++;
status = cursor.getNext(key, data, LockMode.DEFAULT);
}
cursor.close();
long postIterationMemUsage = env.getMemoryUsage();
long postIterationResidentNodes = inlist.getSize();
if (DEBUG) {
System.out.println("postCreateMemUsage: " + postCreateMemUsage);
System.out.println("postEvictMemUsage: " + postEvictMemUsage);
System.out.println("postPreloadMemUsage: " + postPreloadMemUsage);
System.out.println("postIterationMemUsage: " +
postIterationMemUsage);
System.out.println("postEvictResidentNodes: " +
postEvictResidentNodes);
System.out.println("postPreloadResidentNodes: " +
postPreloadResidentNodes);
System.out.println("postIterationResidentNodes: " +
postIterationResidentNodes);
System.out.println("postCreateResidentNodes: " +
postCreateResidentNodes);
}
assertTrue(postEvictMemUsage < postCreateMemUsage);
assertTrue(postEvictMemUsage < postPreloadMemUsage);
assertTrue("postPreloadMemUsage=" + postPreloadMemUsage +
" postIterationMemUsage=" + postIterationMemUsage,
postPreloadMemUsage < postIterationMemUsage);
assertTrue(postIterationMemUsage <= postCreateMemUsage);
assertTrue(postEvictResidentNodes < postPreloadResidentNodes);
//assertEquals(postCreateResidentNodes, postIterationResidentNodes);
assertTrue(postCreateResidentNodes >= postIterationResidentNodes);
myDb.close();
env.close();
}
/**
* Load the entire database with preload.
*/
public void testPreloadEntireDatabase()
throws Throwable {
/* Create a test db with one record */
Database myDb = initEnvAndDb(false, false, false, null);
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
key.setData(TestUtils.getTestArray(0));
data.setData(TestUtils.getTestArray(0));
assertEquals(OperationStatus.SUCCESS, myDb.put(null, key, data));
/* Close and reopen. */
myDb.close();
env.close();
myDb = initEnvAndDb(false, false, false, null);
/*
* Preload the entire database. In JE 2.0.54 this would cause a
* NullPointerException.
*/
myDb.preload(100000);
myDb.close();
env.close();
}
public void testDbClose()
throws Throwable {
/* Set up a test db */
Database myDb = initEnvAndDb(false, false, true, null);
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
Transaction txn = env.beginTransaction(null, null);
for (int i = 2500; i > 0; i--) {
key.setData(TestUtils.getTestArray(i));
data.setData(TestUtils.getTestArray(i));
assertEquals(OperationStatus.SUCCESS,
myDb.put(txn, key, data));
}
/* Create a cursor, use it, then close db without closing cursor. */
Cursor cursor = myDb.openCursor(txn, null);
OperationStatus status = cursor.getFirst(key, data, LockMode.DEFAULT);
try {
myDb.close();
fail("didn't throw DatabaseException for unclosed cursor");
} catch (DatabaseException DBE) {
}
txn.commit();
env.close();
}
public void testDbCloseUnopenedDb()
throws DatabaseException {
EnvironmentConfig envConfig = TestUtils.initEnvConfig();
envConfig.setTransactional(true);
envConfig.setAllowCreate(true);
env = new Environment(envHome, envConfig);
Database myDb = new Database(env);
try {
myDb.close();
} catch (DatabaseException DBE) {
fail("shouldn't catch DatabaseException for closing unopened db");
}
env.close();
}
/**
* Test that open cursor isn't possible on a closed database.
*/
public void testOpenCursor()
throws DatabaseException {
Database db = initEnvAndDb(true, false, true, null);
Cursor cursor = db.openCursor(null, null);
cursor.close();
db.close();
try {
db.openCursor(null, null);
fail("Should throw exception because databse is closed");
} catch (DatabaseException e) {
}
}
public void testBufferOverflowingPut()
throws Throwable {
try {
EnvironmentConfig envConfig = TestUtils.initEnvConfig();
envConfig.setTransactional(true);
//envConfig.setConfigParam("je.log.totalBufferBytes", "5000");
envConfig.setAllowCreate(true);
env = new Environment(envHome, envConfig);
DatabaseConfig dbConfig = new DatabaseConfig();
dbConfig.setSortedDuplicates(true);
dbConfig.setAllowCreate(true);
dbConfig.setTransactional(true);
Database myDb = env.openDatabase(null, "testDB", dbConfig);
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry(new byte[10000000]);
DatabaseEntry getData = new DatabaseEntry();
try {
key.setData(TestUtils.getTestArray(10));
myDb.put(null, key, data);
} catch (DatabaseException DE) {
fail("unexpected DatabaseException");
}
myDb.close();
env.close();
env = null;
} catch (Throwable t) {
t.printStackTrace();
throw t;
}
}
/**
* Set up the environment and db.
*/
private Database initEnvAndDb(boolean dontRunEvictor,
boolean allowDuplicates,
boolean transactional,
String memSize)
throws DatabaseException {
EnvironmentConfig envConfig = TestUtils.initEnvConfig();
envConfig.setTransactional(transactional);
envConfig.setConfigParam
(EnvironmentParams.ENV_CHECK_LEAKS.getName(), "false");
envConfig.setConfigParam(EnvironmentParams.NODE_MAX.getName(), "6");
envConfig.setConfigParam(EnvironmentParams.NODE_MAX_DUPTREE.getName(),
"6");
envConfig.setTxnNoSync(Boolean.getBoolean(TestUtils.NO_SYNC));
if (dontRunEvictor) {
envConfig.setConfigParam(EnvironmentParams.
ENV_RUN_EVICTOR.getName(),
"false");
/*
* Don't let critical eviction run or it will interfer with the
* preload test.
*/
envConfig.setConfigParam(EnvironmentParams.
EVICTOR_CRITICAL_PERCENTAGE.getName(),
"500");
}
if (memSize != null) {
envConfig.setConfigParam(EnvironmentParams.
MAX_MEMORY.getName(),
memSize);
}
envConfig.setAllowCreate(true);
env = new Environment(envHome, envConfig);
// Make a db and open it
DatabaseConfig dbConfig = new DatabaseConfig();
dbConfig.setSortedDuplicates(allowDuplicates);
dbConfig.setAllowCreate(true);
dbConfig.setTransactional(transactional);
Database myDb = env.openDatabase(null, "testDB", dbConfig);
return myDb;
}
/**
* X'd out because this is expected to be used in the debugger to set
* specific breakpoints and step through in a synchronous manner.
*/
private Database pNOCDb;
public void xxtestPutNoOverwriteConcurrently()
throws Throwable {
pNOCDb = initEnvAndDb(true, true, true, null);
JUnitThread tester1 =
new JUnitThread("testNonBlocking1") {
public void testBody() {
try {
Transaction txn1 = env.beginTransaction(null, null);
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
key.setData(TestUtils.getTestArray(1));
data.setData(TestUtils.getTestArray(1));
OperationStatus status =
pNOCDb.putNoOverwrite(txn1, key, data);
txn1.commit();
System.out.println("thread1: " + status);
} catch (DatabaseException DBE) {
DBE.printStackTrace();
fail("caught DatabaseException " + DBE);
}
}
};
JUnitThread tester2 =
new JUnitThread("testNonBlocking2") {
public void testBody() {
try {
Transaction txn2 = env.beginTransaction(null, null);
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
key.setData(TestUtils.getTestArray(1));
data.setData(TestUtils.getTestArray(2));
OperationStatus status =
pNOCDb.putNoOverwrite(txn2, key, data);
txn2.commit();
System.out.println("thread2: " + status);
} catch (DatabaseException DBE) {
DBE.printStackTrace();
fail("caught DatabaseException " + DBE);
}
}
};
tester1.start();
tester2.start();
tester1.finishTest();
tester2.finishTest();
}
}