changeset 5866:5931ad39ea37 stable

evolve: make stablesortcache.save/load use struct.unpack/pack (issue6354) arraytobytes() and arrayfrombytes() is not cross-platform.
author Anton Shestakov <av6@dwimlabs.net>
date Wed, 31 Mar 2021 20:39:37 +0800
parents d7ed88810457
children 3c3809c3f603
files hgext3rd/evolve/stablesort.py tests/test-discovery-obshashrange-cache.t
diffstat 2 files changed, 36 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/hgext3rd/evolve/stablesort.py	Tue Mar 30 19:35:52 2021 +0800
+++ b/hgext3rd/evolve/stablesort.py	Wed Mar 31 20:39:37 2021 +0800
@@ -894,20 +894,31 @@
         assert repo.filtername is None
 
         data = repo.cachevfs.tryread(self._filepath)
+        self._cachekey = self.emptykey
         self._index = array.array(r'l')
         self._data = array.array(r'l')
-        if not data:
-            self._cachekey = self.emptykey
-        else:
+        if data:
             headerdata = data[:self._cachekeysize]
-            self._cachekey = self._deserializecachekey(headerdata)
+            cachekey = self._deserializecachekey(headerdata)
             offset = self._cachekeysize
             indexsizedata = data[offset:offset + S_INDEXSIZE.size]
             indexsize = S_INDEXSIZE.unpack(indexsizedata)[0]
             offset += S_INDEXSIZE.size
-            compat.arrayfrombytes(self._index, data[offset:offset + indexsize])
-            offset += indexsize
-            compat.arrayfrombytes(self._data, data[offset:])
+            if len(data) - offset >= indexsize:
+                index = list(self._deserializedata(data[offset:offset + indexsize]))
+                offset += indexsize
+                expected = index[-1] * self._datastruct.size * 3
+                data = data[offset:]
+            else:
+                # index cannot be read, so we need to abort somehow
+                expected = None
+            if len(data) == expected:
+                self._index.extend(index)
+                self._data.extend(self._deserializedata(data))
+                self._cachekey = cachekey
+            else:
+                repo.ui.debug(b'stablesortcache file seems to be corrupted, '
+                              b'it will be rebuilt from scratch\n')
         self._ondiskkey = self._cachekey
         pass
 
@@ -923,8 +934,8 @@
 
             # data to write
             headerdata = self._serializecachekey()
-            indexdata = compat.arraytobytes(self._index)
-            data = compat.arraytobytes(self._data)
+            indexdata = self._serializedata(self._index)
+            data = self._serializedata(self._data)
             indexsize = S_INDEXSIZE.pack(len(indexdata))
 
             # writing
--- a/tests/test-discovery-obshashrange-cache.t	Tue Mar 30 19:35:52 2021 +0800
+++ b/tests/test-discovery-obshashrange-cache.t	Wed Mar 31 20:39:37 2021 +0800
@@ -336,3 +336,19 @@
   number of revisions:            8
   number of merge:                0
   number of jumps:                0
+
+  $ "$PYTHON" truncate.py main/.hg/cache/evoext-stablesortcache-00 -4
+  $ f -H main/.hg/cache/evoext-stablesortcache-00
+  main/.hg/cache/evoext-stablesortcache-00:
+  0000: 00 00 00 07 4d e3 2a 90 b6 6c d0 83 eb f3 c0 0b |....M.*..l......|
+  0010: 41 27 7a a7 ab ca 51 dd 00 00 00 40 00 00 00 00 |A'z...Q....@....|
+  0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+  0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+  0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+  0050: 00 00 00 00 00 00 00 00                         |........|
+
+  $ hg -R main debugstablesortcache --debug
+  number of revisions:            8
+  stablesortcache file seems to be corrupted, it will be rebuilt from scratch
+  number of merge:                0
+  number of jumps:                0