Skip to content

Commit 46e7f15

Browse files
committed
python3/qcow2-to-stdout: Implement Interval for checking sparse cluster allocation
Instead of using a set with every individual allocated cluster index as a member, use a sorted list of intervals to verify if cluster is allocated - this uses much less memory and directly follows from the JSON format qcow-stream-tool and vhd-tool output now. Signed-off-by: Andrii Sultanov <andriy.sultanov@vates.tech>
1 parent 675254a commit 46e7f15

1 file changed

Lines changed: 58 additions & 0 deletions

File tree

python3/libexec/qcow2-to-stdout.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,64 @@ def write_features(cluster, offset, data_file_name):
9191
offset += 48
9292

9393

94+
class Interval:
95+
"""
96+
Represents the allocated virtual cluster intervals in a sparse file
97+
"""
98+
def __init__(self, lst):
99+
self.intervals = lst
100+
self.intervals.sort(key=lambda x: x[0])
101+
102+
103+
def __contains__(self, cluster):
104+
"""
105+
Checks if cluster is in one of the intervals, removes it from the
106+
interval if true
107+
"""
108+
# Check if cluster is within [min, max]
109+
if self.intervals[-1][1] < cluster or self.intervals[0][0] > cluster:
110+
return False
111+
112+
# Binary search for the interval that could contain the cluster
113+
l = 0
114+
h = len(self.intervals) - 1
115+
while l <= h:
116+
mid = (l + h) // 2
117+
current = self.intervals[mid]
118+
119+
if cluster >= current[0] and cluster <= current[1]:
120+
if cluster == current[0] and cluster == current[1]:
121+
# Remove the cluster from the interval
122+
del self.intervals[mid]
123+
return True
124+
125+
if cluster == current[0]:
126+
# Shrink interval from the left
127+
left = current[0] + 1
128+
right = current[1]
129+
elif cluster == current[1]:
130+
# Shrink interval from the right
131+
left = current[0]
132+
right = current[1] - 1
133+
else:
134+
# Split the original interval into two
135+
left = current[0]
136+
right = cluster
137+
self.intervals.insert(mid+1, [cluster+1, current[1]])
138+
139+
self.intervals[mid] = [left, right]
140+
return True
141+
elif cluster < current[0]:
142+
h = mid - 1
143+
elif cluster > current[1]:
144+
l = mid + 1
145+
146+
return False
147+
148+
def __iter__(self):
149+
return self.intervals.__iter__()
150+
151+
94152
def write_qcow2_content(input_file, cluster_size, refcount_bits,
95153
data_file_name, data_file_raw, diff_file_name,
96154
virtual_size, nonzero_clusters,

0 commit comments

Comments
 (0)