📄 fieldcacheimpl.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 "FieldCacheImpl.h"
CL_NS_USE(util)
CL_NS_USE(index)
CL_NS_DEF(search)
FieldCacheImpl::FieldCacheImpl():
cache(false,true){
}
FieldCacheImpl::~FieldCacheImpl(){
cache.clear();
}
FieldCacheImpl::FileEntry::FileEntry (const TCHAR* field, int32_t type) {
this->field = CLStringIntern::intern(field CL_FILELINE);
this->type = type;
this->custom = NULL;
this->_hashCode = 0;
}
/** Creates one of these objects for a custom comparator. */
FieldCacheImpl::FileEntry::FileEntry (const TCHAR* field, SortComparatorSource* custom) {
this->field = CLStringIntern::intern(field CL_FILELINE);
this->type = SortField::CUSTOM;
this->custom = custom;
this->_hashCode = 0;
}
FieldCacheImpl::FileEntry::~FileEntry(){
CLStringIntern::unintern(field);
}
size_t FieldCacheImpl::FileEntry::hashCode(){
if ( _hashCode == 0 ){
//todo: cache hashcode?
size_t ret = Misc::thashCode(field);
if ( custom != NULL )
ret = ret ^ custom->hashCode();
ret = ret ^ (type*7); //type with a seed
_hashCode = ret;
}
return _hashCode;
}
int32_t FieldCacheImpl::FileEntry::compareTo(const FieldCacheImpl::FileEntry* other) const{
if ( other->field == this->field ){
if ( other->type == this->type ){
if ( other->custom == NULL ){
if ( this->custom == NULL )
return 0; //both null
else
return 1;
}else if ( this->custom == NULL )
return -1;
else if ( other->custom < this->custom )
return -1;
else if ( other->custom > this->custom )
return 1;
else
return 0;
}else if ( other->type > this->type )
return 1;
else
return -1;
}else
return _tcscmp(other->field,this->field);
}
/** Two of these are equal iff they reference the same field and type. */
/*bool FieldCacheImpl::FileEntry::equals (FileEntry* other) {
if (other->field == field && other->type == type) {
if (other->custom == NULL) {
if (custom == NULL)
return true;
} else if (other->custom->equals (custom)) {
return true;
}
}
}*/
/** Composes a hashcode based on the field and type. */
/*size_t FieldCacheImpl::FileEntry::hashCode() {
return field->hashCode() ^ type ^ (custom==NULL ? 0 : custom->hashCode());
}*/
/** See if an object is in the cache. */
FieldCacheAuto* FieldCacheImpl::lookup (IndexReader* reader, const TCHAR* field, int32_t type) {
FieldCacheAuto* ret = NULL;
FileEntry* entry = _CLNEW FileEntry (field, type);
{
SCOPED_LOCK_MUTEX(THIS_LOCK)
fieldcacheCacheReaderType* readerCache = cache.get(reader);
if (readerCache != NULL)
ret = readerCache->get (entry);
_CLDELETE(entry);
}
return ret;
}
/** See if a custom object is in the cache. */
FieldCacheAuto* FieldCacheImpl::lookup (IndexReader* reader, const TCHAR* field, SortComparatorSource* comparer) {
FieldCacheAuto* ret = NULL;
FileEntry* entry = _CLNEW FileEntry (field, comparer);
{
SCOPED_LOCK_MUTEX(THIS_LOCK)
fieldcacheCacheReaderType* readerCache = cache.get(reader);
if (readerCache != NULL)
ret = readerCache->get (entry);
_CLDELETE(entry);
}
return ret;
}
void FieldCacheImpl::closeCallback(CL_NS(index)::IndexReader* reader, void* fieldCacheImpl){
FieldCacheImpl* fci = (FieldCacheImpl*)fieldCacheImpl;
SCOPED_LOCK_MUTEX(fci->THIS_LOCK)
fci->cache.remove(reader);
}
/** Put an object into the cache. */
void FieldCacheImpl::store (IndexReader* reader, const TCHAR* field, int32_t type, FieldCacheAuto* value) {
FileEntry* entry = _CLNEW FileEntry (field, type);
{
SCOPED_LOCK_MUTEX(THIS_LOCK)
fieldcacheCacheReaderType* readerCache = cache.get(reader);
if (readerCache == NULL) {
readerCache = _CLNEW fieldcacheCacheReaderType;
cache.put(reader,readerCache);
reader->addCloseCallback(closeCallback, this);
}
readerCache->put (entry, value);
//this is supposed to return the previous value, but it needs to be deleted!!!
}
}
/** Put a custom object into the cache. */
void FieldCacheImpl::store (IndexReader* reader, const TCHAR* field, SortComparatorSource* comparer, FieldCacheAuto* value) {
FileEntry* entry = _CLNEW FileEntry (field, comparer);
{
SCOPED_LOCK_MUTEX(THIS_LOCK)
fieldcacheCacheReaderType* readerCache = cache.get(reader);
if (readerCache == NULL) {
readerCache = _CLNEW fieldcacheCacheReaderType;
cache.put(reader, readerCache);
reader->addCloseCallback(FieldCacheImpl::closeCallback, this);
}
readerCache->put(entry, value);
//this is supposed to return the previous value, but it needs to be deleted!!!
}
}
// inherit javadocs
FieldCacheAuto* FieldCacheImpl::getInts (IndexReader* reader, const TCHAR* field) {
field = CLStringIntern::intern(field CL_FILELINE);
FieldCacheAuto* ret = lookup (reader, field, SortField::INT);
if (ret == NULL) {
int32_t retLen = reader->maxDoc();
int32_t* retArray = _CL_NEWARRAY(int32_t,retLen+1);
memset(retArray,0,4*(retLen+1));
if (retLen > 0) {
TermDocs* termDocs = reader->termDocs();
Term* term = _CLNEW Term (field, LUCENE_BLANK_STRING);
TermEnum* termEnum = reader->terms (term);
_CLDECDELETE(term);
try {
if (termEnum->term(false) == NULL) {
_CLTHROWA(CL_ERR_Runtime,"no terms in field"); //todo: add detailed error: + field);
}
do {
Term* term = termEnum->term(false);
if (term->field() != field)
break;
TCHAR* end;
int32_t termval = (int32_t)_tcstoi64(term->text(), &end, 10);
termDocs->seek (termEnum);
while (termDocs->next()) {
retArray[termDocs->doc()] = termval;
}
} while (termEnum->next());
} _CLFINALLY(
termDocs->close();
_CLDELETE(termDocs);
termEnum->close();
_CLDELETE(termEnum);
)
}
FieldCacheAuto* fa = _CLNEW FieldCacheAuto(retLen,FieldCacheAuto::INT_ARRAY);
fa->intArray = retArray;
store (reader, field, SortField::INT, fa);
CLStringIntern::unintern(field);
return fa;
}
CLStringIntern::unintern(field);
return ret;
}
// inherit javadocs
FieldCacheAuto* FieldCacheImpl::getFloats (IndexReader* reader, const TCHAR* field){
field = CLStringIntern::intern(field CL_FILELINE);
FieldCacheAuto* ret = lookup (reader, field, SortField::FLOAT);
if (ret == NULL) {
int32_t retLen = reader->maxDoc();
float_t* retArray = _CL_NEWARRAY(float_t,retLen);
for(int i=0;i<retLen;i++)
retArray[i]=0;
if (retLen > 0) {
TermDocs* termDocs = reader->termDocs();
Term* term = _CLNEW Term (field, LUCENE_BLANK_STRING);
TermEnum* termEnum = reader->terms (term);
_CLDECDELETE(term);
try {
if (termEnum->term(false) == NULL) {
_CLTHROWA(CL_ERR_Runtime,"no terms in field "); //todo: make richer error + field);
}
do {
Term* term = termEnum->term(false);
if (term->field() != field)
break;
TCHAR* tmp;
float_t termval = _tcstod(term->text(),&tmp);
termDocs->seek (termEnum);
while (termDocs->next()) {
retArray[termDocs->doc()] = termval;
}
} while (termEnum->next());
} _CLFINALLY(
termDocs->close();
_CLDELETE(termDocs);
termEnum->close();
_CLDELETE(termEnum);
)
}
FieldCacheAuto* fa = _CLNEW FieldCacheAuto(retLen,FieldCacheAuto::FLOAT_ARRAY);
fa->floatArray = retArray;
store (reader, field, SortField::FLOAT, fa);
CLStringIntern::unintern(field);
return fa;
}
CLStringIntern::unintern(field);
return ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -