/*
Copyright (C) 2007 Mobixess Inc. http://www.java-objects-database.com
This file is part of the JODB (Java Objects Database) open source project.
JODB is free software; you can redistribute it and/or modify it under
the terms of version 2 of the GNU General Public License as published
by the Free Software Foundation.
JODB is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package com.mobixess.jodb.tests;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Random;
import com.mobixess.jodb.core.JODBConfig;
import com.mobixess.jodb.core.JODBSessionContainer;
import com.mobixess.jodb.core.JodbMini;
import com.mobixess.jodb.core.index.JODBIndexingAgent;
import com.mobixess.jodb.core.index.JODBIndexingRootAgent;
import com.mobixess.jodb.core.query.JODBQueryList;
import com.mobixess.jodb.core.transaction.ITransactionListener;
import com.mobixess.jodb.core.transaction.JODBSession;
import com.mobixess.jodb.soda.api.Query;
import com.mobixess.jodb.tests.testobjects.ObjectA;
public class IndexingTests {
private static int _testCounter =0;
private static String TEST_DATA_DIR = "./testData/IndexingTests/";
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
IndexingTests indexingTests = new IndexingTests();
indexingTests.randomAddTest();
indexingTests.randomAddSearchWithIndexTest();
indexingTests.sortingTest();
indexingTests.simpleIndexAdd(true);
indexingTests.simpleIndexAdd(false);
System.out.println("Test complete");
}
public void simpleIndexAdd(boolean reopen) throws Exception{
File testFileDir = new File(TEST_DATA_DIR);
testFileDir.mkdirs();
File testFile = new File(testFileDir,SimpleAddTest.class.getSimpleName()+(_testCounter++)+".jdb");
testFile.delete();
if(testFile.exists()){
throw new Exception();
}
JODBSessionContainer sessionContainer = getContainerForFile(testFile);
sessionContainer.configureIndex(ObjectA.class, "_val2", true);
for (int i = 1000; i >= 0; --i) {
ObjectA objectA = new ObjectA((byte)2,(byte)i,null);
sessionContainer.set(objectA);
}
//sessionContainer.printFileMap();
sessionContainer.commit();
if(reopen){
sessionContainer.close();
sessionContainer = getContainerForFile(testFile);
}
//System.err.println("_________________________________________________________");
//sessionContainer.printFileMap();
JODBQueryList list = sessionContainer.getAllObjects();
int total = list.size();
for (int i = 0; i < total; i++) {
ObjectA nextObj = (ObjectA) list.get(i);
nextObj.setVal2((short) i);
sessionContainer.set(nextObj);
}
sessionContainer.commit();
if(reopen){
sessionContainer.close();
sessionContainer = getContainerForFile(testFile);
}
sessionContainer.close();
}
public void randomAddTest() throws Exception{
randomAddTest(true,false);
randomAddTest(true,true);
randomAddTest(false,false);
randomAddTest(false,true);
}
public void randomAddTest(boolean reopen, boolean ascending) throws Exception{
System.err.println("Random test start");
File testFileDir = new File(TEST_DATA_DIR);
testFileDir.mkdirs();
File testFile = new File(testFileDir,SimpleAddTest.class.getSimpleName()+(_testCounter++)+".jdb");
testFile.delete();
if(testFile.exists()){
throw new Exception();
}
JODBSessionContainer sessionContainer = getContainerForFile(testFile);
sessionContainer.configureIndex(ObjectA.class, "_val2", true);
Random random = new Random(376538);
int maxObjects = 10000;
for (int i = maxObjects-1; i >= 0; --i) {
short next = (short) random.nextInt();
ObjectA objectA = new ObjectA((byte)2,next ,null);
sessionContainer.set(objectA);
}
sessionContainer.commit();
if(reopen){
sessionContainer.close();
sessionContainer = getContainerForFile(testFile);
}
Query query = sessionContainer.query();
query.constrain(ObjectA.class);
if(ascending){
query.descend("_val2").orderAscending();
}else{
query.descend("_val2").orderDescending();
}
JODBQueryList list = (JODBQueryList) query.execute();
if(list.size() != maxObjects){
throw new RuntimeException();
}
ObjectA prev = null;
for (int i = 0; i < list.size(); i++) {
ObjectA current = (ObjectA) list.get(i);
//System.err.println("Indexing Random test iter #="+i);
if(prev!=null){
if(ascending){
if( prev.getVal2() > current.getVal2() ){
throw new RuntimeException();
}
}else if(prev.getVal2() < current.getVal2() ){
JODBIndexingAgent indexingAgent = sessionContainer.getIndexingAgent(ObjectA.class.getDeclaredField("_val2") );
long prevID = sessionContainer.getPersistenceStatistics(prev).getObjectID();
long currentID = sessionContainer.getPersistenceStatistics(current).getObjectID();
int prevPosition = indexingAgent.linearIdSearch(prevID);
int currentPosition = indexingAgent.linearIdSearch(currentID);
throw new RuntimeException(""+prevID+" "+prevPosition+" "+ currentID+" "+currentPosition);
}
}
prev = current;
}
//System.err.println("_________________________________________________________");
//sessionContainer.printFileMap();
list = sessionContainer.getAllObjects();
int total = list.size();
for (int i = 0; i < total; i++) {
ObjectA nextObj = (ObjectA) list.get(i);
nextObj.setVal2((short) i);
sessionContainer.set(nextObj);
}
sessionContainer.commit();
if(reopen){
sessionContainer.close();
sessionContainer = getContainerForFile(testFile);
}
query = sessionContainer.query();
query.constrain(ObjectA.class);
if(ascending){
query.descend("_val2").orderAscending();
}else{
query.descend("_val2").orderDescending();
}
list = (JODBQueryList) query.execute();
if(list.size() == 0){
throw new RuntimeException();
}
prev = null;
for (int i = 0; i < list.size(); i++) {
//System.err.println("Indexing Random test iter1 #="+i);
ObjectA current = (ObjectA) list.get(i);
if(prev!=null){
if(ascending){
if( prev.getVal2() > current.getVal2() ){
throw new RuntimeException();
}
}else if(prev.getVal2() < current.getVal2() ){
JODBIndexingAgent indexingAgent = sessionContainer.getIndexingAgent(ObjectA.class.getDeclaredField("_val2") );
long prevID = sessionContainer.getPersistenceStatistics(prev).getObjectID();
long currentID = sessionContainer.getPersistenceStatistics(current).getObjectID();
int prevPosition = indexingAgent.linearIdSearch(prevID);
int currentPosition = indexingAgent.linearIdSearch(currentID);
throw new RuntimeException(" i="+i+" -->"+prevID+" "+prevPosition+" "+prev.getVal2()+" "+ currentID+" "+currentPosition+" "+current.getVal2());
}
}
prev = current;
}
sessionContainer.close();
System.err.println("Random test finish");
}
public void sortingTest() throws Exception{
sortingTest(true,true);
sortingTest(true,false);
sortingTest(false,true);
sortingTest(false,false);
}
public void sortingTest(boolean reopen, boolean ascending) throws Exception{
File testFileDir = new File(TEST_DATA_DIR);
testFileDir.mkdirs();
File testFile = new File(testFileDir,SimpleAddTest.class.getSimpleName()+(_testCounter++)+".jdb");
testFile.delete();
JODBSessionContainer sessionContainer = getContainerForFile(testFile);
sessionContainer.configureIndex(ObjectA.class, "_val1", true);
sessionContainer.configureIndex(ObjectA.class, "_val2", true);
ObjectA objectA1 = new ObjectA((byte)0,(short)2,null);
ObjectA objectA2 = new ObjectA((byte)0,(short)1,null);
ObjectA objectA3 = new ObjectA((byte)0,(short)3,null);
sessionContainer.set(objectA1);
sessionContainer.set(objectA2);
sessionContainer.set(objectA3);
sessionContainer.commit();
if(reopen){
sessionContainer.close();
sessionContainer = getContainerForFile(testFile);
}
Query query = sessionContainer.query();
query.constrain(ObjectA.class);
if(ascending){
query.descend("_val1").orderAscending();
}else{
query.descend("_val1").orderDescending();
}
if(ascending){
query.descend("_val2").orderAscending();
}else{
query.descend("_val2").orderDescending();
}
JODBConfig.setCacheOnSortOperations(false);
List list = query.execute();
if(list.size() == 0){
throw new RuntimeException();
}
ObjectA prev = null;
for (int i = 0; i < list.size(); i++) {
ObjectA current = (ObjectA) list.get(i);
if(prev!=null){
if(ascending){
if( prev.getVal2() > current.getVal2() ){
throw new RuntimeException();
}
}else if(prev.getVal2() < current.getVal2() ){
throw new RuntimeException();
}
}
prev = current;
}
if(reopen){
sessionContainer.close();
sessionContainer = getContainerForFile(testFile);
}
query = sessionContainer.query();
query.constrain(ObjectA.class);
if(ascending){
query.descend("_val2").orderAscending();
}else{
query.descend("_val2").orderDescending();
}
JODBConfig.setCacheOnSortOperations(true);
list = query.execute();
if(list.size() == 0){
throw new RuntimeException();
}
prev = null;
for (int i = 0; i < list.size(); i++) {
ObjectA current = (ObjectA) list.get(i);
if(prev!=null){
if(ascending){
if( prev.getVal2() > current.getVal2() ){
throw new RuntimeException();
}
}else if(prev.getVal2() < current.getVal2() ){
throw new RuntimeException();
}
}
prev = current;
}
JODBConfig.setCacheOnSortOperations(true);
sessionContainer.close();
}
public void randomAddSearchWithIndexTest() throws Exception{
randomAddSearchWithIndexTest(false);
randomAddSearchWithIndexTest(true);
}
public JODBSessionContainer getContainerForFile(File file) throws IOException{
return (JODBSessionContainer) JodbMini.open(file);
}
public void randomAddSearchWithIndexTest(boolean reopen) throws Exception{
File testFileDir = new File(TEST_DATA_DIR);
testFileDir.mkdirs();
File testFile = new File(testFileDir,SimpleAddTest.class.getSimpleName()+(_testCounter++)+".jdb");
testFile.delete();
if(testFile.exists()){
throw new Exception();
}
JODBSessionContainer sessionContainer = getContainerForFile(testFile);
Random random = new Random(376538);
int negatives = 0;
int maxObjects = 10000;
for (int i = maxObjects-1; i >= 0; --i) {
short next = (short) random.nextInt();
if(next<0){
negatives++;
}
ObjectA objectA = new ObjectA((byte)2,next ,null);
sessionContainer.set(objectA);
}
if(negatives ==0 ){
throw new RuntimeException();
}
sessionContainer.commit();
if(reopen){
sessionContainer.close();
sessionContainer = getContainerForFile(testFile);
}
Query query = sessionContainer.query();
query.constrain(ObjectA.class);
query.descend("_val2").constrain(0).smaller();
long queryStart = System.currentTimeMillis();
JODBQueryList list = (JODBQueryList) query.execute();
long noneIndexQuery = System.currentTimeMillis() - queryStart;
System.err.println("noneIndexQuery="+noneIndexQuery);
if(list.size() != negatives){
throw new RuntimeException();
}
sessionContainer.configureIndex(ObjectA.class, "_val2", true);
if(reopen){
sessionContainer.close();
sessionContainer = getContainerForFile(testFile);
}
query = sessionContainer.query();
query.constrain(ObjectA.class);
query.descend("_val2").constrain(0).smaller();
queryStart = System.currentTimeMillis();
list = (JODBQueryList) query.execute();
long queryWithIndex = System.currentTimeMillis() - queryStart;
System.err.println("queryWithIndex="+queryWithIndex);
if(list.size() != negatives){
throw new RuntimeException();
}
sessionContainer.commit();
for (int i = 0; i < list.size(); i++) {
ObjectA current = (ObjectA) list.get(i);
if(current.getVal2()>=0){
throw new RuntimeException();
}
}
sessionContainer.commit();
sessionContainer.close();
}
private static class TransactionListener implements ITransactionListener{
private JODBSessionContainer _sessionContainer;
private Field _indexingField;
public TransactionListener(JODBSessionContainer sessionContainer, Field indexingField) {
_sessionContainer = sessionContainer;
_indexingField = indexingField;
}
public void onCommitFinished(Object objectToBeCommited, JODBSession session) {
// TODO Auto-generated method stub
throw new RuntimeException("Not Implemented");
//
}
public void onCommitStarted(Object objectToBeCommited, JODBSession session) {
try {
JODBIndexingRootAgent agent = session.getIndexingRootAgent();
JODBIndexingAgent indexingAgent = agent.getIndexingAgent(_indexingField, session.getBase());
System.err.println("Commit started for object ");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void onSet(Object object, JODBSession session) {
// TODO Auto-generated method stub
throw new RuntimeException("Not Implemented");
//
}
}
}