2011-09-13 17:44:24 +00:00
|
|
|
/*-
|
|
|
|
* See the file LICENSE for redistribution information.
|
|
|
|
*
|
2012-11-14 21:35:20 +00:00
|
|
|
* Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
|
2011-09-13 17:44:24 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
using System;
|
|
|
|
using System.Collections;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.IO;
|
|
|
|
using System.Text;
|
|
|
|
using System.Threading;
|
|
|
|
using System.Xml;
|
|
|
|
using NUnit.Framework;
|
|
|
|
using BerkeleyDB;
|
|
|
|
|
|
|
|
namespace CsharpAPITest
|
|
|
|
{
|
|
|
|
[TestFixture]
|
|
|
|
public class SecondaryHashDatabaseTest : CSharpTestFixture
|
|
|
|
{
|
|
|
|
|
|
|
|
[TestFixtureSetUp]
|
|
|
|
public void SetUpTestFixture()
|
|
|
|
{
|
|
|
|
testFixtureName = "SecondaryHashDatabaseTest";
|
|
|
|
base.SetUpTestfixture();
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void TestHashFunction()
|
|
|
|
{
|
|
|
|
testName = "TestHashFunction";
|
|
|
|
SetUpTest(true);
|
|
|
|
string dbFileName = testHome + "/" + testName + ".db";
|
|
|
|
string dbSecFileName = testHome + "/" +
|
|
|
|
testName + "_sec.db";
|
|
|
|
|
|
|
|
// Open a primary hash database.
|
|
|
|
HashDatabaseConfig dbConfig =
|
|
|
|
new HashDatabaseConfig();
|
|
|
|
dbConfig.Creation = CreatePolicy.IF_NEEDED;
|
|
|
|
HashDatabase hashDB = HashDatabase.Open(
|
|
|
|
dbFileName, dbConfig);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Define hash function and open a secondary
|
|
|
|
* hash database.
|
|
|
|
*/
|
|
|
|
SecondaryHashDatabaseConfig secDBConfig =
|
|
|
|
new SecondaryHashDatabaseConfig(hashDB, null);
|
|
|
|
secDBConfig.HashFunction =
|
|
|
|
new HashFunctionDelegate(HashFunction);
|
|
|
|
secDBConfig.Creation = CreatePolicy.IF_NEEDED;
|
|
|
|
SecondaryHashDatabase secDB =
|
|
|
|
SecondaryHashDatabase.Open(dbSecFileName,
|
|
|
|
secDBConfig);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Confirm the hash function defined in the configuration.
|
|
|
|
* Call the hash function and the one from secondary
|
|
|
|
* database. If they return the same value, then the hash
|
|
|
|
* function is configured successfully.
|
|
|
|
*/
|
|
|
|
uint data = secDB.HashFunction(BitConverter.GetBytes(1));
|
|
|
|
Assert.AreEqual(0, data);
|
|
|
|
|
|
|
|
// Close all.
|
|
|
|
secDB.Close();
|
|
|
|
hashDB.Close();
|
|
|
|
}
|
|
|
|
|
|
|
|
public uint HashFunction(byte[] data)
|
|
|
|
{
|
|
|
|
data[0] = 0;
|
|
|
|
return BitConverter.ToUInt32(data, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void TestCompare()
|
|
|
|
{
|
|
|
|
testName = "TestCompare";
|
|
|
|
SetUpTest(true);
|
|
|
|
string dbFileName = testHome + "/" + testName + ".db";
|
|
|
|
string dbSecFileName = testHome + "/" + testName +
|
|
|
|
"_sec.db";
|
|
|
|
|
|
|
|
// Open a primary hash database.
|
|
|
|
HashDatabaseConfig dbConfig =
|
|
|
|
new HashDatabaseConfig();
|
|
|
|
dbConfig.Creation = CreatePolicy.ALWAYS;
|
|
|
|
HashDatabase db = HashDatabase.Open(
|
|
|
|
dbFileName, dbConfig);
|
|
|
|
|
|
|
|
// Open a secondary hash database.
|
|
|
|
SecondaryHashDatabaseConfig secConfig =
|
|
|
|
new SecondaryHashDatabaseConfig(null, null);
|
|
|
|
secConfig.Creation = CreatePolicy.IF_NEEDED;
|
|
|
|
secConfig.Primary = db;
|
|
|
|
secConfig.Compare =
|
|
|
|
new EntryComparisonDelegate(SecondaryEntryComparison);
|
|
|
|
SecondaryHashDatabase secDB =
|
|
|
|
SecondaryHashDatabase.Open(dbSecFileName, secConfig);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the compare function set in the configuration
|
|
|
|
* and run it in a comparison to see if it is alright.
|
|
|
|
*/
|
|
|
|
DatabaseEntry dbt1, dbt2;
|
|
|
|
dbt1 = new DatabaseEntry(
|
|
|
|
BitConverter.GetBytes((int)257));
|
|
|
|
dbt2 = new DatabaseEntry(
|
|
|
|
BitConverter.GetBytes((int)255));
|
|
|
|
Assert.Less(0, secDB.Compare(dbt1, dbt2));
|
|
|
|
|
|
|
|
secDB.Close();
|
|
|
|
db.Close();
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void TestDuplicates()
|
|
|
|
{
|
|
|
|
testName = "TestDuplicates";
|
|
|
|
SetUpTest(true);
|
|
|
|
string dbFileName = testHome + "/" + testName + ".db";
|
|
|
|
string dbSecFileName = testHome + "/" + testName
|
|
|
|
+ "_sec.db";
|
|
|
|
|
|
|
|
// Open a primary hash database.
|
|
|
|
HashDatabaseConfig dbConfig =
|
|
|
|
new HashDatabaseConfig();
|
|
|
|
dbConfig.Creation = CreatePolicy.ALWAYS;
|
|
|
|
HashDatabase db = HashDatabase.Open(
|
|
|
|
dbFileName, dbConfig);
|
|
|
|
|
|
|
|
// Open a secondary hash database.
|
|
|
|
SecondaryHashDatabaseConfig secConfig =
|
|
|
|
new SecondaryHashDatabaseConfig(null, null);
|
|
|
|
secConfig.Primary = db;
|
|
|
|
secConfig.Duplicates = DuplicatesPolicy.SORTED;
|
|
|
|
secConfig.Creation = CreatePolicy.IF_NEEDED;
|
|
|
|
SecondaryHashDatabase secDB =
|
|
|
|
SecondaryHashDatabase.Open(
|
|
|
|
dbSecFileName, secConfig);
|
|
|
|
|
|
|
|
// Confirm the duplicate in opened secondary database.
|
|
|
|
Assert.AreEqual(DuplicatesPolicy.SORTED,
|
|
|
|
secDB.Duplicates);
|
|
|
|
|
|
|
|
secDB.Close();
|
|
|
|
db.Close();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Tests to all Open() share the same configuration in
|
|
|
|
* AllTestData.xml.
|
|
|
|
*/
|
|
|
|
[Test]
|
|
|
|
public void TestOpen()
|
|
|
|
{
|
|
|
|
testName = "TestOpen";
|
|
|
|
SetUpTest(true);
|
|
|
|
string dbFileName = testHome + "/" + testName + ".db";
|
|
|
|
string dbSecFileName = testHome + "/" +
|
|
|
|
testName + "_sec.db";
|
|
|
|
|
|
|
|
OpenSecHashDB(testFixtureName, "TestOpen",
|
|
|
|
dbFileName, dbSecFileName, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void TestOpenWithDBName()
|
|
|
|
{
|
|
|
|
testName = "TestOpenWithDBName";
|
|
|
|
SetUpTest(true);
|
|
|
|
string dbFileName = testHome + "/" + testName + ".db";
|
|
|
|
string dbSecFileName = testHome + "/" +
|
|
|
|
testName + "_sec.db";
|
|
|
|
|
|
|
|
OpenSecHashDB(testFixtureName, "TestOpen",
|
|
|
|
dbFileName, dbSecFileName, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void OpenSecHashDB(string className,
|
|
|
|
string funName, string dbFileName, string dbSecFileName,
|
|
|
|
bool ifDBName)
|
|
|
|
{
|
|
|
|
XmlElement xmlElem = Configuration.TestSetUp(
|
|
|
|
className, funName);
|
|
|
|
|
|
|
|
// Open a primary recno database.
|
|
|
|
HashDatabaseConfig primaryDBConfig =
|
|
|
|
new HashDatabaseConfig();
|
|
|
|
primaryDBConfig.Creation = CreatePolicy.IF_NEEDED;
|
|
|
|
HashDatabase primaryDB;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If secondary database name is given, the primary
|
|
|
|
* database is also opened with database name.
|
|
|
|
*/
|
|
|
|
if (ifDBName == false)
|
|
|
|
primaryDB = HashDatabase.Open(dbFileName,
|
|
|
|
primaryDBConfig);
|
|
|
|
else
|
|
|
|
primaryDB = HashDatabase.Open(dbFileName,
|
|
|
|
"primary", primaryDBConfig);
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
// Open a new secondary database.
|
|
|
|
SecondaryHashDatabaseConfig secHashDBConfig =
|
|
|
|
new SecondaryHashDatabaseConfig(
|
|
|
|
primaryDB, null);
|
|
|
|
SecondaryHashDatabaseConfigTest.Config(
|
|
|
|
xmlElem, ref secHashDBConfig, false);
|
|
|
|
secHashDBConfig.Creation =
|
|
|
|
CreatePolicy.IF_NEEDED;
|
|
|
|
|
|
|
|
SecondaryHashDatabase secHashDB;
|
|
|
|
if (ifDBName == false)
|
|
|
|
secHashDB = SecondaryHashDatabase.Open(
|
|
|
|
dbSecFileName, secHashDBConfig);
|
|
|
|
else
|
|
|
|
secHashDB = SecondaryHashDatabase.Open(
|
|
|
|
dbSecFileName, "secondary",
|
|
|
|
secHashDBConfig);
|
|
|
|
|
|
|
|
// Close the secondary database.
|
|
|
|
secHashDB.Close();
|
|
|
|
|
|
|
|
// Open the existing secondary database.
|
|
|
|
SecondaryDatabaseConfig secDBConfig =
|
|
|
|
new SecondaryDatabaseConfig(
|
|
|
|
primaryDB, null);
|
|
|
|
|
|
|
|
SecondaryDatabase secDB;
|
|
|
|
if (ifDBName == false)
|
|
|
|
secDB = SecondaryHashDatabase.Open(
|
|
|
|
dbSecFileName, secDBConfig);
|
|
|
|
else
|
|
|
|
secDB = SecondaryHashDatabase.Open(
|
|
|
|
dbSecFileName, "secondary", secDBConfig);
|
|
|
|
|
|
|
|
// Close secondary database.
|
|
|
|
secDB.Close();
|
|
|
|
}
|
|
|
|
catch (DatabaseException)
|
|
|
|
{
|
|
|
|
throw new TestException();
|
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
// Close primary database.
|
|
|
|
primaryDB.Close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void TestOpenWithinTxn()
|
|
|
|
{
|
|
|
|
testName = "TestOpenWithinTxn";
|
|
|
|
SetUpTest(true);
|
|
|
|
string dbFileName = testName + ".db";
|
|
|
|
string dbSecFileName = testName + "_sec.db";
|
|
|
|
|
|
|
|
OpenSecHashDBWithinTxn(testFixtureName,
|
|
|
|
"TestOpen", testHome, dbFileName,
|
|
|
|
dbSecFileName, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void TestOpenDBNameWithinTxn()
|
|
|
|
{
|
|
|
|
testName = "TestOpenDBNameWithinTxn";
|
|
|
|
SetUpTest(true);
|
|
|
|
string dbFileName = testName + ".db";
|
|
|
|
string dbSecFileName = testName + "_sec.db";
|
|
|
|
|
|
|
|
OpenSecHashDBWithinTxn(testFixtureName,
|
|
|
|
"TestOpen", testHome, dbFileName,
|
|
|
|
dbSecFileName, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void OpenSecHashDBWithinTxn(string className,
|
|
|
|
string funName, string home, string dbFileName,
|
|
|
|
string dbSecFileName, bool ifDbName)
|
|
|
|
{
|
|
|
|
XmlElement xmlElem = Configuration.TestSetUp(
|
|
|
|
className, funName);
|
|
|
|
|
|
|
|
// Open an environment.
|
|
|
|
DatabaseEnvironmentConfig envConfig =
|
|
|
|
new DatabaseEnvironmentConfig();
|
|
|
|
envConfig.Create = true;
|
|
|
|
envConfig.UseTxns = true;
|
|
|
|
envConfig.UseMPool = true;
|
|
|
|
envConfig.UseLogging = true;
|
|
|
|
DatabaseEnvironment env = DatabaseEnvironment.Open(
|
|
|
|
home, envConfig);
|
|
|
|
|
|
|
|
// Open a primary hash database.
|
|
|
|
Transaction openDBTxn = env.BeginTransaction();
|
|
|
|
HashDatabaseConfig dbConfig =
|
|
|
|
new HashDatabaseConfig();
|
|
|
|
dbConfig.Creation = CreatePolicy.IF_NEEDED;
|
|
|
|
dbConfig.Env = env;
|
|
|
|
HashDatabase db = HashDatabase.Open(
|
|
|
|
dbFileName, dbConfig, openDBTxn);
|
|
|
|
openDBTxn.Commit();
|
|
|
|
|
|
|
|
// Open a secondary hash database.
|
|
|
|
Transaction openSecTxn = env.BeginTransaction();
|
|
|
|
SecondaryHashDatabaseConfig secDBConfig =
|
|
|
|
new SecondaryHashDatabaseConfig(db,
|
|
|
|
new SecondaryKeyGenDelegate(SecondaryKeyGen));
|
|
|
|
SecondaryHashDatabaseConfigTest.Config(xmlElem,
|
|
|
|
ref secDBConfig, false);
|
|
|
|
secDBConfig.HashFunction = null;
|
|
|
|
secDBConfig.Env = env;
|
|
|
|
SecondaryHashDatabase secDB;
|
|
|
|
if (ifDbName == false)
|
|
|
|
secDB = SecondaryHashDatabase.Open(
|
|
|
|
dbSecFileName, secDBConfig, openSecTxn);
|
|
|
|
else
|
|
|
|
secDB = SecondaryHashDatabase.Open(
|
|
|
|
dbSecFileName, "secondary", secDBConfig,
|
|
|
|
openSecTxn);
|
|
|
|
openSecTxn.Commit();
|
|
|
|
|
|
|
|
// Confirm its flags configured in secDBConfig.
|
|
|
|
Confirm(xmlElem, secDB, true);
|
|
|
|
secDB.Close();
|
|
|
|
|
|
|
|
// Open the existing secondary database.
|
|
|
|
Transaction secTxn = env.BeginTransaction();
|
|
|
|
SecondaryDatabaseConfig secConfig =
|
|
|
|
new SecondaryDatabaseConfig(db,
|
|
|
|
new SecondaryKeyGenDelegate(SecondaryKeyGen));
|
|
|
|
secConfig.Env = env;
|
|
|
|
|
|
|
|
SecondaryDatabase secExDB;
|
|
|
|
if (ifDbName == false)
|
|
|
|
secExDB = SecondaryHashDatabase.Open(
|
|
|
|
dbSecFileName, secConfig, secTxn);
|
|
|
|
else
|
|
|
|
secExDB = SecondaryHashDatabase.Open(
|
|
|
|
dbSecFileName, "secondary", secConfig,
|
|
|
|
secTxn);
|
|
|
|
secExDB.Close();
|
|
|
|
secTxn.Commit();
|
|
|
|
|
|
|
|
db.Close();
|
|
|
|
env.Close();
|
|
|
|
}
|
|
|
|
|
|
|
|
public DatabaseEntry SecondaryKeyGen(
|
|
|
|
DatabaseEntry key, DatabaseEntry data)
|
|
|
|
{
|
|
|
|
DatabaseEntry dbtGen;
|
|
|
|
dbtGen = new DatabaseEntry(data.Data);
|
|
|
|
return dbtGen;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int SecondaryEntryComparison(
|
|
|
|
DatabaseEntry dbt1, DatabaseEntry dbt2)
|
|
|
|
{
|
|
|
|
int a, b;
|
|
|
|
a = BitConverter.ToInt32(dbt1.Data, 0);
|
|
|
|
b = BitConverter.ToInt32(dbt2.Data, 0);
|
|
|
|
return a - b;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void Confirm(XmlElement xmlElem,
|
|
|
|
SecondaryHashDatabase secDB, bool compulsory)
|
|
|
|
{
|
|
|
|
Configuration.ConfirmUint(xmlElem, "FillFactor",
|
|
|
|
secDB.FillFactor, compulsory);
|
|
|
|
Configuration.ConfirmUint(xmlElem, "NumElements",
|
|
|
|
secDB.TableSize, compulsory);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|