# HG changeset patch # User Pierre-Yves David # Date 2012-07-04 00:00:36 # Node ID f1b7683f3f9537362cdfc17791db771844e5dadf # Parent 8e030168b09ed6edaddb2a2472f149761a2f8284 obsolete: move obsolete markers read/write logic to obsstore object This is the first step toward incremental writing of obsolete marker within a transaction. For this purpose, obsstore is now given its repo sopener. This make it able to handles read and write to the obsstore file itself. Most IO logic is removed from localrepo and handled by obsstore object directly. diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -193,10 +193,7 @@ class localrepository(repo.repository): @storecache('obsstore') def obsstore(self): - store = obsolete.obsstore() - data = self.sopener.tryread('obsstore') - if data: - store.loadmarkers(data) + store = obsolete.obsstore(self.sopener) return store @storecache('00changelog.i') @@ -990,16 +987,8 @@ class localrepository(repo.repository): self.store.write() if '_phasecache' in vars(self): self._phasecache.write() - if 'obsstore' in vars(self) and self.obsstore._new: - # XXX: transaction logic should be used here. But for - # now rewriting the whole file is good enough. - f = self.sopener('obsstore', 'wb', atomictemp=True) - try: - self.obsstore.flushmarkers(f) - f.close() - except: # re-raises - f.discard() - raise + if 'obsstore' in vars(self): + self.obsstore.flushmarkers() for k, ce in self._filecache.items(): if k == 'dirstate': continue diff --git a/mercurial/obsolete.py b/mercurial/obsolete.py --- a/mercurial/obsolete.py +++ b/mercurial/obsolete.py @@ -156,12 +156,17 @@ class obsstore(object): - successors: new -> set(old) """ - def __init__(self): + def __init__(self, sopener): self._all = [] # new markers to serialize self._new = [] self.precursors = {} self.successors = {} + self.sopener = sopener + data = sopener.tryread('obsstore') + if data: + for marker in _readmarkers(data): + self._load(marker) def __iter__(self): return iter(self._all) @@ -193,11 +198,6 @@ class obsstore(object): self._new.append(marker) self._load(marker) - def loadmarkers(self, data): - """Load all markers in data, mark them as known.""" - for marker in _readmarkers(data): - self._load(marker) - def mergemarkers(self, data): other = set(_readmarkers(data)) local = set(self._all) @@ -205,12 +205,21 @@ class obsstore(object): for marker in new: self.add(marker) - def flushmarkers(self, stream): - """Write all markers to a stream + def flushmarkers(self): + """Write all markers on disk After this operation, "new" markers are considered "known".""" - self._writemarkers(stream) - self._new[:] = [] + if self._new: + # XXX: transaction logic should be used here. But for + # now rewriting the whole file is good enough. + f = self.sopener('obsstore', 'wb', atomictemp=True) + try: + self._writemarkers(f) + f.close() + self._new[:] = [] + except: # re-raises + f.discard() + raise def _load(self, marker): self._all.append(marker)