##// END OF EJS Templates
Implement data inlined with the index file...
mason@suse.com -
r2073:1e6745f7 default
parent child Browse files
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 self.revlogversion |= revlog.flagstr(x)
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 flags = v & ~0xFFFF
239 246 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))
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