hgext/remotefilelog/historypack.py
changeset 43077 687b865b95ad
parent 43076 2372284d9457
child 43105 649d3ac37a12
equal deleted inserted replaced
43076:2372284d9457 43077:687b865b95ad
    13     constants,
    13     constants,
    14     shallowutil,
    14     shallowutil,
    15 )
    15 )
    16 
    16 
    17 # (filename hash, offset, size)
    17 # (filename hash, offset, size)
    18 INDEXFORMAT2 = '!20sQQII'
    18 INDEXFORMAT2 = b'!20sQQII'
    19 INDEXENTRYLENGTH2 = struct.calcsize(INDEXFORMAT2)
    19 INDEXENTRYLENGTH2 = struct.calcsize(INDEXFORMAT2)
    20 NODELENGTH = 20
    20 NODELENGTH = 20
    21 
    21 
    22 NODEINDEXFORMAT = '!20sQ'
    22 NODEINDEXFORMAT = b'!20sQ'
    23 NODEINDEXENTRYLENGTH = struct.calcsize(NODEINDEXFORMAT)
    23 NODEINDEXENTRYLENGTH = struct.calcsize(NODEINDEXFORMAT)
    24 
    24 
    25 # (node, p1, p2, linknode)
    25 # (node, p1, p2, linknode)
    26 PACKFORMAT = "!20s20s20s20sH"
    26 PACKFORMAT = b"!20s20s20s20sH"
    27 PACKENTRYLENGTH = 82
    27 PACKENTRYLENGTH = 82
    28 
    28 
    29 ENTRYCOUNTSIZE = 4
    29 ENTRYCOUNTSIZE = 4
    30 
    30 
    31 INDEXSUFFIX = '.histidx'
    31 INDEXSUFFIX = b'.histidx'
    32 PACKSUFFIX = '.histpack'
    32 PACKSUFFIX = b'.histpack'
    33 
    33 
    34 ANC_NODE = 0
    34 ANC_NODE = 0
    35 ANC_P1NODE = 1
    35 ANC_P1NODE = 1
    36 ANC_P2NODE = 2
    36 ANC_P2NODE = 2
    37 ANC_LINKNODE = 3
    37 ANC_LINKNODE = 3
    75 
    75 
    76         raise KeyError((name, node))
    76         raise KeyError((name, node))
    77 
    77 
    78     def add(self, filename, node, p1, p2, linknode, copyfrom):
    78     def add(self, filename, node, p1, p2, linknode, copyfrom):
    79         raise RuntimeError(
    79         raise RuntimeError(
    80             "cannot add to historypackstore (%s:%s)" % (filename, hex(node))
    80             b"cannot add to historypackstore (%s:%s)" % (filename, hex(node))
    81         )
    81         )
    82 
    82 
    83 
    83 
    84 class historypack(basepack.basepack):
    84 class historypack(basepack.basepack):
    85     INDEXSUFFIX = INDEXSUFFIX
    85     INDEXSUFFIX = INDEXSUFFIX
   166             copyfrom = data[offset : offset + copyfromlen]
   166             copyfrom = data[offset : offset + copyfromlen]
   167         return entry, copyfrom
   167         return entry, copyfrom
   168 
   168 
   169     def add(self, filename, node, p1, p2, linknode, copyfrom):
   169     def add(self, filename, node, p1, p2, linknode, copyfrom):
   170         raise RuntimeError(
   170         raise RuntimeError(
   171             "cannot add to historypack (%s:%s)" % (filename, hex(node))
   171             b"cannot add to historypack (%s:%s)" % (filename, hex(node))
   172         )
   172         )
   173 
   173 
   174     def _findnode(self, name, node):
   174     def _findnode(self, name, node):
   175         if self.VERSION == 0:
   175         if self.VERSION == 0:
   176             ancestors = self._getancestors(name, node)
   176             ancestors = self._getancestors(name, node)
   191                 entry, copyfrom = self._readentry(offset)
   191                 entry, copyfrom = self._readentry(offset)
   192                 # Drop the copyfromlen from the end of entry, and replace it
   192                 # Drop the copyfromlen from the end of entry, and replace it
   193                 # with the copyfrom string.
   193                 # with the copyfrom string.
   194                 return entry[:4] + (copyfrom,)
   194                 return entry[:4] + (copyfrom,)
   195 
   195 
   196         raise KeyError("unable to find history for %s:%s" % (name, hex(node)))
   196         raise KeyError(b"unable to find history for %s:%s" % (name, hex(node)))
   197 
   197 
   198     def _findsection(self, name):
   198     def _findsection(self, name):
   199         params = self.params
   199         params = self.params
   200         namehash = hashlib.sha1(name).digest()
   200         namehash = hashlib.sha1(name).digest()
   201         fanoutkey = struct.unpack(
   201         fanoutkey = struct.unpack(
   220         rawentry = struct.unpack(self.INDEXFORMAT, entry)
   220         rawentry = struct.unpack(self.INDEXFORMAT, entry)
   221         x, offset, size, nodeindexoffset, nodeindexsize = rawentry
   221         x, offset, size, nodeindexoffset, nodeindexsize = rawentry
   222         rawnamelen = self._index[
   222         rawnamelen = self._index[
   223             nodeindexoffset : nodeindexoffset + constants.FILENAMESIZE
   223             nodeindexoffset : nodeindexoffset + constants.FILENAMESIZE
   224         ]
   224         ]
   225         actualnamelen = struct.unpack('!H', rawnamelen)[0]
   225         actualnamelen = struct.unpack(b'!H', rawnamelen)[0]
   226         nodeindexoffset += constants.FILENAMESIZE
   226         nodeindexoffset += constants.FILENAMESIZE
   227         actualname = self._index[
   227         actualname = self._index[
   228             nodeindexoffset : nodeindexoffset + actualnamelen
   228             nodeindexoffset : nodeindexoffset + actualnamelen
   229         ]
   229         ]
   230         if actualname != name:
   230         if actualname != name:
   231             raise KeyError(
   231             raise KeyError(
   232                 "found file name %s when looking for %s" % (actualname, name)
   232                 b"found file name %s when looking for %s" % (actualname, name)
   233             )
   233             )
   234         nodeindexoffset += actualnamelen
   234         nodeindexoffset += actualnamelen
   235 
   235 
   236         filenamelength = struct.unpack(
   236         filenamelength = struct.unpack(
   237             '!H', self._data[offset : offset + constants.FILENAMESIZE]
   237             b'!H', self._data[offset : offset + constants.FILENAMESIZE]
   238         )[0]
   238         )[0]
   239         offset += constants.FILENAMESIZE
   239         offset += constants.FILENAMESIZE
   240 
   240 
   241         actualname = self._data[offset : offset + filenamelength]
   241         actualname = self._data[offset : offset + filenamelength]
   242         offset += filenamelength
   242         offset += filenamelength
   243 
   243 
   244         if name != actualname:
   244         if name != actualname:
   245             raise KeyError(
   245             raise KeyError(
   246                 "found file name %s when looking for %s" % (actualname, name)
   246                 b"found file name %s when looking for %s" % (actualname, name)
   247             )
   247             )
   248 
   248 
   249         # Skip entry list size
   249         # Skip entry list size
   250         offset += ENTRYCOUNTSIZE
   250         offset += ENTRYCOUNTSIZE
   251 
   251 
   309         offset = 1
   309         offset = 1
   310         while offset < self.datasize:
   310         while offset < self.datasize:
   311             data = self._data
   311             data = self._data
   312             # <2 byte len> + <filename>
   312             # <2 byte len> + <filename>
   313             filenamelen = struct.unpack(
   313             filenamelen = struct.unpack(
   314                 '!H', data[offset : offset + constants.FILENAMESIZE]
   314                 b'!H', data[offset : offset + constants.FILENAMESIZE]
   315             )[0]
   315             )[0]
   316             offset += constants.FILENAMESIZE
   316             offset += constants.FILENAMESIZE
   317             filename = data[offset : offset + filenamelen]
   317             filename = data[offset : offset + filenamelen]
   318             offset += filenamelen
   318             offset += filenamelen
   319 
   319 
   320             revcount = struct.unpack(
   320             revcount = struct.unpack(
   321                 '!I', data[offset : offset + ENTRYCOUNTSIZE]
   321                 b'!I', data[offset : offset + ENTRYCOUNTSIZE]
   322             )[0]
   322             )[0]
   323             offset += ENTRYCOUNTSIZE
   323             offset += ENTRYCOUNTSIZE
   324 
   324 
   325             for i in pycompat.xrange(revcount):
   325             for i in pycompat.xrange(revcount):
   326                 entry = struct.unpack(
   326                 entry = struct.unpack(
   438 
   438 
   439         self.NODEINDEXFORMAT = NODEINDEXFORMAT
   439         self.NODEINDEXFORMAT = NODEINDEXFORMAT
   440         self.NODEINDEXENTRYLENGTH = NODEINDEXENTRYLENGTH
   440         self.NODEINDEXENTRYLENGTH = NODEINDEXENTRYLENGTH
   441 
   441 
   442     def add(self, filename, node, p1, p2, linknode, copyfrom):
   442     def add(self, filename, node, p1, p2, linknode, copyfrom):
   443         copyfrom = copyfrom or ''
   443         copyfrom = copyfrom or b''
   444         copyfromlen = struct.pack('!H', len(copyfrom))
   444         copyfromlen = struct.pack(b'!H', len(copyfrom))
   445         self.fileentries.setdefault(filename, []).append(
   445         self.fileentries.setdefault(filename, []).append(
   446             (node, p1, p2, linknode, copyfromlen, copyfrom)
   446             (node, p1, p2, linknode, copyfromlen, copyfrom)
   447         )
   447         )
   448 
   448 
   449     def _write(self):
   449     def _write(self):
   469                 )
   469                 )
   470             )
   470             )
   471 
   471 
   472             # Write the file section header
   472             # Write the file section header
   473             self.writeraw(
   473             self.writeraw(
   474                 "%s%s%s"
   474                 b"%s%s%s"
   475                 % (
   475                 % (
   476                     struct.pack('!H', len(filename)),
   476                     struct.pack(b'!H', len(filename)),
   477                     filename,
   477                     filename,
   478                     struct.pack('!I', len(sortednodes)),
   478                     struct.pack(b'!I', len(sortednodes)),
   479                 )
   479                 )
   480             )
   480             )
   481 
   481 
   482             sectionlen = constants.FILENAMESIZE + len(filename) + 4
   482             sectionlen = constants.FILENAMESIZE + len(filename) + 4
   483 
   483 
   486             # Record the node locations for the index
   486             # Record the node locations for the index
   487             locations = self.entrylocations.setdefault(filename, {})
   487             locations = self.entrylocations.setdefault(filename, {})
   488             offset = sectionstart + sectionlen
   488             offset = sectionstart + sectionlen
   489             for node in sortednodes:
   489             for node in sortednodes:
   490                 locations[node] = offset
   490                 locations[node] = offset
   491                 raw = '%s%s%s%s%s%s' % entrymap[node]
   491                 raw = b'%s%s%s%s%s%s' % entrymap[node]
   492                 rawstrings.append(raw)
   492                 rawstrings.append(raw)
   493                 offset += len(raw)
   493                 offset += len(raw)
   494 
   494 
   495             rawdata = ''.join(rawstrings)
   495             rawdata = b''.join(rawstrings)
   496             sectionlen += len(rawdata)
   496             sectionlen += len(rawdata)
   497 
   497 
   498             self.writeraw(rawdata)
   498             self.writeraw(rawdata)
   499 
   499 
   500             # Record metadata for the index
   500             # Record metadata for the index
   521             for filename, (offset, size) in self.files.iteritems()
   521             for filename, (offset, size) in self.files.iteritems()
   522         )
   522         )
   523         files = sorted(files)
   523         files = sorted(files)
   524 
   524 
   525         # node index is after file index size, file index, and node index size
   525         # node index is after file index size, file index, and node index size
   526         indexlensize = struct.calcsize('!Q')
   526         indexlensize = struct.calcsize(b'!Q')
   527         nodeindexoffset = (
   527         nodeindexoffset = (
   528             indexoffset
   528             indexoffset
   529             + indexlensize
   529             + indexlensize
   530             + (len(files) * fileindexlength)
   530             + (len(files) * fileindexlength)
   531             + indexlensize
   531             + indexlensize
   562 
   562 
   563             nodeindexoffset += len(nodelocations) * nodeindexlength
   563             nodeindexoffset += len(nodelocations) * nodeindexlength
   564 
   564 
   565             fileindexentries.append(rawentry)
   565             fileindexentries.append(rawentry)
   566 
   566 
   567         nodecountraw = struct.pack('!Q', nodecount)
   567         nodecountraw = struct.pack(b'!Q', nodecount)
   568         return (
   568         return (
   569             ''.join(fileindexentries) + nodecountraw + ''.join(nodeindexentries)
   569             b''.join(fileindexentries)
   570         )
   570             + nodecountraw
       
   571             + b''.join(nodeindexentries)
       
   572         )