106 |
106 |
107 def write(self, s): |
107 def write(self, s): |
108 self.data.append(str(s)) |
108 self.data.append(str(s)) |
109 self.offset += len(s) |
109 self.offset += len(s) |
110 |
110 |
111 def delayopener(opener, target, divert, buf): |
111 def _divertopener(opener, target): |
112 def o(name, mode='r'): |
112 """build an opener that writes in 'target.a' instead of 'target'""" |
|
113 def _divert(name, mode='r'): |
113 if name != target: |
114 if name != target: |
114 return opener(name, mode) |
115 return opener(name, mode) |
115 if divert: |
116 return opener(name + ".a", mode) |
116 return opener(name + ".a", mode.replace('a', 'w')) |
117 return _divert |
117 # otherwise, divert to memory |
118 |
|
119 def _delayopener(opener, target, buf): |
|
120 """build an opener that stores chunks in 'buf' instead of 'target'""" |
|
121 def _delay(name, mode='r'): |
|
122 if name != target: |
|
123 return opener(name, mode) |
118 return appender(opener, name, mode, buf) |
124 return appender(opener, name, mode, buf) |
119 return o |
125 return _delay |
120 |
126 |
121 class changelog(revlog.revlog): |
127 class changelog(revlog.revlog): |
122 def __init__(self, opener): |
128 def __init__(self, opener): |
123 revlog.revlog.__init__(self, opener, "00changelog.i") |
129 revlog.revlog.__init__(self, opener, "00changelog.i") |
124 if self._initempty: |
130 if self._initempty: |
125 # changelogs don't benefit from generaldelta |
131 # changelogs don't benefit from generaldelta |
126 self.version &= ~revlog.REVLOGGENERALDELTA |
132 self.version &= ~revlog.REVLOGGENERALDELTA |
127 self._generaldelta = False |
133 self._generaldelta = False |
128 self._realopener = opener |
134 self._realopener = opener |
129 self._delayed = False |
135 self._delayed = False |
130 self._delaybuf = [] |
136 self._delaybuf = None |
131 self._divert = False |
137 self._divert = False |
132 self.filteredrevs = frozenset() |
138 self.filteredrevs = frozenset() |
133 |
139 |
134 def tip(self): |
140 def tip(self): |
135 """filtered version of revlog.tip""" |
141 """filtered version of revlog.tip""" |
218 raise error.FilteredIndexError(rev) |
224 raise error.FilteredIndexError(rev) |
219 return super(changelog, self).flags(rev) |
225 return super(changelog, self).flags(rev) |
220 |
226 |
221 def delayupdate(self): |
227 def delayupdate(self): |
222 "delay visibility of index updates to other readers" |
228 "delay visibility of index updates to other readers" |
|
229 |
|
230 if not self._delayed: |
|
231 if len(self) == 0: |
|
232 self._divert = True |
|
233 if self._realopener.exists(self.indexfile + '.a'): |
|
234 self._realopener.unlink(self.indexfile + '.a') |
|
235 self.opener = _divertopener(self._realopener, self.indexfile) |
|
236 else: |
|
237 self._delaybuf = [] |
|
238 self.opener = _delayopener(self._realopener, self.indexfile, |
|
239 self._delaybuf) |
223 self._delayed = True |
240 self._delayed = True |
224 self._divert = (len(self) == 0) |
|
225 self._delaybuf = [] |
|
226 self.opener = delayopener(self._realopener, self.indexfile, |
|
227 self._divert, self._delaybuf) |
|
228 |
241 |
229 def finalize(self, tr): |
242 def finalize(self, tr): |
230 "finalize index updates" |
243 "finalize index updates" |
231 self._delayed = False |
244 self._delayed = False |
232 self.opener = self._realopener |
245 self.opener = self._realopener |
233 # move redirected index data back into place |
246 # move redirected index data back into place |
234 if self._divert: |
247 if self._divert: |
|
248 assert not self._delaybuf |
235 tmpname = self.indexfile + ".a" |
249 tmpname = self.indexfile + ".a" |
236 nfile = self.opener.open(tmpname) |
250 nfile = self.opener.open(tmpname) |
237 nfile.close() |
251 nfile.close() |
238 self.opener.rename(tmpname, self.indexfile) |
252 self.opener.rename(tmpname, self.indexfile) |
239 elif self._delaybuf: |
253 elif self._delaybuf: |
240 fp = self.opener(self.indexfile, 'a') |
254 fp = self.opener(self.indexfile, 'a') |
241 fp.write("".join(self._delaybuf)) |
255 fp.write("".join(self._delaybuf)) |
242 fp.close() |
256 fp.close() |
243 self._delaybuf = [] |
257 self._delaybuf = None |
|
258 self._divert = False |
244 # split when we're done |
259 # split when we're done |
245 self.checkinlinesize(tr) |
260 self.checkinlinesize(tr) |
246 |
261 |
247 def readpending(self, file): |
262 def readpending(self, file): |
248 r = revlog.revlog(self.opener, file) |
263 r = revlog.revlog(self.opener, file) |