comparison mercurial/changelog.py @ 30596:be520fe3a3e9

changelog: keep track of file end in appender (issue5444) Previously, changelog.appender.end() would compute the end of the file by joining all the current appended data and checking the length. This is an O(n) operation. e240e914d226 introduced a seek call before every revlog write, which means we are hitting this O(n) behavior n times, which causes changelog writes during a pull to be n^2. In our large repo, this caused pulling 100k commits to go from 17s to 130s. With this fix, it's back to 17s.
author Durham Goode <durham@fb.com>
date Thu, 15 Dec 2016 11:00:18 -0800
parents 5e4f16874a9f
children afb335353d28
comparison
equal deleted inserted replaced
30595:99bd5479d58b 30596:be520fe3a3e9
77 self.data = buf 77 self.data = buf
78 fp = vfs(name, mode) 78 fp = vfs(name, mode)
79 self.fp = fp 79 self.fp = fp
80 self.offset = fp.tell() 80 self.offset = fp.tell()
81 self.size = vfs.fstat(fp).st_size 81 self.size = vfs.fstat(fp).st_size
82 self._end = self.size
82 83
83 def end(self): 84 def end(self):
84 return self.size + len("".join(self.data)) 85 return self._end
85 def tell(self): 86 def tell(self):
86 return self.offset 87 return self.offset
87 def flush(self): 88 def flush(self):
88 pass 89 pass
89 def close(self): 90 def close(self):
119 return ret 120 return ret
120 121
121 def write(self, s): 122 def write(self, s):
122 self.data.append(str(s)) 123 self.data.append(str(s))
123 self.offset += len(s) 124 self.offset += len(s)
125 self._end += len(s)
124 126
125 def _divertopener(opener, target): 127 def _divertopener(opener, target):
126 """build an opener that writes in 'target.a' instead of 'target'""" 128 """build an opener that writes in 'target.a' instead of 'target'"""
127 def _divert(name, mode='r', checkambig=False): 129 def _divert(name, mode='r', checkambig=False):
128 if name != target: 130 if name != target: