Switch to unified view

a/src/rcldb/rcldb.cpp b/src/rcldb/rcldb.cpp
1
#ifndef lint
1
#ifndef lint
2
static char rcsid[] = "@(#$Id: rcldb.cpp,v 1.123 2007-09-07 08:05:19 dockes Exp $ (C) 2004 J.F.Dockes";
2
static char rcsid[] = "@(#$Id: rcldb.cpp,v 1.124 2007-10-24 08:42:59 dockes Exp $ (C) 2004 J.F.Dockes";
3
#endif
3
#endif
4
/*
4
/*
5
 *   This program is free software; you can redistribute it and/or modify
5
 *   This program is free software; you can redistribute it and/or modify
6
 *   it under the terms of the GNU General Public License as published by
6
 *   it under the terms of the GNU General Public License as published by
7
 *   the Free Software Foundation; either version 2 of the License, or
7
 *   the Free Software Foundation; either version 2 of the License, or
...
...
102
102
103
    // Querying
103
    // Querying
104
    Xapian::Database db;
104
    Xapian::Database db;
105
    Xapian::Query    query; // query descriptor: terms and subqueries
105
    Xapian::Query    query; // query descriptor: terms and subqueries
106
                // joined by operators (or/and etc...)
106
                // joined by operators (or/and etc...)
107
    Xapian::MatchDecider *decider;
107
    Xapian::Enquire *enquire; // Open query descriptor.
108
    Xapian::Enquire      *enquire; // Open query descriptor.
108
    Xapian::MSet     mset;    // Partial result set
109
    Xapian::MSet          mset;    // Partial result set
109
110
110
    // Term frequencies for current query. See makeAbstract, setQuery
111
    // Term frequencies for current query. See makeAbstract, setQuery
111
    map<string, double>  m_termfreqs; 
112
    map<string, double>  m_termfreqs; 
112
    
113
    
113
    Native(Db *db) 
114
    Native(Db *db) 
114
    : m_db(db),
115
    : m_db(db),
115
      m_isopen(false), m_iswritable(false), enquire(0) 
116
      m_isopen(false), m_iswritable(false), decider(0), enquire(0)
116
    { }
117
    { }
117
118
118
    ~Native() {
119
    ~Native() {
120
  delete decider;
119
    delete enquire;
121
    delete enquire;
120
    }
122
    }
121
123
122
    string makeAbstract(Xapian::docid id, const list<string>& terms);
124
    string makeAbstract(Xapian::docid id, const list<string>& terms);
123
125
...
...
132
     *  unique term for replace_document, and for retrieving by
134
     *  unique term for replace_document, and for retrieving by
133
     *  path/ipath (history)
135
     *  path/ipath (history)
134
     */
136
     */
135
    bool subDocs(const string &hash, vector<Xapian::docid>& docids);
137
    bool subDocs(const string &hash, vector<Xapian::docid>& docids);
136
138
137
    /** Keep this inline */
139
};
138
    bool filterMatch(Db *rdb, Xapian::Document &xdoc) {
140
141
class FilterMatcher : public Xapian::MatchDecider {
142
public:
143
    FilterMatcher(const string &topdir)
144
  : m_topdir(topdir)
145
    {}
146
    virtual ~FilterMatcher() {}
147
148
    virtual bool operator()(const Xapian::Document &xdoc) const {
139
    // Parse xapian document's data and populate doc fields
149
    // Parse xapian document's data and populate doc fields
140
    string data = xdoc.get_data();
150
    string data = xdoc.get_data();
141
    ConfSimple parms(&data);
151
    ConfSimple parms(&data);
142
152
143
    // The only filtering for now is on file path (subtree)
153
    // The only filtering for now is on file path (subtree)
144
    string url;
154
    string url;
145
    parms.get(string("url"), url);
155
    parms.get(string("url"), url);
146
  url = url.substr(7);
156
  LOGDEB2(("FilterMatcher topdir [%s] url [%s]\n",
147
  LOGDEB2(("Rcl::Db::Native:filter filter [%s] fn [%s]\n",
148
         rdb->m_filterTopDir.c_str(), url.c_str()));
157
         m_topdir.c_str(), url.c_str()));
149
    if (url.find(rdb->m_filterTopDir) == 0) 
158
    if (url.find(m_topdir, 7) == 7) {
159
      LOGDEB(("FilterMatcher: MATCH\n"));
150
        return true;
160
        return true; 
161
  } else {
162
      LOGDEB(("FilterMatcher: NO MATCH\n"));
151
    return false;
163
        return false;
164
  }
165
    }
152
    }
166
    
167
private:
168
    string m_topdir;
153
};
169
};
154
170
155
    /* See comment in class declaration */
