resultstore: 1st working. Interface needs improvements

This commit is contained in:
Jean-Francois Dockes
2020-12-17 11:15:07 +01:00
parent 3479e7cd85
commit ea9b5ab9eb
10 changed files with 445 additions and 159 deletions
+31 -19
View File
@@ -32,15 +32,17 @@
#include "rcldoc.h"
#include "rclquery.h"
namespace Rcl {
class QResultStore::Internal {
public:
bool testentry(const std::pair<std::string,std::string>& entry) {
return !entry.second.empty() &&
excludedfields.find(entry.first) == excludedfields.end();
(isinc ? fieldspec.find(entry.first) != fieldspec.end() :
fieldspec.find(entry.first) == fieldspec.end());
}
std::map<std::string, int> keyidx;
int ndocs{0};
// Notes: offsets[0] is always 0, not really useful, simpler this
// way. Also could use simple C array instead of c++ vector...
struct docoffs {
@@ -51,7 +53,8 @@ public:
std::vector<int> offsets;
};
std::vector<struct docoffs> docs;
std::set<std::string> excludedfields;
std::set<std::string> fieldspec;
bool isinc{false};
};
QResultStore::QResultStore()
@@ -63,14 +66,17 @@ QResultStore::~QResultStore()
delete m;
}
//{"author", "ipath", "rcludi", "relevancyrating", "sig", "abstract", "caption",
// "filename", "origcharset", "sig"};
// For reference : Fields normally excluded by uprcl:
// {"author", "ipath", "rcludi", "relevancyrating", "sig", "abstract", "caption",
// "filename", "origcharset", "sig"};
bool QResultStore::storeQuery(Rcl::Query& query, std::set<std::string> excl)
bool QResultStore::storeQuery(Rcl::Query& query, std::set<std::string> fldspec,
bool isinc)
{
m->excludedfields = excl;
m->fieldspec = fldspec;
m->isinc = isinc;
/////////////
// Enumerate all existing keys and assign array indexes for
// them. Count documents while we are at it.
@@ -81,10 +87,11 @@ bool QResultStore::storeQuery(Rcl::Query& query, std::set<std::string> excl)
{"fbytes", 4},
{"dbytes", 5}
};
m->ndocs = 0;
for (;;m->ndocs++) {
int count = 0;
for (;;count++) {
Rcl::Doc doc;
if (!query.getDoc(m->ndocs, doc, false)) {
if (!query.getDoc(count, doc, false)) {
break;
}
for (const auto& entry : doc.meta) {
@@ -101,9 +108,9 @@ bool QResultStore::storeQuery(Rcl::Query& query, std::set<std::string> excl)
///////
// Populate the main array with doc-equivalent structures.
m->docs.resize(m->ndocs);
m->docs.resize(count);
for (int i = 0; i < m->ndocs; i++) {
for (int i = 0; i < count; i++) {
Rcl::Doc doc;
if (!query.getDoc(i, doc, false)) {
break;
@@ -168,20 +175,25 @@ bool QResultStore::storeQuery(Rcl::Query& query, std::set<std::string> excl)
return true;
}
const char *QResultStore::fieldvalue(int docindex, const std::string& fldname)
int QResultStore::getCount()
{
if (docindex < 0 || docindex >= m->ndocs) {
return int(m->docs.size());
}
const char *QResultStore::fieldValue(int docindex, const std::string& fldname)
{
if (docindex < 0 || docindex >= int(m->docs.size())) {
return nullptr;
}
auto& vdoc = m->docs[docindex];
auto it = m->keyidx.find(fldname);
if (it == m->keyidx.end()) {
return nullptr;
}
if (it->second < 0 || it->second >= int(vdoc.offsets.size())) {
if (it == m->keyidx.end() ||
it->second < 0 || it->second >= int(vdoc.offsets.size())) {
//??
return nullptr;
}
return vdoc.base + vdoc.offsets[it->second];
}
} // namespace Rcl
+30 -4
View File
@@ -17,24 +17,49 @@
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _QRESULTSTORE_H_INCLUDED_
#define _QRESULTSTORE_H_INCLUDED_
/**
* Implement an efficient way to store the whole or part of a query result set.
* This would naturally be done as a vector<Rcl::Doc>, but the natural
* way leads to a huge space waste (8-10x), which may be a problem in
* some cases. This is mostly used by the uprcl Media Server.
*/
#include <string>
#include <set>
namespace Rcl {
class Query;
}
class QResultStore {
public:
QResultStore();
~QResultStore();
bool storeQuery(Rcl::Query& q, std::set<std::string> excluded = {});
const char *fieldvalue(int docindex, const std::string& fldname);
/**
* Fetch and store the results of the input query.
*
* @param q the executed query object to use for fetching results.
* @param fldspec list of fields to be excluded or included.
* @param isinc if true, the field list defines the fields to be stored,
* else, those to be excluded.
*/
bool storeQuery(Rcl::Query& q, std::set<std::string> fldspec = {},
bool isinc = false);
/** Retrieve count of stored results */
int getCount();
/**
* Retrieve field value.
*
* @param docindex index in query results.
* @param fldname field name.
*/
const char *fieldValue(int docindex, const std::string& fldname);
QResultStore(const QResultStore&) = delete;
QResultStore& operator=(const QResultStore&) = delete;
@@ -43,4 +68,5 @@ private:
Internal *m{nullptr};
};
}
#endif /* _QRESULTSTORE_H_INCLUDED_ */