diff options
author | Christopher Haster <chaster@utexas.edu> | 2020-12-07 08:54:55 +0300 |
---|---|---|
committer | Christopher Haster <geky@geky.net> | 2022-12-17 21:42:05 +0300 |
commit | b4091c6871c05a5439b70db4db13df39e85f1639 (patch) | |
tree | 8038c12224e0b887e6565ec812bae68987cb0f30 /scripts | |
parent | 91ad673c4520c08006272ba3bad133fe21048887 (diff) |
Switched to separate-tag encoding of forward-looking CRCs
Previously forward-looking CRCs was just two new CRC types, one for
commits with forward-looking CRCs, one without. These both contained the
CRC needed to complete the current commit (note that the commit CRC
must come last!).
[-- 32 --|-- 32 --|-- 32 --|-- 32 --]
with: [ crc3 tag | nprog size | nprog crc | commit crc ]
without: [ crc2 tag | commit crc ]
This meant there had to be several checks for the two possible structure
sizes, messying up the implementation.
[-- 32 --|-- 32 --|-- 32 --|-- 32 --|-- 32 --]
with: [nprogcrc tag| nprog size | nprog crc | commit tag | commit crc ]
without: [ commit tag | commit crc ]
But we already have a mechanism for storing optional metadata! The
different metadata tags! So why not use a separate tage for the
forward-looking CRC, separate from the commit CRC?
I wasn't sure this would actually help that much, there are still
necessary conditions for wether or not a forward-looking CRC is there,
but in the end it simplified the code quite nicely, and resulted in a ~200 byte
code-cost saving.
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/readmdir.py | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/scripts/readmdir.py b/scripts/readmdir.py index cf6d9d8..e86b1d9 100755 --- a/scripts/readmdir.py +++ b/scripts/readmdir.py @@ -24,6 +24,7 @@ TAG_TYPES = { 'gstate': (0x700, 0x700), 'movestate': (0x7ff, 0x7ff), 'crc': (0x700, 0x500), + 'nprogcrc': (0x7ff, 0x5ff), } class Tag: @@ -125,9 +126,10 @@ class Tag: return ntag def typerepr(self): - if self.is_('crc') and getattr(self, 'crc', 0xffffffff) != 0xffffffff: + if (self.is_('crc') and not self.is_('nprogcrc') and + getattr(self, 'crc', 0xffffffff) != 0xffffffff): crc_status = ' (bad)' - elif self.is_('crc') and getattr(self, 'erased', False): + elif self.is_('nprogcrc') and getattr(self, 'erased', False): crc_status = ' (era)' else: crc_status = '' @@ -186,6 +188,8 @@ class MetadataPair: self.rev, = struct.unpack('<I', block[0:4]) crc = binascii.crc32(block[0:4]) + etag = None + estate = None # parse tags corrupt = False @@ -199,9 +203,7 @@ class MetadataPair: tag = Tag((int(tag) ^ ntag) & 0x7fffffff) tag.off = off + 4 tag.data = block[off+4:off+tag.dsize] - if tag.is_('crc 0x3'): - crc = binascii.crc32(block[off:off+4*4], crc) - elif tag.is_('crc'): + if tag.is_('crc') and not tag.is_('nprogcrc'): crc = binascii.crc32(block[off:off+2*4], crc) else: crc = binascii.crc32(block[off:off+tag.dsize], crc) @@ -210,25 +212,29 @@ class MetadataPair: self.all_.append(tag) - if tag.is_('crc'): + if tag.is_('nprogcrc') and len(tag.data) == 8: + etag = tag + estate = struct.unpack('<II', tag.data) + elif tag.is_('crc'): # is valid commit? if crc != 0xffffffff: corrupt = True if not corrupt: self.log = self.all_.copy() - # end of commit? - if tag.is_('crc 0x3'): - esize, ecrc = struct.unpack('<II', tag.data[:8]) + if estate: + esize, ecrc = estate dcrc = 0xffffffff ^ binascii.crc32(block[off:off+esize]) if ecrc == dcrc: - tag.erased = True + etag.erased = True corrupt = True - elif tag.is_('crc 0x2'): + elif not (tag.is_('crc 0x0') or tag.is_('crc 0x1')): corrupt = True # reset tag parsing crc = 0 + etag = None + estate = None # find active ids self.ids = list(it.takewhile( @@ -305,7 +311,7 @@ class MetadataPair: f.write('\n') for tag in tags: - f.write("%08x: %08x %-13s %4s %4s" % ( + f.write("%08x: %08x %-14s %3s %4s" % ( tag.off, tag, tag.typerepr(), tag.idrepr(), tag.sizerepr())) if truncate: |