This repository has been archived by the owner on Jan 31, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfilesystem.rb
151 lines (125 loc) · 2.7 KB
/
filesystem.rb
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
class FS
@@inode_count = 0
attr_accessor :name, :inode
def initialize(name)
@@inode_count += 1
@name = name
@inode = @@inode_count
end
def update_inode
@@inode_count += 1
@inode = @@inode_count
end
# for real copy
def initialize_copy(obj)
@@inode_count += 1
@name = obj.name.dup if obj.name
@inode = @@inode_count
end
end
class Branch < FS
attr_accessor :branches, :parent
def initialize(name = nil)
super(name)
@branches = Hash.new
@parent = nil
end
def mkdir(name)
@branches[name] = Branch.new(name)
@branches[name].parent = self
end
def touch(name, data)
@branches[name] = Reaf.new(name, data)
end
def rm
fun = Proc.new{self.parent.branches.delete(self.name)}
cow(fun)
end
def cow(fun)
new_self = self.dup
top = new_self.copy
fun.call
#commit
top.parent.branches[top.name] = top
end
def copy
if self.parent.name != ROOT
self.parent = self.parent.dup
self.parent.branches[self.name] = self
top = self.parent.copy
else
top = self
end
top
end
def show_branch(path = "/")
path += self.name + "/" if self.name
puts path
puts self.inode
if self.branches.size > 0
self.show_each_branch(path)
end
end
def show_each_branch(path)
self.branches.each_value do |branch|
if branch.class == Branch
branch.show_branch(path)
else
data = path + branch.name + " = " + branch.data if branch.name && branch.data
puts data
puts branch.inode
end
end
end
private
def set_parents(obj)
obj.branches.each_values do |v|
v.parent = obj
end
end
# for real copy
def initialize_copy(obj)
super(obj)
end
end
class Reaf < FS
attr_accessor :data
def initialize(name = nil, data = nil)
super(name)
@data = data
end
# for real copy
def initialize_copy(obj)
super(obj)
@data = obj.data.dup if obj.data
end
end
ROOT = "root"
root = Branch.new(ROOT)
root.mkdir("usr")
root.mkdir("bin")
root.branches["usr"].mkdir("local")
root.branches["usr"].branches["local"].mkdir("bin")
root.branches["usr"].branches["local"].touch("test.txt", "This is text.")
puts "---start---"
root.show_branch
puts "---cow(update)---"
root.branches["usr"].branches["local"].branches["bin"].rm
root.show_branch
#
# debug
#
puts "\n---debug---"
p root.branches["usr"].branches["local"].branches["test.txt"].data
p root.branches["usr"].branches["local"].inode
copy = root.dup
# check object_id
puts copy.name.object_id
puts root.name.object_id
puts root.branches.object_id
puts copy.branches.object_id
# check real copy
puts copy.inode
copy.inode = 9
puts root.inode
puts copy.inode