/* $Id$ Copyright (C) 2008 by The Regents of the University of California Redistribution of this file is permitted under the terms of the BSD license Date: 04/04/2008 Author: Alexander Behm */ #include "ftsearchermem.h" #include "common/query.h" #include "common/simmetric.h" #include "listmerger/divideskipmerger.h" #include using namespace std; using namespace tr1; // global vars for performing unittests StringContainerVector strContainer; vector queries; vector queryStrings; vector expectedResults; GramGenFixedLen gramGen(3); SimMetricEd simMetric(gramGen); void init(); void deinit(); bool compareResults(vector& results, const string& identifier); bool testFtIndexerSimple(); int main() { init(); bool passed = false; cout << "NOTE: THESE TESTS MAY TAKE SOME MINUTES, PLEASE BE PATIENT" << endl << endl; cout << "TEST FtIndexerSimple:" << endl; passed = testFtIndexerSimple(); if(passed) cout << "--- PASSED ---" << endl; else cout << "--- FAILED ---" << endl; cout << endl; deinit(); return 0; } void init() { cout << "INITIALIZING UNITTEST" << endl; vector prefixes; prefixes.push_back("string"); prefixes.push_back("example"); prefixes.push_back("test"); prefixes.push_back("hello"); prefixes.push_back("world"); prefixes.push_back("foo"); prefixes.push_back("bar"); vector suffixes; suffixes.push_back("1"); suffixes.push_back("10"); suffixes.push_back("100"); suffixes.push_back("2"); suffixes.push_back("20"); suffixes.push_back("200"); suffixes.push_back("3"); suffixes.push_back("30"); suffixes.push_back("300"); for(unsigned j = 0; j < prefixes.size(); j++) for(unsigned i = 0; i < suffixes.size(); i++) strContainer.insertString(prefixes.at(j) + suffixes.at(i)); // create queries queries.push_back(new Query("xample", simMetric, 2.0f)); queries.push_back(new Query("ring1", simMetric, 2.0f)); queries.push_back(new Query("wrld", simMetric, 2.0f)); queries.push_back(new Query("fooa", simMetric, 2.0f)); queries.push_back(new Query("br", simMetric, 2.0f)); for(unsigned i = 0; i < 10; i++) { queryStrings.push_back("xample"); queryStrings.push_back("ring1"); queryStrings.push_back("wrld"); queryStrings.push_back("fooa"); queryStrings.push_back("br"); } // execute queries on simple index without filters to get expected results FtIndexerSimple<> indexer(&strContainer, &gramGen); indexer.buildIndex(false); DivideSkipMerger<> merger; FtSearcherMem<> searcher(&merger, &indexer); for(vector::iterator iter = queries.begin(); iter != queries.end(); iter++) searcher.search(**iter, expectedResults); // sort expected results sort(expectedResults.begin(), expectedResults.end()); cout << "UNITTEST INITIALIZED" << endl << endl; } void deinit() { for(vector::iterator iter = queries.begin(); iter != queries.end(); iter++) delete *iter; } bool compareResults(vector& results, const string& identifier) { // compare results sort(results.begin(), results.end()); if(results.size() != expectedResults.size()) { cout << "FAILED IN " << identifier << endl; return false; } for(unsigned i = 0; i < results.size(); i++) if(results.at(i) != expectedResults.at(i)) { cout << "FAILED IN " << identifier << endl; return false; } return true; } bool testFtIndexerSimple() { GramGenFixedLen gramGen(3); SimMetricEd simMetric(gramGen); DivideSkipMerger<> merger; FtSearcherMem<> searcher(&merger); bool success = true; // try different filters with different fanouts and values for max string length for(unsigned maxStrLength = 10; maxStrLength <= 200; maxStrLength += 10) { for(unsigned fanout = 1; fanout <= 10; fanout++) { vector results; // begin block for indexer with lengthfilter { FtIndexerSimple<> indexer(&strContainer, &gramGen, maxStrLength, fanout); indexer.addFilter(new LengthFilter(maxStrLength)); indexer.buildIndex(false); // execute queries and compute results results.clear(); searcher.setFtIndexer(&indexer); for(vector::iterator iter = queries.begin(); iter != queries.end(); iter++) searcher.search(**iter, results); success = success && compareResults(results, "FtIndexerSimple, LENGTH FILTER BUILT"); // save index, load it into differrent indexer and repeat indexer.saveIndex("UnittestIndex.ix"); FtIndexerSimple<> loadedIndexer(&strContainer); loadedIndexer.loadIndex("UnittestIndex.ix"); if(loadedIndexer.filterTypes.at(0)->getType() != FT_LENGTH) { cout << "FtIndexerSimple, LENGTH FILTER LOADED INCORRECTLY" << endl; success = false; } results.clear(); searcher.setFtIndexer(&loadedIndexer); for(vector::iterator iter = queries.begin(); iter != queries.end(); iter++) searcher.search(**iter, results); success = success && compareResults(results, "FtIndexerSimple, LENGTH FILTER LOADED"); } // begin block for indexer with checksum filter { FtIndexerSimple<> indexer(&strContainer, &gramGen, maxStrLength, fanout); indexer.addFilter(new ChecksumFilter(maxStrLength)); indexer.buildIndex(false); // execute queries and compute results searcher.setFtIndexer(&indexer); results.clear(); for(vector::iterator iter = queries.begin(); iter != queries.end(); iter++) searcher.search(**iter, results); success = success && compareResults(results, "FtIndexerSimple, CHECKSUM FILTER BUILT"); // save index, load it into differrent indexer and repeat indexer.saveIndex("UnittestIndex.ix"); FtIndexerSimple<> loadedIndexer(&strContainer); loadedIndexer.loadIndex("UnittestIndex.ix"); if(loadedIndexer.filterTypes.at(0)->getType() != FT_CHECKSUM) { cout << "FtIndexerSimple, CHECKSUM FILTER LOADED INCORRECTLY" << endl; success = false; } results.clear(); searcher.setFtIndexer(&loadedIndexer); for(vector::iterator iter = queries.begin(); iter != queries.end(); iter++) searcher.search(**iter, results); success = success && compareResults(results, "FtIndexerSimple, CHECKSUM FILTER LOADED"); } // begin block for indexer with both length and checksum filters { FtIndexerSimple<> indexer(&strContainer, &gramGen, maxStrLength, fanout); indexer.addFilter(new LengthFilter(maxStrLength)); indexer.addFilter(new ChecksumFilter(maxStrLength)); indexer.buildIndex(false); // execute queries and compute results searcher.setFtIndexer(&indexer); results.clear(); for(vector::iterator iter = queries.begin(); iter != queries.end(); iter++) searcher.search(**iter, results); success = success && compareResults(results, "FtIndexerSimple, LENGTH+CHECKSUM FILTER BUILT"); // save index, load it into differrent indexer and repeat indexer.saveIndex("UnittestIndex.ix"); FtIndexerSimple<> loadedIndexer(&strContainer); loadedIndexer.loadIndex("UnittestIndex.ix"); if(loadedIndexer.filterTypes.at(0)->getType() != FT_LENGTH && loadedIndexer.filterTypes.at(1)->getType() != FT_CHECKSUM) { cout << "FtIndexerSimple, LENGTH+CHECKSUM FILTER LOADED INCORRECTLY" << endl; success = false; } results.clear(); searcher.setFtIndexer(&loadedIndexer); for(vector::iterator iter = queries.begin(); iter != queries.end(); iter++) searcher.search(**iter, results); success = success && compareResults(results, "FtIndexerSimple, LENGTH FILTER LOADED"); } } } return success; }