// BK> all test functions are the same except RAMDirectory constructor, so shared code moved here
void checkDir(CuTest *tc, MockRAMDirectory * ramDir) {

    // Check size
    CuAssertTrue(tc, ramDir->sizeInBytes == ramDir->getRecomputedSizeInBytes(), _T("RAMDir size"));

    // open reader to test document count
    IndexReader * reader = IndexReader::open(ramDir);
    CuAssertEquals(tc, docsToAdd, reader->numDocs(), _T("document count"));

    // open search to check if all doc's are there
    IndexSearcher * searcher = _CLNEW IndexSearcher(reader);

    // search for all documents
    Document doc;
    for (int i = 0; i < docsToAdd; i++) {
        searcher->doc(i, doc);
        CuAssertTrue(tc, doc.getField(_T("content")) != NULL, _T("content is NULL"));
    }

    // cleanup
    reader->close();
    searcher->close();
    _CLLDELETE(reader);
    _CLLDELETE(searcher);
}
void testEndThreadException(CuTest *tc) {

    const int MAX_DOCS=1500;
	RAMDirectory ram;
	WhitespaceAnalyzer an;
	IndexWriter* writer = _CLNEW IndexWriter(&ram, &an, true);

    // add some documents
    Document doc;
    for (int i = 0; i < MAX_DOCS; i++) {
        TCHAR * tmp = English::IntToEnglish(i);
        doc.add(* new Field(_T("content"), tmp, Field::STORE_YES | Field::INDEX_UNTOKENIZED));
        writer->addDocument(&doc);
        doc.clear();
        _CLDELETE_ARRAY( tmp );
    }

    CuAssertEquals(tc, MAX_DOCS, writer->docCount());
    
    writer->close();
	_CLLDELETE(writer);
    
    // this sequence is OK: delete searcher after search thread finish
    {
        IndexSearcher * searcher = _CLNEW IndexSearcher(&ram);
        _LUCENE_THREADID_TYPE thread = _LUCENE_THREAD_CREATE(&searchDocs, searcher);
        SCOPED_LOCK_MUTEX(searchMutex);

        CONDITION_WAIT(searchMutex, searchCondition);
//        _LUCENE_SLEEP(9999); //make sure that deleteMutex is being waited on...
        CONDITION_NOTIFYALL(deleteCondition);

        _LUCENE_THREAD_JOIN(thread);

        searcher->close();
        _CLLDELETE(searcher);
    }

    // this produces memory exception: delete searcher after search finish but before thread finish
    {
        IndexSearcher * searcher = _CLNEW IndexSearcher(&ram);
        _LUCENE_THREADID_TYPE thread = _LUCENE_THREAD_CREATE(&searchDocs, searcher);
        SCOPED_LOCK_MUTEX(searchMutex);

        CONDITION_WAIT(searchMutex, searchCondition);
        searcher->close();
        _CLLDELETE(searcher);
        CONDITION_NOTIFYALL(deleteCondition);

        _LUCENE_THREAD_JOIN(thread);
    }


    ram.close();
}
void testRAMDirectorySize(CuTest * tc)  {

    MockRAMDirectory * ramDir = _CLNEW MockRAMDirectory(indexDir);
    WhitespaceAnalyzer analyzer;
    IndexWriter * writer = _CLNEW IndexWriter(ramDir, &analyzer, false);
    writer->optimize();

    CuAssertTrue(tc, ramDir->sizeInBytes == ramDir->getRecomputedSizeInBytes(), _T("RAMDir size"));

    _LUCENE_THREADID_TYPE* threads = _CL_NEWARRAY(_LUCENE_THREADID_TYPE, numThreads);
    ThreadData * tdata = _CL_NEWARRAY(ThreadData, numThreads);

    for (int i=0; i<numThreads; i++) {
        tdata[i].num = i;
        tdata[i].dir = ramDir;
        tdata[i].tc = tc;
        tdata[i].writer = writer;
        threads[i] = _LUCENE_THREAD_CREATE(&indexDocs, &tdata[i]);
    }

    for (int i=0; i<numThreads; i++) {
        _LUCENE_THREAD_JOIN(threads[i]);
    }

    _CLDELETE_ARRAY(threads);
    _CLDELETE_ARRAY(tdata);

    writer->optimize();
    CuAssertTrue(tc, ramDir->sizeInBytes == ramDir->getRecomputedSizeInBytes(), _T("RAMDir size"));

    CuAssertEquals(tc, docsToAdd + (numThreads * (docsPerThread-1)), writer->docCount(), _T("document count"));

    writer->close();
    _CLLDELETE(writer);

    ramDir->close();
    _CLLDELETE(ramDir);
}
// setup the index
void testRAMDirectorySetUp (CuTest *tc) {

    if (strlen(cl_tempDir) + 13 > CL_MAX_PATH)
        CuFail(tc, _T("Not enough space in indexDir buffer"));

    sprintf(indexDir, "%s/RAMDirIndex", cl_tempDir);
    WhitespaceAnalyzer analyzer;
    IndexWriter * writer  = new IndexWriter(indexDir, &analyzer, true);

    // add some documents
    TCHAR * text;
    for (int i = 0; i < docsToAdd; i++) {
        Document doc;
        text = English::IntToEnglish(i);
        doc.add(* new Field(_T("content"), text, Field::STORE_YES | Field::INDEX_UNTOKENIZED));
        writer->addDocument(&doc);
        _CLDELETE_ARRAY(text);
    }

    CuAssertEquals(tc, docsToAdd, writer->docCount(), _T("document count"));
    writer->close();
    _CLDELETE( writer );
}