blob: 2f135f517cd7faa1449f44748542bd3bd8b0039f [file] [log] [blame]
/*
* 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) 2007, 2008 by Nokia Corporation and/or its subsidiary(-ies), all rights reserved.
*/
#include "CLucene/StdHeader.h"
#include "FieldInfos.h"
#include "CLucene/store/Directory.h"
#include "CLucene/document/Document.h"
#include "CLucene/document/Field.h"
#include "CLucene/util/VoidMap.h"
#include "CLucene/util/Misc.h"
#include "CLucene/util/StringIntern.h"
CL_NS_USE(store)
CL_NS_USE(document)
CL_NS_USE(util)
CL_NS_DEF(index)
FieldInfo::FieldInfo(const TCHAR* _fieldName, bool _isIndexed,
int32_t _fieldNumber, bool _storeTermVector, bool _storeOffsetWithTermVector,
bool _storePositionWithTermVector, bool _omitNorms)
: name(CLStringIntern::intern(_fieldName CL_FILELINE))
, isIndexed(_isIndexed)
, number(_fieldNumber)
, storeTermVector(_storeTermVector)
, storeOffsetWithTermVector(_storeOffsetWithTermVector)
, storePositionWithTermVector(_storeTermVector)
, omitNorms(_omitNorms)
{
}
FieldInfo::~FieldInfo()
{
CL_NS(util)::CLStringIntern::unintern(name);
}
// #pragma mark -- FieldInfos
FieldInfos::FieldInfos()
: byName(false, false)
, byNumber(true)
{
}
FieldInfos::~FieldInfos()
{
byName.clear();
byNumber.clear();
}
FieldInfos::FieldInfos(Directory* d, const QString& name)
: byName(false, false)
, byNumber(true)
{
IndexInput* input = d->openInput(name);
try {
read(input);
} _CLFINALLY (
input->close();
_CLDELETE(input);
);
}
void FieldInfos::add(const Document* doc)
{
DocumentFieldEnumeration* fields = doc->fields();
Field* field;
while (fields->hasMoreElements()) {
field = fields->nextElement();
add(field->name(), field->isIndexed(), field->isTermVectorStored());
}
_CLDELETE(fields);
}
void FieldInfos::add(const TCHAR* name, bool isIndexed, bool storeTermVector,
bool storePositionWithTermVector, bool storeOffsetWithTermVector, bool omitNorms)
{
FieldInfo* fi = fieldInfo(name);
if (fi == NULL) {
addInternal(name, isIndexed, storeTermVector,
storePositionWithTermVector,
storeOffsetWithTermVector, omitNorms);
} else {
if (fi->isIndexed != isIndexed) {
// once indexed, always index
fi->isIndexed = true;
}
if (fi->storeTermVector != storeTermVector) {
// once vector, always vector
fi->storeTermVector = true;
}
if (fi->storePositionWithTermVector != storePositionWithTermVector) {
// once vector, always vector
fi->storePositionWithTermVector = true;
}
if (fi->storeOffsetWithTermVector != storeOffsetWithTermVector) {
// once vector, always vector
fi->storeOffsetWithTermVector = true;
}
if (fi->omitNorms != omitNorms) {
// once norms are stored, always store
fi->omitNorms = false;
}
}
}
void FieldInfos::add(const TCHAR** names, bool isIndexed, bool storeTermVectors,
bool storePositionWithTermVector, bool storeOffsetWithTermVector, bool omitNorms)
{
int32_t i=0;
while (names[i] != NULL) {
add(names[i], isIndexed, storeTermVectors, storePositionWithTermVector,
storeOffsetWithTermVector, omitNorms);
++i;
}
}
int32_t FieldInfos::fieldNumber(const TCHAR* fieldName) const
{
FieldInfo* fi = fieldInfo(fieldName);
return (fi != NULL) ? fi->number : -1;
}
FieldInfo* FieldInfos::fieldInfo(const TCHAR* fieldName) const
{
return byName.get(fieldName);
}
const TCHAR* FieldInfos::fieldName(const int32_t fieldNumber) const
{
FieldInfo* fi = fieldInfo(fieldNumber);
return (fi == NULL) ? LUCENE_BLANK_STRING : fi->name;
}
FieldInfo* FieldInfos::fieldInfo(const int32_t fieldNumber) const
{
if (fieldNumber < 0 || (size_t)fieldNumber >= byNumber.size())
return NULL;
return byNumber[fieldNumber];
}
int32_t FieldInfos::size() const
{
return byNumber.size();
}
void FieldInfos::write(Directory* d, const QString& name) const
{
IndexOutput* output = d->createOutput(name);
try {
write(output);
} _CLFINALLY (
output->close();
_CLDELETE(output);
);
}
void FieldInfos::write(IndexOutput* output) const
{
output->writeVInt(size());
FieldInfo* fi;
uint8_t bits;
for (int32_t i = 0; i < size(); ++i) {
fi = fieldInfo(i);
bits = 0x0;
if (fi->isIndexed)
bits |= IS_INDEXED;
if (fi->storeTermVector)
bits |= STORE_TERMVECTOR;
if (fi->storePositionWithTermVector)
bits |= STORE_POSITIONS_WITH_TERMVECTOR;
if (fi->storeOffsetWithTermVector)
bits |= STORE_OFFSET_WITH_TERMVECTOR;
if (fi->omitNorms)
bits |= OMIT_NORMS;
output->writeString(fi->name, _tcslen(fi->name));
output->writeByte(bits);
}
}
void FieldInfos::read(IndexInput* input)
{
int32_t size = input->readVInt();
for (int32_t i = 0; i < size; ++i) {
// we could read name into a string buffer, but we can't be sure what
// the maximum field length will be.
TCHAR* name = input->readString();
uint8_t bits = input->readByte();
bool isIndexed = (bits & IS_INDEXED) != 0;
bool storeTermVector = (bits & STORE_TERMVECTOR) != 0;
bool storePositionsWithTermVector =
(bits & STORE_POSITIONS_WITH_TERMVECTOR) != 0;
bool storeOffsetWithTermVector = (bits & STORE_OFFSET_WITH_TERMVECTOR) != 0;
bool omitNorms = (bits & OMIT_NORMS) != 0;
addInternal(name, isIndexed, storeTermVector,
storePositionsWithTermVector, storeOffsetWithTermVector, omitNorms);
_CLDELETE_CARRAY(name);
}
}
void FieldInfos::addInternal(const TCHAR* name, bool isIndexed,
bool storeTermVector, bool storePositionWithTermVector,
bool storeOffsetWithTermVector, bool omitNorms)
{
FieldInfo* fi = _CLNEW FieldInfo(name, isIndexed, byNumber.size(),
storeTermVector, storePositionWithTermVector, storeOffsetWithTermVector,
omitNorms);
byNumber.push_back(fi);
byName.put(fi->name, fi);
}
bool FieldInfos::hasVectors() const
{
for (int32_t i = 0; i < size(); i++) {
if (fieldInfo(i)->storeTermVector)
return true;
}
return false;
}
CL_NS_END