--- a/mercurial/dirstate.py Thu Oct 26 16:15:36 2017 -0700
+++ b/mercurial/dirstate.py Sat Oct 28 12:35:54 2017 -0700
@@ -1053,6 +1053,9 @@
removed, deleted, clean = [], [], []
dmap = self._map
+ dmap.preload()
+ dcontains = dmap.__contains__
+ dget = dmap.__getitem__
ladd = lookup.append # aka "unsure"
madd = modified.append
aadd = added.append
@@ -1074,7 +1077,7 @@
full = listclean or match.traversedir is not None
for fn, st in self.walk(match, subrepos, listunknown, listignored,
full=full).iteritems():
- if fn not in dmap:
+ if not dcontains(fn):
if (listignored or mexact(fn)) and dirignore(fn):
if listignored:
iadd(fn)
@@ -1089,7 +1092,7 @@
# a list, but falls back to creating a full-fledged iterator in
# general. That is much slower than simply accessing and storing the
# tuple members one by one.
- t = dmap[fn]
+ t = dget(fn)
state = t[0]
mode = t[1]
size = t[2]
@@ -1216,8 +1219,8 @@
return self.copymap
def clear(self):
- self._map = {}
- self.copymap = {}
+ self._map.clear()
+ self.copymap.clear()
self.setparents(nullid, nullid)
def iteritems(self):
@@ -1247,6 +1250,10 @@
def keys(self):
return self._map.keys()
+ def preload(self):
+ """Loads the underlying data, if it's not already loaded"""
+ self._map
+
def nonnormalentries(self):
'''Compute the nonnormal dirstate entries from the dmap'''
try:
@@ -1373,6 +1380,13 @@
if not self._dirtyparents:
self.setparents(*p)
+ # Avoid excess attribute lookups by fast pathing certain checks
+ self.__contains__ = self._map.__contains__
+ self.__getitem__ = self._map.__getitem__
+ self.__setitem__ = self._map.__setitem__
+ self.__delitem__ = self._map.__delitem__
+ self.get = self._map.get
+
def write(self, st, now):
st.write(parsers.pack_dirstate(self._map, self.copymap,
self.parents(), now))