-
Notifications
You must be signed in to change notification settings - Fork 511
Expand file tree
/
Copy pathFileSystem.java
More file actions
137 lines (100 loc) Β· 3.47 KB
/
FileSystem.java
File metadata and controls
137 lines (100 loc) Β· 3.47 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
package ThreadSafeInMemoryFileSystem;
import java.util.*;
class FileSystem {
private final Directory root = new Directory("/", null);
// π Lock Coupling Resolve
private Directory resolveDir(String path) {
String[] parts = path.split("/");
Directory curr = root;
curr.lock.readLock().lock();
try {
for (int i = 1; i < parts.length; i++) {
FileNode next = curr.getChildUnsafe(parts[i]);
if (next == null || !(next instanceof Directory)) {
return null;
}
Directory nextDir = (Directory) next;
nextDir.lock.readLock().lock();
curr.lock.readLock().unlock();
curr = nextDir;
}
return curr;
} finally {
curr.lock.readLock().unlock();
}
}
// π mkdir
public boolean mkdir(String path, String dirName) {
Directory parent = resolveDir(path);
if (parent == null) return false;
parent.lock.writeLock().lock();
try {
if (parent.getChildUnsafe(dirName) != null) return false;
parent.addChild(new Directory(dirName, parent));
return true;
} finally {
parent.lock.writeLock().unlock();
}
}
// π create file
public boolean createFile(String path, String fileName) {
Directory parent = resolveDir(path);
if (parent == null) return false;
parent.lock.writeLock().lock();
try {
if (parent.getChildUnsafe(fileName) != null) return false;
parent.addChild(new File(fileName, parent));
return true;
} finally {
parent.lock.writeLock().unlock();
}
}
// π write
public boolean write(String path, String fileName, String data) {
Directory dir = resolveDir(path);
if (dir == null) return false;
FileNode node = dir.getChildUnsafe(fileName);
if (!(node instanceof File)) return false;
((File) node).write(data);
return true;
}
// π read
public String read(String path, String fileName) {
Directory dir = resolveDir(path);
if (dir == null) return null;
FileNode node = dir.getChildUnsafe(fileName);
if (!(node instanceof File)) return null;
return ((File) node).read();
}
// π ls
public List<String> ls(String path) {
Directory dir = resolveDir(path);
if (dir == null) return List.of();
return dir.list();
}
// π₯ move (deadlock-free)
public boolean move(String srcPath, String destPath, String name) {
Directory src = resolveDir(srcPath);
Directory dest = resolveDir(destPath);
if (src == null || dest == null) return false;
Directory first = src;
Directory second = dest;
// Deadlock avoidance
if (System.identityHashCode(first) > System.identityHashCode(second)) {
first = dest;
second = src;
}
first.lock.writeLock().lock();
second.lock.writeLock().lock();
try {
FileNode node = src.removeChild(name);
if (node == null) return false;
node.parent = dest; // important fix
dest.addChild(node);
return true;
} finally {
second.lock.writeLock().unlock();
first.lock.writeLock().unlock();
}
}
}