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.
297 lines
6.9 KiB
297 lines
6.9 KiB
//
|
|
// ResultMatch.cc
|
|
//
|
|
// ResultMatch: Contains information related to a given
|
|
// document that was matched by a search. For instance, the
|
|
// score of the document for this search. Similar to the
|
|
// DocMatch class but designed for result display purposes.
|
|
//
|
|
// Part of the ht://Dig package <http://www.htdig.org/>
|
|
// Copyright (c) 1995-2004 The ht://Dig Group
|
|
// For copyright details, see the file COPYING in your distribution
|
|
// or the GNU Library General Public License (LGPL) version 2 or later
|
|
// <http://www.gnu.org/copyleft/lgpl.html>
|
|
//
|
|
// $Id: ResultMatch.cc,v 1.10 2004/05/28 13:15:24 lha Exp $
|
|
//
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "htconfig.h"
|
|
#endif /* HAVE_CONFIG_H */
|
|
|
|
#include "ResultMatch.h"
|
|
|
|
// Definition of how to search
|
|
ResultMatch::SortType ResultMatch::mySortType;
|
|
|
|
//*****************************************************************************
|
|
//
|
|
ResultMatch::ResultMatch()
|
|
{
|
|
}
|
|
|
|
|
|
//*****************************************************************************
|
|
//
|
|
ResultMatch::~ResultMatch()
|
|
{
|
|
}
|
|
|
|
|
|
//*****************************************************************************
|
|
// Default-access-methods. Just dummies when that data is not used.
|
|
char *ResultMatch::getTitle()
|
|
{ return ""; }
|
|
|
|
time_t ResultMatch::getTime()
|
|
{ return 0; }
|
|
|
|
void ResultMatch::setTitle(char *)
|
|
{ }
|
|
|
|
void ResultMatch::setTime(time_t)
|
|
{ }
|
|
|
|
// Then for each sort-type, we derive a class, which will keep
|
|
// any necessary additional piece of data, and return the compare-function.
|
|
|
|
// We could have a real cute implementation with global
|
|
// constructors registering a factory method with ResultMatch,
|
|
// so it would just check a list and never need to be changed
|
|
// when new search methods are introduced, but that seems futile.
|
|
// It is more practical to just add search methods here and
|
|
// change the createMatch method, last.
|
|
|
|
|
|
//*****************************************************************************
|
|
class ScoreMatch : public ResultMatch
|
|
{
|
|
// This one needs no additional data
|
|
public:
|
|
virtual ResultMatch::CmpFun getSortFun();
|
|
ScoreMatch();
|
|
~ScoreMatch();
|
|
private:
|
|
static int compare(const void *a1, const void *a2);
|
|
};
|
|
|
|
ScoreMatch::ScoreMatch() {}
|
|
ScoreMatch::~ScoreMatch() {}
|
|
|
|
int
|
|
ScoreMatch::compare(const void *a1, const void *a2)
|
|
{
|
|
ResultMatch *m1 = *((ResultMatch **) a1);
|
|
ResultMatch *m2 = *((ResultMatch **) a2);
|
|
double score1 = m1->getScore();
|
|
double score2 = m2->getScore();
|
|
|
|
if(score1 == score2)
|
|
return 0;
|
|
else if(score1 < score2)
|
|
return 1;
|
|
else
|
|
return -1;
|
|
|
|
// return m2->getScore() - m1->getScore();
|
|
}
|
|
|
|
ResultMatch::CmpFun
|
|
ScoreMatch::getSortFun() { return compare; }
|
|
|
|
//*****************************************************************************
|
|
class TimeMatch : public ResultMatch
|
|
{
|
|
public:
|
|
virtual ResultMatch::CmpFun getSortFun();
|
|
virtual void setTime(time_t);
|
|
virtual time_t getTime();
|
|
TimeMatch();
|
|
~TimeMatch();
|
|
private:
|
|
// We need a time_t here, and to override the get/setTime methods.
|
|
time_t myTime;
|
|
|
|
static int compare(const void *a1, const void *a2);
|
|
};
|
|
|
|
TimeMatch::TimeMatch() {}
|
|
TimeMatch::~TimeMatch() {}
|
|
|
|
void
|
|
TimeMatch::setTime(time_t t)
|
|
{
|
|
myTime = t;
|
|
}
|
|
|
|
time_t TimeMatch::getTime()
|
|
{
|
|
return myTime;
|
|
}
|
|
|
|
int
|
|
TimeMatch::compare(const void *a1, const void *a2)
|
|
{
|
|
ResultMatch *m1 = *((ResultMatch **) a1);
|
|
ResultMatch *m2 = *((ResultMatch **) a2);
|
|
time_t t1 = m1->getTime();
|
|
time_t t2 = m2->getTime();
|
|
|
|
return (int) (t2 - t1);
|
|
}
|
|
|
|
ResultMatch::CmpFun
|
|
TimeMatch::getSortFun() { return compare; }
|
|
|
|
//*****************************************************************************
|
|
class IDMatch : public ResultMatch
|
|
{
|
|
// This one needs no additional data
|
|
public:
|
|
virtual ResultMatch::CmpFun getSortFun();
|
|
IDMatch();
|
|
~IDMatch();
|
|
private:
|
|
static int compare(const void *a1, const void *a2);
|
|
};
|
|
|
|
IDMatch::IDMatch() {}
|
|
IDMatch::~IDMatch() {}
|
|
|
|
int
|
|
IDMatch::compare(const void *a1, const void *a2)
|
|
{
|
|
ResultMatch *m1 = *((ResultMatch **) a1);
|
|
ResultMatch *m2 = *((ResultMatch **) a2);
|
|
int i1 = m1->getID();
|
|
int i2 = m2->getID();
|
|
|
|
return (i1 - i2);
|
|
}
|
|
|
|
ResultMatch::CmpFun
|
|
IDMatch::getSortFun() { return compare; }
|
|
|
|
//*****************************************************************************
|
|
class TitleMatch : public ResultMatch
|
|
{
|
|
public:
|
|
virtual ResultMatch::CmpFun getSortFun();
|
|
virtual void setTitle(char *t);
|
|
virtual char *getTitle();
|
|
TitleMatch();
|
|
~TitleMatch();
|
|
private:
|
|
// We need a String here, and to override the get/setTitle methods.
|
|
// It has to be a String, as the "char *" goes away shortly
|
|
// after creating the object.
|
|
String myTitle;
|
|
|
|
static int compare(const void *a1, const void *a2);
|
|
};
|
|
|
|
TitleMatch::TitleMatch() {}
|
|
TitleMatch::~TitleMatch() {}
|
|
|
|
void
|
|
TitleMatch::setTitle(char *t)
|
|
{
|
|
myTitle = t;
|
|
}
|
|
|
|
char *
|
|
TitleMatch::getTitle()
|
|
{
|
|
return myTitle;
|
|
}
|
|
|
|
int
|
|
TitleMatch::compare(const void *a1, const void *a2)
|
|
{
|
|
ResultMatch *m1 = *((ResultMatch **) a1);
|
|
ResultMatch *m2 = *((ResultMatch **) a2);
|
|
char *t1 = m1->getTitle();
|
|
char *t2 = m2->getTitle();
|
|
|
|
if (!t1) t1 = "";
|
|
if (!t2) t2 = "";
|
|
return mystrcasecmp(t1, t2);
|
|
}
|
|
|
|
ResultMatch::CmpFun
|
|
TitleMatch::getSortFun() { return compare; }
|
|
|
|
//*****************************************************************************
|
|
int
|
|
ResultMatch::setSortType(const String& sorttype)
|
|
{
|
|
static const struct
|
|
{
|
|
char *typest;
|
|
SortType type;
|
|
}
|
|
sorttypes[] =
|
|
{
|
|
{"score", SortByScore},
|
|
{"date", SortByTime},
|
|
{"time", SortByTime},
|
|
{"title", SortByTitle},
|
|
{"id", SortByID}
|
|
};
|
|
int i = 0;
|
|
const char *st = sorttype;
|
|
if (st && *st)
|
|
{
|
|
if (mystrncasecmp("rev", st, 3) == 0)
|
|
st += 3;
|
|
for (i = sizeof(sorttypes)/sizeof(sorttypes[0]); --i >= 0; )
|
|
{
|
|
if (mystrcasecmp(sorttypes[i].typest, st) == 0)
|
|
{
|
|
mySortType = sorttypes[i].type;
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
// If not specified, default to SortByScore
|
|
mySortType = SortByScore;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
//*****************************************************************************
|
|
// Now here's the switchboard: a create-function that returns a
|
|
// "new":ed object of the right class for what to compare.
|
|
// To have the pairing managed in a (dynamically registered)
|
|
// list may seem interesting, but since everything is here
|
|
// anyway, there's little need but a small cuteness-factor.
|
|
// We could also change the guts to use some kind of creator
|
|
// object, if there would be a win.
|
|
|
|
ResultMatch *
|
|
ResultMatch::create()
|
|
{
|
|
switch (mySortType)
|
|
{
|
|
case ResultMatch::SortByScore:
|
|
return new ScoreMatch();
|
|
|
|
case ResultMatch::SortByTime:
|
|
return new TimeMatch();
|
|
|
|
case ResultMatch::SortByTitle:
|
|
return new TitleMatch();
|
|
|
|
case ResultMatch::SortByID:
|
|
return new IDMatch();
|
|
|
|
default:
|
|
// It is doubtful which is better: to abort() or paper
|
|
// over something bad here.
|
|
return new ScoreMatch();
|
|
}
|
|
}
|