44 # whether the changeset changes the file path (ie. is a rename) |
44 # whether the changeset changes the file path (ie. is a rename) |
45 renameflag = 2 |
45 renameflag = 2 |
46 |
46 |
47 # len(mercurial.node.nullid) |
47 # len(mercurial.node.nullid) |
48 _hshlen = 20 |
48 _hshlen = 20 |
|
49 |
49 |
50 |
50 class revmap(object): |
51 class revmap(object): |
51 """trivial hg bin hash - linelog rev bidirectional map |
52 """trivial hg bin hash - linelog rev bidirectional map |
52 |
53 |
53 also stores a flag (uint8) for each revision, and track renames. |
54 also stores a flag (uint8) for each revision, and track renames. |
155 |
156 |
156 def flush(self): |
157 def flush(self): |
157 """write the state down to the file""" |
158 """write the state down to the file""" |
158 if not self.path: |
159 if not self.path: |
159 return |
160 return |
160 if self._lastmaxrev == -1: # write the entire file |
161 if self._lastmaxrev == -1: # write the entire file |
161 with open(self.path, 'wb') as f: |
162 with open(self.path, 'wb') as f: |
162 f.write(self.HEADER) |
163 f.write(self.HEADER) |
163 for i in pycompat.xrange(1, len(self._rev2hsh)): |
164 for i in pycompat.xrange(1, len(self._rev2hsh)): |
164 self._writerev(i, f) |
165 self._writerev(i, f) |
165 else: # append incrementally |
166 else: # append incrementally |
166 with open(self.path, 'ab') as f: |
167 with open(self.path, 'ab') as f: |
167 for i in pycompat.xrange(self._lastmaxrev + 1, |
168 for i in pycompat.xrange( |
168 len(self._rev2hsh)): |
169 self._lastmaxrev + 1, len(self._rev2hsh) |
|
170 ): |
169 self._writerev(i, f) |
171 self._writerev(i, f) |
170 self._lastmaxrev = self.maxrev |
172 self._lastmaxrev = self.maxrev |
171 |
173 |
172 def _load(self): |
174 def _load(self): |
173 """load state from file""" |
175 """load state from file""" |
227 def __contains__(self, f): |
229 def __contains__(self, f): |
228 """(fctx or (node, path)) -> bool. |
230 """(fctx or (node, path)) -> bool. |
229 test if (node, path) is in the map, and is not in a side branch. |
231 test if (node, path) is in the map, and is not in a side branch. |
230 f can be either a tuple of (node, path), or a fctx. |
232 f can be either a tuple of (node, path), or a fctx. |
231 """ |
233 """ |
232 if isinstance(f, tuple): # f: (node, path) |
234 if isinstance(f, tuple): # f: (node, path) |
233 hsh, path = f |
235 hsh, path = f |
234 else: # f: fctx |
236 else: # f: fctx |
235 hsh, path = f.node(), f.path() |
237 hsh, path = f.node(), f.path() |
236 rev = self.hsh2rev(hsh) |
238 rev = self.hsh2rev(hsh) |
237 if rev is None: |
239 if rev is None: |
238 return False |
240 return False |
239 if path is not None and path != self.rev2path(rev): |
241 if path is not None and path != self.rev2path(rev): |
240 return False |
242 return False |
241 return (self.rev2flag(rev) & sidebranchflag) == 0 |
243 return (self.rev2flag(rev) & sidebranchflag) == 0 |
|
244 |
242 |
245 |
243 def getlastnode(path): |
246 def getlastnode(path): |
244 """return the last hash in a revmap, without loading its full content. |
247 """return the last hash in a revmap, without loading its full content. |
245 this is equivalent to `m = revmap(path); m.rev2hsh(m.maxrev)`, but faster. |
248 this is equivalent to `m = revmap(path); m.rev2hsh(m.maxrev)`, but faster. |
246 """ |
249 """ |