mercurial/obsolete.py
changeset 17220 bdac214a4705
parent 17219 494a970f68de
child 17253 67f56ff5afcd
equal deleted inserted replaced
17219:494a970f68de 17220:bdac214a4705
   162         self.precursors = {}
   162         self.precursors = {}
   163         self.successors = {}
   163         self.successors = {}
   164         self.sopener = sopener
   164         self.sopener = sopener
   165         data = sopener.tryread('obsstore')
   165         data = sopener.tryread('obsstore')
   166         if data:
   166         if data:
   167             for marker in _readmarkers(data):
   167             self._load(_readmarkers(data))
   168                 self._load(marker)
       
   169 
   168 
   170     def __iter__(self):
   169     def __iter__(self):
   171         return iter(self._all)
   170         return iter(self._all)
   172 
   171 
   173     def __nonzero__(self):
   172     def __nonzero__(self):
   186             raise ValueError(prec)
   185             raise ValueError(prec)
   187         for succ in succs:
   186         for succ in succs:
   188             if len(succ) != 20:
   187             if len(succ) != 20:
   189                 raise ValueError(succ)
   188                 raise ValueError(succ)
   190         marker = (str(prec), tuple(succs), int(flag), encodemeta(metadata))
   189         marker = (str(prec), tuple(succs), int(flag), encodemeta(metadata))
   191         self.add(transaction, marker)
   190         self.add(transaction, [marker])
   192 
   191 
   193     def add(self, transaction, marker):
   192     def add(self, transaction, markers):
   194         """Add a new marker to the store"""
   193         """Add new markers to the store
   195         if marker not in self._all:
   194 
       
   195         Take care of filtering duplicate.
       
   196         Return the number of new marker."""
       
   197         new = [m for m in markers if m not in self._all]
       
   198         if new:
   196             f = self.sopener('obsstore', 'ab')
   199             f = self.sopener('obsstore', 'ab')
   197             try:
   200             try:
   198                 # Whether the file's current position is at the begin or at
   201                 # Whether the file's current position is at the begin or at
   199                 # the end after opening a file for appending is implementation
   202                 # the end after opening a file for appending is implementation
   200                 # defined. So we must seek to the end before calling tell(),
   203                 # defined. So we must seek to the end before calling tell(),
   202                 # some platforms (issue3543).
   205                 # some platforms (issue3543).
   203                 f.seek(0, 2) # os.SEEK_END
   206                 f.seek(0, 2) # os.SEEK_END
   204                 offset = f.tell()
   207                 offset = f.tell()
   205                 transaction.add('obsstore', offset)
   208                 transaction.add('obsstore', offset)
   206                 # offset == 0: new file - add the version header
   209                 # offset == 0: new file - add the version header
   207                 for bytes in _encodemarkers([marker], offset == 0):
   210                 for bytes in _encodemarkers(new, offset == 0):
   208                     f.write(bytes)
   211                     f.write(bytes)
   209             finally:
   212             finally:
   210                 # XXX: f.close() == filecache invalidation == obsstore rebuilt.
   213                 # XXX: f.close() == filecache invalidation == obsstore rebuilt.
   211                 # call 'filecacheentry.refresh()'  here
   214                 # call 'filecacheentry.refresh()'  here
   212                 f.close()
   215                 f.close()
   213             self._load(marker)
   216             self._load(new)
       
   217         return len(new)
   214 
   218 
   215     def mergemarkers(self, transation, data):
   219     def mergemarkers(self, transation, data):
   216         other = _readmarkers(data)
   220         markers = _readmarkers(data)
   217         local = set(self._all)
   221         self.add(transation, markers)
   218         new = [m for m in other if m not in local]
   222 
   219         for marker in new:
   223     def _load(self, markers):
   220             # XXX: N marker == N x (open, write, close)
   224         for mark in markers:
   221             # we should write them all at once
   225             self._all.append(mark)
   222             self.add(transation, marker)
   226             pre, sucs = mark[:2]
   223 
   227             self.precursors.setdefault(pre, set()).add(mark)
   224     def _load(self, marker):
   228             for suc in sucs:
   225         self._all.append(marker)
   229                 self.successors.setdefault(suc, set()).add(mark)
   226         pre, sucs = marker[:2]
       
   227         self.precursors.setdefault(pre, set()).add(marker)
       
   228         for suc in sucs:
       
   229             self.successors.setdefault(suc, set()).add(marker)
       
   230 
   230 
   231 def _encodemarkers(markers, addheader=False):
   231 def _encodemarkers(markers, addheader=False):
   232     # Kept separate from flushmarkers(), it will be reused for
   232     # Kept separate from flushmarkers(), it will be reused for
   233     # markers exchange.
   233     # markers exchange.
   234     if addheader:
   234     if addheader: