hgext/remotefilelog/historypack.py
changeset 40556 10c10da14c5d
parent 40545 3a333a582d7b
child 40769 e0b485a76009
equal deleted inserted replaced
40555:b6b2a3d22344 40556:10c10da14c5d
    13     constants,
    13     constants,
    14     shallowutil,
    14     shallowutil,
    15 )
    15 )
    16 
    16 
    17 # (filename hash, offset, size)
    17 # (filename hash, offset, size)
    18 INDEXFORMAT0 = '!20sQQ'
    18 INDEXFORMAT2 = '!20sQQII'
    19 INDEXENTRYLENGTH0 = struct.calcsize(INDEXFORMAT0)
    19 INDEXENTRYLENGTH2 = struct.calcsize(INDEXFORMAT2)
    20 INDEXFORMAT1 = '!20sQQII'
       
    21 INDEXENTRYLENGTH1 = struct.calcsize(INDEXFORMAT1)
       
    22 NODELENGTH = 20
    20 NODELENGTH = 20
    23 
    21 
    24 NODEINDEXFORMAT = '!20sQ'
    22 NODEINDEXFORMAT = '!20sQ'
    25 NODEINDEXENTRYLENGTH = struct.calcsize(NODEINDEXFORMAT)
    23 NODEINDEXENTRYLENGTH = struct.calcsize(NODEINDEXFORMAT)
    26 
    24 
    82 
    80 
    83 class historypack(basepack.basepack):
    81 class historypack(basepack.basepack):
    84     INDEXSUFFIX = INDEXSUFFIX
    82     INDEXSUFFIX = INDEXSUFFIX
    85     PACKSUFFIX = PACKSUFFIX
    83     PACKSUFFIX = PACKSUFFIX
    86 
    84 
    87     SUPPORTED_VERSIONS = [0, 1]
    85     SUPPORTED_VERSIONS = [2]
    88 
    86 
    89     def __init__(self, path):
    87     def __init__(self, path):
    90         super(historypack, self).__init__(path)
    88         super(historypack, self).__init__(path)
    91 
    89         self.INDEXFORMAT = INDEXFORMAT2
    92         if self.VERSION == 0:
    90         self.INDEXENTRYLENGTH = INDEXENTRYLENGTH2
    93             self.INDEXFORMAT = INDEXFORMAT0
       
    94             self.INDEXENTRYLENGTH = INDEXENTRYLENGTH0
       
    95         else:
       
    96             self.INDEXFORMAT = INDEXFORMAT1
       
    97             self.INDEXENTRYLENGTH = INDEXENTRYLENGTH1
       
    98 
    91 
    99     def getmissing(self, keys):
    92     def getmissing(self, keys):
   100         missing = []
    93         missing = []
   101         for name, node in keys:
    94         for name, node in keys:
   102             try:
    95             try:
   213         entry = self._bisect(namehash, start, end, self.INDEXENTRYLENGTH)
   206         entry = self._bisect(namehash, start, end, self.INDEXENTRYLENGTH)
   214         if not entry:
   207         if not entry:
   215             raise KeyError(name)
   208             raise KeyError(name)
   216 
   209 
   217         rawentry = struct.unpack(self.INDEXFORMAT, entry)
   210         rawentry = struct.unpack(self.INDEXFORMAT, entry)
   218         if self.VERSION == 0:
   211         x, offset, size, nodeindexoffset, nodeindexsize = rawentry
   219             x, offset, size = rawentry
   212         rawnamelen = self._index[nodeindexoffset:nodeindexoffset +
   220             nodeindexoffset = None
   213                                                  constants.FILENAMESIZE]
   221             nodeindexsize = None
   214         actualnamelen = struct.unpack('!H', rawnamelen)[0]
   222         else:
   215         nodeindexoffset += constants.FILENAMESIZE
   223             x, offset, size, nodeindexoffset, nodeindexsize = rawentry
   216         actualname = self._index[nodeindexoffset:nodeindexoffset +
   224             rawnamelen = self._index[nodeindexoffset:nodeindexoffset +
   217                                                  actualnamelen]
   225                                                      constants.FILENAMESIZE]
   218         if actualname != name:
   226             actualnamelen = struct.unpack('!H', rawnamelen)[0]
   219             raise KeyError("found file name %s when looking for %s" %
   227             nodeindexoffset += constants.FILENAMESIZE
   220                            (actualname, name))
   228             actualname = self._index[nodeindexoffset:nodeindexoffset +
   221         nodeindexoffset += actualnamelen
   229                                                      actualnamelen]
       
   230             if actualname != name:
       
   231                 raise KeyError("found file name %s when looking for %s" %
       
   232                                (actualname, name))
       
   233             nodeindexoffset += actualnamelen
       
   234 
   222 
   235         filenamelength = struct.unpack('!H', self._data[offset:offset +
   223         filenamelength = struct.unpack('!H', self._data[offset:offset +
   236                                                     constants.FILENAMESIZE])[0]
   224                                                     constants.FILENAMESIZE])[0]
   237         offset += constants.FILENAMESIZE
   225         offset += constants.FILENAMESIZE
   238 
   226 
   404     [1]: new in version 1.
   392     [1]: new in version 1.
   405     """
   393     """
   406     INDEXSUFFIX = INDEXSUFFIX
   394     INDEXSUFFIX = INDEXSUFFIX
   407     PACKSUFFIX = PACKSUFFIX
   395     PACKSUFFIX = PACKSUFFIX
   408 
   396 
   409     SUPPORTED_VERSIONS = [0, 1]
   397     SUPPORTED_VERSIONS = [2]
   410 
   398 
   411     def __init__(self, ui, packpath, version=0):
   399     def __init__(self, ui, packpath, version=2):
   412         # internal config: remotefilelog.historypackv1
       
   413         if version == 0 and ui.configbool('remotefilelog', 'historypackv1'):
       
   414             version = 1
       
   415 
       
   416         super(mutablehistorypack, self).__init__(ui, packpath, version=version)
   400         super(mutablehistorypack, self).__init__(ui, packpath, version=version)
   417         self.files = {}
   401         self.files = {}
   418         self.entrylocations = {}
   402         self.entrylocations = {}
   419         self.fileentries = {}
   403         self.fileentries = {}
   420 
   404 
   421         if version == 0:
   405         self.INDEXFORMAT = INDEXFORMAT2
   422             self.INDEXFORMAT = INDEXFORMAT0
   406         self.INDEXENTRYLENGTH = INDEXENTRYLENGTH2
   423             self.INDEXENTRYLENGTH = INDEXENTRYLENGTH0
       
   424         else:
       
   425             self.INDEXFORMAT = INDEXFORMAT1
       
   426             self.INDEXENTRYLENGTH = INDEXENTRYLENGTH1
       
   427 
   407 
   428         self.NODEINDEXFORMAT = NODEINDEXFORMAT
   408         self.NODEINDEXFORMAT = NODEINDEXFORMAT
   429         self.NODEINDEXENTRYLENGTH = NODEINDEXENTRYLENGTH
   409         self.NODEINDEXENTRYLENGTH = NODEINDEXENTRYLENGTH
   430 
   410 
   431     def add(self, filename, node, p1, p2, linknode, copyfrom):
   411     def add(self, filename, node, p1, p2, linknode, copyfrom):
   497     def createindex(self, nodelocations, indexoffset):
   477     def createindex(self, nodelocations, indexoffset):
   498         fileindexformat = self.INDEXFORMAT
   478         fileindexformat = self.INDEXFORMAT
   499         fileindexlength = self.INDEXENTRYLENGTH
   479         fileindexlength = self.INDEXENTRYLENGTH
   500         nodeindexformat = self.NODEINDEXFORMAT
   480         nodeindexformat = self.NODEINDEXFORMAT
   501         nodeindexlength = self.NODEINDEXENTRYLENGTH
   481         nodeindexlength = self.NODEINDEXENTRYLENGTH
   502         version = self.VERSION
       
   503 
   482 
   504         files = ((hashlib.sha1(filename).digest(), filename, offset, size)
   483         files = ((hashlib.sha1(filename).digest(), filename, offset, size)
   505                 for filename, (offset, size) in self.files.iteritems())
   484                 for filename, (offset, size) in self.files.iteritems())
   506         files = sorted(files)
   485         files = sorted(files)
   507 
   486 
   513         fileindexentries = []
   492         fileindexentries = []
   514         nodeindexentries = []
   493         nodeindexentries = []
   515         nodecount = 0
   494         nodecount = 0
   516         for namehash, filename, offset, size in files:
   495         for namehash, filename, offset, size in files:
   517             # File section index
   496             # File section index
   518             if version == 0:
   497             nodelocations = self.entrylocations[filename]
   519                 rawentry = struct.pack(fileindexformat, namehash, offset, size)
   498 
   520             else:
   499             nodeindexsize = len(nodelocations) * nodeindexlength
   521                 nodelocations = self.entrylocations[filename]
   500 
   522 
   501             rawentry = struct.pack(fileindexformat, namehash, offset, size,
   523                 nodeindexsize = len(nodelocations) * nodeindexlength
   502                                    nodeindexoffset, nodeindexsize)
   524 
   503             # Node index
   525                 rawentry = struct.pack(fileindexformat, namehash, offset, size,
   504             nodeindexentries.append(struct.pack(constants.FILENAMESTRUCT,
   526                                        nodeindexoffset, nodeindexsize)
   505                                                 len(filename)) + filename)
   527                 # Node index
   506             nodeindexoffset += constants.FILENAMESIZE + len(filename)
   528                 nodeindexentries.append(struct.pack(constants.FILENAMESTRUCT,
   507 
   529                                                     len(filename)) + filename)
   508             for node, location in sorted(nodelocations.iteritems()):
   530                 nodeindexoffset += constants.FILENAMESIZE + len(filename)
   509                 nodeindexentries.append(struct.pack(nodeindexformat, node,
   531 
   510                                                     location))
   532                 for node, location in sorted(nodelocations.iteritems()):
   511                 nodecount += 1
   533                     nodeindexentries.append(struct.pack(nodeindexformat, node,
   512 
   534                                                         location))
   513             nodeindexoffset += len(nodelocations) * nodeindexlength
   535                     nodecount += 1
       
   536 
       
   537                 nodeindexoffset += len(nodelocations) * nodeindexlength
       
   538 
   514 
   539             fileindexentries.append(rawentry)
   515             fileindexentries.append(rawentry)
   540 
   516 
   541         nodecountraw = ''
   517         nodecountraw = ''
   542         if version == 1:
   518         nodecountraw = struct.pack('!Q', nodecount)
   543             nodecountraw = struct.pack('!Q', nodecount)
       
   544         return (''.join(fileindexentries) + nodecountraw +
   519         return (''.join(fileindexentries) + nodecountraw +
   545                 ''.join(nodeindexentries))
   520                 ''.join(nodeindexentries))