IDZEBRA 2.2.8
drdwr.c
Go to the documentation of this file.
1/* This file is part of the Zebra server.
2 Copyright (C) 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
21
22#if HAVE_CONFIG_H
23#include <config.h>
24#endif
25#include <sys/types.h>
26#include <fcntl.h>
27#if HAVE_UNISTD_H
28#include <unistd.h>
29#endif
30#include <string.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <assert.h>
34
35#include "dict-p.h"
36
38{
39 struct Dict_file_block *p;
40 for (p=bf->lru_back; p; p = p->lru_next)
41 {
42 printf(" %d", p->no);
43 }
44 printf("\n");
45 fflush(stdout);
46}
47
48static struct Dict_file_block *find_block(Dict_BFile bf, int no)
49{
50 struct Dict_file_block *p;
51
52 for (p=bf->hash_array[no% bf->hash_size]; p; p=p->h_next)
53 if (p->no == no)
54 break;
55 return p;
56}
57
58static void release_block(Dict_BFile bf, struct Dict_file_block *p)
59{
60 assert(p);
61
62 /* remove from lru queue */
63 if (p->lru_prev)
64 p->lru_prev->lru_next = p->lru_next;
65 else
66 bf->lru_back = p->lru_next;
67 if (p->lru_next)
68 p->lru_next->lru_prev = p->lru_prev;
69 else
70 bf->lru_front = p->lru_prev;
71
72 /* remove from hash chain */
73 *p->h_prev = p->h_next;
74 if (p->h_next)
75 p->h_next->h_prev = p->h_prev;
76
77 /* move to list of free blocks */
78 p->h_next = bf->free_list;
79 bf->free_list = p;
80}
81
82void dict_bf_flush_blocks(Dict_BFile bf, int no_to_flush)
83{
84 struct Dict_file_block *p;
85 int i;
86 for (i=0; i != no_to_flush && bf->lru_back; i++)
87 {
88 p = bf->lru_back;
89 if (p->dirty)
90 {
91 if (!bf->compact_flag)
92 bf_write(bf->bf, p->no, 0, 0, p->data);
93 else
94 {
95 int effective_block = p->no / bf->block_size;
96 int effective_offset = p->no -
97 effective_block * bf->block_size;
98 int remain = bf->block_size - effective_offset;
99
100 if (remain >= p->nbytes)
101 {
102 bf_write(bf->bf, effective_block, effective_offset,
103 p->nbytes, p->data);
104#if 0
105 yaz_log(YLOG_LOG, "bf_write no=%d offset=%d size=%d",
106 effective_block, effective_offset,
107 p->nbytes);
108#endif
109
110 }
111 else
112 {
113#if 0
114 yaz_log(YLOG_LOG, "bf_write1 no=%d offset=%d size=%d",
115 effective_block, effective_offset,
116 remain);
117#endif
118 bf_write(bf->bf, effective_block, effective_offset,
119 remain, p->data);
120#if 0
121 yaz_log(YLOG_LOG, "bf_write2 no=%d offset=%d size=%d",
122 effective_block+1, 0, p->nbytes - remain);
123#endif
124 bf_write(bf->bf, effective_block+1, 0,
125 p->nbytes - remain, (char*)p->data + remain);
126 }
127 }
128 }
129 release_block(bf, p);
130 }
131}
132
134{
135 struct Dict_file_block *p, **pp;
136
137 if (!bf->free_list)
139 assert(bf->free_list);
140 p = bf->free_list;
141 bf->free_list = p->h_next;
142 p->dirty = 0;
143 p->no = no;
144
145 /* insert at front in lru chain */
146 p->lru_next = NULL;
147 p->lru_prev = bf->lru_front;
148 if (bf->lru_front)
149 bf->lru_front->lru_next = p;
150 else
151 bf->lru_back = p;
152 bf->lru_front = p;
153
154 /* insert in hash chain */
155 pp = bf->hash_array + (no % bf->hash_size);
156 p->h_next = *pp;
157 p->h_prev = pp;
158 if (*pp)
159 (*pp)->h_prev = &p->h_next;
160 *pp = p;
161
162 return p;
163}
164
165static void move_to_front(Dict_BFile bf, struct Dict_file_block *p)
166{
167 /* Already at front? */
168 if (!p->lru_next)
169 return ;
170
171 /* Remove */
172 if (p->lru_prev)
173 p->lru_prev->lru_next = p->lru_next;
174 else
175 bf->lru_back = p->lru_next;
176 p->lru_next->lru_prev = p->lru_prev;
177
178 /* Insert at front */
179 p->lru_next = NULL;
180 p->lru_prev = bf->lru_front;
181 if (bf->lru_front)
182 bf->lru_front->lru_next = p;
183 else
184 bf->lru_back = p;
185 bf->lru_front = p;
186}
187
188int dict_bf_readp(Dict_BFile bf, int no, void **bufp)
189{
190 struct Dict_file_block *p;
191 int i;
192 if ((p = find_block(bf, no)))
193 {
194 *bufp = p->data;
195 move_to_front(bf, p);
196 bf->hits++;
197 return 1;
198 }
199 bf->misses++;
200 p = alloc_block(bf, no);
201
202 if (!bf->compact_flag)
203 i = bf_read(bf->bf, no, 0, 0, p->data);
204 else
205 {
206 int effective_block = no / bf->block_size;
207 int effective_offset = no - effective_block * bf->block_size;
208
209 i = bf_read(bf->bf, effective_block, effective_offset,
210 bf->block_size - effective_offset, p->data);
211 if (i > 0 && effective_offset > 0)
212 i = bf_read(bf->bf, effective_block+1, 0, effective_offset,
213 (char*) p->data + bf->block_size - effective_offset);
214 i = 1;
215 }
216 if (i > 0)
217 {
218 *bufp = p->data;
219 return i;
220 }
221 release_block(bf, p);
222 *bufp = NULL;
223 return i;
224}
225
226int dict_bf_newp(Dict_BFile dbf, int no, void **bufp, int nbytes)
227{
228 struct Dict_file_block *p;
229 if (!(p = find_block(dbf, no)))
230 p = alloc_block(dbf, no);
231 else
232 move_to_front(dbf, p);
233 *bufp = p->data;
234 memset(p->data, 0, dbf->block_size);
235 p->dirty = 1;
236 p->nbytes = nbytes;
237#if 0
238 printf("bf_newp of %d:", no);
239 dict_pr_lru(dbf);
240#endif
241 return 1;
242}
243
245{
246 struct Dict_file_block *p;
247 if ((p = find_block(dbf, no)))
248 {
249 p->dirty = 1;
250 return 0;
251 }
252 return -1;
253}
254
255/*
256 * Local variables:
257 * c-basic-offset: 4
258 * c-file-style: "Stroustrup"
259 * indent-tabs-mode: nil
260 * End:
261 * vim: shiftwidth=4 tabstop=8 expandtab
262 */
263
int bf_read(BFile bf, zint no, int offset, int nbytes, void *buf)
read from block file (may call exit)
Definition bfile.c:205
int bf_write(BFile bf, zint no, int offset, int nbytes, const void *buf)
writes block of bytes to file (may call exit)
Definition bfile.c:232
static void release_block(Dict_BFile bf, struct Dict_file_block *p)
Definition drdwr.c:58
void dict_bf_flush_blocks(Dict_BFile bf, int no_to_flush)
Definition drdwr.c:82
int dict_bf_newp(Dict_BFile dbf, int no, void **bufp, int nbytes)
Definition drdwr.c:226
int dict_bf_readp(Dict_BFile bf, int no, void **bufp)
Definition drdwr.c:188
static struct Dict_file_block * find_block(Dict_BFile bf, int no)
Definition drdwr.c:48
void dict_pr_lru(Dict_BFile bf)
Definition drdwr.c:37
int dict_bf_touch(Dict_BFile dbf, int no)
Definition drdwr.c:244
static void move_to_front(Dict_BFile bf, struct Dict_file_block *p)
Definition drdwr.c:165
static struct Dict_file_block * alloc_block(Dict_BFile bf, int no)
Definition drdwr.c:133
struct Dict_file_block ** h_prev
Definition dict-p.h:45
struct Dict_file_block * lru_next
Definition dict-p.h:46
struct Dict_file_block * lru_prev
Definition dict-p.h:46
void * data
Definition dict-p.h:47
struct Dict_file_block * h_next
Definition dict-p.h:45
struct Dict_file_block * free_list
Definition dict-p.h:59
struct Dict_file_block * lru_front
Definition dict-p.h:62
struct Dict_file_block * lru_back
Definition dict-p.h:62
struct Dict_file_block ** hash_array
Definition dict-p.h:60