##// END OF EJS Templates
revlog: support using an existing file handle when reading revlogs...
Gregory Szorc -
r26377:dfef0d3b default
parent child Browse files
Show More
@@ -932,11 +932,23 b' class revlog(object):'
932 932 else:
933 933 self._chunkcache = offset, data
934 934
935 def _loadchunk(self, offset, length):
936 if self._inline:
937 df = self.opener(self.indexfile)
935 def _loadchunk(self, offset, length, df=None):
936 """Load a chunk/segment from the revlog.
937
938 Accepts absolute offset, length to read, and an optional existing
939 file handle to read from.
940
941 If an existing file handle is passed, it will be seeked and the
942 original seek position will NOT be restored.
943 """
944 if df is not None:
945 closehandle = False
938 946 else:
939 df = self.opener(self.datafile)
947 if self._inline:
948 df = self.opener(self.indexfile)
949 else:
950 df = self.opener(self.datafile)
951 closehandle = True
940 952
941 953 # Cache data both forward and backward around the requested
942 954 # data, in a fixed size window. This helps speed up operations
@@ -947,13 +959,14 b' class revlog(object):'
947 959 - realoffset)
948 960 df.seek(realoffset)
949 961 d = df.read(reallength)
950 df.close()
962 if closehandle:
963 df.close()
951 964 self._addchunk(realoffset, d)
952 965 if offset != realoffset or reallength != length:
953 966 return util.buffer(d, offset - realoffset, length)
954 967 return d
955 968
956 def _getchunk(self, offset, length):
969 def _getchunk(self, offset, length, df=None):
957 970 o, d = self._chunkcache
958 971 l = len(d)
959 972
@@ -965,21 +978,21 b' class revlog(object):'
965 978 return d # avoid a copy
966 979 return util.buffer(d, cachestart, cacheend - cachestart)
967 980
968 return self._loadchunk(offset, length)
981 return self._loadchunk(offset, length, df=df)
969 982
970 def _chunkraw(self, startrev, endrev):
983 def _chunkraw(self, startrev, endrev, df=None):
971 984 start = self.start(startrev)
972 985 end = self.end(endrev)
973 986 if self._inline:
974 987 start += (startrev + 1) * self._io.size
975 988 end += (endrev + 1) * self._io.size
976 989 length = end - start
977 return self._getchunk(start, length)
990 return self._getchunk(start, length, df=df)
978 991
979 def _chunk(self, rev):
980 return decompress(self._chunkraw(rev, rev))
992 def _chunk(self, rev, df=None):
993 return decompress(self._chunkraw(rev, rev, df=df))
981 994
982 def _chunks(self, revs):
995 def _chunks(self, revs, df=None):
983 996 '''faster version of [self._chunk(rev) for rev in revs]
984 997
985 998 Assumes that revs is in ascending order.'''
@@ -999,14 +1012,14 b' class revlog(object):'
999 1012 while True:
1000 1013 # ensure that the cache doesn't change out from under us
1001 1014 _cache = self._chunkcache
1002 self._chunkraw(revs[0], revs[-1])
1015 self._chunkraw(revs[0], revs[-1], df=df)
1003 1016 if _cache == self._chunkcache:
1004 1017 break
1005 1018 offset, data = _cache
1006 1019 except OverflowError:
1007 1020 # issue4215 - we can't cache a run of chunks greater than
1008 1021 # 2G on Windows
1009 return [self._chunk(rev) for rev in revs]
1022 return [self._chunk(rev, df=df) for rev in revs]
1010 1023
1011 1024 for rev in revs:
1012 1025 chunkstart = start(rev)
@@ -1038,9 +1051,12 b' class revlog(object):'
1038 1051 return mdiff.textdiff(self.revision(rev1),
1039 1052 self.revision(rev2))
1040 1053
1041 def revision(self, nodeorrev):
1054 def revision(self, nodeorrev, _df=None):
1042 1055 """return an uncompressed revision of a given node or revision
1043 1056 number.
1057
1058 _df is an existing file handle to read from. It is meant to only be
1059 used internally.
1044 1060 """
1045 1061 if isinstance(nodeorrev, int):
1046 1062 rev = nodeorrev
@@ -1091,7 +1107,7 b' class revlog(object):'
1091 1107 # drop cache to save memory
1092 1108 self._cache = None
1093 1109
1094 bins = self._chunks(chain)
1110 bins = self._chunks(chain, df=_df)
1095 1111 if text is None:
1096 1112 text = str(bins[0])
1097 1113 bins = bins[1:]
General Comments 0
You need to be logged in to leave comments. Login now