##// END OF EJS Templates
Implement revlogng....
mason@suse.com -
r2072:74d3f533 default
parent child Browse files
Show More
@@ -11,8 +11,9 from demandload import demandload
11 demandload(globals(), "os time util")
11 demandload(globals(), "os time util")
12
12
13 class changelog(revlog):
13 class changelog(revlog):
14 def __init__(self, opener):
14 def __init__(self, opener, defversion=0):
15 revlog.__init__(self, opener, "00changelog.i", "00changelog.d")
15 revlog.__init__(self, opener, "00changelog.i", "00changelog.d",
16 defversion)
16
17
17 def extract(self, text):
18 def extract(self, text):
18 if not text:
19 if not text:
@@ -1268,7 +1268,7 def copy(ui, repo, *pats, **opts):
1268
1268
1269 def debugancestor(ui, index, rev1, rev2):
1269 def debugancestor(ui, index, rev1, rev2):
1270 """find the ancestor revision of two revisions in a given index"""
1270 """find the ancestor revision of two revisions in a given index"""
1271 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index, "")
1271 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index, "", 0)
1272 a = r.ancestor(r.lookup(rev1), r.lookup(rev2))
1272 a = r.ancestor(r.lookup(rev1), r.lookup(rev2))
1273 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1273 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1274
1274
@@ -1372,7 +1372,7 def debugstate(ui, repo):
1372 def debugdata(ui, file_, rev):
1372 def debugdata(ui, file_, rev):
1373 """dump the contents of an data file revision"""
1373 """dump the contents of an data file revision"""
1374 r = revlog.revlog(util.opener(os.getcwd(), audit=False),
1374 r = revlog.revlog(util.opener(os.getcwd(), audit=False),
1375 file_[:-2] + ".i", file_)
1375 file_[:-2] + ".i", file_, 0)
1376 try:
1376 try:
1377 ui.write(r.revision(r.lookup(rev)))
1377 ui.write(r.revision(r.lookup(rev)))
1378 except KeyError:
1378 except KeyError:
@@ -1380,18 +1380,19 def debugdata(ui, file_, rev):
1380
1380
1381 def debugindex(ui, file_):
1381 def debugindex(ui, file_):
1382 """dump the contents of an index file"""
1382 """dump the contents of an index file"""
1383 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_, "")
1383 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_, "", 0)
1384 ui.write(" rev offset length base linkrev" +
1384 ui.write(" rev offset length base linkrev" +
1385 " nodeid p1 p2\n")
1385 " nodeid p1 p2\n")
1386 for i in range(r.count()):
1386 for i in range(r.count()):
1387 e = r.index[i]
1387 node = r.node(i)
1388 pp = r.parents(node)
1388 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1389 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1389 i, e[0], e[1], e[2], e[3],
1390 i, r.start(i), r.length(i), r.base(i), r.linkrev(node),
1390 short(e[6]), short(e[4]), short(e[5])))
1391 short(node), short(pp[0]), short(pp[1])))
1391
1392
1392 def debugindexdot(ui, file_):
1393 def debugindexdot(ui, file_):
1393 """dump an index DAG as a .dot file"""
1394 """dump an index DAG as a .dot file"""
1394 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_, "")
1395 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_, "", 0)
1395 ui.write("digraph G {\n")
1396 ui.write("digraph G {\n")
1396 for i in range(r.count()):
1397 for i in range(r.count()):
1397 e = r.index[i]
1398 e = r.index[i]
@@ -11,10 +11,11 from demandload import *
11 demandload(globals(), "bdiff")
11 demandload(globals(), "bdiff")
12
12
13 class filelog(revlog):
13 class filelog(revlog):
14 def __init__(self, opener, path):
14 def __init__(self, opener, path, defversion=0):
15 revlog.__init__(self, opener,
15 revlog.__init__(self, opener,
16 os.path.join("data", self.encodedir(path + ".i")),
16 os.path.join("data", self.encodedir(path + ".i")),
17 os.path.join("data", self.encodedir(path + ".d")))
17 os.path.join("data", self.encodedir(path + ".d")),
18 defversion)
18
19
19 # This avoids a collision between a file named foo and a dir named
20 # This avoids a collision between a file named foo and a dir named
20 # foo.i or foo.d
21 # foo.i or foo.d
@@ -10,8 +10,8 import filelog, manifest, changelog, dir
10 from node import *
10 from node import *
11 from i18n import gettext as _
11 from i18n import gettext as _
12 from demandload import *
12 from demandload import *
13 demandload(globals(), "re lock transaction tempfile stat mdiff errno ui")
14 demandload(globals(), "appendfile changegroup")
13 demandload(globals(), "appendfile changegroup")
14 demandload(globals(), "re lock transaction tempfile stat mdiff errno ui revlog")
15
15
16 class localrepository(object):
16 class localrepository(object):
17 def __del__(self):
17 def __del__(self):
@@ -35,8 +35,20 class localrepository(object):
35 self.ui = ui.ui(parentui=parentui)
35 self.ui = ui.ui(parentui=parentui)
36 self.opener = util.opener(self.path)
36 self.opener = util.opener(self.path)
37 self.wopener = util.opener(self.root)
37 self.wopener = util.opener(self.root)
38 self.manifest = manifest.manifest(self.opener)
38
39 self.changelog = changelog.changelog(self.opener)
39 try:
40 self.ui.readconfig(self.join("hgrc"), self.root)
41 except IOError:
42 pass
43
44 v = self.ui.revlogopts
45 self.revlogversion = int(v.get('format', 0))
46 for x in v.get('flags', "").split():
47 self.revlogversion |= revlog.flagstr(x)
48
49 self.manifest = manifest.manifest(self.opener, self.revlogversion)
50 self.changelog = changelog.changelog(self.opener, self.revlogversion)
51 self.revlogversion = self.changelog.version
40 self.tagscache = None
52 self.tagscache = None
41 self.nodetagscache = None
53 self.nodetagscache = None
42 self.encodepats = None
54 self.encodepats = None
@@ -48,11 +60,6 class localrepository(object):
48 os.mkdir(self.join("data"))
60 os.mkdir(self.join("data"))
49
61
50 self.dirstate = dirstate.dirstate(self.opener, self.ui, self.root)
62 self.dirstate = dirstate.dirstate(self.opener, self.ui, self.root)
51 try:
52 self.ui.readconfig(self.join("hgrc"), self.root)
53 except IOError:
54 pass
55
56 def hook(self, name, throw=False, **args):
63 def hook(self, name, throw=False, **args):
57 def runhook(name, cmd):
64 def runhook(name, cmd):
58 self.ui.note(_("running hook %s: %s\n") % (name, cmd))
65 self.ui.note(_("running hook %s: %s\n") % (name, cmd))
@@ -167,7 +174,7 class localrepository(object):
167 def file(self, f):
174 def file(self, f):
168 if f[0] == '/':
175 if f[0] == '/':
169 f = f[1:]
176 f = f[1:]
170 return filelog.filelog(self.opener, f)
177 return filelog.filelog(self.opener, f, self.revlogversion)
171
178
172 def getcwd(self):
179 def getcwd(self):
173 return self.dirstate.getcwd()
180 return self.dirstate.getcwd()
@@ -12,10 +12,11 from demandload import *
12 demandload(globals(), "bisect array")
12 demandload(globals(), "bisect array")
13
13
14 class manifest(revlog):
14 class manifest(revlog):
15 def __init__(self, opener):
15 def __init__(self, opener, defversion=0):
16 self.mapcache = None
16 self.mapcache = None
17 self.listcache = None
17 self.listcache = None
18 revlog.__init__(self, opener, "00manifest.i", "00manifest.d")
18 revlog.__init__(self, opener, "00manifest.i", "00manifest.d",
19 defversion)
19
20
20 def read(self, node):
21 def read(self, node):
21 if node == nullid: return {} # don't upset local cache
22 if node == nullid: return {} # don't upset local cache
@@ -16,6 +16,10 from demandload import demandload
16 demandload(globals(), "binascii changegroup errno heapq mdiff os")
16 demandload(globals(), "binascii changegroup errno heapq mdiff os")
17 demandload(globals(), "sha struct zlib")
17 demandload(globals(), "sha struct zlib")
18
18
19 # revlog version strings
20 REVLOGV0 = 0
21 REVLOGNG = 1
22
19 def hash(text, p1, p2):
23 def hash(text, p1, p2):
20 """generate a hash from the given text and its parent hashes
24 """generate a hash from the given text and its parent hashes
21
25
@@ -51,7 +55,19 def decompress(bin):
51 if t == 'u': return bin[1:]
55 if t == 'u': return bin[1:]
52 raise RevlogError(_("unknown compression type %r") % t)
56 raise RevlogError(_("unknown compression type %r") % t)
53
57
54 indexformat = ">4l20s20s20s"
58 indexformatv0 = ">4l20s20s20s"
59 # index ng:
60 # 6 bytes offset
61 # 2 bytes flags
62 # 4 bytes compressed length
63 # 4 bytes uncompressed length
64 # 4 bytes: base rev
65 # 4 bytes link rev
66 # 4 bytes parent 1 rev
67 # 4 bytes parent 2 rev
68 # 32 bytes: nodeid
69 indexformatng = ">Qiiiiii20s12x"
70 versionformat = ">i"
55
71
56 class lazyparser(object):
72 class lazyparser(object):
57 """
73 """
@@ -63,18 +79,16 class lazyparser(object):
63 the lazy objects in revlog with the underlying objects for
79 the lazy objects in revlog with the underlying objects for
64 efficiency in cases where we look at most of the nodes.
80 efficiency in cases where we look at most of the nodes.
65 """
81 """
66 def __init__(self, data, revlog):
82 def __init__(self, data, revlog, indexformat):
67 self.data = data
83 self.data = data
68 self.s = struct.calcsize(indexformat)
84 self.s = struct.calcsize(indexformat)
85 self.indexformat = indexformat
69 self.l = len(data)/self.s
86 self.l = len(data)/self.s
70 self.index = [None] * self.l
87 self.index = [None] * self.l
71 self.map = {nullid: -1}
88 self.map = {nullid: -1}
72 self.all = 0
89 self.all = 0
73 self.revlog = revlog
90 self.revlog = revlog
74
91
75 def trunc(self, pos):
76 self.l = pos/self.s
77
78 def load(self, pos=None):
92 def load(self, pos=None):
79 if self.all: return
93 if self.all: return
80 if pos is not None:
94 if pos is not None:
@@ -89,10 +103,11 class lazyparser(object):
89 self.revlog.nodemap = self.map
103 self.revlog.nodemap = self.map
90
104
91 while i < end:
105 while i < end:
106 if not self.index[i]:
92 d = self.data[i * self.s: (i + 1) * self.s]
107 d = self.data[i * self.s: (i + 1) * self.s]
93 e = struct.unpack(indexformat, d)
108 e = struct.unpack(self.indexformat, d)
94 self.index[i] = e
109 self.index[i] = e
95 self.map[e[6]] = i
110 self.map[e[-1]] = i
96 i += 1
111 i += 1
97
112
98 class lazyindex(object):
113 class lazyindex(object):
@@ -108,12 +123,12 class lazyindex(object):
108 return self.p.index[pos]
123 return self.p.index[pos]
109 def __getitem__(self, pos):
124 def __getitem__(self, pos):
110 return self.p.index[pos] or self.load(pos)
125 return self.p.index[pos] or self.load(pos)
126 def __setitem__(self, pos, item):
127 self.p.index[pos] = item
111 def __delitem__(self, pos):
128 def __delitem__(self, pos):
112 del self.p.index[pos]
129 del self.p.index[pos]
113 def append(self, e):
130 def append(self, e):
114 self.p.index.append(e)
131 self.p.index.append(e)
115 def trunc(self, pos):
116 self.p.trunc(pos)
117
132
118 class lazymap(object):
133 class lazymap(object):
119 """a lazy version of the node map"""
134 """a lazy version of the node map"""
@@ -133,10 +148,10 class lazymap(object):
133 yield nullid
148 yield nullid
134 for i in xrange(self.p.l):
149 for i in xrange(self.p.l):
135 try:
150 try:
136 yield self.p.index[i][6]
151 yield self.p.index[i][-1]
137 except:
152 except:
138 self.p.load(i)
153 self.p.load(i)
139 yield self.p.index[i][6]
154 yield self.p.index[i][-1]
140 def __getitem__(self, key):
155 def __getitem__(self, key):
141 try:
156 try:
142 return self.p.map[key]
157 return self.p.map[key]
@@ -178,7 +193,7 class revlog(object):
178 remove data, and can use some simple techniques to avoid the need
193 remove data, and can use some simple techniques to avoid the need
179 for locking while reading.
194 for locking while reading.
180 """
195 """
181 def __init__(self, opener, indexfile, datafile):
196 def __init__(self, opener, indexfile, datafile, defversion=0):
182 """
197 """
183 create a revlog object
198 create a revlog object
184
199
@@ -192,11 +207,14 class revlog(object):
192 self.indexstat = None
207 self.indexstat = None
193 self.cache = None
208 self.cache = None
194 self.chunkcache = None
209 self.chunkcache = None
210 self.defversion = defversion
195 self.load()
211 self.load()
196
212
197 def load(self):
213 def load(self):
214 v = self.defversion
198 try:
215 try:
199 f = self.opener(self.indexfile)
216 f = self.opener(self.indexfile)
217 i = f.read()
200 except IOError, inst:
218 except IOError, inst:
201 if inst.errno != errno.ENOENT:
219 if inst.errno != errno.ENOENT:
202 raise
220 raise
@@ -214,55 +232,102 class revlog(object):
214 and st.st_ctime == oldst.st_ctime):
232 and st.st_ctime == oldst.st_ctime):
215 return
233 return
216 self.indexstat = st
234 self.indexstat = st
217 i = f.read()
235 if len(i) > 0:
236 v = struct.unpack(versionformat, i[:4])[0]
237 if v != 0:
238 flags = v & ~0xFFFF
239 fmt = v & 0xFFFF
240 if fmt != REVLOGNG or (flags & ~(REVLOGNGINLINEDATA)):
241 raise RevlogError(
242 _("unknown version format %d or flags %x on %s") %
243 (v, flags, self.indexfile))
244 self.version = v
245 if v == 0:
246 self.indexformat = indexformatv0
247 else:
248 self.indexformat = indexformatng
218
249
219 if i and i[:4] != "\0\0\0\0":
250 if i:
220 raise RevlogError(_("incompatible revlog signature on %s") %
251 if st and st.st_size > 10000:
221 self.indexfile)
222
223 if len(i) > 10000:
224 # big index, let's parse it on demand
252 # big index, let's parse it on demand
225 parser = lazyparser(i, self)
253 parser = lazyparser(i, self, self.indexformat)
226 self.index = lazyindex(parser)
254 self.index = lazyindex(parser)
227 self.nodemap = lazymap(parser)
255 self.nodemap = lazymap(parser)
228 else:
256 else:
229 s = struct.calcsize(indexformat)
257 self.parseindex(i)
230 l = len(i) / s
258 if self.version != 0:
231 self.index = [None] * l
259 e = list(self.index[0])
232 m = [None] * l
260 type = self.ngtype(e[0])
261 e[0] = self.offset_type(0, type)
262 self.index[0] = e
263 else:
264 self.nodemap = { nullid: -1}
265 self.index = []
233
266
267
268 def parseindex(self, data):
269 s = struct.calcsize(self.indexformat)
270 l = len(data)
271 self.index = []
272 self.nodemap = {nullid: -1}
273 off = 0
234 n = 0
274 n = 0
235 for f in xrange(0, l * s, s):
275 while off < l:
236 # offset, size, base, linkrev, p1, p2, nodeid
276 e = struct.unpack(self.indexformat, data[off:off + s])
237 e = struct.unpack(indexformat, i[f:f + s])
277 self.index.append(e)
238 m[n] = (e[6], n)
278 self.nodemap[e[-1]] = n
239 self.index[n] = e
240 n += 1
279 n += 1
280 off += s
241
281
242 self.nodemap = dict(m)
282 def ngoffset(self, q):
243 self.nodemap[nullid] = -1
283 if q & 0xFFFF:
284 raise RevlogError(_('%s: incompatible revision flag %x') %
285 (self.indexfile, type))
286 return long(q >> 16)
287
288 def ngtype(self, q):
289 return int(q & 0xFFFF)
290
291 def offset_type(self, offset, type):
292 return long(long(offset) << 16 | type)
293
294 def loadindexmap(self):
295 """loads both the map and the index from the lazy parser"""
296 if isinstance(self.index, lazyindex):
297 p = self.index.p
298 p.load()
244
299
245 def tip(self): return self.node(len(self.index) - 1)
300 def tip(self): return self.node(len(self.index) - 1)
246 def count(self): return len(self.index)
301 def count(self): return len(self.index)
247 def node(self, rev): return (rev < 0) and nullid or self.index[rev][6]
302 def node(self, rev):
303 return (rev < 0) and nullid or self.index[rev][-1]
248 def rev(self, node):
304 def rev(self, node):
249 try:
305 try:
250 return self.nodemap[node]
306 return self.nodemap[node]
251 except KeyError:
307 except KeyError:
252 raise RevlogError(_('%s: no node %s') % (self.indexfile, hex(node)))
308 raise RevlogError(_('%s: no node %s') % (self.indexfile, hex(node)))
253 def linkrev(self, node): return self.index[self.rev(node)][3]
309 def linkrev(self, node): return self.index[self.rev(node)][-4]
254 def parents(self, node):
310 def parents(self, node):
255 if node == nullid: return (nullid, nullid)
311 if node == nullid: return (nullid, nullid)
256 return self.index[self.rev(node)][4:6]
312 r = self.rev(node)
313 d = self.index[r][-3:-1]
314 if self.version == 0:
315 return d
316 return [ self.node(x) for x in d ]
317 def start(self, rev):
318 if rev < 0:
319 return -1
320 if self.version != 0:
321 return self.ngoffset(self.index[rev][0])
322 return self.index[rev][0]
323 def end(self, rev): return self.start(rev) + self.length(rev)
257
324
258 def start(self, rev): return (rev < 0) and -1 or self.index[rev][0]
259 def length(self, rev):
325 def length(self, rev):
260 if rev < 0:
326 if rev < 0:
261 return 0
327 return 0
262 else:
328 else:
263 return self.index[rev][1]
329 return self.index[rev][1]
264 def end(self, rev): return self.start(rev) + self.length(rev)
330 def base(self, rev): return (rev < 0) and rev or self.index[rev][-5]
265 def base(self, rev): return (rev < 0) and rev or self.index[rev][2]
266
331
267 def reachable(self, rev, stop=None):
332 def reachable(self, rev, stop=None):
268 reachable = {}
333 reachable = {}
@@ -501,18 +566,18 class revlog(object):
501 """apply a list of patches to a string"""
566 """apply a list of patches to a string"""
502 return mdiff.patches(t, pl)
567 return mdiff.patches(t, pl)
503
568
504 def chunk(self, rev):
569 def chunk(self, rev, df=None, cachelen=4096):
505 start, length = self.start(rev), self.length(rev)
570 start, length = self.start(rev), self.length(rev)
506 end = start + length
571 end = start + length
507
572 def loadcache(df):
508 def loadcache():
573 cache_length = max(cachelen, length) # 4k
509 cache_length = max(4096 * 1024, length) # 4Mo
574 if not df:
510 df = self.opener(self.datafile)
575 df = self.opener(self.datafile)
511 df.seek(start)
576 df.seek(start)
512 self.chunkcache = (start, df.read(cache_length))
577 self.chunkcache = (start, df.read(cache_length))
513
578
514 if not self.chunkcache:
579 if not self.chunkcache:
515 loadcache()
580 loadcache(df)
516
581
517 cache_start = self.chunkcache[0]
582 cache_start = self.chunkcache[0]
518 cache_end = cache_start + len(self.chunkcache[1])
583 cache_end = cache_start + len(self.chunkcache[1])
@@ -520,7 +585,7 class revlog(object):
520 # it is cached
585 # it is cached
521 offset = start - cache_start
586 offset = start - cache_start
522 else:
587 else:
523 loadcache()
588 loadcache(df)
524 offset = 0
589 offset = 0
525
590
526 #def checkchunk():
591 #def checkchunk():
@@ -555,16 +620,18 class revlog(object):
555 rev = self.rev(node)
620 rev = self.rev(node)
556 base = self.base(rev)
621 base = self.base(rev)
557
622
623 df = self.opener(self.datafile)
624
558 # do we have useful data cached?
625 # do we have useful data cached?
559 if self.cache and self.cache[1] >= base and self.cache[1] < rev:
626 if self.cache and self.cache[1] >= base and self.cache[1] < rev:
560 base = self.cache[1]
627 base = self.cache[1]
561 text = self.cache[2]
628 text = self.cache[2]
562 else:
629 else:
563 text = self.chunk(base)
630 text = self.chunk(base, df=df)
564
631
565 bins = []
632 bins = []
566 for r in xrange(base + 1, rev + 1):
633 for r in xrange(base + 1, rev + 1):
567 bins.append(self.chunk(r))
634 bins.append(self.chunk(r, df=df))
568
635
569 text = self.patches(text, bins)
636 text = self.patches(text, bins)
570
637
@@ -621,19 +688,30 class revlog(object):
621 if t >= 0:
688 if t >= 0:
622 offset = self.end(t)
689 offset = self.end(t)
623
690
691 if self.version == 0:
624 e = (offset, l, base, link, p1, p2, node)
692 e = (offset, l, base, link, p1, p2, node)
693 else:
694 e = (self.offset_type(offset, 0), l, len(text),
695 base, link, self.rev(p1), self.rev(p2), node)
625
696
626 self.index.append(e)
697 self.index.append(e)
627 self.nodemap[node] = n
698 self.nodemap[node] = n
628 entry = struct.pack(indexformat, *e)
699 entry = struct.pack(self.indexformat, *e)
629
700
630 transaction.add(self.datafile, e[0])
701 transaction.add(self.datafile, offset)
702 transaction.add(self.indexfile, n * len(entry))
631 f = self.opener(self.datafile, "a")
703 f = self.opener(self.datafile, "a")
632 if data[0]:
704 if data[0]:
633 f.write(data[0])
705 f.write(data[0])
634 f.write(data[1])
706 f.write(data[1])
635 transaction.add(self.indexfile, n * len(entry))
707 f = self.opener(self.indexfile, "a")
636 self.opener(self.indexfile, "a").write(entry)
708
709 if len(self.index) == 1 and self.version != 0:
710 l = struct.pack(versionformat, self.version)
711 f.write(l)
712 entry = entry[4:]
713
714 f.write(entry)
637
715
638 self.cache = (node, n, text)
716 self.cache = (node, n, text)
639 return node
717 return node
@@ -748,16 +826,12 class revlog(object):
748 base = prev = -1
826 base = prev = -1
749 start = end = measure = 0
827 start = end = measure = 0
750 if r:
828 if r:
751 base = self.base(t)
752 start = self.start(base)
753 end = self.end(t)
829 end = self.end(t)
754 measure = self.length(base)
755 prev = self.tip()
756
830
831 ifh = self.opener(self.indexfile, "a+")
832 transaction.add(self.indexfile, ifh.tell())
757 transaction.add(self.datafile, end)
833 transaction.add(self.datafile, end)
758 transaction.add(self.indexfile, r * struct.calcsize(indexformat))
759 dfh = self.opener(self.datafile, "a")
834 dfh = self.opener(self.datafile, "a")
760 ifh = self.opener(self.indexfile, "a")
761
835
762 # loop through our set of deltas
836 # loop through our set of deltas
763 chain = None
837 chain = None
@@ -794,6 +868,7 class revlog(object):
794
868
795 if chain != prev or (end - start + len(cdelta)) > measure * 2:
869 if chain != prev or (end - start + len(cdelta)) > measure * 2:
796 # flush our writes here so we can read it in revision
870 # flush our writes here so we can read it in revision
871 if dfh:
797 dfh.flush()
872 dfh.flush()
798 ifh.flush()
873 ifh.flush()
799 text = self.revision(chain)
874 text = self.revision(chain)
@@ -803,19 +878,21 class revlog(object):
803 raise RevlogError(_("consistency error adding group"))
878 raise RevlogError(_("consistency error adding group"))
804 measure = len(text)
879 measure = len(text)
805 else:
880 else:
881 if self.version == 0:
806 e = (end, len(cdelta), base, link, p1, p2, node)
882 e = (end, len(cdelta), base, link, p1, p2, node)
883 else:
884 e = (self.offset_type(end, 0), len(cdelta), -1, base,
885 link, self.rev(p1), self.rev(p2), node)
807 self.index.append(e)
886 self.index.append(e)
808 self.nodemap[node] = r
887 self.nodemap[node] = r
809 dfh.write(cdelta)
888 dfh.write(cdelta)
810 ifh.write(struct.pack(indexformat, *e))
889 ifh.write(struct.pack(self.indexformat, *e))
811
890
812 t, r, chain, prev = r, r + 1, node, node
891 t, r, chain, prev = r, r + 1, node, node
813 base = self.base(t)
892 base = self.base(t)
814 start = self.start(base)
893 start = self.start(base)
815 end = self.end(t)
894 end = self.end(t)
816
895
817 dfh.close()
818 ifh.close()
819 if node is None:
896 if node is None:
820 raise RevlogError(_("group to be added is empty"))
897 raise RevlogError(_("group to be added is empty"))
821 return node
898 return node
@@ -824,32 +901,34 class revlog(object):
824 if self.count() == 0 or rev >= self.count():
901 if self.count() == 0 or rev >= self.count():
825 return
902 return
826
903
904 if isinstance(self.index, lazyindex):
905 self.loadindexmap()
906
827 # When stripping away a revision, we need to make sure it
907 # When stripping away a revision, we need to make sure it
828 # does not actually belong to an older changeset.
908 # does not actually belong to an older changeset.
829 # The minlink parameter defines the oldest revision
909 # The minlink parameter defines the oldest revision
830 # we're allowed to strip away.
910 # we're allowed to strip away.
831 while minlink > self.index[rev][3]:
911 while minlink > self.index[rev][-4]:
832 rev += 1
912 rev += 1
833 if rev >= self.count():
913 if rev >= self.count():
834 return
914 return
835
915
836 # first truncate the files on disk
916 # first truncate the files on disk
837 end = self.start(rev)
917 end = self.start(rev)
838 self.opener(self.datafile, "a").truncate(end)
918 df = self.opener(self.datafile, "a")
839 end = rev * struct.calcsize(indexformat)
919 df.truncate(end)
840 self.opener(self.indexfile, "a").truncate(end)
920 end = rev * struct.calcsize(self.indexformat)
921
922 indexf = self.opener(self.indexfile, "a")
923 indexf.truncate(end)
841
924
842 # then reset internal state in memory to forget those revisions
925 # then reset internal state in memory to forget those revisions
843 self.cache = None
926 self.cache = None
844 self.chunkcache = None
927 self.chunkcache = None
845 for p in self.index[rev:]:
928 for x in xrange(rev, self.count()):
846 del self.nodemap[p[6]]
929 del self.nodemap[self.node(x)]
847 del self.index[rev:]
848
930
849 # truncating the lazyindex also truncates the lazymap.
931 del self.index[rev:]
850 if isinstance(self.index, lazyindex):
851 self.index.trunc(end)
852
853
932
854 def checksize(self):
933 def checksize(self):
855 expected = 0
934 expected = 0
@@ -870,7 +949,7 class revlog(object):
870 f = self.opener(self.indexfile)
949 f = self.opener(self.indexfile)
871 f.seek(0, 2)
950 f.seek(0, 2)
872 actual = f.tell()
951 actual = f.tell()
873 s = struct.calcsize(indexformat)
952 s = struct.calcsize(self.indexformat)
874 i = actual / s
953 i = actual / s
875 di = actual - (i * s)
954 di = actual - (i * s)
876 except IOError, inst:
955 except IOError, inst:
@@ -32,6 +32,7 class statichttprepository(localrepo.loc
32 def __init__(self, ui, path):
32 def __init__(self, ui, path):
33 self.path = (path + "/.hg")
33 self.path = (path + "/.hg")
34 self.ui = ui
34 self.ui = ui
35 self.revlogversion = 0
35 self.opener = opener(self.path)
36 self.opener = opener(self.path)
36 self.manifest = manifest.manifest(self.opener)
37 self.manifest = manifest.manifest(self.opener)
37 self.changelog = changelog.changelog(self.opener)
38 self.changelog = changelog.changelog(self.opener)
@@ -29,6 +29,7 class ui(object):
29 self.diffcache = None
29 self.diffcache = None
30 self.header = []
30 self.header = []
31 self.prev_header = []
31 self.prev_header = []
32 self.revlogopts = self.configrevlog()
32 else:
33 else:
33 # parentui may point to an ui object which is already a child
34 # parentui may point to an ui object which is already a child
34 self.parentui = parentui.parentui or parentui
35 self.parentui = parentui.parentui or parentui
@@ -134,6 +135,12 class ui(object):
134 result.append(path)
135 result.append(path)
135 return result
136 return result
136
137
138 def configrevlog(self):
139 ret = {}
140 for x in self.configitems("revlog"):
141 k = x[0].lower()
142 ret[k] = x[1]
143 return ret
137 def diffopts(self):
144 def diffopts(self):
138 if self.diffcache:
145 if self.diffcache:
139 return self.diffcache
146 return self.diffcache
General Comments 0
You need to be logged in to leave comments. Login now