Skip to content
Navigation Menu
{{ message }}
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHeapFile.java
More file actions
351 lines (279 loc) · 9.33 KB
/
Copy pathHeapFile.java
File metadata and controls
351 lines (279 loc) · 9.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
package simpledb;
import java.io.*;
import java.util.*;
import com.sun.jndi.url.iiopname.iiopnameURLContextFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
/**
* HeapFile is an implementation of a DbFile that stores a collection of tuples
* in no particular order. Tuples are stored on pages, each of which is a fixed
* size, and the file is simply a collection of those pages. HeapFile works
* closely with HeapPage. The format of HeapPages is described in the HeapPage
* constructor.
*
* @see simpledb.HeapPage#HeapPage
* @author Sam Madden
*/
public class HeapFile implements DbFile {
public class HeapFileIterator implements DbFileIterator{
int curPage;
int pageSize;
int numPages;
TransactionId tid;
int fileID;
Iterator<Tuple> i = null;
HeapFileIterator(int pageSize, int numPages, TransactionId tid, int fileID) throws DbException, TransactionAbortedException{
this.curPage = 0;
this.pageSize = pageSize;
this.numPages = numPages;
this.tid = tid;
this.fileID = fileID;
}
@Override
public boolean hasNext() throws DbException, TransactionAbortedException {
//System.out.println("HeapFileIterator hasNext()");
// If not open
if (this.i == null) {
return false;
}
//If there are tuples left in the current page
if(i.hasNext()){
return true;
}
//If not, search through all the future pages
for (int pageIndex = this.curPage+1; pageIndex < this.numPages; pageIndex++){
PageId pid = new HeapPageId(this.fileID, pageIndex);
BufferPool bf = Database.getBufferPool();
HeapPage heapPage = (HeapPage) bf.getPage(this.tid, pid, Permissions.READ_WRITE);
Iterator<Tuple> temp = heapPage.iterator();
// Page "pageIndex" contains a tuple; return true
if(temp.hasNext()){
return true;
}
}
//No pages contain tuples - return false
return false;
}
@Override
public void close() {
this.i = null;
}
@Override
public void open() throws DbException, TransactionAbortedException {
//System.out.println("HeapFileIterator open()");
PageId pid = new HeapPageId(this.fileID, 0);
BufferPool bf = Database.getBufferPool();
Page my_page = bf.getPage(this.tid, pid, Permissions.READ_WRITE);
//System.out.println("Page: " + my_page);
HeapPage heapPage = (HeapPage) my_page;
//System.out.println("open3");
//System.out.println("HeapPage: " + heapPage);
this.i = heapPage.iterator();
//System.out.println("open-- start1");
//System.out.println("open-- end");
}
@Override
public void rewind() throws DbException, TransactionAbortedException {
close();
open();
}
@Override
public Tuple next() throws DbException, TransactionAbortedException,
NoSuchElementException {
//System.out.println("HeapFileIterator next()");
// If no call to open
if (this.i == null) {
//System.out.println("current internal iterator is null");
throw new NoSuchElementException();
}
// If the current page has an available tuple
if (this.i.hasNext()) {
return this.i.next();
}
// If the current page does not have a tuple, move onto the next page that does
while (this.i.hasNext() == false) {
if (this.hasNext()){
//System.out.println("CURRENT PAGE: " + this.curPage);
this.curPage += 1;
PageId pid = new HeapPageId(this.fileID, this.curPage);
BufferPool bf = Database.getBufferPool();
HeapPage heapPage = (HeapPage) bf.getPage(this.tid, pid, Permissions.READ_WRITE);
this.i = heapPage.iterator();
} else{
System.out.println("external iterator has no next page");
System.out.println("current page: " + this.curPage);
throw new NoSuchElementException();
}
}
return this.i.next(); // is this skipping the first tuple of every page? we'll see!
}
}
/**
* Constructs a heap file backed by the specified file.
*
* @param f
* the file that stores the on-disk backing store for this heap
* file.
*/
public File file;
public TupleDesc schema;
public Map<TransactionId, DbFileIterator> iterators;
public HeapFile(File f, TupleDesc td) {
this.file = f;
this.schema = td;
this.iterators = new HashMap<TransactionId, DbFileIterator>();
}
/**
* Returns the File backing this HeapFile on disk.
*
* @return the File backing this HeapFile on disk.
*/
public File getFile() {
return this.file;
}
/**
* Returns an ID uniquely identifying this HeapFile. Implementation note:
* you will need to generate this tableid somewhere ensure that each
* HeapFile has a "unique id," and that you always return the same value for
* a particular HeapFile. We suggest hashing the absolute file name of the
* file underlying the heapfile, i.e. f.getAbsoluteFile().hashCode().
*
* @return an ID uniquely identifying this HeapFile.
*/
public int getId() {
return this.file.getAbsoluteFile().hashCode();
}
/**
* Returns the TupleDesc of the table stored in this DbFile.
*
* @return TupleDesc of this DbFile.
*/
public TupleDesc getTupleDesc() {
return this.schema;
}
/**
* Read the specified page from disk.
*
* @throws IllegalArgumentException if the page does not exist in this file.
*/
// see DbFile.java for javadocs
public Page readPage(PageId pid) {
byte[] buffer = new byte[BufferPool.getPageSize()];
FileInputStream fs = null;
HeapPage page = null;
HeapPageId hpid = (HeapPageId)pid;
try{
fs = new FileInputStream(this.file);
fs.skip(pid.pageNumber()*BufferPool.getPageSize());
fs.read(buffer);
fs.close();
page = new HeapPage(hpid, buffer);
} catch (IOException e){
e.printStackTrace();
}
return page;
}
/**
* Push the specified page to disk.
*
* @param p The page to write. page.getId().pageno() specifies the offset into the file where the page should be written.
* @throws IOException if the write fails
*
*/
// see DbFile.java for javadocs
public void writePage(Page page) throws IOException {
// some code goes here
// not necessary for lab 1
byte[] buffer = page.getPageData();
int off = page.getId().pageNumber()*BufferPool.getPageSize();
RandomAccessFile file_random = new RandomAccessFile(file, "rw");
file_random.seek(off);
file_random.write(buffer, 0, BufferPool.getPageSize());
file_random.close();
}
/**
* Returns the number of pages in this HeapFile.
*/
public int numPages() {
//System.out.println("HeapFile numPages()");
//long file_length = this.file.length();
//System.out.println(" file_length = " + file_length);
//System.out.println(" bufferPool page size = " + BufferPool.getPageSize());
return (int) (this.file.length() / BufferPool.getPageSize());
}
// see DbFile.java for javadocs
public ArrayList<Page> insertTuple(TransactionId tid, Tuple t)
throws DbException, IOException, TransactionAbortedException {
// some code goes here
// not necessary for lab1
ArrayList<Page> output = new ArrayList<Page>();
boolean found_space = false;
for(int i = 0; i< numPages() ;i++)
{
//HeapPageId hpid = new HeapPageId(t.getRecordId().getPageId().getTableId(), i);
HeapPageId hpid = new HeapPageId(getId(), i);
Page right_page = Database.getBufferPool().getPage(tid, hpid,Permissions.READ_WRITE);
HeapPage right_hpage = (HeapPage) right_page;
if(right_hpage.getNumEmptySlots()>0)
{
//RecordId t_rid = new RecordId(hpid, t.getRecordId().tupleno());
//t.setRecordId(t_rid);
right_hpage.insertTuple(t);
//right_hpage.markDirty(true, tid);
output.add(right_hpage);
found_space = true;
break;
}
}
if(!found_space)
{
byte[] empty = HeapPage.createEmptyPageData();
//int tableid = t.getRecordId().getPageId().getTableId();
int tableid = getId();
//System.out.println("HeapFile::HeapFile() - tableID: "+tableid);
HeapPageId hid = new HeapPageId(tableid,numPages());
HeapPage empty_hpage = new HeapPage(hid, empty);
empty_hpage.insertTuple(t);
writePage(empty_hpage);
//RecordId t_rid = new RecordId(hid, t.getRecordId().tupleno());
//t.setRecordId(t_rid);
//empty_hpage.markDirty(true, tid);
output.add(empty_hpage);
}
return output;
}
// see DbFile.java for javadocs
public ArrayList<Page> deleteTuple(TransactionId tid, Tuple t) throws DbException,
TransactionAbortedException {
// some code goes here
// not necessary for lab1
ArrayList<Page> output = new ArrayList<Page>();
RecordId t_rid = t.getRecordId();
PageId pid = t_rid.getPageId();
Page right_page = Database.getBufferPool().getPage(tid, pid, Permissions.READ_WRITE);
HeapPage right_hpage = (HeapPage) right_page;
right_hpage.deleteTuple(t);
right_hpage.markDirty(true, tid);
output.add(right_page);
return output;
}
// see DbFile.java for javadocs
public DbFileIterator iterator(TransactionId tid) {
//int pageSize, int numPages, TransactionId tid, int fileID
try {
HeapFileIterator it = new HeapFileIterator(BufferPool.getPageSize(), this.numPages(), tid, this.getId());
return it;
} catch (DbException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.print("error DBException in creating DBFileIteartor");
} catch (TransactionAbortedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.print("error Transaction Aborted in creating DBFileIterator");
}
System.out.println("there was an error,, returning null");
return null;
}
}
You can’t perform that action at this time.
