diff options
Diffstat (limited to '3rdparty/clucene/src/CLucene/index/SegmentInfos.cpp')
-rw-r--r-- | 3rdparty/clucene/src/CLucene/index/SegmentInfos.cpp | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/3rdparty/clucene/src/CLucene/index/SegmentInfos.cpp b/3rdparty/clucene/src/CLucene/index/SegmentInfos.cpp new file mode 100644 index 000000000..f62c4061a --- /dev/null +++ b/3rdparty/clucene/src/CLucene/index/SegmentInfos.cpp @@ -0,0 +1,259 @@ +/* + * 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. + * + * Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +*/ +#include "CLucene/StdHeader.h" +#include "SegmentInfos.h" + +#include "CLucene/store/Directory.h" +#include "CLucene/util/Misc.h" + +CL_NS_USE(store) +CL_NS_USE(util) +CL_NS_DEF(index) + +SegmentInfo::SegmentInfo(const QString& Name, const int32_t DocCount, + CL_NS(store)::Directory* Dir) + : docCount(DocCount) + , dir(Dir) +{ + //Func - Constructor. Initialises SegmentInfo. + //Pre - Name holds the unique name in the directory Dir + // DocCount holds the number of documents in the segment + // Dir holds the Directory where the segment resides + //Post - The instance has been created. name contains the duplicated string + // Name. docCount = DocCount and dir references Dir + name = Name; +} + +SegmentInfo::~SegmentInfo() +{ +} + +SegmentInfos::SegmentInfos(bool _deleteMembers) + : deleteMembers(_deleteMembers) +{ + //Func - Constructor + //Pre - deleteMembers indicates if the instance to be created must delete + // all SegmentInfo instances it manages when the instance is destroyed + // or not true -> must delete, false may not delete + //Post - An instance of SegmentInfos has been created. + + //initialize counter to 0 + counter = 0; + version = Misc::currentTimeMillis(); +} + +SegmentInfos::~SegmentInfos() +{ + //Func - Destructor + //Pre - true + //Post - The instance has been destroyed. Depending on the constructor used + // the SegmentInfo instances that this instance managed have been + // deleted or not. + + if (deleteMembers) { + segmentInfosType::iterator it; + for (it = infos.begin(); it != infos.end(); ++it) + _CLLDELETE(*it); + } + //Clear the list of SegmentInfo instances - make sure everything is deleted + infos.clear(); +} + +SegmentInfo* SegmentInfos::info(int32_t i) const +{ + //Func - Returns a reference to the i-th SegmentInfo in the list. + //Pre - i >= 0 + //Post - A reference to the i-th SegmentInfo instance has been returned + + CND_PRECONDITION(i >= 0, "i contains negative number"); + + //Get the i-th SegmentInfo instance + SegmentInfo *ret = infos.value(i, 0); + + //Condition check to see if the i-th SegmentInfo has been retrieved + CND_CONDITION(ret != NULL, "No SegmentInfo instance found"); + + return ret; +} + +void SegmentInfos::clearto(size_t _min) +{ + // Make sure we actually need to remove + if (infos.size() > _min) { + segmentInfosType::iterator itr; + segmentInfosType::iterator eitr = infos.end(); + segmentInfosType::iterator bitr = infos.begin() + _min; + + for(itr = bitr; itr != eitr; ++itr) + _CLLDELETE((*itr)); + infos.erase(bitr, eitr); + } +} + +void SegmentInfos::add(SegmentInfo* info) +{ + infos.push_back(info); +} + +int32_t SegmentInfos::size() const +{ + return infos.size(); +} + +void SegmentInfos::read(Directory* directory) +{ + //Func - Reads segments file that resides in directory. + //Pre - directory contains a valid reference + //Post - The segments file has been read and for each segment found + // a SegmentsInfo intance has been created and stored. + + //Open an IndexInput to the segments file and check if valid + IndexInput* input = directory->openInput(QLatin1String("segments")); + if (input) { + try { + int32_t format = input->readInt(); + // file contains explicit format info + if (format < 0) { + // check that it is a format we can understand + if (format < FORMAT) { + TCHAR err[30]; + _sntprintf(err, 30, _T("Unknown format version: %d"), format); + _CLTHROWT(CL_ERR_Runtime, err); + } + // read version + version = input->readLong(); + // read counter + counter = input->readInt(); + } else { + // file is in old format without explicit format info + counter = format; + } + + //Temporary variable for storing the name of the segment + char aname[CL_MAX_PATH] = { 0 }; + TCHAR tname[CL_MAX_PATH] = { 0 }; + + //read segmentInfos + for (int32_t i = input->readInt(); i > 0; --i) { + // read the name of the segment + input->readString(tname, CL_MAX_PATH); + STRCPY_TtoA(aname, tname, CL_MAX_PATH); + + //Instantiate a new SegmentInfo Instance + SegmentInfo* si = _CLNEW SegmentInfo(QLatin1String(aname), + input->readInt(), directory); + + //Condition check to see if si points to an instance + CND_CONDITION(si != NULL, "Memory allocation for si failed") ; + + //store SegmentInfo si + infos.push_back(si); + } + + if (format >= 0) { + // in old format the version number may be at the end of the file + if (input->getFilePointer() >= input->length()) { + // old file format without version number + version = Misc::currentTimeMillis(); + } else { + // read version + version = input->readLong(); + } + } + } _CLFINALLY ( + //destroy the inputStream input. The destructor of IndexInput will + //also close the Inputstream input + _CLDELETE(input); + ); + } +} + +void SegmentInfos::write(Directory* directory) +{ + //Func - Writes a new segments file based upon the SegmentInfo instances it manages + //Pre - directory is a valid reference to a Directory + //Post - The new segment has been written to disk + + //Open an IndexOutput to the segments file and check if valid + IndexOutput* output = directory->createOutput(QLatin1String("segments.new")); + if (output) { + try { + // write FORMAT + output->writeInt(FORMAT); + // every write changes the index + output->writeLong(++version); + // Write the counter + output->writeInt(counter); + + // Write the number of SegmentInfo Instances which is equal to the number + // of segments in directory as each SegmentInfo manages a single segment + output->writeInt(infos.size()); + + //temporary value for wide segment name + TCHAR tname[CL_MAX_PATH]; + + //Iterate through all the SegmentInfo instances + for (uint32_t i = 0; i < infos.size(); ++i) { + //Retrieve the SegmentInfo + SegmentInfo *si = infos.value(i, 0); + //Condition check to see if si has been retrieved + CND_CONDITION(si != NULL, "No SegmentInfo instance found"); + + //Write the name of the current segment + int32_t count = si->name.toWCharArray(tname); + tname[count] = '\0'; + output->writeString(tname, _tcslen(tname)); + + //Write the number of documents in the segment + output->writeInt(si->docCount); + } + } _CLFINALLY( + output->close(); + _CLDELETE(output); + ); + + // install new segment info + directory->renameFile(QLatin1String("segments.new"), + QLatin1String("segments")); + } +} + + +int64_t SegmentInfos::readCurrentVersion(Directory* directory) +{ + int32_t format = 0; + int64_t version = 0; + IndexInput* input = directory->openInput(QLatin1String("segments")); + try { + format = input->readInt(); + if (format < 0){ + if (format < FORMAT) { + TCHAR err[30]; + _sntprintf(err, 30, _T("Unknown format version: %d"), format); + _CLTHROWT(CL_ERR_Runtime, err); + } + // read version + version = input->readLong(); + } + } _CLFINALLY ( + input->close(); + _CLDELETE(input); + ); + + if (format < 0) + return version; + + // We cannot be sure about the format of the file. Therefore we have to + // read the whole file and cannot simply seek to the version entry. + SegmentInfos segmentInfos; + segmentInfos.read(directory); + return segmentInfos.getVersion(); +} + +CL_NS_END |