You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

170 lines
3.7 KiB

/* Message indexing
*
* Author: Sam Magnuson <zachsman@wiw.org>
* This code is under GPL
*
*/
#ifndef kmmsgindex_h
#define kmmsgindex_h
#include "kmfolder.h"
#include <qmap.h>
#include <qobject.h>
#include <qstring.h>
#include <qintdict.h>
#include <qdatetime.h>
#include <qvaluelist.h>
#include <qvaluestack.h>
#include <qguardedptr.h>
class KMMsgIndexRef;
class KMIndexSearchTarget;
class KMSearchPattern;
class KMSearchRule;
class KMSearch;
/**
* @short UNUSED full text index for messages
*
* KMMsgIndex provides a full test message indexer. It is currently unused.
* @author Sam Magnuson <zachsman@wiw.org>
*/
class KMMsgIndex : public QObject
{
Q_OBJECT
enum { INDEX_IDLE, INDEX_RESTORE, INDEX_CREATE } mIndexState;
QValueList<QGuardedPtr<KMFolder> > mOpenedFolders;
//book-keeping
struct {
int fd;
Q_INT32 count, used, indexed, removed;
KMMsgIndexRef *ref;
QString loc;
} mTermIndex;
struct {
int fd;
QString loc;
QMap<QCString, int> body;
struct {
int next_hnum;
QMap<QCString, Q_UINT16> header_lookup;
QMap<Q_UINT16, QMap<QCString, int> > headers;
} h;
} mTermTOC;
struct {
int fd;
QString loc;
QIntDict<void> known;
} mTermProcessed;
//state information
struct {
int timer_id;
QValueStack<Q_UINT32> serNums;
QValueStack<QGuardedPtr<KMFolder> > folders;
//these are used for partial creates..
} create;
struct {
int timer_id;
bool reading_processed, restart_index;
} restore;
int delay_cnt;
QTime mLastSearch; //when last index lookup was performed
QIntDict<KMIndexSearchTarget> mActiveSearches; //for async search
public:
KMMsgIndex(QObject *parent=NULL, const char *name=NULL);
~KMMsgIndex() { reset(); }
void init();
void remove();
bool canHandleQuery(KMSearchRule *);
bool canHandleQuery(KMSearchPattern *);
QValueList<Q_UINT32> query(KMSearchRule *, bool full_phrase_search=TRUE);
QValueList<Q_UINT32> query(KMSearchPattern *, bool full_phras_search=TRUE);
//convenient..
bool startQuery(KMSearch *);
bool stopQuery(KMSearch *);
bool stopQuery(int id) { return mActiveSearches.remove(id); }
//force the cleanup..
void cleanUp();
private:
//internal
bool recreateIndex();
void readIndex();
void syncIndex();
void flush();
void reset(bool =TRUE);
bool createState(bool =TRUE);
bool restoreState(bool =TRUE);
int addBucket(int, Q_UINT32);
QValueList<Q_UINT32> find(QString, bool, KMSearchRule *, bool =FALSE,
Q_UINT16 =0);
void values(int, int, QValueList<Q_UINT32> &);
void values(int, int, QIntDict<void> &);
int processMsg(Q_UINT32);
bool addHeaderTerm(Q_UINT16, const char *, uchar, Q_UINT32);
bool addBodyTerm(const char *, uchar, Q_UINT32);
int allocTermChunk(int);
bool isTimeForClean();
bool isKillTerm(const char *, uchar);
bool isKillHeader(const char *, uchar);
protected:
void timerEvent(QTimerEvent *);
private slots:
void slotAddMsg(KMFolder *, Q_UINT32);
void slotRemoveMsg(KMFolder *, Q_UINT32);
};
class KMIndexSearchTarget : public QObject
{
Q_OBJECT
int mId;
bool mVerifyResult;
QValueList<QGuardedPtr<KMFolder> > mOpenedFolders;
QValueStack<Q_UINT32> mSearchResult;
QGuardedPtr<KMSearch> mSearch;
public:
KMIndexSearchTarget(KMSearch *);
~KMIndexSearchTarget();
void stop(bool stop_search=TRUE) {
if(stop_search && mSearch)
emit proxyFinished(true);
mSearch = NULL;
}
KMSearch *search() const { return mSearch; }
int id() const { return mId; }
protected:
void timerEvent(QTimerEvent *);
signals:
void proxyFound(Q_UINT32);
void proxyFinished(bool);
};
#endif /* __KMMSGINDEX_H__ */