e8edf62d08343ab05c7c054849188615e36e9caa
[idzebra-moved-to-github.git] / index / limit.c
1 /* This file is part of the Zebra server.
2    Copyright (C) 1995-2008 Index Data
3
4 Zebra is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
7 version.
8
9 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18 */
19
20 #include <stdio.h>
21 #include <assert.h>
22
23 #include <yaz/xmalloc.h>
24 #include <yaz/diagbib1.h>
25 #include "index.h"
26
27 #define ZEBRA_LIMIT_DEBUG 0
28
29 struct zebra_limit {
30     int complement_flag;
31     zint *ids;
32 };
33
34 void zebra_limit_destroy(struct zebra_limit *zl)
35 {
36     if (zl)
37     {
38         xfree(zl->ids);
39         xfree(zl);
40     }
41 }
42
43 struct zebra_limit *zebra_limit_create(int complement_flag, zint *ids)
44 {
45     struct zebra_limit *zl = 0;
46     size_t i;
47     if (ids)
48     {
49         for (i = 0; ids[i]; i++)
50             ;
51         zl = xmalloc(sizeof(*zl));
52         zl->ids = xmalloc((i+1) * sizeof(*ids));
53         memcpy(zl->ids, ids, (i+1) * sizeof(*ids));
54         zl->complement_flag = complement_flag;
55     }
56     return zl;
57 }
58
59 static int zebra_limit_filter_cb(const void *buf, void *data)
60 {
61     struct zebra_limit *zl = data;
62     const struct it_key *key = buf;
63     size_t i;
64
65 #if ZEBRA_LIMIT_DEBUG
66     yaz_log(YLOG_LOG, "zebra_limit_filter_cb zl=%p key->len=%d", zl, key->len);
67 #endif
68     for (i = 0; zl->ids[i]; i++)
69     {
70 #if ZEBRA_LIMIT_DEBUG
71         yaz_log(YLOG_LOG, " i=%d ids=" ZINT_FORMAT " mem=" ZINT_FORMAT,
72                 i, zl->ids[i], key->mem[1]);
73 #endif
74         if (zl->ids[i] == key->mem[1])
75         {
76 #if ZEBRA_LIMIT_DEBUG
77             yaz_log(YLOG_LOG, " match. Ret=%d", zl->complement_flag ? 0:1);
78 #endif
79             return zl->complement_flag ? 0 : 1;
80         }
81     }
82 #if ZEBRA_LIMIT_DEBUG
83     yaz_log(YLOG_LOG, " no match. Ret=%d", zl->complement_flag ? 1:0);
84 #endif
85     return zl->complement_flag ? 1 : 0;
86 }
87
88 static void zebra_limit_destroy_cb(void *data)
89 {
90     zebra_limit_destroy(data);
91 }
92
93 void zebra_limit_for_rset(struct zebra_limit *zl,
94                           int (**filter_func)(const void *buf, void *data),
95                           void (**filter_destroy)(void *data),
96                           void **filter_data)
97 {
98 #if ZEBRA_LIMIT_DEBUG
99     yaz_log(YLOG_LOG, "zebra_limit_for_rset debug enabled zl=%p", zl);
100 #endif
101     if (zl && zl->ids)
102     {
103         struct zebra_limit *hl;
104
105 #if ZEBRA_LIMIT_DEBUG
106         yaz_log(YLOG_LOG, "enable limit");
107 #endif
108         hl = zebra_limit_create(zl->complement_flag, zl->ids);
109         *filter_data = hl;
110         *filter_func = zebra_limit_filter_cb;
111         *filter_destroy = zebra_limit_destroy_cb;
112     }
113     else
114     {
115         *filter_data = 0;
116         *filter_func = 0;
117         *filter_destroy = 0;
118     }
119 }
120                           
121 /*
122  * Local variables:
123  * c-basic-offset: 4
124  * indent-tabs-mode: nil
125  * End:
126  * vim: shiftwidth=4 tabstop=8 expandtab
127  */
128