-
Notifications
You must be signed in to change notification settings - Fork 1
/
FileTable.java
139 lines (127 loc) · 4.39 KB
/
FileTable.java
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
/*
* @file FileTbale.java
* @brief FileTable has two purposes; it maintains user-thread level file
* tables and a system-wide file table. Each individual FileTable contains a
* vector of FileTableEntry objects and a reference to the root directory.
*
* The class manages FileTableEntry(s) through falloc – create fileTableEntry –
* and ffree – remove fileTableEntry.
*
* @author Chris Grass
* @date December 14, 2012
*/
import java.util.Vector;
public class FileTable {
private Vector<FileTableEntry> table; // the actual entity of this file table
private Directory dir; // the root directory
/**
* Constructor
* @param dir .
* @pre .
* @post .
* constructs a FileTable
*/
public FileTable( Directory directory ) { // constructor
table = new Vector<FileTableEntry>(); // instantiate a file table
dir = directory; // receive a reference to the Director
} // from the file system
/**
* falloc
* @param String filename, String mode .
* @pre .
* @post .
* @return returns reference to new FileTableEntry; null if error
* creates a FileTableEntry based on filename and mode.
*/
public synchronized FileTableEntry falloc( String filename, String mode ) {
// retrieve iNum from dir for corresponding filename. -1 if none exists
short iNum = -1;
Inode inode = null;
//busy loop
while (true){
iNum = dir.namei( filename );
if(iNum<0){ //if new file, create Inode
if(mode.compareTo("r")==0) //if no file exists and trying to read
return null;
inode = new Inode();
iNum = dir.ialloc(filename); //allocate iNum from freeList
}
else
inode = new Inode(iNum); //push existing Inode to memory
if(inode.flag==-1)
return null;
if(mode.compareTo("r")==0){ //if read-only, check if flag
if(inode.flag!=3){ //is set to writing(3)
inode.flag=2; //if so, wait for flag to clear
break;
}
}
// mode is w, w+, or a
else{
if(inode.flag < 2 ){ //is set to writing(3)
inode.flag = 3;
break; //if so, wait for flag to clear
}
}
}
// allocate a new file table entry for this file name
FileTableEntry newEntry = new FileTableEntry(inode,iNum,mode);
table.add(newEntry); //add newEntry to table
// increment this inode's count
inode.count++; //increment inode's count
// immediately write back this inode to the disk
inode.toDisk(iNum); //save updated inode to disk
// return a reference to this file table entry
return newEntry;
}
/**
* ffree
* @param FileTableEntry e .
* @pre .
* @post .
* @return true on success, false if e doesn't exist in table.
* removes FileTableEntry from table and decrements inode.count
*/
public synchronized boolean ffree( FileTableEntry e ) {
// receive a file table entry reference
int loc = findLoc(e); //find index of entry
if (loc<0) //if table doesn't contain e
return false; //return false
e.inode.count--;
if (e.inode.count == 0)
e.inode.flag = 0;
e.inode.toDisk(e.iNumber); //save updated inode to disk
return table.remove(table.elementAt(loc)); //remove e from table
}
/**
* fempty
* @param .
* @pre .
* @post .
* test for empty table
*/
public synchronized boolean fempty() {
return table.isEmpty(); // return if table is empty
} // should be called before starting a format
/**
* findLoc
* @param FileTableEntry entry
* @pre .
* @post .
* finds and returns index of entry. returns -1 if not found
*/
private int findLoc(FileTableEntry entry){
int index = -1;
for(int i = 0; i <table.size(); i++){
if(table.elementAt(i).equals(entry))
return i;
}
return index;//-1 if error or not found
}
public FileTableEntry findFtEnt(short iNum){
for (int i = 0; i<table.size(); i++)
if(table.elementAt(i).iNumber == iNum)
return table.elementAt(i);
return null;
}
}