15
15
#include " fts-flatcurve-config.h"
16
16
extern " C" {
17
17
#include " lib.h"
18
+ #include " array.h"
18
19
#include " file-create-locked.h"
19
20
#include " hash.h"
20
21
#include " mail-storage-private.h"
@@ -148,8 +149,13 @@ struct flatcurve_xapian {
148
149
bool closing:1 ;
149
150
};
150
151
152
+ struct flatcurve_fts_query_xapian_maybe {
153
+ Xapian::Query *query;
154
+ };
155
+
151
156
struct flatcurve_fts_query_xapian {
152
157
Xapian::Query *query;
158
+ ARRAY (struct flatcurve_fts_query_xapian_maybe ) maybe_queries;
153
159
};
154
160
155
161
struct flatcurve_xapian_db_iter {
@@ -185,6 +191,7 @@ struct fts_flatcurve_xapian_query_iter {
185
191
Xapian::Enquire *enquire;
186
192
Xapian::MSetIterator i;
187
193
struct fts_flatcurve_xapian_query_result *result;
194
+ int curr_query;
188
195
};
189
196
190
197
static void
@@ -1465,6 +1472,8 @@ fts_flatcurve_build_query_arg_term(struct flatcurve_fts_query *query,
1465
1472
const char *term)
1466
1473
{
1467
1474
const char *hdr;
1475
+ bool maybe = FALSE ;
1476
+ struct flatcurve_fts_query_xapian_maybe *mquery;
1468
1477
Xapian::Query::op op = Xapian::Query::OP_INVALID;
1469
1478
Xapian::Query *oldq, q;
1470
1479
struct flatcurve_fts_query_xapian *x = query->xapian ;
@@ -1529,7 +1538,7 @@ fts_flatcurve_build_query_arg_term(struct flatcurve_fts_query *query,
1529
1538
* appears in the general pool of header
1530
1539
* terms for the message, not to a specific
1531
1540
* header, so this is only a maybe match. */
1532
- query-> maybe = TRUE ;
1541
+ maybe = TRUE ;
1533
1542
}
1534
1543
} else {
1535
1544
hdr = t_str_lcase (arg->hdr_field_name );
@@ -1545,9 +1554,17 @@ fts_flatcurve_build_query_arg_term(struct flatcurve_fts_query *query,
1545
1554
q = Xapian::Query (Xapian::Query::OP_AND_NOT,
1546
1555
Xapian::Query::MatchAll, q);
1547
1556
1548
- if (x->query == NULL )
1557
+ if (maybe) {
1558
+ /* Maybe searches are not added to the "master search" query; they
1559
+ * will be run independently. Matches will be placed in the maybe
1560
+ * results array. */
1561
+ if (!array_is_created (&x->maybe_queries ))
1562
+ p_array_init (&x->maybe_queries , query->pool , 4 );
1563
+ mquery = array_append_space (&x->maybe_queries );
1564
+ mquery->query = new Xapian::Query (std_move (q));
1565
+ } else if (x->query == NULL ) {
1549
1566
x->query = new Xapian::Query (std_move (q));
1550
- else {
1567
+ } else {
1551
1568
oldq = x->query ;
1552
1569
x->query = new Xapian::Query (op, *(x->query ), q);
1553
1570
delete (oldq);
@@ -1642,29 +1659,59 @@ fts_flatcurve_xapian_query_iter_init(struct flatcurve_fts_query *query)
1642
1659
struct fts_flatcurve_xapian_query_iter *iter;
1643
1660
1644
1661
iter = p_new (query->pool , struct fts_flatcurve_xapian_query_iter , 1 );
1662
+ /* -1: "Master" query
1663
+ * >= 0: Current index of maybe_queries */
1664
+ iter->curr_query = -1 ;
1645
1665
iter->query = query;
1646
1666
iter->result = p_new (query->pool ,
1647
1667
struct fts_flatcurve_xapian_query_result , 1 );
1648
1668
1649
1669
return iter;
1650
1670
}
1651
1671
1672
+ static void
1673
+ fts_flatcurve_xapian_query_iter_clear_current (struct fts_flatcurve_xapian_query_iter *iter)
1674
+ {
1675
+ iter->i .~MSetIterator ();
1676
+ delete (iter->enquire );
1677
+ iter->enquire = NULL ;
1678
+ }
1679
+
1652
1680
struct fts_flatcurve_xapian_query_result *
1653
1681
fts_flatcurve_xapian_query_iter_next (struct fts_flatcurve_xapian_query_iter *iter)
1654
1682
{
1655
1683
Xapian::MSet m;
1684
+ const struct flatcurve_fts_query_xapian_maybe *mquery;
1656
1685
enum flatcurve_xapian_db_opts opts =
1657
1686
ENUM_EMPTY (flatcurve_xapian_db_opts);
1687
+ Xapian::Query *q = NULL ;
1658
1688
1659
1689
if (iter->enquire == NULL ) {
1660
- if ((iter->query ->xapian ->query == NULL ) ||
1690
+ /* Master query. */
1691
+ if (iter->curr_query == -1 ) {
1692
+ if (iter->query ->xapian ->query == NULL )
1693
+ ++iter->curr_query ;
1694
+ else
1695
+ q = iter->query ->xapian ->query ;
1696
+ }
1697
+
1698
+ /* Maybe queries. */
1699
+ if ((iter->curr_query >= 0 ) &&
1700
+ (array_is_created (&iter->query ->xapian ->maybe_queries )) &&
1701
+ (array_count (&iter->query ->xapian ->maybe_queries ) > iter->curr_query )) {
1702
+ mquery = array_idx (&iter->query ->xapian ->maybe_queries ,
1703
+ iter->curr_query );
1704
+ q = mquery->query ;
1705
+ }
1706
+
1707
+ if ((q == NULL ) ||
1661
1708
((iter->db = fts_flatcurve_xapian_read_db (iter->query ->backend , opts)) == NULL ))
1662
1709
return NULL ;
1663
1710
1664
1711
iter->enquire = new Xapian::Enquire (*iter->db );
1665
1712
iter->enquire ->set_docid_order (
1666
1713
Xapian::Enquire::DONT_CARE);
1667
- iter->enquire ->set_query (*iter-> query -> xapian -> query );
1714
+ iter->enquire ->set_query (*q );
1668
1715
1669
1716
try {
1670
1717
m = iter->enquire ->get_mset (0 ,
@@ -1685,9 +1732,13 @@ fts_flatcurve_xapian_query_iter_next(struct fts_flatcurve_xapian_query_iter *ite
1685
1732
iter->i = m.begin ();
1686
1733
}
1687
1734
1688
- if (iter->i == m.end ())
1689
- return NULL ;
1735
+ if (iter->i == m.end ()) {
1736
+ fts_flatcurve_xapian_query_iter_clear_current (iter);
1737
+ ++iter->curr_query ;
1738
+ return fts_flatcurve_xapian_query_iter_next (iter);
1739
+ }
1690
1740
1741
+ iter->result ->maybe = (iter->curr_query >= 0 );
1691
1742
iter->result ->score = iter->i .get_weight ();
1692
1743
/* MSet docid can be an "interleaved" docid generated by
1693
1744
* Xapian::Database when handling multiple DBs at once. Instead, we
@@ -1707,8 +1758,7 @@ fts_flatcurve_xapian_query_iter_deinit(struct fts_flatcurve_xapian_query_iter **
1707
1758
/* Need to explicitly call dtor, or else MSet doesn't release memory
1708
1759
* allocated internally. */
1709
1760
*_iter = NULL ;
1710
- iter->i .~MSetIterator ();
1711
- delete (iter->enquire );
1761
+ fts_flatcurve_xapian_query_iter_clear_current (iter);
1712
1762
p_free (iter->query ->pool , iter->result );
1713
1763
p_free (iter->query ->pool , iter);
1714
1764
}
@@ -1723,7 +1773,10 @@ bool fts_flatcurve_xapian_run_query(struct flatcurve_fts_query *query,
1723
1773
if ((iter = fts_flatcurve_xapian_query_iter_init (query)) == NULL )
1724
1774
return FALSE ;
1725
1775
while ((result = fts_flatcurve_xapian_query_iter_next (iter)) != NULL ) {
1726
- seq_range_array_add (&r->uids , result->uid );
1776
+ if (result->maybe )
1777
+ seq_range_array_add (&r->maybe_uids , result->uid );
1778
+ else
1779
+ seq_range_array_add (&r->uids , result->uid );
1727
1780
score = array_append_space (&r->scores );
1728
1781
score->score = (float )result->score ;
1729
1782
score->uid = result->uid ;
@@ -1734,7 +1787,15 @@ bool fts_flatcurve_xapian_run_query(struct flatcurve_fts_query *query,
1734
1787
1735
1788
void fts_flatcurve_xapian_destroy_query (struct flatcurve_fts_query *query)
1736
1789
{
1790
+ struct flatcurve_fts_query_xapian_maybe *mquery;
1791
+
1737
1792
delete (query->xapian ->query );
1793
+ if (array_is_created (&query->xapian ->maybe_queries )) {
1794
+ array_foreach_modifiable (&query->xapian ->maybe_queries , mquery) {
1795
+ delete (mquery->query );
1796
+ }
1797
+ array_free (&query->xapian ->maybe_queries );
1798
+ }
1738
1799
}
1739
1800
1740
1801
const char *fts_flatcurve_xapian_library_version ()
0 commit comments