Show More
@@ -1175,8 +1175,37 b' class imanifestrevisionstored(imanifestr' | |||||
1175 | def readdelta(shallow=False): |
|
1175 | def readdelta(shallow=False): | |
1176 | """Obtain the manifest data structure representing changes from parent. |
|
1176 | """Obtain the manifest data structure representing changes from parent. | |
1177 |
|
1177 | |||
1178 |
This manifest is compared to its 1st parent. A new manifest |
|
1178 | This manifest is compared to its 1st parent. A new manifest | |
1179 | those differences is constructed. |
|
1179 | representing those differences is constructed. | |
|
1180 | ||||
|
1181 | If `shallow` is True, this will read the delta for this directory, | |||
|
1182 | without recursively reading subdirectory manifests. Instead, any | |||
|
1183 | subdirectory entry will be reported as it appears in the manifest, i.e. | |||
|
1184 | the subdirectory will be reported among files and distinguished only by | |||
|
1185 | its 't' flag. This only apply if the underlying manifest support it. | |||
|
1186 | ||||
|
1187 | The returned object conforms to the ``imanifestdict`` interface. | |||
|
1188 | """ | |||
|
1189 | ||||
|
1190 | def read_any_fast_delta(valid_bases, *, shallow=False): | |||
|
1191 | """read some manifest information as fast if possible | |||
|
1192 | ||||
|
1193 | This might return a "delta", a manifest object containing only file | |||
|
1194 | changed compared to another revisions. The `valid_bases` argument | |||
|
1195 | control the set of revision that might be used as a base. | |||
|
1196 | ||||
|
1197 | If no delta can be retrieved quickly, a full read of the manifest will | |||
|
1198 | be performed instead. | |||
|
1199 | ||||
|
1200 | The function return a tuple with two elements. The first one is the | |||
|
1201 | delta base used (or None if we did a full read), the second one is the | |||
|
1202 | manifest information. | |||
|
1203 | ||||
|
1204 | If `shallow` is True, this will read the delta for this directory, | |||
|
1205 | without recursively reading subdirectory manifests. Instead, any | |||
|
1206 | subdirectory entry will be reported as it appears in the manifest, i.e. | |||
|
1207 | the subdirectory will be reported among files and distinguished only by | |||
|
1208 | its 't' flag. This only apply if the underlying manifest support it. | |||
1180 |
|
1209 | |||
1181 | The returned object conforms to the ``imanifestdict`` interface. |
|
1210 | The returned object conforms to the ``imanifestdict`` interface. | |
1182 | """ |
|
1211 | """ |
@@ -14,6 +14,7 b' import weakref' | |||||
14 | from typing import ( |
|
14 | from typing import ( | |
15 | ByteString, |
|
15 | ByteString, | |
16 | Callable, |
|
16 | Callable, | |
|
17 | Collection, | |||
17 | Dict, |
|
18 | Dict, | |
18 | Iterable, |
|
19 | Iterable, | |
19 | Iterator, |
|
20 | Iterator, | |
@@ -2261,6 +2262,24 b' class ManifestCtx:' | |||||
2261 | d = mdiff.patchtext(store.revdiff(store.deltaparent(r), r)) |
|
2262 | d = mdiff.patchtext(store.revdiff(store.deltaparent(r), r)) | |
2262 | return manifestdict(store.nodeconstants.nodelen, d) |
|
2263 | return manifestdict(store.nodeconstants.nodelen, d) | |
2263 |
|
2264 | |||
|
2265 | def read_any_fast_delta( | |||
|
2266 | self, | |||
|
2267 | valid_bases: Collection[int], | |||
|
2268 | *, | |||
|
2269 | shallow: bool = False, | |||
|
2270 | ) -> Tuple[Optional[int], ManifestDict]: | |||
|
2271 | """see `imanifestrevisionstored` documentation""" | |||
|
2272 | store = self._storage() | |||
|
2273 | r = store.rev(self._node) | |||
|
2274 | deltaparent = store.deltaparent(r) | |||
|
2275 | if deltaparent != nullrev and deltaparent in valid_bases: | |||
|
2276 | d = mdiff.patchtext(store.revdiff(deltaparent, r)) | |||
|
2277 | return ( | |||
|
2278 | deltaparent, | |||
|
2279 | manifestdict(store.nodeconstants.nodelen, d), | |||
|
2280 | ) | |||
|
2281 | return (None, self.read()) | |||
|
2282 | ||||
2264 | def find(self, key: bytes) -> Tuple[bytes, bytes]: |
|
2283 | def find(self, key: bytes) -> Tuple[bytes, bytes]: | |
2265 | return self.read().find(key) |
|
2284 | return self.read().find(key) | |
2266 |
|
2285 | |||
@@ -2379,16 +2398,7 b' class TreeManifestCtx:' | |||||
2379 | return self._storage().parents(self._node) |
|
2398 | return self._storage().parents(self._node) | |
2380 |
|
2399 | |||
2381 | def readdelta(self, shallow: bool = False) -> AnyManifestDict: |
|
2400 | def readdelta(self, shallow: bool = False) -> AnyManifestDict: | |
2382 | """Returns a manifest containing just the entries that are present |
|
2401 | """see `imanifestrevisionstored` documentation""" | |
2383 | in this manifest, but not in its p1 manifest. This is efficient to read |
|
|||
2384 | if the revlog delta is already p1. |
|
|||
2385 |
|
||||
2386 | If `shallow` is True, this will read the delta for this directory, |
|
|||
2387 | without recursively reading subdirectory manifests. Instead, any |
|
|||
2388 | subdirectory entry will be reported as it appears in the manifest, i.e. |
|
|||
2389 | the subdirectory will be reported among files and distinguished only by |
|
|||
2390 | its 't' flag. |
|
|||
2391 | """ |
|
|||
2392 | store = self._storage() |
|
2402 | store = self._storage() | |
2393 | if shallow: |
|
2403 | if shallow: | |
2394 | r = store.rev(self._node) |
|
2404 | r = store.rev(self._node) | |
@@ -2407,6 +2417,69 b' class TreeManifestCtx:' | |||||
2407 | md.setflag(f, fl1) |
|
2417 | md.setflag(f, fl1) | |
2408 | return md |
|
2418 | return md | |
2409 |
|
2419 | |||
|
2420 | def read_any_fast_delta( | |||
|
2421 | self, | |||
|
2422 | valid_bases: Collection[int], | |||
|
2423 | *, | |||
|
2424 | shallow: bool = False, | |||
|
2425 | ) -> Tuple[Optional[int], AnyManifestDict]: | |||
|
2426 | """see `imanifestrevisionstored` documentation""" | |||
|
2427 | store = self._storage() | |||
|
2428 | r = store.rev(self._node) | |||
|
2429 | deltaparent = store.deltaparent(r) | |||
|
2430 | ||||
|
2431 | can_use_delta = deltaparent != nullrev and deltaparent in valid_bases | |||
|
2432 | ||||
|
2433 | if shallow: | |||
|
2434 | if can_use_delta: | |||
|
2435 | return (deltaparent, self._read_storage_delta_shallow()) | |||
|
2436 | else: | |||
|
2437 | d = store.revision(self._node) | |||
|
2438 | return (None, manifestdict(store.nodeconstants.nodelen, d)) | |||
|
2439 | else: | |||
|
2440 | # note: This use "slow_delta" here is cargo culted from the previous | |||
|
2441 | # implementation. I am not sure it make sense since the goal here is to | |||
|
2442 | # be fast, so why are we computing a delta? On the other hand, tree | |||
|
2443 | # manifest delta as fairly "cheap" and allow for skipping whole part of | |||
|
2444 | # the tree that a full read would access. So it might be a good idea. | |||
|
2445 | # | |||
|
2446 | # If we realize we don't need delta here, we should simply use: | |||
|
2447 | # | |||
|
2448 | # return (None, self.read()) | |||
|
2449 | if can_use_delta: | |||
|
2450 | return (None, self._read_storage_slow_delta(base=deltaparent)) | |||
|
2451 | else: | |||
|
2452 | parents = [ | |||
|
2453 | p | |||
|
2454 | for p in store.parentrevs(r) | |||
|
2455 | if p is not nullrev and p in valid_bases | |||
|
2456 | ] | |||
|
2457 | if parents: | |||
|
2458 | best_base = max(parents) | |||
|
2459 | else: | |||
|
2460 | best_base = max(valid_bases) | |||
|
2461 | return (None, self._read_storage_slow_delta(base=best_base)) | |||
|
2462 | ||||
|
2463 | def _read_storage_delta_shallow(self) -> ManifestDict: | |||
|
2464 | store = self._storage() | |||
|
2465 | r = store.rev(self._node) | |||
|
2466 | d = mdiff.patchtext(store.revdiff(store.deltaparent(r), r)) | |||
|
2467 | return manifestdict(store.nodeconstants.nodelen, d) | |||
|
2468 | ||||
|
2469 | def _read_storage_slow_delta(self, base) -> 'TreeManifest': | |||
|
2470 | store = self._storage() | |||
|
2471 | if base is None: | |||
|
2472 | base = store.deltaparent(store.rev(self._node)) | |||
|
2473 | m0 = self._manifestlog.get(self._dir, store.node(base)).read() | |||
|
2474 | m1 = self.read() | |||
|
2475 | md = treemanifest(self._manifestlog.nodeconstants, dir=self._dir) | |||
|
2476 | for f, ((n0, fl0), (n1, fl1)) in m0.diff(m1).items(): | |||
|
2477 | if n1: | |||
|
2478 | md[f] = n1 | |||
|
2479 | if fl1: | |||
|
2480 | md.setflag(f, fl1) | |||
|
2481 | return md | |||
|
2482 | ||||
2410 | def readfast(self, shallow=False) -> AnyManifestDict: |
|
2483 | def readfast(self, shallow=False) -> AnyManifestDict: | |
2411 | """Calls either readdelta or read, based on which would be less work. |
|
2484 | """Calls either readdelta or read, based on which would be less work. | |
2412 | readdelta is called if the delta is against the p1, and therefore can be |
|
2485 | readdelta is called if the delta is against the p1, and therefore can be |
General Comments 0
You need to be logged in to leave comments.
Login now