#include "CLucene/StdHeader.h" #include "IndexReader.h" #include "CLucene/store/Directory.h" #include "CLucene/store/FSDirectory.h" #include "CLucene/store/Lock.h" #include "CLucene/document/Document.h" #include "SegmentInfos.h" #include "SegmentsReader.h" #include #include "Terms.h" using namespace lucene::util; namespace lucene{ namespace index { IndexReader::IndexReader(Directory& dir):directory(dir) { writeLock = NULL; } IndexReader::~IndexReader() { if (writeLock != NULL) { writeLock->release(); // release write lock /* DSR:CL_BUG_LEAK: writeLock must also be deleted. */ delete writeLock; writeLock = NULL; } } //static IndexReader& IndexReader::open(const char_t* path, const bool closeDir){ return open(FSDirectory::getDirectory(path,false), closeDir); } //static IndexReader& IndexReader::open( Directory& directory, const bool closeDir){ void* ret; LuceneLock* lock = NULL; LOCK_MUTEX(DIRECTORIES_MUTEX); // in- & inter-process sync #ifndef CLUCENE_LITE lock = directory.makeLock(_T("commit.lock")); #endif IndexReaderLockWith with ( lock,&directory,closeDir ); ret = with.run(); #ifndef CLUCENE_LITE delete lock; #endif UNLOCK_MUTEX(DIRECTORIES_MUTEX); return *(IndexReader*)ret; } void* IndexReaderLockWith::doBody() { SegmentInfos infos; infos.read(*directory); if (infos.size() == 1){ // index is optimized IndexReader* ret = new SegmentReader(infos.info(0), closeDir); return ret; } SegmentReader** readers = new SegmentReader*[infos.size()]; for (uint_t i = 0; i < infos.size(); i++) readers[i] = new SegmentReader(infos.info(i), i==infos.size()-1); return new SegmentsReader(*directory, readers, infos.size()); } //static long_t IndexReader::lastModified(const char_t* directory) { struct Struct_Stat buf; Cmd_Stat(directory, &buf); return buf.st_mtime; } //static long_t IndexReader::lastModified(const Directory& directory) { return directory.fileModified(_T("segments")); } //static bool IndexReader::indexExists(const char_t* directory) { char_t f[CL_MAX_DIR]; stringCopy(f,directory); stringCat(f, _T("/segments")); return lucene::util::Misc::dir_Exists(f); } //static bool IndexReader::indexExists(const Directory& directory) { return directory.fileExists(_T("segments")); } TermDocs& IndexReader::termDocs(Term* term) const { TermDocs& _termDocs = termDocs(); _termDocs.seek(term); return _termDocs; } TermPositions& IndexReader::termPositions( Term* term) { TermPositions& _termPositions = termPositions(); _termPositions.seek(term); return _termPositions; } #ifndef CLUCENE_LITE void IndexReader::Delete(const int_t docNum) { LOCK_MUTEX(Delete_LOCK); if (writeLock == NULL) { lucene::store::LuceneLock* wl = directory.makeLock(_T("write.lock")); if (!wl->obtain()){ // obtain write lock delete wl; _THROWC("Index locked for write or no write access."); } writeLock = wl; } doDelete(docNum); UNLOCK_MUTEX(Delete_LOCK); } int_t IndexReader::Delete(Term* term) { TermDocs* docs = &termDocs(term); if ( docs == NULL ) return 0; int_t n = 0; _TRY { while (docs->next()) { Delete(docs->Doc()); n++; } } _FINALLY ( docs->close(); ); return n; } #endif void IndexReader::close() { LOCK_MUTEX(close_LOCK); doClose(); if (writeLock != NULL) { writeLock->release(); // release write lock /* DSR:CL_BUG_LEAK: writeLock must also be deleted. */ delete writeLock; writeLock = NULL; } UNLOCK_MUTEX(close_LOCK); } //static bool IndexReader::isLocked(const Directory& directory) { return directory.fileExists(_T("write.lock")); } //static bool IndexReader::isLocked(const char_t* directory) { char_t f[CL_MAX_DIR]; stringCopy( f, directory ); stringCat ( f,_T("/write.lock") ); return lucene::util::Misc::dir_Exists(f); } #ifndef CLUCENE_LITE //static void IndexReader::unlock(Directory& directory){ try{ directory.deleteFile(_T("write.lock"),false); }catch(...){} try{ directory.deleteFile(_T("commit.lock"),false); }catch(...){} } #endif //CLUCENE_LITE }}