Move sort/filtering code out of reslist
This commit is contained in:
+75
-3
@@ -17,10 +17,10 @@ static char rcsid[] = "@(#$Id: docseq.cpp,v 1.11 2008-09-29 08:59:20 dockes Exp
|
||||
* Free Software Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "docseq.h"
|
||||
#include "filtseq.h"
|
||||
#include "sortseq.h"
|
||||
#include "debuglog.h"
|
||||
|
||||
int DocSequence::getSeqSlice(int offs, int cnt, vector<ResListEntry>& result)
|
||||
{
|
||||
@@ -35,3 +35,75 @@ int DocSequence::getSeqSlice(int offs, int cnt, vector<ResListEntry>& result)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DocSource::unwind()
|
||||
{
|
||||
RefCntr<DocSequence> base = m_seq;
|
||||
while (!m_seq.isNull() && !(m_seq->getSourceSeq()).isNull()) {
|
||||
base = m_seq->getSourceSeq();
|
||||
}
|
||||
m_seq = base;
|
||||
}
|
||||
|
||||
bool DocSource::buildStack()
|
||||
{
|
||||
LOGDEB2(("DocSource::buildStack()\n"));
|
||||
unwind();
|
||||
|
||||
if (m_seq.isNull())
|
||||
return false;
|
||||
|
||||
// Filtering must be done before sorting, (which may
|
||||
// truncates the original list)
|
||||
if (m_seq->canFilter()) {
|
||||
if (!m_seq->setFiltSpec(m_fspec)) {
|
||||
LOGERR(("DocSource::buildStack: setfiltspec failed\n"));
|
||||
}
|
||||
} else {
|
||||
if (m_fspec.isNotNull()) {
|
||||
m_seq =
|
||||
RefCntr<DocSequence>(new DocSeqFiltered(m_seq, m_fspec));
|
||||
}
|
||||
}
|
||||
|
||||
if (m_seq->canSort()) {
|
||||
if (!m_seq->setSortSpec(m_sspec)) {
|
||||
LOGERR(("DocSource::buildStack: setsortspec failed\n"));
|
||||
}
|
||||
} else {
|
||||
if (m_sspec.isNotNull()) {
|
||||
m_seq = RefCntr<DocSequence>(new DocSeqSorted(m_seq, m_sspec));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
string DocSource::o_sort_trans;
|
||||
string DocSource::o_filt_trans;
|
||||
|
||||
string DocSource::title()
|
||||
{
|
||||
string qual;
|
||||
if (m_fspec.isNotNull() && !m_sspec.isNotNull())
|
||||
qual = string(" (") + o_filt_trans + string(")");
|
||||
else if (!m_fspec.isNotNull() && m_sspec.isNotNull())
|
||||
qual = string(" (") + o_sort_trans + string(")");
|
||||
else if (m_fspec.isNotNull() && m_sspec.isNotNull())
|
||||
qual = string(" (") + o_sort_trans + string(",") + o_filt_trans + string(")");
|
||||
return m_seq->title() + qual;
|
||||
}
|
||||
|
||||
bool DocSource::setFiltSpec(const DocSeqFiltSpec &f)
|
||||
{
|
||||
LOGDEB2(("DocSource::setFiltSpec\n"));
|
||||
m_fspec = f;
|
||||
buildStack();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DocSource::setSortSpec(const DocSeqSortSpec &s)
|
||||
{
|
||||
LOGDEB2(("DocSource::setSortSpec\n"));
|
||||
m_sspec = s;
|
||||
buildStack();
|
||||
return true;
|
||||
}
|
||||
|
||||
+46
-10
@@ -44,8 +44,8 @@ class DocSeqSortSpec {
|
||||
crits.push_back(fld);
|
||||
dirs.push_back(desc);
|
||||
}
|
||||
bool isNotNull() {return sortdepth > 0;}
|
||||
|
||||
bool isNotNull() const {return sortdepth > 0;}
|
||||
void reset() {crits.clear(); dirs.clear();sortdepth = 0;}
|
||||
int sortdepth; // We only re-sort the first sortdepth most relevant docs
|
||||
std::vector<Field> crits;
|
||||
std::vector<bool> dirs;
|
||||
@@ -64,7 +64,7 @@ class DocSeqFiltSpec {
|
||||
std::vector<Crit> crits;
|
||||
std::vector<string> values;
|
||||
void reset() {crits.clear(); values.clear();}
|
||||
bool isNotNull() {return crits.size() != 0;}
|
||||
bool isNotNull() const {return crits.size() != 0;}
|
||||
};
|
||||
|
||||
/** Interface for a list of documents coming from some source.
|
||||
@@ -94,7 +94,7 @@ class DocSequence {
|
||||
virtual bool getDoc(int num, Rcl::Doc &doc, string *sh = 0) = 0;
|
||||
|
||||
/** Get next page of documents. This accumulates entries into the result
|
||||
* list (doesn't reset it). */
|
||||
* list parameter (doesn't reset it). */
|
||||
virtual int getSeqSlice(int offs, int cnt, vector<ResListEntry>& result);
|
||||
|
||||
/** Get abstract for document. This is special because it may take time.
|
||||
@@ -130,14 +130,15 @@ class DocSequence {
|
||||
}
|
||||
virtual list<string> expand(Rcl::Doc &) {return list<string>();}
|
||||
|
||||
/** Optional functionality. Yeah, not nice */
|
||||
/** Optional functionality. */
|
||||
virtual bool canFilter() {return false;}
|
||||
virtual bool setFiltSpec(DocSeqFiltSpec &) {return false;}
|
||||
virtual bool canSort() {return false;}
|
||||
virtual bool setSortSpec(DocSeqSortSpec &) {return false;}
|
||||
virtual bool setFiltSpec(const DocSeqFiltSpec &) {return false;}
|
||||
virtual bool setSortSpec(const DocSeqSortSpec &) {return false;}
|
||||
virtual RefCntr<DocSequence> getSourceSeq() {return RefCntr<DocSequence>();}
|
||||
|
||||
private:
|
||||
string m_title;
|
||||
string m_title;
|
||||
};
|
||||
|
||||
/** A modifier has a child sequence which does the real work and does
|
||||
@@ -145,8 +146,8 @@ class DocSequence {
|
||||
*/
|
||||
class DocSeqModifier : public DocSequence {
|
||||
public:
|
||||
DocSeqModifier(const string &t, RefCntr<DocSequence> iseq)
|
||||
: DocSequence(t), m_seq(iseq)
|
||||
DocSeqModifier(RefCntr<DocSequence> iseq)
|
||||
: DocSequence(""), m_seq(iseq)
|
||||
{}
|
||||
virtual ~DocSeqModifier() {}
|
||||
|
||||
@@ -168,10 +169,45 @@ public:
|
||||
{
|
||||
m_seq->getUTerms(terms);
|
||||
}
|
||||
virtual string title() {return m_seq->title();}
|
||||
virtual RefCntr<DocSequence> getSourceSeq() {return m_seq;}
|
||||
|
||||
protected:
|
||||
RefCntr<DocSequence> m_seq;
|
||||
};
|
||||
|
||||
// A DocSource can juggle docseqs of different kinds to implement
|
||||
// sorting and filtering in ways depending on the base seqs capabilities
|
||||
class DocSource : public DocSeqModifier {
|
||||
public:
|
||||
DocSource(RefCntr<DocSequence> iseq)
|
||||
: DocSeqModifier(iseq)
|
||||
{}
|
||||
virtual bool canFilter() {return true;}
|
||||
virtual bool canSort() {return true;}
|
||||
virtual bool setFiltSpec(const DocSeqFiltSpec &);
|
||||
virtual bool setSortSpec(const DocSeqSortSpec &);
|
||||
virtual bool getDoc(int num, Rcl::Doc &doc, string *sh = 0)
|
||||
{
|
||||
return m_seq->getDoc(num, doc, sh);
|
||||
}
|
||||
virtual int getResCnt()
|
||||
{
|
||||
return m_seq->getResCnt();
|
||||
}
|
||||
static void set_translations(const string& sort, const string& filt)
|
||||
{
|
||||
o_sort_trans = sort;
|
||||
o_filt_trans = filt;
|
||||
}
|
||||
virtual string title();
|
||||
private:
|
||||
bool buildStack();
|
||||
void unwind();
|
||||
DocSeqFiltSpec m_fspec;
|
||||
DocSeqSortSpec m_sspec;
|
||||
static string o_sort_trans;
|
||||
static string o_filt_trans;
|
||||
};
|
||||
|
||||
#endif /* _DOCSEQ_H_INCLUDED_ */
|
||||
|
||||
+22
-26
@@ -28,7 +28,7 @@ static char rcsid[] = "@(#$Id: docseqdb.cpp,v 1.9 2008-11-13 10:57:46 dockes Exp
|
||||
DocSequenceDb::DocSequenceDb(RefCntr<Rcl::Query> q, const string &t,
|
||||
RefCntr<Rcl::SearchData> sdata)
|
||||
: DocSequence(t), m_q(q), m_sdata(sdata), m_fsdata(sdata),
|
||||
m_rescnt(-1), m_filt(false),
|
||||
m_rescnt(-1),
|
||||
m_queryBuildAbstract(true),
|
||||
m_queryReplaceAbstract(false)
|
||||
{
|
||||
@@ -98,39 +98,31 @@ list<string> DocSequenceDb::expand(Rcl::Doc &doc)
|
||||
return m_q->expand(doc);
|
||||
}
|
||||
|
||||
bool DocSequenceDb::setFiltSpec(DocSeqFiltSpec &fs)
|
||||
bool DocSequenceDb::setFiltSpec(const DocSeqFiltSpec &fs)
|
||||
{
|
||||
if (!fs.isNotNull()) {
|
||||
m_fsdata = m_sdata;
|
||||
m_filt = false;
|
||||
return m_q->setQuery(m_sdata);
|
||||
}
|
||||
|
||||
// We build a search spec by adding a filtering layer to the base one.
|
||||
m_fsdata = RefCntr<Rcl::SearchData>(new Rcl::SearchData(Rcl::SCLT_AND));
|
||||
Rcl::SearchDataClauseSub *cl =
|
||||
new Rcl::SearchDataClauseSub(Rcl::SCLT_SUB, m_sdata);
|
||||
m_fsdata->addClause(cl);
|
||||
LOGDEB(("DocSequenceDb::setFiltSpec\n"));
|
||||
if (fs.isNotNull()) {
|
||||
// We build a search spec by adding a filtering layer to the base one.
|
||||
m_fsdata = RefCntr<Rcl::SearchData>(new Rcl::SearchData(Rcl::SCLT_AND));
|
||||
Rcl::SearchDataClauseSub *cl =
|
||||
new Rcl::SearchDataClauseSub(Rcl::SCLT_SUB, m_sdata);
|
||||
m_fsdata->addClause(cl);
|
||||
|
||||
for (unsigned int i = 0; i < fs.crits.size(); i++) {
|
||||
switch (fs.crits[i]) {
|
||||
case DocSeqFiltSpec::DSFS_MIMETYPE:
|
||||
m_fsdata->addFiletype(fs.values[i]);
|
||||
for (unsigned int i = 0; i < fs.crits.size(); i++) {
|
||||
switch (fs.crits[i]) {
|
||||
case DocSeqFiltSpec::DSFS_MIMETYPE:
|
||||
m_fsdata->addFiletype(fs.values[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_fsdata = m_sdata;
|
||||
}
|
||||
m_filt = true;
|
||||
return m_q->setQuery(m_fsdata);
|
||||
}
|
||||
|
||||
// Need a way to access the translations for filtered ...
|
||||
string DocSequenceDb::title()
|
||||
{
|
||||
LOGDEB(("DOcSequenceDb::title()\n"));
|
||||
return m_filt ? DocSequence::title() + " (filtered)" : DocSequence::title();
|
||||
}
|
||||
|
||||
bool DocSequenceDb::setSortSpec(DocSeqSortSpec &sortspec)
|
||||
bool DocSequenceDb::setSortSpec(const DocSeqSortSpec &sortspec)
|
||||
{
|
||||
LOGDEB(("DocSequenceDb::setSortSpec\n"));
|
||||
if (sortspec.isNotNull()) {
|
||||
bool ascending = false;
|
||||
for (unsigned int i = 0; i < sortspec.crits.size(); i++) {
|
||||
@@ -149,3 +141,7 @@ bool DocSequenceDb::setSortSpec(DocSeqSortSpec &sortspec)
|
||||
return m_q->setQuery(m_fsdata);
|
||||
}
|
||||
|
||||
bool DocSequenceDb::setQuery()
|
||||
{
|
||||
return m_q->setQuery(m_fsdata);
|
||||
}
|
||||
|
||||
@@ -41,10 +41,10 @@ class DocSequenceDb : public DocSequence {
|
||||
virtual string getDescription();
|
||||
virtual list<string> expand(Rcl::Doc &doc);
|
||||
virtual bool canFilter() {return true;}
|
||||
virtual bool setFiltSpec(DocSeqFiltSpec &filtspec);
|
||||
virtual bool setFiltSpec(const DocSeqFiltSpec &filtspec);
|
||||
virtual bool canSort() {return true;}
|
||||
virtual bool setSortSpec(DocSeqSortSpec &sortspec);
|
||||
virtual string title();
|
||||
virtual bool setSortSpec(const DocSeqSortSpec &sortspec);
|
||||
virtual bool setQuery();
|
||||
virtual void setAbstractParams(bool qba, bool qra)
|
||||
{
|
||||
m_queryBuildAbstract = qba;
|
||||
@@ -56,7 +56,6 @@ class DocSequenceDb : public DocSequence {
|
||||
RefCntr<Rcl::SearchData> m_sdata;
|
||||
RefCntr<Rcl::SearchData> m_fsdata; // Filtered
|
||||
int m_rescnt;
|
||||
bool m_filt;
|
||||
bool m_queryBuildAbstract;
|
||||
bool m_queryReplaceAbstract;
|
||||
};
|
||||
|
||||
@@ -40,13 +40,6 @@ static bool filter(const DocSeqFiltSpec& fs, const Rcl::Doc *x)
|
||||
return 0;
|
||||
}
|
||||
|
||||
DocSeqFiltered::DocSeqFiltered(RefCntr<DocSequence> iseq,
|
||||
DocSeqFiltSpec &filtspec,
|
||||
const std::string &t)
|
||||
: DocSeqModifier(t, iseq), m_spec(filtspec)
|
||||
{
|
||||
}
|
||||
|
||||
bool DocSeqFiltered::setFiltSpec(DocSeqFiltSpec &filtspec)
|
||||
{
|
||||
m_spec = filtspec;
|
||||
@@ -59,7 +52,7 @@ bool DocSeqFiltered::getDoc(int idx, Rcl::Doc &doc, string *)
|
||||
LOGDEB1(("DocSeqFiltered: fetching %d\n", idx));
|
||||
|
||||
if (idx >= (int)m_dbindices.size()) {
|
||||
// Have to fetch xapian docs and filter until we get enough or
|
||||
// Have to fetch docs and filter until we get enough or
|
||||
// fail
|
||||
m_dbindices.reserve(idx+1);
|
||||
|
||||
|
||||
+4
-3
@@ -30,9 +30,10 @@
|
||||
* according to the given criteria.
|
||||
*/
|
||||
class DocSeqFiltered : public DocSeqModifier {
|
||||
public:
|
||||
DocSeqFiltered(RefCntr<DocSequence> iseq, DocSeqFiltSpec &filtspec,
|
||||
const std::string &t);
|
||||
public:
|
||||
DocSeqFiltered(RefCntr<DocSequence> iseq, DocSeqFiltSpec &filtspec)
|
||||
: DocSeqModifier(iseq), m_spec(filtspec)
|
||||
{}
|
||||
virtual ~DocSeqFiltered() {}
|
||||
virtual bool canFilter() {return true;}
|
||||
virtual bool setFiltSpec(DocSeqFiltSpec &filtspec);
|
||||
|
||||
@@ -68,13 +68,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
DocSeqSorted::DocSeqSorted(RefCntr<DocSequence> iseq, DocSeqSortSpec &sortspec,
|
||||
const std::string &t)
|
||||
: DocSeqModifier(t, iseq)
|
||||
{
|
||||
setSortSpec(sortspec);
|
||||
}
|
||||
|
||||
bool DocSeqSorted::setSortSpec(DocSeqSortSpec &sortspec)
|
||||
{
|
||||
m_spec = sortspec;
|
||||
|
||||
+5
-2
@@ -30,8 +30,11 @@
|
||||
*/
|
||||
class DocSeqSorted : public DocSeqModifier {
|
||||
public:
|
||||
DocSeqSorted(RefCntr<DocSequence> iseq, DocSeqSortSpec &sortspec,
|
||||
const std::string &t);
|
||||
DocSeqSorted(RefCntr<DocSequence> iseq, DocSeqSortSpec &sortspec)
|
||||
: DocSeqModifier(iseq)
|
||||
{
|
||||
setSortSpec(sortspec);
|
||||
}
|
||||
virtual ~DocSeqSorted() {}
|
||||
virtual bool canSort() {return true;}
|
||||
virtual bool setSortSpec(DocSeqSortSpec &sortspec);
|
||||
|
||||
Reference in New Issue
Block a user