ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Tree-M/MT/MTfile.cpp
Revision: 1.2
Committed: Wed May 23 02:11:14 2001 UTC (23 years ago) by root
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +103 -8 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 /*********************************************************************
2 * *
3 * Copyright (c) 1997,1998, 1999 *
4 * Multimedia DB Group and DEIS - CSITE-CNR, *
5 * University of Bologna, Bologna, ITALY. *
6 * *
7 * All Rights Reserved. *
8 * *
9 * Permission to use, copy, and distribute this software and its *
10 * documentation for NON-COMMERCIAL purposes and without fee is *
11 * hereby granted provided that this copyright notice appears in *
12 * all copies. *
13 * *
14 * THE AUTHORS MAKE NO REPRESENTATIONS OR WARRANTIES ABOUT THE *
15 * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING *
16 * BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, *
17 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. THE AUTHOR *
18 * SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A *
19 * RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS *
20 * DERIVATIVES. *
21 * *
22 *********************************************************************/
23
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <string.h>
27 #ifdef UNIX
28 #include <unistd.h>
29 #else
30 #include <io.h>
31 #endif
32
33 #ifdef UNIX
34 #define O_BINARY 0
35 #endif
36
37 #include "MTfile.h"
38
39 extern int IOread, IOwrite;
40
41 // The first page in the file has these "magic words"
42 // and the head of the deleted page list.
43 static char magic[]="GiST data file";
44
45 void
46 MTfile::Create(const char *filename)
47 {
48 if(IsOpen()) return;
49 /*#d##D#
50 fileHandle=open(filename, O_RDWR|O_BINARY);
51 if(fileHandle>=0) {
52 close(fileHandle);
53 return;
54 }
55 */
56 fileHandle=open(filename, O_BINARY|O_RDWR|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE);
57 if(fileHandle<0) return;
58 SetOpen(1);
59
60 /* Reserve page 0 */
61 char *page=new char[PageSize()];
62
63 memset(page, 0, PageSize());
64 memcpy(page, magic, sizeof magic);
65 write(fileHandle, page, PageSize());
66 delete page;
67 }
68
69 void
70 MTfile::Open(const char *filename)
71 {
72 char *page;
73
74 if(IsOpen()) return;
75 fileHandle=open(filename, O_RDWR|O_BINARY);
76 if(fileHandle<0) return;
77 // Verify that the magic words are there
78 page=new char[PageSize()];
79 read(fileHandle, page, PageSize());
80 if(memcmp(page, magic, sizeof(magic))) {
81 close(fileHandle);
82 delete page;
83 return;
84 }
85 delete page;
86 SetOpen(1);
87 }
88
89 void
90 MTfile::Close()
91 {
92 if(!IsOpen()) return;
93 Sync();
94 close(fileHandle);
95 SetOpen(0);
96 }
97
98 MTfile::~MTfile()
99 {
100 setcache (0);
101 }
102
103 void MTfile::setcache(unsigned int pages)
104 {
105 Sync();
106
107 if (cachesize)
108 {
109 for (int i = cachesize; i--; )
110 delete [] cache[i].buf;
111
112 delete [] cache;
113 }
114
115 cachesize = pages;
116
117 if (cachesize)
118 {
119 cache = new Page[pages];
120 for (int i = cachesize; i--; )
121 {
122 cache[i].seq = 0;
123 cache[i].dirty = 0;
124 cache[i].page = (GiSTpage) -1;
125 cache[i].buf = new char[PageSize()];
126 }
127 }
128 }
129
130 static unsigned int seq;
131
132 MTfile::Page *MTfile::newpage(GiSTpage page)
133 {
134 Page *p = &cache[0];
135
136 for (int i = cachesize; --i; ) {
137 if (cache[i].seq < p->seq)
138 p = &cache[i];
139 }
140
141 if (p->dirty)
142 flushpage (p);
143
144 p->seq = ++seq;
145 //min->dirty = 0;
146 p->page = page;
147
148 return p;
149 }
150
151 MTfile::Page *MTfile::findpage(GiSTpage page)
152 {
153 for (int i = cachesize; i--; )
154 if (cache[i].page == page)
155 return &cache[i];
156
157 return 0;
158 }
159
160 void MTfile::flushpage(Page *p)
161 {
162 assert (IsOpen());
163 lseek (fileHandle, p->page*PageSize(), SEEK_SET);
164 write (fileHandle, p->buf, PageSize());
165 p->dirty = 0;
166 IOwrite++;
167 }
168
169 void
170 MTfile::Read(GiSTpage page, char *buf)
171 {
172 if(IsOpen()) {
173 Page *p = findpage (page);
174
175 if (p)
176 {
177 p->seq = ++seq;
178 memcpy (buf, p->buf, PageSize ());
179 return;
180 }
181
182 lseek(fileHandle, page*PageSize(), SEEK_SET);
183 read(fileHandle, buf, PageSize());
184 IOread++;
185
186 p = newpage (page);
187
188 memcpy (p->buf, buf, PageSize());
189 }
190 }
191
192 void
193 MTfile::Write(GiSTpage page, const char *buf)
194 {
195 Page *p = findpage (page);
196
197 if (!p)
198 p = newpage (page);
199
200 memcpy (p->buf, buf, PageSize ());
201 p->seq = ++seq;
202 p->dirty++;
203 }
204
205 void MTfile::Sync()
206 {
207 for (int i = cachesize; i--; )
208 if (cache[i].dirty)
209 flushpage (&cache[i]);
210 }
211
212 GiSTpage
213 MTfile::Allocate()
214 {
215 GiSTpage page;
216 char *buf;
217
218 if(!IsOpen()) return (0);
219 // See if there's a deleted page
220 buf=new char[PageSize()];
221 Read(0, buf);
222 memcpy(&page, buf+sizeof(magic), sizeof(GiSTpage));
223 if(page) {
224 // Reclaim this page
225 Read(page, buf);
226 Write(0, buf);
227 }
228 else {
229 page=lseek(fileHandle, 0, SEEK_END)/PageSize();
230 memset(buf, 0, PageSize());
231 write(fileHandle, buf, PageSize());
232 }
233 delete buf;
234 return page;
235 }
236
237 void
238 MTfile::Deallocate(GiSTpage page)
239 {
240 char *buf;
241 GiSTpage temp;
242
243 if(!IsOpen()) return;
244 // Get the old head of the list
245 buf=new char[PageSize()];
246 Read(0, buf);
247 memcpy(&temp, buf+sizeof(magic), sizeof(GiSTpage));
248 // Write the new head of the list
249 memcpy(buf+sizeof(magic), &page, sizeof(GiSTpage));
250 Write(0, buf);
251 // In our new head, put link to old head
252 memcpy(buf+sizeof(magic), &temp, sizeof(GiSTpage));
253 Write(page, buf);
254 delete buf;
255 }