… | |
… | |
88 | |
88 | |
89 | void |
89 | void |
90 | MTfile::Close() |
90 | MTfile::Close() |
91 | { |
91 | { |
92 | if(!IsOpen()) return; |
92 | if(!IsOpen()) return; |
|
|
93 | Sync(); |
93 | close(fileHandle); |
94 | close(fileHandle); |
94 | SetOpen(0); |
95 | SetOpen(0); |
95 | } |
96 | } |
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 | |
97 | void |
169 | void |
98 | MTfile::Read(GiSTpage page, char *buf) |
170 | MTfile::Read(GiSTpage page, char *buf) |
99 | { |
171 | { |
100 | if(IsOpen()) { |
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 | |
101 | lseek(fileHandle, page*PageSize(), SEEK_SET); |
182 | lseek(fileHandle, page*PageSize(), SEEK_SET); |
102 | read(fileHandle, buf, PageSize()); |
183 | read(fileHandle, buf, PageSize()); |
103 | IOread++; |
184 | IOread++; |
|
|
185 | |
|
|
186 | p = newpage (page); |
|
|
187 | |
|
|
188 | memcpy (p->buf, buf, PageSize()); |
104 | } |
189 | } |
105 | } |
190 | } |
106 | |
191 | |
107 | void |
192 | void |
108 | MTfile::Write(GiSTpage page, const char *buf) |
193 | MTfile::Write(GiSTpage page, const char *buf) |
109 | { |
194 | { |
110 | if(IsOpen()) { |
195 | Page *p = findpage (page); |
111 | lseek(fileHandle, page*PageSize(), SEEK_SET); |
196 | |
112 | write(fileHandle, buf, PageSize()); |
197 | if (!p) |
113 | IOwrite++; |
198 | p = newpage (page); |
114 | } |
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]); |
115 | } |
210 | } |
116 | |
211 | |
117 | GiSTpage |
212 | GiSTpage |
118 | MTfile::Allocate() |
213 | MTfile::Allocate() |
119 | { |
214 | { |