Server crashed when bad sorting critieria was given
[idzebra-moved-to-github.git] / index / sortidx.c
1 /*
2  * Copyright (C) 1998-2002, Index Data ApS
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Id: sortidx.c,v 1.6 2002-02-18 11:46:58 adam Exp $
7  */
8  
9 #include <string.h>
10
11 #include <yaz/log.h>
12 #include <bfile.h>
13 #include <sortidx.h>
14
15 #define SORT_IDX_BLOCKSIZE 64
16
17 struct sortFileHead {
18     int sysno_max;
19 };
20
21 struct sortFile {
22     int type;
23     BFile bf;
24     struct sortFile *next;
25     struct sortFileHead head;
26 };
27
28 struct sortIdx {
29     BFiles bfs;
30     int write_flag;
31     int sysno;
32     char *entry_buf;
33     struct sortFile *current_file;
34     struct sortFile *files;
35 };
36
37 SortIdx sortIdx_open (BFiles bfs, int write_flag)
38 {
39     SortIdx si = (SortIdx) xmalloc (sizeof(*si));
40     si->bfs = bfs;
41     si->write_flag = write_flag;
42     si->current_file = NULL;
43     si->files = NULL;
44     si->entry_buf = (char *) xmalloc (SORT_IDX_ENTRYSIZE);
45     return si;
46 }
47
48 void sortIdx_close (SortIdx si)
49 {
50     struct sortFile *sf = si->files;
51     while (sf)
52     {
53         struct sortFile *sf_next = sf->next;
54         if (sf->bf)
55             bf_close (sf->bf);
56         xfree (sf);
57         sf = sf_next;
58     }
59     xfree (si->entry_buf);
60     xfree (si);
61 }
62
63 int sortIdx_type (SortIdx si, int type)
64 {
65     char fname[80];
66     struct sortFile *sf;
67     if (si->current_file && si->current_file->type == type)
68         return 0;
69     for (sf = si->files; sf; sf = sf->next)
70         if (sf->type == type)
71         {
72             si->current_file = sf;
73             return 0;
74         }
75     sf = (struct sortFile *) xmalloc (sizeof(*sf));
76     sf->type = type;
77     sf->bf = NULL;
78     sprintf (fname, "sort%d", type);
79     logf (LOG_DEBUG, "sort idx %s wr=%d", fname, si->write_flag);
80     sf->bf = bf_open (si->bfs, fname, SORT_IDX_BLOCKSIZE, si->write_flag);
81     if (!sf->bf)
82     {
83         xfree (sf);
84         return -1;
85     }
86     if (!bf_read (sf->bf, 0, 0, sizeof(sf->head), &sf->head))
87     {
88         sf->head.sysno_max = 0;
89         if (!si->write_flag)
90         {
91             bf_close (sf->bf);
92             xfree (sf);
93             return -1;
94         }
95     }
96     sf->next = si->files;
97     si->current_file = si->files = sf;
98     return 0;
99 }
100
101 void sortIdx_sysno (SortIdx si, int sysno)
102 {
103     si->sysno = sysno;
104 }
105
106 void sortIdx_add (SortIdx si, const char *buf, int len)
107 {
108     if (!si->current_file || !si->current_file->bf)
109         return;
110     if (len > SORT_IDX_ENTRYSIZE)
111     {
112         len = SORT_IDX_ENTRYSIZE;
113         memcpy (si->entry_buf, buf, len);
114     }
115     else
116     {
117         memcpy (si->entry_buf, buf, len);
118         memset (si->entry_buf+len, 0, SORT_IDX_ENTRYSIZE-len);
119     }
120     bf_write (si->current_file->bf, si->sysno+1, 0, 0, si->entry_buf);
121 }
122
123 void sortIdx_read (SortIdx si, char *buf)
124 {
125     bf_read (si->current_file->bf, si->sysno+1, 0, 0, buf);
126 }