Include sizes in references to blocks in each file's data list.
[cumulus.git] / lbs.py
diff --git a/lbs.py b/lbs.py
index 7a391c7..80240e7 100644 (file)
--- a/lbs.py
+++ b/lbs.py
@@ -18,6 +18,9 @@ FORMAT_VERSION = (0, 6)         # LBS Snapshot v0.6
 # Maximum number of nested indirect references allowed in a snapshot.
 MAX_RECURSION_DEPTH = 3
 
+# All segments which have been accessed this session.
+accessed_segments = set()
+
 class Struct:
     """A class which merely acts as a data container.
 
@@ -136,7 +139,11 @@ class ObjectStore:
 
     @staticmethod
     def parse_ref(refstr):
-        m = re.match(r"^([-0-9a-f]+)\/([0-9a-f]+)(\(\S+\))?(\[(\d+)\+(\d+)\])?$", refstr)
+        m = re.match(r"^zero\[(\d+)\]$", refstr)
+        if m:
+            return ("zero", None, None, (0, int(m.group(1))))
+
+        m = re.match(r"^([-0-9a-f]+)\/([0-9a-f]+)(\(\S+\))?(\[((\d+)\+)?(\d+)\])?$", refstr)
         if not m: return
 
         segment = m.group(1)
@@ -148,11 +155,16 @@ class ObjectStore:
             checksum = checksum.lstrip("(").rstrip(")")
 
         if slice is not None:
-            slice = (int(m.group(5)), int(m.group(6)))
+            if m.group(5) is None:
+                # Abbreviated slice
+                slice = (0, int(m.group(7)))
+            else:
+                slice = (int(m.group(6)), int(m.group(7)))
 
         return (segment, object, checksum, slice)
 
     def get_segment(self, segment):
+        accessed_segments.add(segment)
         raw = self.store.lowlevel_open(segment + ".tar.gpg")
 
         (input, output) = os.popen2("lbs-filter-gpg --decrypt")
@@ -188,6 +200,7 @@ class ObjectStore:
             f.close()
 
     def load_object(self, segment, object):
+        accessed_segments.add(segment)
         path = os.path.join(self.get_cachedir(), segment, object)
         if not os.access(path, os.R_OK):
             self.extract_segment(segment)
@@ -206,6 +219,9 @@ class ObjectStore:
 
         (segment, object, checksum, slice) = self.parse_ref(refstr)
 
+        if segment == "zero":
+            return "\0" * slice[1]
+
         data = self.load_object(segment, object)
 
         if checksum is not None: