mercurial/manifest.py
branchstable
changeset 42378 c3484ddbdb96
parent 42377 0546ead39a7e
child 42380 12bd4e2d4d06
equal deleted inserted replaced
42377:0546ead39a7e 42378:c3484ddbdb96
   124 
   124 
   125 def _cmp(a, b):
   125 def _cmp(a, b):
   126     return (a > b) - (a < b)
   126     return (a > b) - (a < b)
   127 
   127 
   128 class _lazymanifest(object):
   128 class _lazymanifest(object):
       
   129     """A pure python manifest backed by a byte string.  It is supplimented with
       
   130     internal lists as it is modified, until it is compacted back to a pure byte
       
   131     string.
       
   132 
       
   133     ``data`` is the initial manifest data.
       
   134 
       
   135     ``positions`` is a list of offsets, one per manifest entry.  Positive
       
   136     values are offsets into ``data``, negative values are offsets into the
       
   137     ``extradata`` list.  When an entry is removed, its entry is dropped from
       
   138     ``positions``.  The values are encoded such that when walking the list and
       
   139     indexing into ``data`` or ``extradata`` as appropriate, the entries are
       
   140     sorted by filename.
       
   141 
       
   142     ``extradata`` is a list of (key, hash, flags) for entries that were added or
       
   143     modified since the manifest was created or compacted.
       
   144     """
   129     def __init__(self, data, positions=None, extrainfo=None, extradata=None,
   145     def __init__(self, data, positions=None, extrainfo=None, extradata=None,
   130                  hasremovals=False):
   146                  hasremovals=False):
   131         if positions is None:
   147         if positions is None:
   132             self.positions = self.findlines(data)
   148             self.positions = self.findlines(data)
   133             self.extrainfo = [0] * len(self.positions)
   149             self.extrainfo = [0] * len(self.positions)
   244             raise KeyError
   260             raise KeyError
   245         cur = self.positions[needle]
   261         cur = self.positions[needle]
   246         self.positions = self.positions[:needle] + self.positions[needle + 1:]
   262         self.positions = self.positions[:needle] + self.positions[needle + 1:]
   247         self.extrainfo = self.extrainfo[:needle] + self.extrainfo[needle + 1:]
   263         self.extrainfo = self.extrainfo[:needle] + self.extrainfo[needle + 1:]
   248         if cur >= 0:
   264         if cur >= 0:
       
   265             # This does NOT unsort the list as far as the search functions are
       
   266             # concerned, as they only examine lines mapped by self.positions.
   249             self.data = self.data[:cur] + '\x00' + self.data[cur + 1:]
   267             self.data = self.data[:cur] + '\x00' + self.data[cur + 1:]
   250             self.hasremovals = True
   268             self.hasremovals = True
   251 
   269 
   252     def __setitem__(self, key, value):
   270     def __setitem__(self, key, value):
   253         if not isinstance(key, bytes):
   271         if not isinstance(key, bytes):
   295         self.extrainfo = [0] * len(self.positions)
   313         self.extrainfo = [0] * len(self.positions)
   296         while i < len(self.positions):
   314         while i < len(self.positions):
   297             if self.positions[i] >= 0:
   315             if self.positions[i] >= 0:
   298                 cur = self.positions[i]
   316                 cur = self.positions[i]
   299                 last_cut = cur
   317                 last_cut = cur
       
   318 
       
   319                 # Collect all contiguous entries in the buffer at the current
       
   320                 # offset, breaking out only for added/modified items held in
       
   321                 # extradata, or a deleted line prior to the next position.
   300                 while True:
   322                 while True:
   301                     self.positions[i] = offset
   323                     self.positions[i] = offset
   302                     i += 1
   324                     i += 1
   303                     if i == len(self.positions) or self.positions[i] < 0:
   325                     if i == len(self.positions) or self.positions[i] < 0:
   304                         break
   326                         break