-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnode.py
101 lines (73 loc) · 3.57 KB
/
node.py
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
class Node:
"""Class representing a filesystem node
Properties:
- path: a list of strings
- delete_conflicts_down: an optional Boolean flag used during constructing a merger
- index: an optional bitmap
- has_destructor_on_dir: optional bool flag used by get_any_merger(): whether there is a destructor command on a directory value on this node
- has_constructor_on_empty_child: optional bool flag used by get_any_merger(): whether there is a constructor command on an empty value on a child noe
- delete_creators_strictly_down: optional bool flag used by get_any_merger(): whether to discard commands with non-empty output below this node
- delete_creators_down: optional bool flag used by get_any_merger(): whether to discard commands with non-empty output on this node and below
- delete_destructors_up: optional bool flag used by get_any_merger(): whether to discard destructors on this node (and above)
Usage:
paths are lists of names (strings), e.g.
n = Node(['dir1', 'dir2', 'filename'])
"""
def __init__(self, path):
"""Constructor
Arguments:
- path: a list of strings, e.g. ['dir1', 'dir2', 'filename']
"""
assert isinstance(path, list)
self.path = path
self.delete_conflicts_down = None
self.index = None
self.has_destructor_on_dir = None
self.has_constructor_on_empty_child = None
self.delete_creators_strictly_down = None
self.delete_creators_down = None
self.delete_destructors_up = None
def as_string(self):
"""Return a string representation of the object"""
return '/'.join(self.path)
def equals(self, other):
"""Whether the curent object is equal to another Node object
Arguments:
- other: a Node object
"""
return (self.comp(other) == 0)
def is_ancestor_of(self, other):
"""Whether the current object is an ancestor of another Node object"""
if len(self.path) >= len(other.path):
return False
return (self.path == other.path[0:len(self.path)])
def is_descendant_of(self, other):
"""Whether the current object is a descendand of another Node object"""
return other.is_ancestor_of(self)
def is_parent_of(self, other):
"""Whether the current object is the parent of another Node object"""
return (self.path == other.path[0:-1])
def get_parent(self):
"""Get an object representing the parent of the current object"""
return Node(self.path[0:-1])
def comp(self, other):
"""Comparison function (returning -1,0,1) following lexicographic order"""
if self.path == other.path:
return 0
if self.path < other.path:
return -1
return 1
def is_less(self, other):
"""Whether the current object is less than another following lexicographic order"""
return (self.comp(other) == -1)
def is_greater(self, other):
"""Whether the current object is greater than another following lexicographic order"""
return (self.comp(other) == 1)
if __name__ == '__main__':
# Test code
assert Node(['a','b','c']).is_descendant_of(Node(['a']))
assert not Node(['a','c']).is_descendant_of(Node(['x']))
assert Node(['a','b','c']).equals(Node(['a','b','c','d']).get_parent())
assert Node(['a','b','c']).is_less(Node(['a','c']))
assert Node([]).is_parent_of(Node(['a']))
print("Tests done")