comparison mercurial/localrepo.py @ 1806:a2c69737e65e

Automatic nesting into running transactions in the same repository. This associates a transaction handle with a given repository object, and any additional calls to start new transactions reuse that transaction. For the 2700 patch import run, this brings the system time down from 1m20s to 50s, mostly by skipping backups of the dirstate file. (note, this patch does not change hg import to use the nested transaction, mq is the only user right now)
author mason@suse.com
date Tue, 28 Feb 2006 12:24:54 -0600
parents 8a7a24b96697
children f1f43ea22cbf
comparison
equal deleted inserted replaced
1805:2af98c4b2587 1806:a2c69737e65e
11 from i18n import gettext as _ 11 from i18n import gettext as _
12 from demandload import * 12 from demandload import *
13 demandload(globals(), "re lock transaction tempfile stat mdiff errno") 13 demandload(globals(), "re lock transaction tempfile stat mdiff errno")
14 14
15 class localrepository(object): 15 class localrepository(object):
16 def __del__(self):
17 self.transhandle = None
16 def __init__(self, ui, path=None, create=0): 18 def __init__(self, ui, path=None, create=0):
17 if not path: 19 if not path:
18 p = os.getcwd() 20 p = os.getcwd()
19 while not os.path.isdir(os.path.join(p, ".hg")): 21 while not os.path.isdir(os.path.join(p, ".hg")):
20 oldp = p 22 oldp = p
35 self.changelog = changelog.changelog(self.opener) 37 self.changelog = changelog.changelog(self.opener)
36 self.tagscache = None 38 self.tagscache = None
37 self.nodetagscache = None 39 self.nodetagscache = None
38 self.encodepats = None 40 self.encodepats = None
39 self.decodepats = None 41 self.decodepats = None
42 self.transhandle = None
40 43
41 if create: 44 if create:
42 os.mkdir(self.path) 45 os.mkdir(self.path)
43 os.mkdir(self.join("data")) 46 os.mkdir(self.join("data"))
44 47
213 if fd: 216 if fd:
214 return fd.write(data) 217 return fd.write(data)
215 return self.wopener(filename, 'w').write(data) 218 return self.wopener(filename, 'w').write(data)
216 219
217 def transaction(self): 220 def transaction(self):
221 tr = self.transhandle
222 if tr != None and tr.running():
223 return tr.nest()
224
218 # save dirstate for undo 225 # save dirstate for undo
219 try: 226 try:
220 ds = self.opener("dirstate").read() 227 ds = self.opener("dirstate").read()
221 except IOError: 228 except IOError:
222 ds = "" 229 ds = ""
223 self.opener("journal.dirstate", "w").write(ds) 230 self.opener("journal.dirstate", "w").write(ds)
224 231
225 def after(): 232 tr = transaction.transaction(self.ui.warn, self.opener,
226 util.rename(self.join("journal"), self.join("undo")) 233 self.join("journal"),
227 util.rename(self.join("journal.dirstate"), 234 aftertrans(self.path))
228 self.join("undo.dirstate")) 235 self.transhandle = tr
229 236 return tr
230 return transaction.transaction(self.ui.warn, self.opener,
231 self.join("journal"), after)
232 237
233 def recover(self): 238 def recover(self):
234 l = self.lock() 239 l = self.lock()
235 if os.path.exists(self.join("journal")): 240 if os.path.exists(self.join("journal")):
236 self.ui.status(_("rolling back interrupted transaction\n")) 241 self.ui.status(_("rolling back interrupted transaction\n"))
1877 (files, changesets, revisions)) 1882 (files, changesets, revisions))
1878 1883
1879 if errors[0]: 1884 if errors[0]:
1880 self.ui.warn(_("%d integrity errors encountered!\n") % errors[0]) 1885 self.ui.warn(_("%d integrity errors encountered!\n") % errors[0])
1881 return 1 1886 return 1
1887
1888 # used to avoid circular references so destructors work
1889 def aftertrans(base):
1890 p = base
1891 def a():
1892 util.rename(os.path.join(p, "journal"), os.path.join(p, "undo"))
1893 util.rename(os.path.join(p, "journal.dirstate"),
1894 os.path.join(p, "undo.dirstate"))
1895 return a
1896