comparison mercurial/changelog.py @ 9166:e6162b854ed5

changelog: move delayopener outside of class to eliminate reference cycle
author Matt Mackall <mpm@selenic.com>
date Sat, 18 Jul 2009 12:34:38 -0500
parents 07f9b2f4a9aa
children 0c072e63e3e7
comparison
equal deleted inserted replaced
9165:07f9b2f4a9aa 9166:e6162b854ed5
85 85
86 def write(self, s): 86 def write(self, s):
87 self.data.append(str(s)) 87 self.data.append(str(s))
88 self.offset += len(s) 88 self.offset += len(s)
89 89
90 def delayopener(opener, target, divert, buf):
91 def o(name, mode='r'):
92 if name != target:
93 return opener(name, mode)
94 if divert:
95 return opener(name + ".a", mode.replace('a', 'w'))
96 # otherwise, divert to memory
97 return appender(opener(name, mode), buf)
98 return o
99
90 class changelog(revlog.revlog): 100 class changelog(revlog.revlog):
91 def __init__(self, opener): 101 def __init__(self, opener):
92 revlog.revlog.__init__(self, opener, "00changelog.i") 102 revlog.revlog.__init__(self, opener, "00changelog.i")
93 self._realopener = opener 103 self._realopener = opener
94 self._delayed = False 104 self._delayed = False
97 def delayupdate(self): 107 def delayupdate(self):
98 "delay visibility of index updates to other readers" 108 "delay visibility of index updates to other readers"
99 self._delayed = True 109 self._delayed = True
100 self._divert = (len(self) == 0) 110 self._divert = (len(self) == 0)
101 self._delaybuf = [] 111 self._delaybuf = []
102 self.opener = self._delayopener 112 self.opener = delayopener(self._realopener, self.indexfile,
113 self._divert, self._delaybuf)
103 114
104 def finalize(self, tr): 115 def finalize(self, tr):
105 "finalize index updates" 116 "finalize index updates"
106 self._delayed = False 117 self._delayed = False
107 self.opener = self._realopener 118 self.opener = self._realopener
108 # move redirected index data back into place 119 # move redirected index data back into place
109 if self._divert: 120 if self._divert:
110 n = self._realopener(self.indexfile).name 121 n = self.opener(self.indexfile + ".a").name
111 util.rename(n + ".a", n) 122 util.rename(n, n[:-2])
112 elif self._delaybuf: 123 elif self._delaybuf:
113 fp = self.opener(self.indexfile, 'a') 124 fp = self.opener(self.indexfile, 'a')
114 fp.write("".join(self._delaybuf)) 125 fp.write("".join(self._delaybuf))
115 fp.close() 126 fp.close()
116 self._delaybuf = [] 127 self._delaybuf = []
117 # split when we're done 128 # split when we're done
118 self.checkinlinesize(tr) 129 self.checkinlinesize(tr)
119
120 def _delayopener(self, name, mode='r'):
121 fp = self._realopener(name, mode)
122 # only divert the index
123 if not name == self.indexfile:
124 return fp
125 # if we're doing an initial clone, divert to another file
126 if self._divert:
127 if not len(self):
128 # make sure to truncate the file
129 mode = mode.replace('a', 'w')
130 return self._realopener(name + ".a", mode)
131 # otherwise, divert to memory
132 return appender(fp, self._delaybuf)
133 130
134 def readpending(self, file): 131 def readpending(self, file):
135 r = revlog.revlog(self.opener, file) 132 r = revlog.revlog(self.opener, file)
136 self.index = r.index 133 self.index = r.index
137 self.nodemap = r.nodemap 134 self.nodemap = r.nodemap