From: Michael Vrable Date: Wed, 5 Feb 2014 04:20:09 +0000 (-0800) Subject: Change syntax for size-assertion slices. This is an incompatible change. X-Git-Url: http://git.vrable.net/?p=cumulus.git;a=commitdiff_plain;h=da1d95d3242ee9d596e60b8d5bfcf9e5bedcd80f Change syntax for size-assertion slices. This is an incompatible change. Simplify the syntax by replacing the [=nnn] syntax with just [nnn]. Slices that do not specify a size are written [0+nnn]; the old backup tool has been doing this already since about v0.8. Before that point, [nnn] was a shorthand for [0+nnn], and will be mis-interpreted by modern tools. --- diff --git a/NEWS b/NEWS index eeb15be..1dbe28c 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,8 @@ 0.11 [???] - SNAPSHOT FORMAT CHANGES: + - The object slice syntax has been simplified; backup restores + are still possible but rebuilding the local database from + snapshots before v0.8 will require translation. - Timestamps encoded into the top-level snapshot file name are now UTC instead of the local time zone. This should avoid ambiguity and ensure sorted order is chronological order in diff --git a/doc/format.txt b/doc/format.txt index 19bf2f2..2c40075 100644 --- a/doc/format.txt +++ b/doc/format.txt @@ -149,18 +149,20 @@ is invalid to select using the slice syntax a range of bytes that does not fall within the original object. The slice specification should be appended to an object name, for example: a704eeae-97f2-4f30-91a4-d4473956366b/000001ad[264+1000] -selects only bytes 264..1263 from the original object. As an -abbreviation, the slice syntax +selects only bytes 264..1263 from the original object. + +The slice syntax [] -is shorthand for - [0+] -In place of a traditional slice, the annotation - [=] -may be used. This is somewhat similar to specifying [], but +indicates that all bytes of the object are to be used, but additionally asserts that the referenced object is exactly -bytes long--that is, this slice syntax does not change the bytes -returned at all, but can be used to provide information about the -underlying object store. +bytes long. Older versions of Cumulus can also use the syntax + [=] +as a synonym for length assertions, but this notation is deprecated. + +(In older versions of the format, the syntax [] was a shorthand +for [0+]: that is, select the first bytes of the object +but make no assertions about the overall size. The backup tool has not +generated such slices since v0.8.) Both a checksum and a slice can be used. In this case, the checksum is given first, followed by the slice. The checksum is computed over the @@ -176,7 +178,7 @@ object must have a slice specification appended to indicate the size of the object. For example zero[1024] represents a block consisting of 1024 null bytes. A checksum should not -be given. The slice syntax should use the abbreviated length-only form. +be given. FILE METADATA LISTING diff --git a/python/cumulus/__init__.py b/python/cumulus/__init__.py index c5961c7..323a7c7 100644 --- a/python/cumulus/__init__.py +++ b/python/cumulus/__init__.py @@ -343,7 +343,7 @@ class CumulusStore: if m: return ("zero", None, None, (0, int(m.group(1)), False)) - m = re.match(r"^([-0-9a-f]+)\/([0-9a-f]+)(\(\S+\))?(\[(((\d+)\+)?(\d+)|=(\d+))\])?$", refstr) + m = re.match(r"^([-0-9a-f]+)\/([0-9a-f]+)(\(\S+\))?(\[(=?(\d+)|(\d+)\+(\d+))\])?$", refstr) if not m: return segment = m.group(1) @@ -355,12 +355,9 @@ class CumulusStore: checksum = checksum.lstrip("(").rstrip(")") if slice is not None: - if m.group(9) is not None: + if m.group(6) is not None: # Size-assertion slice - slice = (0, int(m.group(9)), True) - elif m.group(6) is None: - # Abbreviated slice - slice = (0, int(m.group(8)), False) + slice = (0, int(m.group(6)), True) else: slice = (int(m.group(7)), int(m.group(8)), False) @@ -451,6 +448,9 @@ class CumulusStore: if slice is not None: (start, length, exact) = slice + # Note: The following assertion check may need to be commented out + # to restore from pre-v0.8 snapshots, as the syntax for + # size-assertion slices has changed. if exact and len(data) != length: raise ValueError data = data[start:start+length] if len(data) != length: raise IndexError diff --git a/ref.cc b/ref.cc index c5a7768..2a45781 100644 --- a/ref.cc +++ b/ref.cc @@ -97,9 +97,7 @@ string ObjectReference::to_string() const if (range_valid) { char buf[64]; - if (range_exact) { - sprintf(buf, "[=%zu]", range_length); - } else if (type == REF_ZERO) { + if (range_exact || type == REF_ZERO) { sprintf(buf, "[%zu]", range_length); } else { sprintf(buf, "[%zu+%zu]", range_start, range_length); @@ -166,6 +164,9 @@ ObjectReference ObjectReference::parse(const std::string& str) if (*t == '[') { t++; + // An equal sign was once used for a length assertion but is now + // deprecated. Skip it if present, and mark that we are expecting a + // length-only reference. if (*t == '=') { range_exact = true; t++; @@ -179,6 +180,7 @@ ObjectReference ObjectReference::parse(const std::string& str) if (*t == ']') { string val(s, t - s); range2 = atoll(val.c_str()); + range_exact = true; } else { if (*t != '+') return ObjectReference();