hgext/remotefilelog/datapack.py
changeset 40507 e2a1584e9e3f
parent 40506 10c10da14c5d
child 41365 876494fd967d
equal deleted inserted replaced
40506:10c10da14c5d 40507:e2a1584e9e3f
     1 from __future__ import absolute_import
     1 from __future__ import absolute_import
     2 
     2 
     3 import struct
     3 import struct
       
     4 import zlib
     4 
     5 
     5 from mercurial.node import hex, nullid
     6 from mercurial.node import hex, nullid
     6 from mercurial.i18n import _
     7 from mercurial.i18n import _
     7 from mercurial import (
     8 from mercurial import (
     8     pycompat,
     9     pycompat,
     9     util,
    10     util,
    10 )
    11 )
    11 from . import (
    12 from . import (
    12     basepack,
    13     basepack,
    13     constants,
    14     constants,
    14     lz4wrapper,
       
    15     shallowutil,
    15     shallowutil,
    16 )
    16 )
    17 
    17 
    18 NODELENGTH = 20
    18 NODELENGTH = 20
    19 
    19 
   193         deltastart = deltabasestart + NODELENGTH
   193         deltastart = deltabasestart + NODELENGTH
   194         rawdeltalen = rawentry[deltastart:deltastart + 8]
   194         rawdeltalen = rawentry[deltastart:deltastart + 8]
   195         deltalen = struct.unpack('!Q', rawdeltalen)[0]
   195         deltalen = struct.unpack('!Q', rawdeltalen)[0]
   196 
   196 
   197         delta = rawentry[deltastart + 8:deltastart + 8 + deltalen]
   197         delta = rawentry[deltastart + 8:deltastart + 8 + deltalen]
   198         delta = lz4wrapper.lz4decompress(delta)
   198         delta = self._decompress(delta)
   199 
   199 
   200         if getmeta:
   200         if getmeta:
   201             metastart = deltastart + 8 + deltalen
   201             metastart = deltastart + 8 + deltalen
   202             metalen = struct.unpack_from('!I', rawentry, metastart)[0]
   202             metalen = struct.unpack_from('!I', rawentry, metastart)[0]
   203 
   203 
   204             rawmeta = rawentry[metastart + 4:metastart + 4 + metalen]
   204             rawmeta = rawentry[metastart + 4:metastart + 4 + metalen]
   205             meta = shallowutil.parsepackmeta(rawmeta)
   205             meta = shallowutil.parsepackmeta(rawmeta)
   206             return filename, node, deltabasenode, delta, meta
   206             return filename, node, deltabasenode, delta, meta
   207         else:
   207         else:
   208             return filename, node, deltabasenode, delta
   208             return filename, node, deltabasenode, delta
       
   209 
       
   210     def _decompress(self, data):
       
   211         return zlib.decompress(data)
   209 
   212 
   210     def add(self, name, node, data):
   213     def add(self, name, node, data):
   211         raise RuntimeError("cannot add to datapack (%s:%s)" % (name, node))
   214         raise RuntimeError("cannot add to datapack (%s:%s)" % (name, node))
   212 
   215 
   213     def _find(self, node):
   216     def _find(self, node):
   298             # <8 byte len> + <delta>
   301             # <8 byte len> + <delta>
   299             rawdeltalen = data[offset:offset + 8]
   302             rawdeltalen = data[offset:offset + 8]
   300             deltalen = struct.unpack('!Q', rawdeltalen)[0]
   303             deltalen = struct.unpack('!Q', rawdeltalen)[0]
   301             offset += 8
   304             offset += 8
   302 
   305 
   303             # it has to be at least long enough for the lz4 header.
   306             # TODO(augie): we should store a header that is the
   304             assert deltalen >= 4
   307             # uncompressed size.
   305 
   308             uncompressedlen = len(self._decompress(
   306             # python-lz4 stores the length of the uncompressed field as a
   309                 data[offset:offset + deltalen]))
   307             # little-endian 32-bit integer at the start of the data.
       
   308             uncompressedlen = struct.unpack('<I', data[offset:offset + 4])[0]
       
   309             offset += deltalen
   310             offset += deltalen
   310 
   311 
   311             # <4 byte len> + <metadata-list>
   312             # <4 byte len> + <metadata-list>
   312             metalen = struct.unpack_from('!I', data, offset)[0]
   313             metalen = struct.unpack_from('!I', data, offset)[0]
   313             offset += 4 + metalen
   314             offset += 4 + metalen
   397     INDEXENTRYLENGTH = datapack.INDEXENTRYLENGTH
   398     INDEXENTRYLENGTH = datapack.INDEXENTRYLENGTH
   398 
   399 
   399     # v1 has metadata support
   400     # v1 has metadata support
   400     SUPPORTED_VERSIONS = [2]
   401     SUPPORTED_VERSIONS = [2]
   401 
   402 
       
   403     def _compress(self, data):
       
   404         return zlib.compress(data)
       
   405 
   402     def add(self, name, node, deltabasenode, delta, metadata=None):
   406     def add(self, name, node, deltabasenode, delta, metadata=None):
   403         # metadata is a dict, ex. {METAKEYFLAG: flag}
   407         # metadata is a dict, ex. {METAKEYFLAG: flag}
   404         if len(name) > 2**16:
   408         if len(name) > 2**16:
   405             raise RuntimeError(_("name too long %s") % name)
   409             raise RuntimeError(_("name too long %s") % name)
   406         if len(node) != 20:
   410         if len(node) != 20:
   409         if node in self.entries:
   413         if node in self.entries:
   410             # The revision has already been added
   414             # The revision has already been added
   411             return
   415             return
   412 
   416 
   413         # TODO: allow configurable compression
   417         # TODO: allow configurable compression
   414         delta = lz4wrapper.lz4compress(delta)
   418         delta = self._compress(delta)
   415 
   419 
   416         rawdata = ''.join((
   420         rawdata = ''.join((
   417             struct.pack('!H', len(name)), # unsigned 2 byte int
   421             struct.pack('!H', len(name)), # unsigned 2 byte int
   418             name,
   422             name,
   419             node,
   423             node,