171
/* See comment in class declaration */
156
bool Native::subDocs(const string &hash, vector<Xapian::docid>& docids) 
172
bool Native::subDocs(const string &hash, vector<Xapian::docid>& docids) 
157
{
173
{
158
    docids.clear();
174
    docids.clear();
159
    string qterm = "Q"+ hash + "|";
175
    string qterm = "Q"+ hash + "|";
160
    string ermsg;
176
    string ermsg;
...
...
1422
    }
1438
    }
1423
    m_reason.erase();
1439
    m_reason.erase();
1424
    LOGDEB(("Db::setQuery:\n"));
1440
    LOGDEB(("Db::setQuery:\n"));
1425
1441
1426
    m_filterTopDir = sdata->getTopdir();
1442
    m_filterTopDir = sdata->getTopdir();
1443
    delete m_ndb->decider;
1444
    m_ndb->decider = 0;
1445
    if (!m_filterTopDir.empty())
1446
  m_ndb->decider = new FilterMatcher(m_filterTopDir);
1427
    m_dbindices.clear();
1447
    m_dbindices.clear();
1428
    m_qOpts = opts;
1448
    m_qOpts = opts;
1429
    m_ndb->m_termfreqs.clear();
1449
    m_ndb->m_termfreqs.clear();
1430
1450
1431
    Xapian::Query xq;
1451
    Xapian::Query xq;
...
...
1758
    if (!m_ndb || !m_ndb->enquire) {
1778
    if (!m_ndb || !m_ndb->enquire) {
1759
    LOGERR(("Db::getDoc: no query opened\n"));
1779
    LOGERR(("Db::getDoc: no query opened\n"));
1760
    return false;
1780
    return false;
1761
    }
1781
    }
1762
1782
1763
    // For now the only post-query filter is on dir subtree
1764
    bool postqfilter = !m_filterTopDir.empty();
1765
    LOGDEB1(("Topdir %s postqflt %d\n", m_asdata.topdir.c_str(), postqfilter));
1766
1767
    int xapi;
1783
    int xapi;
1768
    if (postqfilter) {
1784
    if (m_ndb->decider) {
1769
    // There is a postquery filter, does this fall in already known area ?
1785
    // There is a postquery filter, does this fall in already known area ?
1770
    if (exti >= (int)m_dbindices.size()) {
1786
    if (exti >= (int)m_dbindices.size()) {
1771
        // Have to fetch xapian docs and filter until we get
1787
        // Have to fetch xapian docs and filter until we get
1772
        // enough or fail
1788
        // enough or fail
1773
        m_dbindices.reserve(exti+1);
1789
        m_dbindices.reserve(exti+1);
...
...
1794
        }
1810
        }
1795
        first = m_ndb->mset.get_firstitem();
1811
        first = m_ndb->mset.get_firstitem();
1796
        for (unsigned int i = 0; i < m_ndb->mset.size() ; i++) {
1812
        for (unsigned int i = 0; i < m_ndb->mset.size() ; i++) {
1797
            LOGDEB(("Db::getDoc: [%d]\n", i));
1813
            LOGDEB(("Db::getDoc: [%d]\n", i));
1798
            Xapian::Document xdoc = m_ndb->mset[i].get_document();
1814
            Xapian::Document xdoc = m_ndb->mset[i].get_document();
1799
          if (m_ndb->filterMatch(this, xdoc)) {
1815
          if ((*m_ndb->decider)(xdoc)) {
1800
            m_dbindices.push_back(first + i);
1816
            m_dbindices.push_back(first + i);
1801
            }
1817
            }
1802
        }
1818
        }
1803
        first = first + m_ndb->mset.size();
1819
        first = first + m_ndb->mset.size();
1804
        }
1820
        }
1805
    }
1821
    }
1806
    xapi = m_dbindices[exti];
1822
    xapi = m_dbindices[exti];
1807
    } else {
1823
    } else {
1808
    xapi = exti;
1824
    xapi = exti;
1809
    }
1825
    }
1810
1811
1826
1812
    // From there on, we work with a xapian enquire item number. Fetch it
1827
    // From there on, we work with a xapian enquire item number. Fetch it
1813
    int first = m_ndb->mset.get_firstitem();
1828
    int first = m_ndb->mset.get_firstitem();
1814
    int last = first + m_ndb->mset.size() -1;
1829
    int last = first + m_ndb->mset.size() -1;
1815
1830