equal
deleted
inserted
replaced
55 vfs.unlink(tmpname) |
55 vfs.unlink(tmpname) |
56 |
56 |
57 def nonnormalentries(dmap): |
57 def nonnormalentries(dmap): |
58 '''Compute the nonnormal dirstate entries from the dmap''' |
58 '''Compute the nonnormal dirstate entries from the dmap''' |
59 try: |
59 try: |
60 return parsers.nonnormalotherparententries(dmap) |
60 return parsers.nonnormalotherparententries(dmap._map) |
61 except AttributeError: |
61 except AttributeError: |
62 nonnorm = set() |
62 nonnorm = set() |
63 otherparent = set() |
63 otherparent = set() |
64 for fname, e in dmap.iteritems(): |
64 for fname, e in dmap.iteritems(): |
65 if e[0] != 'n' or e[3] == -1: |
65 if e[0] != 'n' or e[3] == -1: |
177 try: |
177 try: |
178 makefilefoldmap = parsers.make_file_foldmap |
178 makefilefoldmap = parsers.make_file_foldmap |
179 except AttributeError: |
179 except AttributeError: |
180 pass |
180 pass |
181 else: |
181 else: |
182 return makefilefoldmap(self._map, util.normcasespec, |
182 return makefilefoldmap(self._map._map, util.normcasespec, |
183 util.normcasefallback) |
183 util.normcasefallback) |
184 |
184 |
185 f = {} |
185 f = {} |
186 normcase = util.normcase |
186 normcase = util.normcase |
187 for name, s in self._map.iteritems(): |
187 for name, s in self._map.iteritems(): |
236 raise |
236 raise |
237 return [nullid, nullid] |
237 return [nullid, nullid] |
238 |
238 |
239 @propertycache |
239 @propertycache |
240 def _dirs(self): |
240 def _dirs(self): |
241 return util.dirs(self._map, 'r') |
241 return util.dirs(self._map._map, 'r') |
242 |
242 |
243 def dirs(self): |
243 def dirs(self): |
244 return self._dirs |
244 return self._dirs |
245 |
245 |
246 @rootcache('.hgignore') |
246 @rootcache('.hgignore') |
442 'changed parallelly')) |
442 'changed parallelly')) |
443 self._pendingmode = mode |
443 self._pendingmode = mode |
444 return fp |
444 return fp |
445 |
445 |
446 def _read(self): |
446 def _read(self): |
447 self._map = {} |
447 self._map = dirstatemap() |
|
448 |
448 self._copymap = {} |
449 self._copymap = {} |
449 # ignore HG_PENDING because identity is used only for writing |
450 # ignore HG_PENDING because identity is used only for writing |
450 self._identity = util.filestat.frompath( |
451 self._identity = util.filestat.frompath( |
451 self._opener.join(self._filename)) |
452 self._opener.join(self._filename)) |
452 try: |
453 try: |
471 # size. |
472 # size. |
472 # |
473 # |
473 # This heuristic is imperfect in many ways, so in a future dirstate |
474 # This heuristic is imperfect in many ways, so in a future dirstate |
474 # format update it makes sense to just record the number of entries |
475 # format update it makes sense to just record the number of entries |
475 # on write. |
476 # on write. |
476 self._map = parsers.dict_new_presized(len(st) / 71) |
477 self._map._map = parsers.dict_new_presized(len(st) / 71) |
477 |
478 |
478 # Python's garbage collector triggers a GC each time a certain number |
479 # Python's garbage collector triggers a GC each time a certain number |
479 # of container objects (the number being defined by |
480 # of container objects (the number being defined by |
480 # gc.get_threshold()) are allocated. parse_dirstate creates a tuple |
481 # gc.get_threshold()) are allocated. parse_dirstate creates a tuple |
481 # for each file in the dirstate. The C version then immediately marks |
482 # for each file in the dirstate. The C version then immediately marks |
486 # this can get very expensive. As a workaround, disable GC while |
487 # this can get very expensive. As a workaround, disable GC while |
487 # parsing the dirstate. |
488 # parsing the dirstate. |
488 # |
489 # |
489 # (we cannot decorate the function directly since it is in a C module) |
490 # (we cannot decorate the function directly since it is in a C module) |
490 parse_dirstate = util.nogc(parsers.parse_dirstate) |
491 parse_dirstate = util.nogc(parsers.parse_dirstate) |
491 p = parse_dirstate(self._map, self._copymap, st) |
492 p = parse_dirstate(self._map._map, self._copymap, st) |
492 if not self._dirtypl: |
493 if not self._dirtypl: |
493 self._pl = p |
494 self._pl = p |
494 |
495 |
495 def invalidate(self): |
496 def invalidate(self): |
496 '''Causes the next access to reread the dirstate. |
497 '''Causes the next access to reread the dirstate. |
729 if self._checkcase: |
730 if self._checkcase: |
730 return self._normalize(path, isknown, ignoremissing) |
731 return self._normalize(path, isknown, ignoremissing) |
731 return path |
732 return path |
732 |
733 |
733 def clear(self): |
734 def clear(self): |
734 self._map = {} |
735 self._map = dirstatemap() |
735 self._nonnormalset = set() |
736 self._nonnormalset = set() |
736 self._otherparentset = set() |
737 self._otherparentset = set() |
737 if "_dirs" in self.__dict__: |
738 if "_dirs" in self.__dict__: |
738 delattr(self, "_dirs") |
739 delattr(self, "_dirs") |
739 self._copymap = {} |
740 self._copymap = {} |
838 end = start + delaywrite |
839 end = start + delaywrite |
839 time.sleep(end - clock) |
840 time.sleep(end - clock) |
840 now = end # trust our estimate that the end is near now |
841 now = end # trust our estimate that the end is near now |
841 break |
842 break |
842 |
843 |
843 st.write(parsers.pack_dirstate(self._map, self._copymap, self._pl, now)) |
844 st.write(parsers.pack_dirstate(self._map._map, self._copymap, self._pl, |
|
845 now)) |
844 self._nonnormalset, self._otherparentset = nonnormalentries(self._map) |
846 self._nonnormalset, self._otherparentset = nonnormalentries(self._map) |
845 st.close() |
847 st.close() |
846 self._lastnormaltime = 0 |
848 self._lastnormaltime = 0 |
847 self._dirty = self._dirtypl = False |
849 self._dirty = self._dirtypl = False |
848 |
850 |
977 except OSError as inst: # nf not found on disk - it is dirstate only |
979 except OSError as inst: # nf not found on disk - it is dirstate only |
978 if nf in dmap: # does it exactly match a missing file? |
980 if nf in dmap: # does it exactly match a missing file? |
979 results[nf] = None |
981 results[nf] = None |
980 else: # does it match a missing directory? |
982 else: # does it match a missing directory? |
981 if alldirs is None: |
983 if alldirs is None: |
982 alldirs = util.dirs(dmap) |
984 alldirs = util.dirs(dmap._map) |
983 if nf in alldirs: |
985 if nf in alldirs: |
984 if matchedir: |
986 if matchedir: |
985 matchedir(nf) |
987 matchedir(nf) |
986 notfoundadd(nf) |
988 notfoundadd(nf) |
987 else: |
989 else: |
1337 self._opener.rename(backupname, filename, checkambig=True) |
1339 self._opener.rename(backupname, filename, checkambig=True) |
1338 |
1340 |
1339 def clearbackup(self, tr, backupname): |
1341 def clearbackup(self, tr, backupname): |
1340 '''Clear backup file''' |
1342 '''Clear backup file''' |
1341 self._opener.unlink(backupname) |
1343 self._opener.unlink(backupname) |
|
1344 |
|
1345 class dirstatemap(object): |
|
1346 def __init__(self): |
|
1347 self._map = {} |
|
1348 |
|
1349 def iteritems(self): |
|
1350 return self._map.iteritems() |
|
1351 |
|
1352 def __iter__(self): |
|
1353 return iter(self._map) |
|
1354 |
|
1355 def get(self, key, default=None): |
|
1356 return self._map.get(key, default) |
|
1357 |
|
1358 def __contains__(self, key): |
|
1359 return key in self._map |
|
1360 |
|
1361 def __setitem__(self, key, value): |
|
1362 self._map[key] = value |
|
1363 |
|
1364 def __getitem__(self, key): |
|
1365 return self._map[key] |
|
1366 |
|
1367 def __delitem__(self, key): |
|
1368 del self._map[key] |
|
1369 |
|
1370 def keys(self): |
|
1371 return self._map.keys() |