📄 indexreader.cpp
字号:
/*------------------------------------------------------------------------------
* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
*
* Distributable under the terms of either the Apache License (Version 2.0) or
* the GNU Lesser General Public License, as specified in the COPYING file.
------------------------------------------------------------------------------*/
#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 "CLucene/search/Similarity.h"
#include "SegmentInfos.h"
#include "MultiReader.h"
#include "Terms.h"
CL_NS_USE(util)
CL_NS_USE(store)
CL_NS_DEF(index)
IndexReader::IndexReader(Directory* dir):
directory(_CL_POINTER(dir)){
//Constructor.
//Func - Creates an instance of IndexReader
//Pre - true
//Post - An instance has been created with writeLock = NULL
writeLock = NULL;
segmentInfos = NULL;
directoryOwner = false;
closeDirectory = false;
stale = false;
hasChanges = false;
}
IndexReader::IndexReader(Directory* directory, SegmentInfos* segmentInfos, bool closeDirectory) {
this->directory = _CL_POINTER(directory);
this->segmentInfos = segmentInfos;
directoryOwner = true;
this->closeDirectory = closeDirectory;
stale = false;
hasChanges = false;
writeLock = NULL;
}
IndexReader::~IndexReader(){
//Func - Destructor
// Destroys the instance and releases the writeLock if needed
//Pre - true
//Post - The instance has been destroyed if pre(writeLock) exists is has been released
if (writeLock != NULL) {
//release writeLock
writeLock->release();
_CLDELETE(writeLock);
}
_CLDELETE(segmentInfos);
_CLDECDELETE(directory);
}
IndexReader* IndexReader::open(const char* path){
//Func - Static method.
// Returns an IndexReader reading the index in an FSDirectory in the named path.
//Pre - path != NULL and contains the path of the index for which an IndexReader must be
// instantiated
// closeDir indicates if the directory needs to be closed
//Post - An IndexReader has been returned that reads tnhe index located at path
CND_PRECONDITION(path != NULL, "path is NULL");
Directory* dir = FSDirectory::getDirectory(path,false);
IndexReader* reader = open(dir,true);
//because fsdirectory will now have a refcount of 1 more than
//if the reader had been opened with a directory object,
//we need to do a refdec
_CLDECDELETE(dir);
return reader;
}
IndexReader* IndexReader::open( Directory* directory, bool closeDirectory){
//Func - Static method.
// Returns an IndexReader reading the index in an FSDirectory in the named path.
//Pre - directory represents a directory
// closeDir indicates if the directory needs to be closed
//Post - An IndexReader has been returned that reads the index located at directory
// in- & inter-process sync
SCOPED_LOCK_MUTEX(directory->THIS_LOCK)
IndexReader* ret = NULL;
LuceneLock* lock = directory->makeLock("commit.lock");
//Instantiate an IndexReaderLockWith which can produce an IndexReader
IndexReaderLockWith with(lock,directory);
try{
//Create an IndexReader reading the index
ret = (IndexReader*)with.run();
}_CLFINALLY(
_CLDELETE( lock );
);
ret->closeDirectory = closeDirectory;
CND_CONDITION(ret != NULL,"ret is NULL");
//return reference
return ret;
}
void* IndexReader::IndexReaderLockWith::doBody() {
//Func - Reads the segmentinfo file and depending on the number of segments found
// it returns a SegmentsReader or a SegmentReader
//Pre - directory != NULL
//Post - Depending on the number of Segments present in directory this method
// returns an empty SegmentsReader when there are no segments, a SegmentReader when
// directory contains 1 segment and a nonempty SegmentsReader when directory
// contains multiple segements
CND_PRECONDITION(directory != NULL, "directory is NULL");
//Instantiate SegmentInfos
SegmentInfos* infos = _CLNEW SegmentInfos;
try{
//Have SegmentInfos read the segments file in directory
infos->read(directory);
}catch(...){
//make sure infos is cleaned up
_CLDELETE(infos);
throw;
}
// If there is at least one segment (if infos.size() >= 1), the last
// SegmentReader object will close the directory when the SegmentReader
// object itself is closed (see SegmentReader::doClose).
// If there are no segments, there will be no "last SegmentReader object"
// to fulfill this responsibility, so we need to explicitly close the
// directory in the segmentsreader.close
//Count the number segments in the directory
const uint32_t nSegs = infos->size();
if (nSegs == 1 ) {
// index is optimized
return _CLNEW SegmentReader(infos, infos->info(0));
}else{
//Instantiate an array of pointers to SegmentReaders of size nSegs (The number of segments in the index)
IndexReader** readers = NULL;
if (nSegs > 0){
uint32_t infosize=infos->size();
readers = _CL_NEWARRAY(IndexReader*,infosize+1);
for (uint32_t i = 0; i < infosize; i++) {
//Instantiate a SegementReader responsible for reading the i-th segment and store it in
//the readers array
readers[i] = _CLNEW SegmentReader(infos->info(i));
}
readers[infosize] = NULL;
}
//return an instance of SegmentsReader which is a reader that manages all Segments
return _CLNEW MultiReader(directory, infos, readers);
}// end if
}
uint64_t IndexReader::lastModified(const char* directory) {
//Func - Static method
// Returns the time the index in the named directory was last modified.
//Pre - directory != NULL and contains the path name of the directory to check
//Post - The last modified time of the index has been returned
CND_PRECONDITION(directory != NULL, "directory is NULL");
return FSDirectory::fileModified(directory,"segments");
}
int64_t IndexReader::getCurrentVersion(Directory* directory) {
return SegmentInfos::readCurrentVersion(directory);
}
int64_t IndexReader::getCurrentVersion(const char* directory){
Directory* dir = FSDirectory::getDirectory(directory, false);
int64_t version = getCurrentVersion(dir);
dir->close();
_CLDECDELETE(dir);
return version;
}
uint64_t IndexReader::lastModified(const Directory* directory) {
//Func - Static method
// Returns the time the index in this directory was last modified.
//Pre - directory contains a valid reference
//Post - The last modified time of the index has been returned
return directory->fileModified("segments");
}
bool IndexReader::indexExists(const char* directory){
//Func - Static method
// Checks if an index exists in the named directory
//Pre - directory != NULL
//Post - Returns true if an index exists at the specified directory->
// If the directory does not exist or if there is no index in it.
// false is returned.
CND_PRECONDITION(directory != NULL, "directory is NULL");
//Create a buffer of length CL_MAXDIR
char f[CL_MAX_PATH+10]; //add 10 in case that directory is already 260 long
//Copy the directory string to the buffer
strcpy(f,directory);
//Cat the name of the segments to buffer
strcat(f, "/segments");
//Check if the segments file exists
return Misc::dir_Exists(f);
}
void IndexReader::setNorm(int32_t doc, const TCHAR* field, uint8_t value){
SCOPED_LOCK_MUTEX(THIS_LOCK)
if(directoryOwner)
aquireWriteLock();
doSetNorm(doc, field, value);
hasChanges = true;
}
void IndexReader::aquireWriteLock() {
if (stale)
_CLTHROWA(CL_ERR_IO,"IndexReader out of date and no longer valid for delete, undelete, or setNorm operations");
if (writeLock == NULL) {
LuceneLock* writeLock = directory->makeLock("write.lock");
if (!writeLock->obtain(LUCENE_WRITE_LOCK_TIMEOUT)) // obtain write lock
_CLTHROWA(CL_ERR_IO,"Index locked for write"); // + writeLock
this->writeLock = writeLock;
// we have to check whether index has changed since this reader was opened.
// if so, this reader is no longer valid for deletion
if (SegmentInfos::readCurrentVersion(directory) > segmentInfos->getVersion()) {
stale = true;
this->writeLock->release();
_CLDELETE(this->writeLock);
_CLTHROWA(CL_ERR_IO,"IndexReader out of date and no longer valid for delete, undelete, or setNorm operations");
}
}
}
void IndexReader::setNorm(int32_t doc, const TCHAR* field, float_t value){
setNorm(doc, field, CL_NS(search)::Similarity::encodeNorm(value));
}
bool IndexReader::indexExists(const Directory* directory){
//Func - Static method
// Checks if an index exists in the directory
//Pre - directory is a valid reference
//Post - Returns true if an index exists at the specified directory->
// If the directory does not exist or if there is no index in it.
// false is returned.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -