Removed stupid line. Work on insertion in dictionary. Not finished yet.
[idzebra-moved-to-github.git] / dict / drdwr.c
1 /*
2  * Copyright (C) 1994, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: drdwr.c,v $
7  * Revision 1.5  1994-09-01 17:49:38  adam
8  * Removed stupid line. Work on insertion in dictionary. Not finished yet.
9  *
10  */
11
12 #include <sys/types.h>
13 #include <fcntl.h>
14 #include <unistd.h>
15 #include <string.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <assert.h>
19
20 #include <dict.h>
21
22 static void pr_lru (Dict_BFile bf)
23 {
24     struct Dict_file_block *p;
25     for (p=bf->lru_back; p; p = p->lru_next)
26     {
27         printf (" %d", p->no);
28     }
29     printf ("\n");
30     fflush (stdout);
31 }
32
33 static struct Dict_file_block *find_block (Dict_BFile bf, int no)
34 {
35     struct Dict_file_block *p;
36
37     for (p=bf->hash_array[no% bf->hash_size]; p; p=p->h_next)
38         if (p->no == no)
39             break;
40     return p;
41 }
42
43 static void release_block (Dict_BFile bf, struct Dict_file_block *p)
44 {
45     assert (p);
46
47     /* remove from lru queue */    
48     if (p->lru_prev)
49         p->lru_prev->lru_next = p->lru_next;
50     else
51         bf->lru_back = p->lru_next;
52     if (p->lru_next)
53         p->lru_next->lru_prev = p->lru_prev;
54     else
55         bf->lru_front = p->lru_prev;
56
57     /* remove from hash chain */
58     *p->h_prev = p->h_next;
59     if (p->h_next)
60         p->h_next->h_prev = p->h_prev;
61
62     /* move to list of free blocks */
63     p->h_next = bf->free_list;
64     bf->free_list = p;
65 }
66
67 void dict_bf_flush_blocks (Dict_BFile bf, int no_to_flush)
68 {
69     struct Dict_file_block *p;
70     int i;
71     for (i=0; i != no_to_flush && bf->lru_back; i++)
72     {
73         p = bf->lru_back;
74         if (p->dirty)
75         {
76             bf_write (bf->bf, p->no, 0, 0, p->data);
77         }
78         release_block (bf, p);
79     }
80 }
81
82 static struct Dict_file_block *alloc_block (Dict_BFile bf, int no)
83 {
84     struct Dict_file_block *p, **pp;
85
86     if (!bf->free_list)
87         dict_bf_flush_blocks (bf, 1);
88     assert (bf->free_list);
89     p = bf->free_list;
90     bf->free_list = p->h_next;
91     p->dirty = 0;
92     p->no = no;
93
94     /* insert at front in lru chain */
95     p->lru_next = NULL;
96     p->lru_prev = bf->lru_front;
97     if (bf->lru_front)
98         bf->lru_front->lru_next = p;
99     else
100         bf->lru_back = p;
101     bf->lru_front = p;
102
103     /* insert in hash chain */
104     pp = bf->hash_array + (no % bf->hash_size);
105     p->h_next = *pp;
106     p->h_prev = pp;
107     if (*pp)
108         (*pp)->h_prev = &p->h_next;
109     *pp = p;
110    
111     return p;
112 }
113
114 static void move_to_front (Dict_BFile bf, struct Dict_file_block *p)
115 {
116     /* Already at front? */
117     if (!p->lru_next)
118         return ;   
119
120     /* Remove */
121     if (p->lru_prev)
122         p->lru_prev->lru_next = p->lru_next;
123     else
124         bf->lru_back = p->lru_next;
125     p->lru_next->lru_prev = p->lru_prev;
126
127     /* Insert at front */
128     p->lru_next = NULL;
129     p->lru_prev = bf->lru_front;
130     if (bf->lru_front)
131         bf->lru_front->lru_next = p;
132     else
133         bf->lru_back = p;
134     bf->lru_front = p;
135 }
136
137 int dict_bf_readp (Dict_BFile bf, int no, void **bufp)
138 {
139     struct Dict_file_block *p;
140     int i;
141     if ((p = find_block (bf, no)))
142     {
143         *bufp = p->data;
144         move_to_front (bf, p);
145         bf->hits++;
146         return 1;
147     }
148     bf->misses++;
149     p = alloc_block (bf, no);
150     i = bf_read (bf->bf, no, 0, 0, p->data);
151     if (i > 0)
152     {
153         *bufp = p->data;
154         return i;
155     }
156     release_block (bf, p);
157     *bufp = NULL;
158     return i;
159 }
160
161 int dict_bf_newp (Dict_BFile dbf, int no, void **bufp)
162 {
163     struct Dict_file_block *p;
164     if (!(p = find_block (dbf, no)))
165         p = alloc_block (dbf, no);
166     else
167         move_to_front (dbf, p);
168     *bufp = p->data;
169     memset (p->data, 0, dbf->block_size);
170     p->dirty = 1;
171 #if 1
172     printf ("bf_newp of %d:", no);
173     pr_lru (dbf);
174 #endif
175     return 1;
176 }
177
178 int dict_bf_touch (Dict_BFile dbf, int no)
179 {
180     struct Dict_file_block *p;
181     if ((p = find_block (dbf, no)))
182     {
183         p->dirty = 1;
184         return 0;
185     }
186     return -1;
187 }
188