##// END OF EJS Templates
revlogv2: also keep track for the size of the "data" file...
marmoute -
r48016:4abd474a default
parent child Browse files
Show More
@@ -1156,7 +1156,6 b' coreconfigitem('
1156 1156 # - for stripping operation
1157 1157 # - for rollback operation
1158 1158 # * proper streaming (race free) of the docket file
1159 # * store the data size in the docket to simplify sidedata rewrite.
1160 1159 # * track garbage data to evemtually allow rewriting -existing- sidedata.
1161 1160 # * Exchange-wise, we will also need to do something more efficient than
1162 1161 # keeping references to the affected revlogs, especially memory-wise when
@@ -2088,7 +2088,10 b' class revlog(object):'
2088 2088 if not self._inline:
2089 2089 try:
2090 2090 dfh = self._datafp(b"r+")
2091 dfh.seek(0, os.SEEK_END)
2091 if self._docket is None:
2092 dfh.seek(0, os.SEEK_END)
2093 else:
2094 dfh.seek(self._docket.data_end, os.SEEK_SET)
2092 2095 except IOError as inst:
2093 2096 if inst.errno != errno.ENOENT:
2094 2097 raise
@@ -2455,16 +2458,10 b' class revlog(object):'
2455 2458 to `n - 1`'s sidedata being written after `n`'s data.
2456 2459
2457 2460 TODO cache this in a docket file before getting out of experimental."""
2458 if self._format_version != REVLOGV2:
2461 if self._docket is None:
2459 2462 return self.end(prev)
2460
2461 offset = 0
2462 for rev, entry in enumerate(self.index):
2463 sidedata_end = entry[8] + entry[9]
2464 # Sidedata for a previous rev has potentially been written after
2465 # this rev's end, so take the max.
2466 offset = max(self.end(rev), offset, sidedata_end)
2467 return offset
2463 else:
2464 return self._docket.data_end
2468 2465
2469 2466 def _writeentry(self, transaction, entry, data, link, offset, sidedata):
2470 2467 # Files opened in a+ mode have inconsistent behavior on various
@@ -2488,7 +2485,10 b' class revlog(object):'
2488 2485 else:
2489 2486 ifh.seek(self._docket.index_end, os.SEEK_SET)
2490 2487 if dfh:
2491 dfh.seek(0, os.SEEK_END)
2488 if self._docket is None:
2489 dfh.seek(0, os.SEEK_END)
2490 else:
2491 dfh.seek(self._docket.data_end, os.SEEK_SET)
2492 2492
2493 2493 curr = len(self) - 1
2494 2494 if not self._inline:
@@ -2511,6 +2511,7 b' class revlog(object):'
2511 2511 self._enforceinlinesize(transaction)
2512 2512 if self._docket is not None:
2513 2513 self._docket.index_end = self._writinghandles[0].tell()
2514 self._docket.data_end = self._writinghandles[1].tell()
2514 2515
2515 2516 nodemaputil.setup_persistent_nodemap(transaction, self)
2516 2517
@@ -2673,18 +2674,19 b' class revlog(object):'
2673 2674 return
2674 2675
2675 2676 # first truncate the files on disk
2676 end = self.start(rev)
2677 data_end = self.start(rev)
2677 2678 if not self._inline:
2678 transaction.add(self._datafile, end)
2679 transaction.add(self._datafile, data_end)
2679 2680 end = rev * self.index.entry_size
2680 2681 else:
2681 end += rev * self.index.entry_size
2682 end = data_end + (rev * self.index.entry_size)
2682 2683
2683 2684 transaction.add(self._indexfile, end)
2684 2685 if self._docket is not None:
2685 2686 # XXX we could, leverage the docket while stripping. However it is
2686 2687 # not powerfull enough at the time of this comment
2687 2688 self._docket.index_end = end
2689 self._docket.data_end = data_end
2688 2690 self._docket.write(transaction, stripping=True)
2689 2691
2690 2692 # then reset internal state in memory to forget those revisions
@@ -3210,7 +3212,11 b' class revlog(object):'
3210 3212 # append the new sidedata
3211 3213 with self._writing(transaction):
3212 3214 ifh, dfh = self._writinghandles
3213 dfh.seek(0, os.SEEK_END)
3215 if self._docket is not None:
3216 dfh.seek(self._docket.data_end, os.SEEK_SET)
3217 else:
3218 dfh.seek(0, os.SEEK_END)
3219
3214 3220 current_offset = dfh.tell()
3215 3221 for rev in range(startrev, endrev + 1):
3216 3222 entry = self.index[rev]
@@ -3242,6 +3248,8 b' class revlog(object):'
3242 3248 dfh.write(serialized_sidedata)
3243 3249 new_entries.append(entry)
3244 3250 current_offset += len(serialized_sidedata)
3251 if self._docket is not None:
3252 self._docket.data_end = dfh.tell()
3245 3253
3246 3254 # rewrite the new index entries
3247 3255 ifh.seek(startrev * self.index.entry_size)
@@ -32,9 +32,11 b' from . import ('
32 32 # * 4 bytes: revlog version
33 33 # | This is mandatory as docket must be compatible with the previous
34 34 # | revlog index header.
35 # * 8 bytes: size of index data
36 # * 8 bytes: pending size of index data
37 S_HEADER = struct.Struct(constants.INDEX_HEADER.format + 'LL')
35 # * 8 bytes: size of index-data
36 # * 8 bytes: pending size of index-data
37 # * 8 bytes: size of data
38 # * 8 bytes: pending size of data
39 S_HEADER = struct.Struct(constants.INDEX_HEADER.format + 'LLLL')
38 40
39 41
40 42 class RevlogDocket(object):
@@ -47,6 +49,8 b' class RevlogDocket(object):'
47 49 version_header=None,
48 50 index_end=0,
49 51 pending_index_end=0,
52 data_end=0,
53 pending_data_end=0,
50 54 ):
51 55 self._version_header = version_header
52 56 self._read_only = bool(use_pending)
@@ -54,14 +58,19 b' class RevlogDocket(object):'
54 58 self._radix = revlog.radix
55 59 self._path = revlog._docket_file
56 60 self._opener = revlog.opener
57 # this assert should be True as long as we have a single index filename
61 # thes asserts should be True as long as we have a single index filename
58 62 assert index_end <= pending_index_end
63 assert data_end <= pending_data_end
59 64 self._initial_index_end = index_end
60 65 self._pending_index_end = pending_index_end
66 self._initial_data_end = data_end
67 self._pending_data_end = pending_data_end
61 68 if use_pending:
62 69 self._index_end = self._pending_index_end
70 self._data_end = self._pending_data_end
63 71 else:
64 72 self._index_end = self._initial_index_end
73 self._data_end = self._initial_data_end
65 74
66 75 def index_filepath(self):
67 76 """file path to the current index file associated to this docket"""
@@ -78,6 +87,16 b' class RevlogDocket(object):'
78 87 self._index_end = new_size
79 88 self._dirty = True
80 89
90 @property
91 def data_end(self):
92 return self._data_end
93
94 @data_end.setter
95 def data_end(self, new_size):
96 if new_size != self._data_end:
97 self._data_end = new_size
98 self._dirty = True
99
81 100 def write(self, transaction, pending=False, stripping=False):
82 101 """write the modification of disk if any
83 102
@@ -102,15 +121,19 b' class RevlogDocket(object):'
102 121 def _serialize(self, pending=False):
103 122 if pending:
104 123 official_index_end = self._initial_index_end
124 official_data_end = self._initial_data_end
105 125 else:
106 126 official_index_end = self._index_end
127 official_data_end = self._data_end
107 128
108 129 # this assert should be True as long as we have a single index filename
109 assert official_index_end <= self._index_end
130 assert official_data_end <= self._data_end
110 131 data = (
111 132 self._version_header,
112 133 official_index_end,
113 134 self._index_end,
135 official_data_end,
136 self._data_end,
114 137 )
115 138 return S_HEADER.pack(*data)
116 139
@@ -127,12 +150,18 b' def default_docket(revlog, version_heade'
127 150 def parse_docket(revlog, data, use_pending=False):
128 151 """given some docket data return a docket object for the given revlog"""
129 152 header = S_HEADER.unpack(data[: S_HEADER.size])
130 version_header, index_size, pending_index_size = header
153 version_header = header[0]
154 index_size = header[1]
155 pending_index_size = header[2]
156 data_size = header[3]
157 pending_data_size = header[4]
131 158 docket = RevlogDocket(
132 159 revlog,
133 160 use_pending=use_pending,
134 161 version_header=version_header,
135 162 index_end=index_size,
136 163 pending_index_end=pending_index_size,
164 data_end=data_size,
165 pending_data_end=pending_data_size,
137 166 )
138 167 return docket
General Comments 0
You need to be logged in to leave comments. Login now