~ubuntu-branches/ubuntu/wily/ruby-ferret/wily-proposed

« back to all changes in this revision

Viewing changes to ext/filter.c

  • Committer: Bazaar Package Importer
  • Author(s): Antonio Terceiro
  • Date: 2011-07-28 00:02:49 UTC
  • Revision ID: james.westby@ubuntu.com-20110728000249-v0443y69ftcpxwi6
Tags: upstream-0.11.6
ImportĀ upstreamĀ versionĀ 0.11.6

Show diffs side-by-side

added added

removed removed

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