2 * Copyright (C) 1994-2002, Index Data
4 * Sebastian Hammer, Adam Dickmeiss
6 * $Id: rstemp.c,v 1.27 2002-02-20 17:30:01 adam Exp $
17 #include <sys/types.h>
23 static void *r_create(RSET ct, const struct rset_control *sel, void *parms);
24 static RSFD r_open (RSET ct, int flag);
25 static void r_close (RSFD rfd);
26 static void r_delete (RSET ct);
27 static void r_rewind (RSFD rfd);
28 static int r_count (RSET ct);
29 static int r_read (RSFD rfd, void *buf, int *term_index);
30 static int r_write (RSFD rfd, const void *buf);
32 static const struct rset_control control =
45 const struct rset_control *rset_kind_temp = &control;
47 struct rset_temp_info {
50 size_t key_size; /* key size */
51 char *buf_mem; /* window buffer */
52 size_t buf_size; /* size of window */
53 size_t pos_end; /* last position in set */
54 size_t pos_cur; /* current position in set */
55 size_t pos_buf; /* position of first byte in window */
56 size_t pos_border; /* position of last byte+1 in window */
57 int dirty; /* window is dirty */
58 int hits; /* no of hits */
62 struct rset_temp_rfd {
63 struct rset_temp_info *info;
64 struct rset_temp_rfd *next;
67 static void *r_create(RSET ct, const struct rset_control *sel, void *parms)
69 rset_temp_parms *temp_parms = (rset_temp_parms *) parms;
70 struct rset_temp_info *info;
72 info = (struct rset_temp_info *) xmalloc (sizeof(struct rset_temp_info));
75 info->key_size = temp_parms->key_size;
76 info->buf_size = 4096;
77 info->buf_mem = (char *) xmalloc (info->buf_size);
83 if (!temp_parms->temp_path)
84 info->temp_path = NULL;
87 info->temp_path = (char *) xmalloc (strlen(temp_parms->temp_path)+1);
88 strcpy (info->temp_path, temp_parms->temp_path);
90 ct->no_rset_terms = 1;
91 ct->rset_terms = (RSET_TERM *) xmalloc (sizeof(*ct->rset_terms));
92 ct->rset_terms[0] = temp_parms->rset_term;
96 static RSFD r_open (RSET ct, int flag)
98 struct rset_temp_info *info = (struct rset_temp_info *) ct->buf;
99 struct rset_temp_rfd *rfd;
101 assert (info->fd == -1);
104 if (flag & RSETF_WRITE)
105 info->fd = open (info->fname, O_BINARY|O_RDWR|O_CREAT, 0666);
107 info->fd = open (info->fname, O_BINARY|O_RDONLY);
110 logf (LOG_FATAL|LOG_ERRNO, "open %s", info->fname);
114 rfd = (struct rset_temp_rfd *) xmalloc (sizeof(*rfd));
121 flush current window to file if file is assocated with set
123 static void r_flush (RSFD rfd, int mk)
125 struct rset_temp_info *info = ((struct rset_temp_rfd*) rfd)->info;
127 if (!info->fname && mk)
132 sprintf (template, "%s/zrsXXXXXX", info->temp_path);
134 info->fd = mkstemp (template);
138 logf (LOG_FATAL|LOG_ERRNO, "mkstemp %s", template);
141 info->fname = (char *) xmalloc (strlen(template)+1);
142 strcpy (info->fname, template);
144 char *s = (char*) tempnam (info->temp_path, "zrs");
145 info->fname = (char *) xmalloc (strlen(s)+1);
146 strcpy (info->fname, s);
148 logf (LOG_DEBUG, "creating tempfile %s", info->fname);
149 info->fd = open (info->fname, O_BINARY|O_RDWR|O_CREAT, 0666);
152 logf (LOG_FATAL|LOG_ERRNO, "open %s", info->fname);
157 if (info->fname && info->fd != -1 && info->dirty)
162 if (lseek (info->fd, info->pos_buf, SEEK_SET) == -1)
164 logf (LOG_FATAL|LOG_ERRNO, "lseek %s", info->fname);
167 count = info->buf_size;
168 if (count > info->pos_end - info->pos_buf)
169 count = info->pos_end - info->pos_buf;
170 if ((r = write (info->fd, info->buf_mem, count)) < (int) count)
173 logf (LOG_FATAL|LOG_ERRNO, "read %s", info->fname);
175 logf (LOG_FATAL, "write of %ld but got %ld",
176 (long) count, (long) r);
183 static void r_close (RSFD rfd)
185 struct rset_temp_info *info = ((struct rset_temp_rfd*)rfd)->info;
188 if (info->fname && info->fd != -1)
196 static void r_delete (RSET ct)
198 struct rset_temp_info *info = (struct rset_temp_info*) ct->buf;
201 unlink (info->fname);
202 xfree (info->buf_mem);
203 logf (LOG_DEBUG, "r_delete: set size %ld", (long) info->pos_end);
206 logf (LOG_DEBUG, "r_delete: unlink %s", info->fname);
207 unlink (info->fname);
211 xfree (info->temp_path);
212 rset_term_destroy (ct->rset_terms[0]);
213 xfree (ct->rset_terms);
218 read from file to window if file is assocated with set -
221 static void r_reread (RSFD rfd)
223 struct rset_temp_info *info = ((struct rset_temp_rfd*)rfd)->info;
230 info->pos_border = info->pos_cur + info->buf_size;
231 if (info->pos_border > info->pos_end)
232 info->pos_border = info->pos_end;
233 count = info->pos_border - info->pos_buf;
236 if (lseek (info->fd, info->pos_buf, SEEK_SET) == -1)
238 logf (LOG_FATAL|LOG_ERRNO, "lseek %s", info->fname);
241 if ((r = read (info->fd, info->buf_mem, count)) < (int) count)
244 logf (LOG_FATAL|LOG_ERRNO, "read %s", info->fname);
246 logf (LOG_FATAL, "read of %ld but got %ld",
247 (long) count, (long) r);
253 info->pos_border = info->pos_end;
256 static void r_rewind (RSFD rfd)
258 struct rset_temp_info *info = ((struct rset_temp_rfd*)rfd)->info;
266 static int r_count (RSET ct)
268 struct rset_temp_info *info = (struct rset_temp_info *) ct->buf;
270 return info->pos_end / info->key_size;
273 static int r_read (RSFD rfd, void *buf, int *term_index)
275 struct rset_temp_info *info = ((struct rset_temp_rfd*)rfd)->info;
277 size_t nc = info->pos_cur + info->key_size;
279 if (nc > info->pos_border)
281 if (nc > info->pos_end)
284 info->pos_buf = info->pos_cur;
287 memcpy (buf, info->buf_mem + (info->pos_cur - info->pos_buf),
294 static int r_write (RSFD rfd, const void *buf)
296 struct rset_temp_info *info = ((struct rset_temp_rfd*)rfd)->info;
298 size_t nc = info->pos_cur + info->key_size;
300 if (nc > info->pos_buf + info->buf_size)
303 info->pos_buf = info->pos_cur;
304 if (info->pos_buf < info->pos_end)
308 memcpy (info->buf_mem + (info->pos_cur - info->pos_buf), buf,
311 if (nc > info->pos_end)
312 info->pos_border = info->pos_end = nc;