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

File Contents

# User Rev Content
1 root 1.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 root 1.2 Sync();
94 root 1.1 close(fileHandle);
95     SetOpen(0);
96     }
97    
98 root 1.2 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 root 1.1 void
170     MTfile::Read(GiSTpage page, char *buf)
171     {
172     if(IsOpen()) {
173 root 1.2 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 root 1.1 }
190     }
191    
192     void
193     MTfile::Write(GiSTpage page, const char *buf)
194     {
195 root 1.2 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 root 1.1 }
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     }