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 |
close(fileHandle); |
94 |
SetOpen(0); |
95 |
} |
96 |
|
97 |
void |
98 |
MTfile::Read(GiSTpage page, char *buf) |
99 |
{ |
100 |
if(IsOpen()) { |
101 |
lseek(fileHandle, page*PageSize(), SEEK_SET); |
102 |
read(fileHandle, buf, PageSize()); |
103 |
IOread++; |
104 |
} |
105 |
} |
106 |
|
107 |
void |
108 |
MTfile::Write(GiSTpage page, const char *buf) |
109 |
{ |
110 |
if(IsOpen()) { |
111 |
lseek(fileHandle, page*PageSize(), SEEK_SET); |
112 |
write(fileHandle, buf, PageSize()); |
113 |
IOwrite++; |
114 |
} |
115 |
} |
116 |
|
117 |
GiSTpage |
118 |
MTfile::Allocate() |
119 |
{ |
120 |
GiSTpage page; |
121 |
char *buf; |
122 |
|
123 |
if(!IsOpen()) return (0); |
124 |
// See if there's a deleted page |
125 |
buf=new char[PageSize()]; |
126 |
Read(0, buf); |
127 |
memcpy(&page, buf+sizeof(magic), sizeof(GiSTpage)); |
128 |
if(page) { |
129 |
// Reclaim this page |
130 |
Read(page, buf); |
131 |
Write(0, buf); |
132 |
} |
133 |
else { |
134 |
page=lseek(fileHandle, 0, SEEK_END)/PageSize(); |
135 |
memset(buf, 0, PageSize()); |
136 |
write(fileHandle, buf, PageSize()); |
137 |
} |
138 |
delete buf; |
139 |
return page; |
140 |
} |
141 |
|
142 |
void |
143 |
MTfile::Deallocate(GiSTpage page) |
144 |
{ |
145 |
char *buf; |
146 |
GiSTpage temp; |
147 |
|
148 |
if(!IsOpen()) return; |
149 |
// Get the old head of the list |
150 |
buf=new char[PageSize()]; |
151 |
Read(0, buf); |
152 |
memcpy(&temp, buf+sizeof(magic), sizeof(GiSTpage)); |
153 |
// Write the new head of the list |
154 |
memcpy(buf+sizeof(magic), &page, sizeof(GiSTpage)); |
155 |
Write(0, buf); |
156 |
// In our new head, put link to old head |
157 |
memcpy(buf+sizeof(magic), &temp, sizeof(GiSTpage)); |
158 |
Write(page, buf); |
159 |
delete buf; |
160 |
} |