mercurial/revlog.py
changeset 6261 7c8101b5ceb1
parent 6228 c0c4c7b1e8d3
child 6264 3a775af0bc9f
equal deleted inserted replaced
6260:f295206ae1f9 6261:7c8101b5ceb1
   975         trindex = trinfo[2]
   975         trindex = trinfo[2]
   976         dataoff = self.start(trindex)
   976         dataoff = self.start(trindex)
   977 
   977 
   978         tr.add(self.datafile, dataoff)
   978         tr.add(self.datafile, dataoff)
   979         df = self.opener(self.datafile, 'w')
   979         df = self.opener(self.datafile, 'w')
   980         calc = self._io.size
   980         try:
   981         for r in xrange(self.count()):
   981             calc = self._io.size
   982             start = self.start(r) + (r + 1) * calc
   982             for r in xrange(self.count()):
   983             length = self.length(r)
   983                 start = self.start(r) + (r + 1) * calc
   984             fp.seek(start)
   984                 length = self.length(r)
   985             d = fp.read(length)
   985                 fp.seek(start)
   986             df.write(d)
   986                 d = fp.read(length)
       
   987                 df.write(d)
       
   988         finally:
       
   989             df.close()
       
   990 
   987         fp.close()
   991         fp.close()
   988         df.close()
       
   989         fp = self.opener(self.indexfile, 'w', atomictemp=True)
   992         fp = self.opener(self.indexfile, 'w', atomictemp=True)
   990         self.version &= ~(REVLOGNGINLINEDATA)
   993         self.version &= ~(REVLOGNGINLINEDATA)
   991         self._inline = False
   994         self._inline = False
   992         for i in xrange(self.count()):
   995         for i in xrange(self.count()):
   993             e = self._io.packentry(self.index[i], self.node, self.version, i)
   996             e = self._io.packentry(self.index[i], self.node, self.version, i)
   994             fp.write(e)
   997             fp.write(e)
   995 
   998 
       
   999         fp.close()
   996         # if we don't call rename, the temp file will never replace the
  1000         # if we don't call rename, the temp file will never replace the
   997         # real index
  1001         # real index
   998         fp.rename()
  1002         fp.rename()
   999 
  1003 
  1000         tr.replace(self.indexfile, trindex * calc)
  1004         tr.replace(self.indexfile, trindex * calc)
  1011         """
  1015         """
  1012         dfh = None
  1016         dfh = None
  1013         if not self._inline:
  1017         if not self._inline:
  1014             dfh = self.opener(self.datafile, "a")
  1018             dfh = self.opener(self.datafile, "a")
  1015         ifh = self.opener(self.indexfile, "a+")
  1019         ifh = self.opener(self.indexfile, "a+")
  1016         return self._addrevision(text, transaction, link, p1, p2, d, ifh, dfh)
  1020         try:
       
  1021             return self._addrevision(text, transaction, link, p1, p2, d, ifh, dfh)
       
  1022         finally:
       
  1023             if dfh:
       
  1024                 dfh.close()
       
  1025             ifh.close()
  1017 
  1026 
  1018     def _addrevision(self, text, transaction, link, p1, p2, d, ifh, dfh):
  1027     def _addrevision(self, text, transaction, link, p1, p2, d, ifh, dfh):
  1019         node = hash(text, p1, p2)
  1028         node = hash(text, p1, p2)
  1020         if node in self.nodemap:
  1029         if node in self.nodemap:
  1021             return node
  1030             return node
  1152         else:
  1161         else:
  1153             transaction.add(self.indexfile, isize, r)
  1162             transaction.add(self.indexfile, isize, r)
  1154             transaction.add(self.datafile, end)
  1163             transaction.add(self.datafile, end)
  1155             dfh = self.opener(self.datafile, "a")
  1164             dfh = self.opener(self.datafile, "a")
  1156 
  1165 
  1157         # loop through our set of deltas
  1166         try:
  1158         chain = None
  1167             # loop through our set of deltas
  1159         for chunk in revs:
  1168             chain = None
  1160             node, p1, p2, cs = struct.unpack("20s20s20s20s", chunk[:80])
  1169             for chunk in revs:
  1161             link = linkmapper(cs)
  1170                 node, p1, p2, cs = struct.unpack("20s20s20s20s", chunk[:80])
  1162             if node in self.nodemap:
  1171                 link = linkmapper(cs)
  1163                 # this can happen if two branches make the same change
  1172                 if node in self.nodemap:
  1164                 # if unique:
  1173                     # this can happen if two branches make the same change
  1165                 #    raise RevlogError(_("already have %s") % hex(node[:4]))
  1174                     # if unique:
  1166                 chain = node
  1175                     #    raise RevlogError(_("already have %s") % hex(node[:4]))
  1167                 continue
  1176                     chain = node
  1168             delta = buffer(chunk, 80)
  1177                     continue
  1169             del chunk
  1178                 delta = buffer(chunk, 80)
  1170 
  1179                 del chunk
  1171             for p in (p1, p2):
  1180 
  1172                 if not p in self.nodemap:
  1181                 for p in (p1, p2):
  1173                     raise LookupError(p, self.indexfile, _('unknown parent'))
  1182                     if not p in self.nodemap:
  1174 
  1183                         raise LookupError(p, self.indexfile, _('unknown parent'))
  1175             if not chain:
  1184 
  1176                 # retrieve the parent revision of the delta chain
  1185                 if not chain:
  1177                 chain = p1
  1186                     # retrieve the parent revision of the delta chain
  1178                 if not chain in self.nodemap:
  1187                     chain = p1
  1179                     raise LookupError(chain, self.indexfile, _('unknown base'))
  1188                     if not chain in self.nodemap:
  1180 
  1189                         raise LookupError(chain, self.indexfile, _('unknown base'))
  1181             # full versions are inserted when the needed deltas become
  1190 
  1182             # comparable to the uncompressed text or when the previous
  1191                 # full versions are inserted when the needed deltas become
  1183             # version is not the one we have a delta against. We use
  1192                 # comparable to the uncompressed text or when the previous
  1184             # the size of the previous full rev as a proxy for the
  1193                 # version is not the one we have a delta against. We use
  1185             # current size.
  1194                 # the size of the previous full rev as a proxy for the
  1186 
  1195                 # current size.
  1187             if chain == prev:
  1196 
  1188                 cdelta = compress(delta)
  1197                 if chain == prev:
  1189                 cdeltalen = len(cdelta[0]) + len(cdelta[1])
  1198                     cdelta = compress(delta)
  1190                 textlen = mdiff.patchedsize(textlen, delta)
  1199                     cdeltalen = len(cdelta[0]) + len(cdelta[1])
  1191 
  1200                     textlen = mdiff.patchedsize(textlen, delta)
  1192             if chain != prev or (end - start + cdeltalen) > textlen * 2:
  1201 
  1193                 # flush our writes here so we can read it in revision
  1202                 if chain != prev or (end - start + cdeltalen) > textlen * 2:
  1194                 if dfh:
  1203                     # flush our writes here so we can read it in revision
  1195                     dfh.flush()
  1204                     if dfh:
  1196                 ifh.flush()
  1205                         dfh.flush()
  1197                 text = self.revision(chain)
  1206                     ifh.flush()
  1198                 if len(text) == 0:
  1207                     text = self.revision(chain)
  1199                     # skip over trivial delta header
  1208                     if len(text) == 0:
  1200                     text = buffer(delta, 12)
  1209                         # skip over trivial delta header
  1201                 else:
  1210                         text = buffer(delta, 12)
  1202                     text = mdiff.patches(text, [delta])
  1211                     else:
  1203                 del delta
  1212                         text = mdiff.patches(text, [delta])
  1204                 chk = self._addrevision(text, transaction, link, p1, p2, None,
  1213                     del delta
  1205                                         ifh, dfh)
  1214                     chk = self._addrevision(text, transaction, link, p1, p2, None,
  1206                 if not dfh and not self._inline:
  1215                                             ifh, dfh)
  1207                     # addrevision switched from inline to conventional
  1216                     if not dfh and not self._inline:
  1208                     # reopen the index
  1217                         # addrevision switched from inline to conventional
  1209                     dfh = self.opener(self.datafile, "a")
  1218                         # reopen the index
  1210                     ifh = self.opener(self.indexfile, "a")
       
  1211                 if chk != node:
       
  1212                     raise RevlogError(_("consistency error adding group"))
       
  1213                 textlen = len(text)
       
  1214             else:
       
  1215                 e = (offset_type(end, 0), cdeltalen, textlen, base,
       
  1216                      link, self.rev(p1), self.rev(p2), node)
       
  1217                 self.index.insert(-1, e)
       
  1218                 self.nodemap[node] = r
       
  1219                 entry = self._io.packentry(e, self.node, self.version, r)
       
  1220                 if self._inline:
       
  1221                     ifh.write(entry)
       
  1222                     ifh.write(cdelta[0])
       
  1223                     ifh.write(cdelta[1])
       
  1224                     self.checkinlinesize(transaction, ifh)
       
  1225                     if not self._inline:
       
  1226                         dfh = self.opener(self.datafile, "a")
  1219                         dfh = self.opener(self.datafile, "a")
  1227                         ifh = self.opener(self.indexfile, "a")
  1220                         ifh = self.opener(self.indexfile, "a")
       
  1221                     if chk != node:
       
  1222                         raise RevlogError(_("consistency error adding group"))
       
  1223                     textlen = len(text)
  1228                 else:
  1224                 else:
  1229                     dfh.write(cdelta[0])
  1225                     e = (offset_type(end, 0), cdeltalen, textlen, base,
  1230                     dfh.write(cdelta[1])
  1226                          link, self.rev(p1), self.rev(p2), node)
  1231                     ifh.write(entry)
  1227                     self.index.insert(-1, e)
  1232 
  1228                     self.nodemap[node] = r
  1233             t, r, chain, prev = r, r + 1, node, node
  1229                     entry = self._io.packentry(e, self.node, self.version, r)
  1234             base = self.base(t)
  1230                     if self._inline:
  1235             start = self.start(base)
  1231                         ifh.write(entry)
  1236             end = self.end(t)
  1232                         ifh.write(cdelta[0])
       
  1233                         ifh.write(cdelta[1])
       
  1234                         self.checkinlinesize(transaction, ifh)
       
  1235                         if not self._inline:
       
  1236                             dfh = self.opener(self.datafile, "a")
       
  1237                             ifh = self.opener(self.indexfile, "a")
       
  1238                     else:
       
  1239                         dfh.write(cdelta[0])
       
  1240                         dfh.write(cdelta[1])
       
  1241                         ifh.write(entry)
       
  1242 
       
  1243                 t, r, chain, prev = r, r + 1, node, node
       
  1244                 base = self.base(t)
       
  1245                 start = self.start(base)
       
  1246                 end = self.end(t)
       
  1247         finally:
       
  1248             if dfh:
       
  1249                 dfh.close()
       
  1250             ifh.close()
  1237 
  1251 
  1238         return node
  1252         return node
  1239 
  1253 
  1240     def strip(self, minlink):
  1254     def strip(self, minlink):
  1241         """truncate the revlog on the first revision with a linkrev >= minlink
  1255         """truncate the revlog on the first revision with a linkrev >= minlink