mercurial/manifest.py
changeset 29824 58d4ecdc531e
parent 29823 27c0792e834c
child 29825 426d931e5db2
equal deleted inserted replaced
29823:27c0792e834c 29824:58d4ecdc531e
   888             subp2 = m2._dirs.get(d, emptytree)._node
   888             subp2 = m2._dirs.get(d, emptytree)._node
   889             if subp1 == revlog.nullid:
   889             if subp1 == revlog.nullid:
   890                 subp1, subp2 = subp2, subp1
   890                 subp1, subp2 = subp2, subp1
   891             writesubtree(subm, subp1, subp2)
   891             writesubtree(subm, subp1, subp2)
   892 
   892 
   893 class manifest(revlog.revlog):
   893 class manifestrevlog(revlog.revlog):
       
   894     '''A revlog that stores manifest texts. This is responsible for caching the
       
   895     full-text manifest contents.
       
   896     '''
       
   897     def __init__(self, opener, indexfile):
       
   898         super(manifestrevlog, self).__init__(opener, indexfile)
       
   899 
       
   900         # During normal operations, we expect to deal with not more than four
       
   901         # revs at a time (such as during commit --amend). When rebasing large
       
   902         # stacks of commits, the number can go up, hence the config knob below.
       
   903         cachesize = 4
       
   904         opts = getattr(opener, 'options', None)
       
   905         if opts is not None:
       
   906             cachesize = opts.get('manifestcachesize', cachesize)
       
   907         self._fulltextcache = util.lrucachedict(cachesize)
       
   908 
       
   909     @property
       
   910     def fulltextcache(self):
       
   911         return self._fulltextcache
       
   912 
       
   913     def clearcaches(self):
       
   914         super(manifestrevlog, self).clearcaches()
       
   915         self._fulltextcache.clear()
       
   916 
       
   917 class manifest(manifestrevlog):
   894     def __init__(self, opener, dir='', dirlogcache=None):
   918     def __init__(self, opener, dir='', dirlogcache=None):
   895         '''The 'dir' and 'dirlogcache' arguments are for internal use by
   919         '''The 'dir' and 'dirlogcache' arguments are for internal use by
   896         manifest.manifest only. External users should create a root manifest
   920         manifest.manifest only. External users should create a root manifest
   897         log with manifest.manifest(opener) and call dirlog() on it.
   921         log with manifest.manifest(opener) and call dirlog() on it.
   898         '''
   922         '''
   906         if opts is not None:
   930         if opts is not None:
   907             cachesize = opts.get('manifestcachesize', cachesize)
   931             cachesize = opts.get('manifestcachesize', cachesize)
   908             usetreemanifest = opts.get('treemanifest', usetreemanifest)
   932             usetreemanifest = opts.get('treemanifest', usetreemanifest)
   909             usemanifestv2 = opts.get('manifestv2', usemanifestv2)
   933             usemanifestv2 = opts.get('manifestv2', usemanifestv2)
   910         self._mancache = util.lrucachedict(cachesize)
   934         self._mancache = util.lrucachedict(cachesize)
   911         self._fulltextcache = util.lrucachedict(cachesize)
       
   912         self._treeinmem = usetreemanifest
   935         self._treeinmem = usetreemanifest
   913         self._treeondisk = usetreemanifest
   936         self._treeondisk = usetreemanifest
   914         self._usemanifestv2 = usemanifestv2
   937         self._usemanifestv2 = usemanifestv2
   915         indexfile = "00manifest.i"
   938         indexfile = "00manifest.i"
   916         if dir:
   939         if dir:
   917             assert self._treeondisk, 'opts is %r' % opts
   940             assert self._treeondisk, 'opts is %r' % opts
   918             if not dir.endswith('/'):
   941             if not dir.endswith('/'):
   919                 dir = dir + '/'
   942                 dir = dir + '/'
   920             indexfile = "meta/" + dir + "00manifest.i"
   943             indexfile = "meta/" + dir + "00manifest.i"
   921         revlog.revlog.__init__(self, opener, indexfile)
   944         super(manifest, self).__init__(opener, indexfile)
   922         self._dir = dir
   945         self._dir = dir
   923         # The dirlogcache is kept on the root manifest log
   946         # The dirlogcache is kept on the root manifest log
   924         if dir:
   947         if dir:
   925             self._dirlogcache = dirlogcache
   948             self._dirlogcache = dirlogcache
   926         else:
   949         else:
  1014         else:
  1037         else:
  1015             text = self.revision(node)
  1038             text = self.revision(node)
  1016             m = self._newmanifest(text)
  1039             m = self._newmanifest(text)
  1017             arraytext = array.array('c', text)
  1040             arraytext = array.array('c', text)
  1018         self._mancache[node] = m
  1041         self._mancache[node] = m
  1019         self._fulltextcache[node] = arraytext
  1042         self.fulltextcache[node] = arraytext
  1020         return m
  1043         return m
  1021 
  1044 
  1022     def readshallow(self, node):
  1045     def readshallow(self, node):
  1023         '''Reads the manifest in this directory. When using flat manifests,
  1046         '''Reads the manifest in this directory. When using flat manifests,
  1024         this manifest will generally have files in subdirectories in it. Does
  1047         this manifest will generally have files in subdirectories in it. Does
  1034             return m.find(f)
  1057             return m.find(f)
  1035         except KeyError:
  1058         except KeyError:
  1036             return None, None
  1059             return None, None
  1037 
  1060 
  1038     def add(self, m, transaction, link, p1, p2, added, removed):
  1061     def add(self, m, transaction, link, p1, p2, added, removed):
  1039         if (p1 in self._fulltextcache and not self._treeinmem
  1062         if (p1 in self.fulltextcache and not self._treeinmem
  1040             and not self._usemanifestv2):
  1063             and not self._usemanifestv2):
  1041             # If our first parent is in the manifest cache, we can
  1064             # If our first parent is in the manifest cache, we can
  1042             # compute a delta here using properties we know about the
  1065             # compute a delta here using properties we know about the
  1043             # manifest up-front, which may save time later for the
  1066             # manifest up-front, which may save time later for the
  1044             # revlog layer.
  1067             # revlog layer.
  1046             _checkforbidden(added)
  1069             _checkforbidden(added)
  1047             # combine the changed lists into one sorted iterator
  1070             # combine the changed lists into one sorted iterator
  1048             work = heapq.merge([(x, False) for x in added],
  1071             work = heapq.merge([(x, False) for x in added],
  1049                                [(x, True) for x in removed])
  1072                                [(x, True) for x in removed])
  1050 
  1073 
  1051             arraytext, deltatext = m.fastdelta(self._fulltextcache[p1], work)
  1074             arraytext, deltatext = m.fastdelta(self.fulltextcache[p1], work)
  1052             cachedelta = self.rev(p1), deltatext
  1075             cachedelta = self.rev(p1), deltatext
  1053             text = util.buffer(arraytext)
  1076             text = util.buffer(arraytext)
  1054             n = self.addrevision(text, transaction, link, p1, p2, cachedelta)
  1077             n = self.addrevision(text, transaction, link, p1, p2, cachedelta)
  1055         else:
  1078         else:
  1056             # The first parent manifest isn't already loaded, so we'll
  1079             # The first parent manifest isn't already loaded, so we'll
  1066                 text = m.text(self._usemanifestv2)
  1089                 text = m.text(self._usemanifestv2)
  1067                 n = self.addrevision(text, transaction, link, p1, p2)
  1090                 n = self.addrevision(text, transaction, link, p1, p2)
  1068                 arraytext = array.array('c', text)
  1091                 arraytext = array.array('c', text)
  1069 
  1092 
  1070         self._mancache[n] = m
  1093         self._mancache[n] = m
  1071         self._fulltextcache[n] = arraytext
  1094         self.fulltextcache[n] = arraytext
  1072 
  1095 
  1073         return n
  1096         return n
  1074 
  1097 
  1075     def _addtree(self, m, transaction, link, m1, m2):
  1098     def _addtree(self, m, transaction, link, m1, m2):
  1076         # If the manifest is unchanged compared to one parent,
  1099         # If the manifest is unchanged compared to one parent,
  1093         m.setnode(n)
  1116         m.setnode(n)
  1094         return n
  1117         return n
  1095 
  1118 
  1096     def clearcaches(self):
  1119     def clearcaches(self):
  1097         super(manifest, self).clearcaches()
  1120         super(manifest, self).clearcaches()
  1098         self._fulltextcache.clear()
       
  1099         self._mancache.clear()
  1121         self._mancache.clear()
  1100         self._dirlogcache = {'': self}
  1122         self._dirlogcache = {'': self}