2 * Copyright (c) 1995-2001, Index Data.
3 * See the file LICENSE for details.
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.2 2001-10-26 20:22:31 adam
8 * Less LOG_LOG messages.
10 * Revision 1.1 1999/11/30 14:02:45 adam
13 * Revision 1.5 1999/07/14 10:59:27 adam
14 * Changed functions isc_getmethod, isams_getmethod.
15 * Improved fatal error handling (such as missing EXPLAIN schema).
17 * Revision 1.4 1999/05/26 07:49:14 adam
20 * Revision 1.3 1999/05/20 12:57:18 adam
21 * Implemented TCL filter. Updated recctrl system.
23 * Revision 1.2 1999/05/15 14:35:48 adam
26 * Revision 1.1 1999/05/12 13:08:06 adam
27 * First version of ISAMS.
43 typedef unsigned ISAMS_BLOCK_SIZE;
61 void *decodeClientData;
66 void isams_getmethod (ISAMS_M m)
72 m->compare_item = NULL;
78 ISAMS isams_open (BFiles bfs, const char *name, int writeflag,
81 ISAMS is = (ISAMS) xmalloc (sizeof(*is));
83 is->method = (ISAMS_M) xmalloc (sizeof(*is->method));
84 memcpy (is->method, method, sizeof(*method));
85 is->block_size = is->method->block_size;
86 is->debug = is->method->debug;
88 is->bf = bf_open (bfs, name, is->block_size, writeflag);
90 if (!bf_read (is->bf, 0, 0, sizeof(ISAMS_head), &is->head))
92 is->head.last_block = 1;
93 is->head.last_offset = 0;
95 memcpy (&is->head_old, &is->head, sizeof(is->head));
96 is->merge_buf = (char *) xmalloc(2*is->block_size);
97 memset(is->merge_buf, 0, 2*is->block_size);
101 int isams_close (ISAMS is)
103 if (memcmp(&is->head, &is->head_old, sizeof(is->head)))
105 if (is->head.last_offset)
106 bf_write(is->bf, is->head.last_block, 0, is->head.last_offset,
108 bf_write (is->bf, 0, 0, sizeof(is->head), &is->head);
111 xfree (is->merge_buf);
117 ISAMS_P isams_merge (ISAMS is, ISAMS_I data)
119 char i_item[128], *i_item_ptr;
122 int first_block = is->head.last_block;
123 int first_offset = is->head.last_offset;
126 r_clientData = (*is->method->code_start)(ISAMC_ENCODE);
128 is->head.last_offset += sizeof(int);
129 if (is->head.last_offset > is->block_size)
132 logf (LOG_LOG, "first_block=%d", first_block);
133 bf_write(is->bf, is->head.last_block, 0, 0, is->merge_buf);
134 (is->head.last_block)++;
135 is->head.last_offset -= is->block_size;
136 memcpy (is->merge_buf, is->merge_buf + is->block_size,
137 is->head.last_offset);
142 i_more = (*data->read_item)(data->clientData, &i_item_ptr, &i_mode);
149 char *r_out_ptr = is->merge_buf + is->head.last_offset;
152 (*is->method->code_item)(ISAMC_ENCODE, r_clientData,
153 &r_out_ptr, &i_item_ptr);
154 is->head.last_offset = r_out_ptr - is->merge_buf;
155 if (is->head.last_offset > is->block_size)
157 bf_write(is->bf, is->head.last_block, 0, 0, is->merge_buf);
158 (is->head.last_block)++;
159 is->head.last_offset -= is->block_size;
160 memcpy (is->merge_buf, is->merge_buf + is->block_size,
161 is->head.last_offset);
166 (*is->method->code_stop)(ISAMC_ENCODE, r_clientData);
167 if (first_block == is->head.last_block)
168 memcpy(is->merge_buf + first_offset, &count, sizeof(int));
169 else if (first_block == is->head.last_block-1)
171 int gap = first_offset + sizeof(int) - is->block_size;
172 assert (gap <= (int) sizeof(int));
175 if (gap < (int) sizeof(int))
176 bf_write(is->bf, first_block, first_offset, sizeof(int)-gap,
178 memcpy (is->merge_buf, ((char*)&count)+(sizeof(int)-gap), gap);
181 bf_write(is->bf, first_block, first_offset, sizeof(int), &count);
185 bf_write(is->bf, first_block, first_offset, sizeof(int), &count);
187 return first_block * is->block_size + first_offset;
190 ISAMS_PP isams_pp_open (ISAMS is, ISAMS_P pos)
192 ISAMS_PP pp = (ISAMS_PP) xmalloc (sizeof(*pp));
195 logf (LOG_LOG, "isams: isams_pp_open pos=%ld", (long) pos);
197 pp->decodeClientData = (*is->method->code_start)(ISAMC_DECODE);
200 pp->buf = (char *) xmalloc(is->block_size*2);
201 pp->block_no = pos/is->block_size;
202 pp->block_offset = pos - pp->block_no * is->block_size;
204 logf (LOG_LOG, "isams: isams_pp_open off=%d no=%d",
205 pp->block_offset, pp->block_no);
208 bf_read (is->bf, pp->block_no, 0, 0, pp->buf);
209 bf_read (is->bf, pp->block_no+1, 0, 0, pp->buf + is->block_size);
210 memcpy(&pp->numKeys, pp->buf + pp->block_offset, sizeof(int));
212 logf (LOG_LOG, "isams: isams_pp_open numKeys=%d", pp->numKeys);
213 pp->block_offset += sizeof(int);
218 void isams_pp_close (ISAMS_PP pp)
220 (*pp->is->method->code_stop)(ISAMC_DECODE, pp->decodeClientData);
225 int isams_pp_num (ISAMS_PP pp)
230 int isams_pp_read (ISAMS_PP pp, void *buf)
232 return isams_read_item (pp, (char **) &buf);
235 int isams_read_item (ISAMS_PP pp, char **dst)
238 if (pp->numRead >= pp->numKeys)
241 if (pp->block_offset > pp->is->block_size)
243 pp->block_offset -= pp->is->block_size;
245 memcpy (pp->buf, pp->buf + pp->is->block_size, pp->is->block_size);
246 bf_read (pp->is->bf, pp->block_no+1, 0, 0,
247 pp->buf + pp->is->block_size);
249 src = pp->buf + pp->block_offset;
250 (*pp->is->method->code_item)(ISAMC_DECODE, pp->decodeClientData,
252 pp->block_offset = src - pp->buf;