Mercurial > public > mercurial-scm > hg
comparison mercurial/manifest.py @ 29961:774a15b129e8
manifest: move manifest.add onto manifestrevlog
This moves add and _addtree onto manifestrevlog. manifestrevlog is responsible
for all serialization decisions, so therefore the add function should live on
it. This will allow us to call add() from manifestlog, which lets us further
break our dependency on manifest.
author | Durham Goode <durham@fb.com> |
---|---|
date | Tue, 20 Sep 2016 12:24:01 -0700 |
parents | da75bc36202c |
children | 6b5a9a01f29d |
comparison
equal
deleted
inserted
replaced
29960:da75bc36202c | 29961:774a15b129e8 |
---|---|
944 if dir not in self._dirlogcache: | 944 if dir not in self._dirlogcache: |
945 self._dirlogcache[dir] = manifestrevlog(self.opener, dir, | 945 self._dirlogcache[dir] = manifestrevlog(self.opener, dir, |
946 self._dirlogcache) | 946 self._dirlogcache) |
947 return self._dirlogcache[dir] | 947 return self._dirlogcache[dir] |
948 | 948 |
949 def add(self, m, transaction, link, p1, p2, added, removed): | |
950 if (p1 in self.fulltextcache and util.safehasattr(m, 'fastdelta') | |
951 and not self._usemanifestv2): | |
952 # If our first parent is in the manifest cache, we can | |
953 # compute a delta here using properties we know about the | |
954 # manifest up-front, which may save time later for the | |
955 # revlog layer. | |
956 | |
957 _checkforbidden(added) | |
958 # combine the changed lists into one sorted iterator | |
959 work = heapq.merge([(x, False) for x in added], | |
960 [(x, True) for x in removed]) | |
961 | |
962 arraytext, deltatext = m.fastdelta(self.fulltextcache[p1], work) | |
963 cachedelta = self.rev(p1), deltatext | |
964 text = util.buffer(arraytext) | |
965 n = self.addrevision(text, transaction, link, p1, p2, cachedelta) | |
966 else: | |
967 # The first parent manifest isn't already loaded, so we'll | |
968 # just encode a fulltext of the manifest and pass that | |
969 # through to the revlog layer, and let it handle the delta | |
970 # process. | |
971 if self._treeondisk: | |
972 m1 = self.read(p1) | |
973 m2 = self.read(p2) | |
974 n = self._addtree(m, transaction, link, m1, m2) | |
975 arraytext = None | |
976 else: | |
977 text = m.text(self._usemanifestv2) | |
978 n = self.addrevision(text, transaction, link, p1, p2) | |
979 arraytext = array.array('c', text) | |
980 | |
981 self.fulltextcache[n] = arraytext | |
982 | |
983 return n | |
984 | |
985 def _addtree(self, m, transaction, link, m1, m2): | |
986 # If the manifest is unchanged compared to one parent, | |
987 # don't write a new revision | |
988 if m.unmodifiedsince(m1) or m.unmodifiedsince(m2): | |
989 return m.node() | |
990 def writesubtree(subm, subp1, subp2): | |
991 sublog = self.dirlog(subm.dir()) | |
992 sublog.add(subm, transaction, link, subp1, subp2, None, None) | |
993 m.writesubtrees(m1, m2, writesubtree) | |
994 text = m.dirtext(self._usemanifestv2) | |
995 # Double-check whether contents are unchanged to one parent | |
996 if text == m1.dirtext(self._usemanifestv2): | |
997 n = m1.node() | |
998 elif text == m2.dirtext(self._usemanifestv2): | |
999 n = m2.node() | |
1000 else: | |
1001 n = self.addrevision(text, transaction, link, m1.node(), m2.node()) | |
1002 # Save nodeid so parent manifest can calculate its nodeid | |
1003 m.setnode(n) | |
1004 return n | |
1005 | |
949 class manifestlog(object): | 1006 class manifestlog(object): |
950 """A collection class representing the collection of manifest snapshots | 1007 """A collection class representing the collection of manifest snapshots |
951 referenced by commits in the repository. | 1008 referenced by commits in the repository. |
952 | 1009 |
953 In this situation, 'manifest' refers to the abstract concept of a snapshot | 1010 In this situation, 'manifest' refers to the abstract concept of a snapshot |
1231 try: | 1288 try: |
1232 return m.find(f) | 1289 return m.find(f) |
1233 except KeyError: | 1290 except KeyError: |
1234 return None, None | 1291 return None, None |
1235 | 1292 |
1236 def add(self, m, transaction, link, p1, p2, added, removed): | |
1237 if (p1 in self.fulltextcache and util.safehasattr(m, 'fastdelta') | |
1238 and not self._usemanifestv2): | |
1239 # If our first parent is in the manifest cache, we can | |
1240 # compute a delta here using properties we know about the | |
1241 # manifest up-front, which may save time later for the | |
1242 # revlog layer. | |
1243 | |
1244 _checkforbidden(added) | |
1245 # combine the changed lists into one sorted iterator | |
1246 work = heapq.merge([(x, False) for x in added], | |
1247 [(x, True) for x in removed]) | |
1248 | |
1249 arraytext, deltatext = m.fastdelta(self.fulltextcache[p1], work) | |
1250 cachedelta = self.rev(p1), deltatext | |
1251 text = util.buffer(arraytext) | |
1252 n = self.addrevision(text, transaction, link, p1, p2, cachedelta) | |
1253 else: | |
1254 # The first parent manifest isn't already loaded, so we'll | |
1255 # just encode a fulltext of the manifest and pass that | |
1256 # through to the revlog layer, and let it handle the delta | |
1257 # process. | |
1258 if self._treeondisk: | |
1259 m1 = self.read(p1) | |
1260 m2 = self.read(p2) | |
1261 n = self._addtree(m, transaction, link, m1, m2) | |
1262 arraytext = None | |
1263 else: | |
1264 text = m.text(self._usemanifestv2) | |
1265 n = self.addrevision(text, transaction, link, p1, p2) | |
1266 arraytext = array.array('c', text) | |
1267 | |
1268 self._mancache[n] = m | |
1269 self.fulltextcache[n] = arraytext | |
1270 | |
1271 return n | |
1272 | |
1273 def _addtree(self, m, transaction, link, m1, m2): | |
1274 # If the manifest is unchanged compared to one parent, | |
1275 # don't write a new revision | |
1276 if m.unmodifiedsince(m1) or m.unmodifiedsince(m2): | |
1277 return m.node() | |
1278 def writesubtree(subm, subp1, subp2): | |
1279 sublog = self.dirlog(subm.dir()) | |
1280 sublog.add(subm, transaction, link, subp1, subp2, None, None) | |
1281 m.writesubtrees(m1, m2, writesubtree) | |
1282 text = m.dirtext(self._usemanifestv2) | |
1283 # Double-check whether contents are unchanged to one parent | |
1284 if text == m1.dirtext(self._usemanifestv2): | |
1285 n = m1.node() | |
1286 elif text == m2.dirtext(self._usemanifestv2): | |
1287 n = m2.node() | |
1288 else: | |
1289 n = self.addrevision(text, transaction, link, m1.node(), m2.node()) | |
1290 # Save nodeid so parent manifest can calculate its nodeid | |
1291 m.setnode(n) | |
1292 return n | |
1293 | |
1294 def clearcaches(self): | 1293 def clearcaches(self): |
1295 super(manifest, self).clearcaches() | 1294 super(manifest, self).clearcaches() |
1296 self._mancache.clear() | 1295 self._mancache.clear() |