1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
#include "search.h"
#include "symbol.h"
#include <string.h>
#include "internal.h"
/***************************************************************************
*
* Filter
*
***************************************************************************/
void filt_destroy_i(Filter *filt)
{
h_destroy(filt->cache);
free(filt);
}
void filt_deref(Filter *filt)
{
if (--(filt->ref_cnt) == 0) {
filt->destroy_i(filt);
}
}
BitVector *filt_get_bv(Filter *filt, IndexReader *ir)
{
CacheObject *co = (CacheObject *)h_get(filt->cache, ir);
if (!co) {
BitVector *bv;
if (!ir->cache) {
ir_add_cache(ir);
}
bv = filt->get_bv_i(filt, ir);
co = co_create(filt->cache, ir->cache, filt, ir,
(free_ft)&bv_destroy, (void *)bv);
}
return (BitVector *)co->obj;
}
static char *filt_to_s_i(Filter *filt)
{
return estrdup(S(filt->name));
}
static unsigned long filt_hash_default(Filter *filt)
{
(void)filt;
return 0;
}
static int filt_eq_default(Filter *filt, Filter *o)
{
(void)filt; (void)o;
return false;
}
Filter *filt_create(size_t size, Symbol name)
{
Filter *filt = (Filter *)emalloc(size);
filt->cache = co_hash_create();
filt->name = name;
filt->to_s = &filt_to_s_i;
filt->hash = &filt_hash_default;
filt->eq = &filt_eq_default;
filt->destroy_i = &filt_destroy_i;
filt->ref_cnt = 1;
return filt;
}
unsigned long filt_hash(Filter *filt)
{
return sym_hash(filt->name) ^ filt->hash(filt);
}
int filt_eq(Filter *filt, Filter *o)
{
return ((filt == o)
|| ((filt->name == o->name)
&& (filt->eq == o->eq)
&& (filt->eq(filt, o))));
}
/***************************************************************************
*
* QueryFilter
*
***************************************************************************/
#define QF(filt) ((QueryFilter *)(filt))
typedef struct QueryFilter
{
Filter super;
Query *query;
} QueryFilter;
static char *qfilt_to_s(Filter *filt)
{
Query *query = QF(filt)->query;
char *query_str = query->to_s(query, NULL);
char *filter_str = strfmt("QueryFilter< %s >", query_str);
free(query_str);
return filter_str;
}
static BitVector *qfilt_get_bv_i(Filter *filt, IndexReader *ir)
{
BitVector *bv = bv_new_capa(ir->max_doc(ir));
Searcher *sea = isea_new(ir);
Weight *weight = q_weight(QF(filt)->query, sea);
Scorer *scorer = weight->scorer(weight, ir);
if (scorer) {
while (scorer->next(scorer)) {
bv_set(bv, scorer->doc);
}
scorer->destroy(scorer);
}
weight->destroy(weight);
free(sea);
return bv;
}
static unsigned long qfilt_hash(Filter *filt)
{
return q_hash(QF(filt)->query);
}
static int qfilt_eq(Filter *filt, Filter *o)
{
return q_eq(QF(filt)->query, QF(o)->query);
}
static void qfilt_destroy_i(Filter *filt)
{
Query *query = QF(filt)->query;
q_deref(query);
filt_destroy_i(filt);
}
Filter *qfilt_new_nr(Query *query)
{
Filter *filt = filt_new(QueryFilter);
QF(filt)->query = query;
filt->get_bv_i = &qfilt_get_bv_i;
filt->hash = &qfilt_hash;
filt->eq = &qfilt_eq;
filt->to_s = &qfilt_to_s;
filt->destroy_i = &qfilt_destroy_i;
return filt;
}
Filter *qfilt_new(Query *query)
{
REF(query);
return qfilt_new_nr(query);
}
|