1 /* $Id: sortidx.c,v 1.23 2006-12-20 08:37:49 adam Exp $
2 Copyright (C) 1995-2006
5 This file is part of the Zebra server.
7 Zebra is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 #include <yaz/xmalloc.h>
29 #include <idzebra/isamb.h>
30 #include <idzebra/bfile.h>
34 #define SORT_MAX_TERM 110
36 #define SORT_IDX_BLOCKSIZE 64
40 char term[SORT_MAX_TERM];
44 static void sort_term_log_item(int level, const void *b, const char *txt)
48 memcpy(&a1, b, sizeof(a1));
50 yaz_log(level, "%s " ZINT_FORMAT " %s", txt, a1.sysno, a1.term);
53 int sort_term_compare(const void *a, const void *b)
55 struct sort_term a1, b1;
57 memcpy(&a1, a, sizeof(a1));
58 memcpy(&b1, b, sizeof(b1));
60 if (a1.sysno > b1.sysno)
62 else if (a1.sysno < b1.sysno)
67 void *sort_term_code_start(void)
72 void sort_term_encode(void *p, char **dst, const char **src)
76 memcpy(&a1, *src, sizeof(a1));
79 zebra_zint_encode(dst, a1.sysno); /* encode record id */
80 strcpy(*dst, a1.term); /* then sort term, 0 terminated */
81 *dst += strlen(a1.term) + 1;
84 void sort_term_decode(void *p, char **dst, const char **src)
88 zebra_zint_decode(src, &a1.sysno);
90 strcpy(a1.term, *src);
91 *src += strlen(a1.term) + 1;
93 memcpy(*dst, &a1, sizeof(a1));
97 void sort_term_code_reset(void *p)
101 void sort_term_code_stop(void *p)
106 struct sort_term_stream {
112 int sort_term_code_read(void *vp, char **dst, int *insertMode)
114 struct sort_term_stream *s = (struct sort_term_stream *) vp;
121 *insertMode = s->insert_flag;
122 memcpy(*dst, &s->st, sizeof(s->st));
123 *dst += sizeof(s->st);
128 struct sortFileHead {
140 struct sortFile *next;
141 struct sortFileHead head;
146 struct zebra_sort_index {
152 struct sortFile *current_file;
153 struct sortFile *files;
156 zebra_sort_index_t zebra_sort_open(BFiles bfs, int write_flag, int type)
158 zebra_sort_index_t si = (zebra_sort_index_t) xmalloc(sizeof(*si));
160 si->write_flag = write_flag;
161 si->current_file = NULL;
164 si->entry_buf = (char *) xmalloc(SORT_IDX_ENTRYSIZE);
168 void zebra_sort_close(zebra_sort_index_t si)
170 struct sortFile *sf = si->files;
173 struct sortFile *sf_next = sf->next;
176 case ZEBRA_SORT_TYPE_FLAT:
179 case ZEBRA_SORT_TYPE_ISAMB:
181 isamb_pp_close(sf->isam_pp);
182 isamb_set_root_ptr(sf->u.isamb, sf->isam_p);
183 isamb_close(sf->u.isamb);
189 xfree(si->entry_buf);
193 int zebra_sort_type(zebra_sort_index_t si, int id)
195 int isam_block_size = 4096;
199 if (si->current_file && si->current_file->id == id)
201 for (sf = si->files; sf; sf = sf->next)
204 si->current_file = sf;
207 sf = (struct sortFile *) xmalloc(sizeof(*sf));
210 method.compare_item = sort_term_compare;
211 method.log_item = sort_term_log_item;
212 method.codec.start = sort_term_code_start;
213 method.codec.encode = sort_term_encode;
214 method.codec.decode = sort_term_decode;
215 method.codec.reset = sort_term_code_reset;
216 method.codec.stop = sort_term_code_stop;
220 case ZEBRA_SORT_TYPE_FLAT:
222 sprintf(fname, "sort%d", id);
223 yaz_log(YLOG_DEBUG, "sort idx %s wr=%d", fname, si->write_flag);
224 sf->u.bf = bf_open(si->bfs, fname, SORT_IDX_BLOCKSIZE, si->write_flag);
230 if (!bf_read(sf->u.bf, 0, 0, sizeof(sf->head), &sf->head))
232 sf->head.sysno_max = 0;
241 case ZEBRA_SORT_TYPE_ISAMB:
242 sprintf(fname, "sortb%d", id);
244 sf->u.isamb = isamb_open2(si->bfs, fname, si->write_flag, &method,
246 /* no_cat */ 1, &isam_block_size,
247 /* use_root_ptr */ 1);
255 sf->isam_p = isamb_get_root_ptr(sf->u.isamb);
262 sf->next = si->files;
263 si->current_file = si->files = sf;
267 void zebra_sort_sysno(zebra_sort_index_t si, zint sysno)
269 struct sortFile *sf = si->current_file;
270 zint new_sysno = rec_sysno_to_int(sysno);
272 for (sf = si->files; sf; sf = sf->next)
276 if (sf->isam_pp && new_sysno < si->sysno && sf->isam_pp)
278 isamb_pp_close(sf->isam_pp);
282 si->sysno = new_sysno;
286 void zebra_sort_delete(zebra_sort_index_t si)
288 struct sortFile *sf = si->current_file;
290 if (!sf || !sf->u.bf)
294 case ZEBRA_SORT_TYPE_FLAT:
295 zebra_sort_add(si, "", 0);
297 case ZEBRA_SORT_TYPE_ISAMB:
299 if (sf->no_deleted == 0)
301 struct sort_term_stream s;
304 s.st.sysno = si->sysno;
309 isamc_i.clientData = &s;
310 isamc_i.read_item = sort_term_code_read;
312 isamb_merge(sf->u.isamb, &sf->isam_p, &isamc_i);
319 void zebra_sort_add(zebra_sort_index_t si, const char *buf, int len)
321 struct sortFile *sf = si->current_file;
323 if (!sf || !sf->u.bf)
327 case ZEBRA_SORT_TYPE_FLAT:
328 if (len > SORT_IDX_ENTRYSIZE)
330 len = SORT_IDX_ENTRYSIZE;
331 memcpy(si->entry_buf, buf, len);
335 memcpy(si->entry_buf, buf, len);
336 memset(si->entry_buf+len, 0, SORT_IDX_ENTRYSIZE-len);
338 bf_write(sf->u.bf, si->sysno+1, 0, 0, si->entry_buf);
340 case ZEBRA_SORT_TYPE_ISAMB:
342 if (sf->no_inserted == 0)
344 struct sort_term_stream s;
347 s.st.sysno = si->sysno;
348 if (len >= SORT_MAX_TERM)
349 len = SORT_MAX_TERM-1;
350 memcpy(s.st.term, buf, len);
351 s.st.term[len] = '\0';
354 isamc_i.clientData = &s;
355 isamc_i.read_item = sort_term_code_read;
357 isamb_merge(sf->u.isamb, &sf->isam_p, &isamc_i);
364 void zebra_sort_read(zebra_sort_index_t si, char *buf)
367 struct sortFile *sf = si->current_file;
373 case ZEBRA_SORT_TYPE_FLAT:
374 r = bf_read(sf->u.bf, si->sysno+1, 0, 0, buf);
376 memset(buf, 0, SORT_IDX_ENTRYSIZE);
378 case ZEBRA_SORT_TYPE_ISAMB:
379 memset(buf, 0, SORT_IDX_ENTRYSIZE);
383 struct sort_term st, st_untilbuf;
386 sf->isam_pp = isamb_pp_open(sf->u.isamb, sf->isam_p, 1);
393 r = isamb_pp_read(sf->isam_pp, &st);
396 if (st.sysno == si->sysno)
398 yaz_log(YLOG_LOG, "Received sysno=" ZINT_FORMAT " looking for "
399 ZINT_FORMAT, st.sysno, si->sysno);
402 st_untilbuf.sysno = si->sysno;
403 st_untilbuf.term[0] = '\0';
404 r = isamb_pp_forward(sf->isam_pp, &st, &st_untilbuf);
410 if (st.sysno != si->sysno)
412 yaz_log(YLOG_LOG, "Received sysno=" ZINT_FORMAT " looking for "
413 ZINT_FORMAT, st.sysno, si->sysno);
416 if (strlen(st.term) < SORT_IDX_ENTRYSIZE)
417 strcpy(buf, st.term);
419 memcpy(buf, st.term, SORT_IDX_ENTRYSIZE);
428 * indent-tabs-mode: nil
430 * vim: shiftwidth=4 tabstop=8 expandtab