Show More
@@ -43,12 +43,23 b' class localrepository(object):' | |||
|
43 | 43 | |
|
44 | 44 | v = self.ui.revlogopts |
|
45 | 45 | self.revlogversion = int(v.get('format', 0)) |
|
46 | flags = 0 | |
|
46 | 47 | for x in v.get('flags', "").split(): |
|
47 |
|
|
|
48 | flags |= revlog.flagstr(x) | |
|
49 | ||
|
50 | v = self.revlogversion | flags | |
|
51 | self.manifest = manifest.manifest(self.opener, v) | |
|
52 | self.changelog = changelog.changelog(self.opener, v) | |
|
48 | 53 | |
|
49 | self.manifest = manifest.manifest(self.opener, self.revlogversion) | |
|
50 | self.changelog = changelog.changelog(self.opener, self.revlogversion) | |
|
51 | self.revlogversion = self.changelog.version | |
|
54 | # the changelog might not have the inline index flag | |
|
55 | # on. If the format of the changelog is the same as found in | |
|
56 | # .hgrc, apply any flags found in the .hgrc as well. | |
|
57 | # Otherwise, just version from the changelog | |
|
58 | v = self.changelog.version | |
|
59 | if v == self.revlogversion: | |
|
60 | v |= flags | |
|
61 | self.revlogversion = v | |
|
62 | ||
|
52 | 63 | self.tagscache = None |
|
53 | 64 | self.nodetagscache = None |
|
54 | 65 | self.encodepats = None |
@@ -20,6 +20,14 b' demandload(globals(), "sha struct zlib")' | |||
|
20 | 20 | REVLOGV0 = 0 |
|
21 | 21 | REVLOGNG = 1 |
|
22 | 22 | |
|
23 | # revlog flags | |
|
24 | REVLOGNGINLINEDATA = (1 << 16) | |
|
25 | ||
|
26 | def flagstr(flag): | |
|
27 | if flag == "inline": | |
|
28 | return REVLOGNGINLINEDATA | |
|
29 | raise RevlogError(_("unknown revlog flag %s" % flag)) | |
|
30 | ||
|
23 | 31 | def hash(text, p1, p2): |
|
24 | 32 | """generate a hash from the given text and its parent hashes |
|
25 | 33 | |
@@ -234,13 +242,19 b' class revlog(object):' | |||
|
234 | 242 | self.indexstat = st |
|
235 | 243 | if len(i) > 0: |
|
236 | 244 | v = struct.unpack(versionformat, i[:4])[0] |
|
237 | if v != 0: | |
|
238 | 245 |
|
|
239 | 246 |
|
|
240 | if fmt != REVLOGNG or (flags & ~(REVLOGNGINLINEDATA)): | |
|
241 | raise RevlogError( | |
|
242 | _("unknown version format %d or flags %x on %s") % | |
|
243 |
( |
|
|
247 | if fmt == 0: | |
|
248 | if flags: | |
|
249 | raise RevlogError(_("index %s invalid flags %x for format v0" % | |
|
250 | (self.indexfile, flags))) | |
|
251 | elif fmt == REVLOGNG: | |
|
252 | if flags & ~REVLOGNGINLINEDATA: | |
|
253 | raise RevlogError(_("index %s invalid flags %x for revlogng" % | |
|
254 | (self.indexfile, flags))) | |
|
255 | else: | |
|
256 | raise RevlogError(_("index %s invalid format %d" % | |
|
257 | (self.indexfile, fmt))) | |
|
244 | 258 | self.version = v |
|
245 | 259 | if v == 0: |
|
246 | 260 | self.indexformat = indexformatv0 |
@@ -248,13 +262,17 b' class revlog(object):' | |||
|
248 | 262 | self.indexformat = indexformatng |
|
249 | 263 | |
|
250 | 264 | if i: |
|
251 | if st and st.st_size > 10000: | |
|
265 | if not self.inlinedata() and st and st.st_size > 10000: | |
|
252 | 266 | # big index, let's parse it on demand |
|
253 | 267 | parser = lazyparser(i, self, self.indexformat) |
|
254 | 268 | self.index = lazyindex(parser) |
|
255 | 269 | self.nodemap = lazymap(parser) |
|
256 | 270 | else: |
|
257 | 271 | self.parseindex(i) |
|
272 | if self.inlinedata(): | |
|
273 | # we've already got the entire data file read in, save it | |
|
274 | # in the chunk data | |
|
275 | self.chunkcache = (0, i) | |
|
258 | 276 | if self.version != 0: |
|
259 | 277 | e = list(self.index[0]) |
|
260 | 278 | type = self.ngtype(e[0]) |
@@ -270,6 +288,7 b' class revlog(object):' | |||
|
270 | 288 | l = len(data) |
|
271 | 289 | self.index = [] |
|
272 | 290 | self.nodemap = {nullid: -1} |
|
291 | inline = self.inlinedata() | |
|
273 | 292 | off = 0 |
|
274 | 293 | n = 0 |
|
275 | 294 | while off < l: |
@@ -278,6 +297,8 b' class revlog(object):' | |||
|
278 | 297 | self.nodemap[e[-1]] = n |
|
279 | 298 | n += 1 |
|
280 | 299 | off += s |
|
300 | if inline: | |
|
301 | off += e[1] | |
|
281 | 302 | |
|
282 | 303 | def ngoffset(self, q): |
|
283 | 304 | if q & 0xFFFF: |
@@ -297,6 +318,7 b' class revlog(object):' | |||
|
297 | 318 | p = self.index.p |
|
298 | 319 | p.load() |
|
299 | 320 | |
|
321 | def inlinedata(self): return self.version & REVLOGNGINLINEDATA | |
|
300 | 322 | def tip(self): return self.node(len(self.index) - 1) |
|
301 | 323 | def count(self): return len(self.index) |
|
302 | 324 | def node(self, rev): |
@@ -568,10 +590,16 b' class revlog(object):' | |||
|
568 | 590 | |
|
569 | 591 | def chunk(self, rev, df=None, cachelen=4096): |
|
570 | 592 | start, length = self.start(rev), self.length(rev) |
|
593 | inline = self.inlinedata() | |
|
594 | if inline: | |
|
595 | start += (rev + 1) * struct.calcsize(self.indexformat) | |
|
571 | 596 | end = start + length |
|
572 | 597 | def loadcache(df): |
|
573 | 598 | cache_length = max(cachelen, length) # 4k |
|
574 | 599 | if not df: |
|
600 | if inline: | |
|
601 | df = self.opener(self.indexfile) | |
|
602 | else: | |
|
575 | 603 | df = self.opener(self.datafile) |
|
576 | 604 | df.seek(start) |
|
577 | 605 | self.chunkcache = (start, df.read(cache_length)) |
@@ -620,6 +648,10 b' class revlog(object):' | |||
|
620 | 648 | rev = self.rev(node) |
|
621 | 649 | base = self.base(rev) |
|
622 | 650 | |
|
651 | if self.inlinedata(): | |
|
652 | # we probably have the whole chunk cached | |
|
653 | df = None | |
|
654 | else: | |
|
623 | 655 | df = self.opener(self.datafile) |
|
624 | 656 | |
|
625 | 657 | # do we have useful data cached? |
@@ -643,6 +675,40 b' class revlog(object):' | |||
|
643 | 675 | self.cache = (node, rev, text) |
|
644 | 676 | return text |
|
645 | 677 | |
|
678 | def checkinlinesize(self, fp, tr): | |
|
679 | if not self.inlinedata(): | |
|
680 | return | |
|
681 | size = fp.tell() | |
|
682 | if size < 131072: | |
|
683 | return | |
|
684 | tr.add(self.datafile, 0) | |
|
685 | df = self.opener(self.datafile, 'w') | |
|
686 | calc = struct.calcsize(self.indexformat) | |
|
687 | for r in xrange(self.count()): | |
|
688 | start = self.start(r) + (r + 1) * calc | |
|
689 | length = self.length(r) | |
|
690 | fp.seek(start) | |
|
691 | d = fp.read(length) | |
|
692 | df.write(d) | |
|
693 | fp.close() | |
|
694 | df.close() | |
|
695 | fp = self.opener(self.indexfile, 'w', atomic=True) | |
|
696 | self.version &= ~(REVLOGNGINLINEDATA) | |
|
697 | if self.count(): | |
|
698 | x = self.index[0] | |
|
699 | e = struct.pack(self.indexformat, *x)[4:] | |
|
700 | l = struct.pack(versionformat, self.version) | |
|
701 | fp.write(l) | |
|
702 | fp.write(e) | |
|
703 | ||
|
704 | for i in xrange(1, self.count()): | |
|
705 | x = self.index[i] | |
|
706 | e = struct.pack(self.indexformat, *x) | |
|
707 | fp.write(e) | |
|
708 | ||
|
709 | fp.close() | |
|
710 | self.chunkcache = None | |
|
711 | ||
|
646 | 712 | def addrevision(self, text, transaction, link, p1=None, p2=None, d=None): |
|
647 | 713 | """add a revision to the log |
|
648 | 714 | |
@@ -698,6 +764,7 b' class revlog(object):' | |||
|
698 | 764 | self.nodemap[node] = n |
|
699 | 765 | entry = struct.pack(self.indexformat, *e) |
|
700 | 766 | |
|
767 | if not self.inlinedata(): | |
|
701 | 768 | transaction.add(self.datafile, offset) |
|
702 | 769 | transaction.add(self.indexfile, n * len(entry)) |
|
703 | 770 | f = self.opener(self.datafile, "a") |
@@ -705,6 +772,9 b' class revlog(object):' | |||
|
705 | 772 | f.write(data[0]) |
|
706 | 773 | f.write(data[1]) |
|
707 | 774 | f = self.opener(self.indexfile, "a") |
|
775 | else: | |
|
776 | f = self.opener(self.indexfile, "a+") | |
|
777 | transaction.add(self.indexfile, f.tell()) | |
|
708 | 778 | |
|
709 | 779 | if len(self.index) == 1 and self.version != 0: |
|
710 | 780 | l = struct.pack(versionformat, self.version) |
@@ -713,6 +783,11 b' class revlog(object):' | |||
|
713 | 783 | |
|
714 | 784 | f.write(entry) |
|
715 | 785 | |
|
786 | if self.inlinedata(): | |
|
787 | f.write(data[0]) | |
|
788 | f.write(data[1]) | |
|
789 | self.checkinlinesize(f, transaction) | |
|
790 | ||
|
716 | 791 | self.cache = (node, n, text) |
|
717 | 792 | return node |
|
718 | 793 | |
@@ -830,6 +905,9 b' class revlog(object):' | |||
|
830 | 905 | |
|
831 | 906 | ifh = self.opener(self.indexfile, "a+") |
|
832 | 907 | transaction.add(self.indexfile, ifh.tell()) |
|
908 | if self.inlinedata(): | |
|
909 | dfh = None | |
|
910 | else: | |
|
833 | 911 | transaction.add(self.datafile, end) |
|
834 | 912 | dfh = self.opener(self.datafile, "a") |
|
835 | 913 | |
@@ -885,6 +963,19 b' class revlog(object):' | |||
|
885 | 963 | link, self.rev(p1), self.rev(p2), node) |
|
886 | 964 | self.index.append(e) |
|
887 | 965 | self.nodemap[node] = r |
|
966 | if self.inlinedata(): | |
|
967 | ifh.write(struct.pack(self.indexformat, *e)) | |
|
968 | ifh.write(cdelta) | |
|
969 | self.checkinlinesize(ifh, transaction) | |
|
970 | if not self.inlinedata(): | |
|
971 | dfh = self.opener(self.datafile, "a") | |
|
972 | ifh = self.opener(self.indexfile, "a") | |
|
973 | else: | |
|
974 | if not dfh: | |
|
975 | # addrevision switched from inline to conventional | |
|
976 | # reopen the index | |
|
977 | dfh = self.opener(self.datafile, "a") | |
|
978 | ifh = self.opener(self.indexfile, "a") | |
|
888 | 979 | dfh.write(cdelta) |
|
889 | 980 | ifh.write(struct.pack(self.indexformat, *e)) |
|
890 | 981 | |
@@ -915,9 +1006,12 b' class revlog(object):' | |||
|
915 | 1006 | |
|
916 | 1007 | # first truncate the files on disk |
|
917 | 1008 | end = self.start(rev) |
|
1009 | if not self.inlinedata(): | |
|
918 | 1010 | df = self.opener(self.datafile, "a") |
|
919 | 1011 | df.truncate(end) |
|
920 | 1012 | end = rev * struct.calcsize(self.indexformat) |
|
1013 | else: | |
|
1014 | end += rev * struct.calcsize(self.indexformat) | |
|
921 | 1015 | |
|
922 | 1016 | indexf = self.opener(self.indexfile, "a") |
|
923 | 1017 | indexf.truncate(end) |
@@ -952,6 +1046,12 b' class revlog(object):' | |||
|
952 | 1046 | s = struct.calcsize(self.indexformat) |
|
953 | 1047 | i = actual / s |
|
954 | 1048 | di = actual - (i * s) |
|
1049 | if self.inlinedata(): | |
|
1050 | databytes = 0 | |
|
1051 | for r in xrange(self.count()): | |
|
1052 | databytes += self.length(r) | |
|
1053 | dd = 0 | |
|
1054 | di = actual - self.count() * s - databytes | |
|
955 | 1055 | except IOError, inst: |
|
956 | 1056 | if inst.errno != errno.ENOENT: |
|
957 | 1057 | raise |
General Comments 0
You need to be logged in to leave comments.
Login now