Show More
@@ -20,7 +20,7 b' for inline in (True, False):' | |||||
20 | index, cache = parsers.parse_index2(data, inline) |
|
20 | index, cache = parsers.parse_index2(data, inline) | |
21 | index.slicechunktodensity(list(range(len(index))), 0.5, 262144) |
|
21 | index.slicechunktodensity(list(range(len(index))), 0.5, 262144) | |
22 | index.stats() |
|
22 | index.stats() | |
23 | index.findsnapshots({}, 0) |
|
23 | index.findsnapshots({}, 0, len(index) - 1) | |
24 | 10 in index |
|
24 | 10 in index | |
25 | for rev in range(len(index)): |
|
25 | for rev in range(len(index)): | |
26 | index.reachableroots(0, [len(index)-1], [rev]) |
|
26 | index.reachableroots(0, [len(index)-1], [rev]) |
@@ -1446,16 +1446,25 b' static PyObject *index_issnapshot(indexO' | |||||
1446 | static PyObject *index_findsnapshots(indexObject *self, PyObject *args) |
|
1446 | static PyObject *index_findsnapshots(indexObject *self, PyObject *args) | |
1447 | { |
|
1447 | { | |
1448 | Py_ssize_t start_rev; |
|
1448 | Py_ssize_t start_rev; | |
|
1449 | Py_ssize_t end_rev; | |||
1449 | PyObject *cache; |
|
1450 | PyObject *cache; | |
1450 | Py_ssize_t base; |
|
1451 | Py_ssize_t base; | |
1451 | Py_ssize_t rev; |
|
1452 | Py_ssize_t rev; | |
1452 | PyObject *key = NULL; |
|
1453 | PyObject *key = NULL; | |
1453 | PyObject *value = NULL; |
|
1454 | PyObject *value = NULL; | |
1454 | const Py_ssize_t length = index_length(self); |
|
1455 | const Py_ssize_t length = index_length(self); | |
1455 |
if (!PyArg_ParseTuple(args, "O!n", &PyDict_Type, &cache, &start_rev |
|
1456 | if (!PyArg_ParseTuple(args, "O!nn", &PyDict_Type, &cache, &start_rev, | |
|
1457 | &end_rev)) { | |||
1456 | return NULL; |
|
1458 | return NULL; | |
1457 | } |
|
1459 | } | |
1458 | for (rev = start_rev; rev < length; rev++) { |
|
1460 | end_rev += 1; | |
|
1461 | if (end_rev > length) { | |||
|
1462 | end_rev = length; | |||
|
1463 | } | |||
|
1464 | if (start_rev < 0) { | |||
|
1465 | start_rev = 0; | |||
|
1466 | } | |||
|
1467 | for (rev = start_rev; rev < end_rev; rev++) { | |||
1459 | int issnap; |
|
1468 | int issnap; | |
1460 | PyObject *allvalues = NULL; |
|
1469 | PyObject *allvalues = NULL; | |
1461 | issnap = index_issnapshotrev(self, rev); |
|
1470 | issnap = index_issnapshotrev(self, rev); |
@@ -799,18 +799,6 b' def _candidategroups(' | |||||
799 | yield None |
|
799 | yield None | |
800 |
|
800 | |||
801 |
|
801 | |||
802 | def _findsnapshots(revlog, cache, start_rev): |
|
|||
803 | """find snapshot from start_rev to tip""" |
|
|||
804 | if util.safehasattr(revlog.index, b'findsnapshots'): |
|
|||
805 | revlog.index.findsnapshots(cache, start_rev) |
|
|||
806 | else: |
|
|||
807 | deltaparent = revlog.deltaparent |
|
|||
808 | issnapshot = revlog.issnapshot |
|
|||
809 | for rev in revlog.revs(start_rev): |
|
|||
810 | if issnapshot(rev): |
|
|||
811 | cache[deltaparent(rev)].append(rev) |
|
|||
812 |
|
||||
813 |
|
||||
814 | def _refinedgroups(revlog, p1, p2, cachedelta): |
|
802 | def _refinedgroups(revlog, p1, p2, cachedelta): | |
815 | good = None |
|
803 | good = None | |
816 | # First we try to reuse a the delta contained in the bundle. |
|
804 | # First we try to reuse a the delta contained in the bundle. | |
@@ -832,13 +820,13 b' def _refinedgroups(revlog, p1, p2, cache' | |||||
832 | yield None |
|
820 | yield None | |
833 | return |
|
821 | return | |
834 | # XXX cache me higher |
|
822 | # XXX cache me higher | |
835 | snapshots = collections.defaultdict(list) |
|
823 | snapshot_cache = SnapshotCache() | |
836 | groups = _rawgroups( |
|
824 | groups = _rawgroups( | |
837 | revlog, |
|
825 | revlog, | |
838 | p1, |
|
826 | p1, | |
839 | p2, |
|
827 | p2, | |
840 | cachedelta, |
|
828 | cachedelta, | |
841 |
snapshot |
|
829 | snapshot_cache, | |
842 | ) |
|
830 | ) | |
843 | for candidates in groups: |
|
831 | for candidates in groups: | |
844 | good = yield candidates |
|
832 | good = yield candidates | |
@@ -861,12 +849,12 b' def _refinedgroups(revlog, p1, p2, cache' | |||||
861 | break |
|
849 | break | |
862 | good = yield (base,) |
|
850 | good = yield (base,) | |
863 | # refine snapshot up |
|
851 | # refine snapshot up | |
864 | if not snapshots: |
|
852 | if not snapshot_cache.snapshots: | |
865 |
|
|
853 | snapshot_cache.update(revlog, good + 1) | |
866 | previous = None |
|
854 | previous = None | |
867 | while good != previous: |
|
855 | while good != previous: | |
868 | previous = good |
|
856 | previous = good | |
869 | children = tuple(sorted(c for c in snapshots[good])) |
|
857 | children = tuple(sorted(c for c in snapshot_cache.snapshots[good])) | |
870 | good = yield children |
|
858 | good = yield children | |
871 |
|
859 | |||
872 | if debug_info is not None: |
|
860 | if debug_info is not None: | |
@@ -876,7 +864,7 b' def _refinedgroups(revlog, p1, p2, cache' | |||||
876 | yield None |
|
864 | yield None | |
877 |
|
865 | |||
878 |
|
866 | |||
879 |
def _rawgroups(revlog, p1, p2, cachedelta, snapshot |
|
867 | def _rawgroups(revlog, p1, p2, cachedelta, snapshot_cache=None): | |
880 | """Provides group of revision to be tested as delta base |
|
868 | """Provides group of revision to be tested as delta base | |
881 |
|
869 | |||
882 | This lower level function focus on emitting delta theorically interresting |
|
870 | This lower level function focus on emitting delta theorically interresting | |
@@ -907,9 +895,9 b' def _rawgroups(revlog, p1, p2, cachedelt' | |||||
907 | yield parents |
|
895 | yield parents | |
908 |
|
896 | |||
909 | if sparse and parents: |
|
897 | if sparse and parents: | |
910 |
if snapshot |
|
898 | if snapshot_cache is None: | |
911 | # map: base-rev: [snapshot-revs] |
|
899 | # map: base-rev: [snapshot-revs] | |
912 | snapshots = collections.defaultdict(list) |
|
900 | snapshot_cache = SnapshotCache() | |
913 | # See if we can use an existing snapshot in the parent chains to use as |
|
901 | # See if we can use an existing snapshot in the parent chains to use as | |
914 | # a base for a new intermediate-snapshot |
|
902 | # a base for a new intermediate-snapshot | |
915 | # |
|
903 | # | |
@@ -923,7 +911,7 b' def _rawgroups(revlog, p1, p2, cachedelt' | |||||
923 | break |
|
911 | break | |
924 | parents_snaps[idx].add(s) |
|
912 | parents_snaps[idx].add(s) | |
925 | snapfloor = min(parents_snaps[0]) + 1 |
|
913 | snapfloor = min(parents_snaps[0]) + 1 | |
926 |
|
|
914 | snapshot_cache.update(revlog, snapfloor) | |
927 | # search for the highest "unrelated" revision |
|
915 | # search for the highest "unrelated" revision | |
928 | # |
|
916 | # | |
929 | # Adding snapshots used by "unrelated" revision increase the odd we |
|
917 | # Adding snapshots used by "unrelated" revision increase the odd we | |
@@ -961,7 +949,7 b' def _rawgroups(revlog, p1, p2, cachedelt' | |||||
961 | for idx, snaps in sorted(parents_snaps.items(), reverse=True): |
|
949 | for idx, snaps in sorted(parents_snaps.items(), reverse=True): | |
962 | siblings = set() |
|
950 | siblings = set() | |
963 | for s in snaps: |
|
951 | for s in snaps: | |
964 | siblings.update(snapshots[s]) |
|
952 | siblings.update(snapshot_cache.snapshots[s]) | |
965 | # Before considering making a new intermediate snapshot, we check |
|
953 | # Before considering making a new intermediate snapshot, we check | |
966 | # if an existing snapshot, children of base we consider, would be |
|
954 | # if an existing snapshot, children of base we consider, would be | |
967 | # suitable. |
|
955 | # suitable. | |
@@ -989,7 +977,7 b' def _rawgroups(revlog, p1, p2, cachedelt' | |||||
989 | # revisions instead of starting our own. Without such re-use, |
|
977 | # revisions instead of starting our own. Without such re-use, | |
990 | # topological branches would keep reopening new full chains. Creating |
|
978 | # topological branches would keep reopening new full chains. Creating | |
991 | # more and more snapshot as the repository grow. |
|
979 | # more and more snapshot as the repository grow. | |
992 | yield tuple(snapshots[nullrev]) |
|
980 | yield tuple(snapshot_cache.snapshots[nullrev]) | |
993 |
|
981 | |||
994 | if not sparse: |
|
982 | if not sparse: | |
995 | # other approach failed try against prev to hopefully save us a |
|
983 | # other approach failed try against prev to hopefully save us a | |
@@ -997,6 +985,62 b' def _rawgroups(revlog, p1, p2, cachedelt' | |||||
997 | yield (prev,) |
|
985 | yield (prev,) | |
998 |
|
986 | |||
999 |
|
987 | |||
|
988 | class SnapshotCache: | |||
|
989 | __slots__ = ('snapshots', '_start_rev', '_end_rev') | |||
|
990 | ||||
|
991 | def __init__(self): | |||
|
992 | # XXX should probably be a set ? | |||
|
993 | self.snapshots = collections.defaultdict(list) | |||
|
994 | self._start_rev = None | |||
|
995 | self._end_rev = None | |||
|
996 | ||||
|
997 | def update(self, revlog, start_rev=0): | |||
|
998 | """find snapshots from start_rev to tip""" | |||
|
999 | nb_revs = len(revlog) | |||
|
1000 | end_rev = nb_revs - 1 | |||
|
1001 | if start_rev > end_rev: | |||
|
1002 | return # range is empty | |||
|
1003 | ||||
|
1004 | if self._start_rev is None: | |||
|
1005 | assert self._end_rev is None | |||
|
1006 | self._update(revlog, start_rev, end_rev) | |||
|
1007 | elif not (self._start_rev <= start_rev and end_rev <= self._end_rev): | |||
|
1008 | if start_rev < self._start_rev: | |||
|
1009 | self._update(revlog, start_rev, self._start_rev - 1) | |||
|
1010 | if self._end_rev < end_rev: | |||
|
1011 | self._update(revlog, self._end_rev + 1, end_rev) | |||
|
1012 | ||||
|
1013 | if self._start_rev is None: | |||
|
1014 | assert self._end_rev is None | |||
|
1015 | self._end_rev = end_rev | |||
|
1016 | self._start_rev = start_rev | |||
|
1017 | else: | |||
|
1018 | self._start_rev = min(self._start_rev, start_rev) | |||
|
1019 | self._end_rev = max(self._end_rev, end_rev) | |||
|
1020 | assert self._start_rev <= self._end_rev, ( | |||
|
1021 | self._start_rev, | |||
|
1022 | self._end_rev, | |||
|
1023 | ) | |||
|
1024 | ||||
|
1025 | def _update(self, revlog, start_rev, end_rev): | |||
|
1026 | """internal method that actually do update content""" | |||
|
1027 | assert self._start_rev is None or ( | |||
|
1028 | start_rev < self._start_rev or start_rev > self._end_rev | |||
|
1029 | ), (self._start_rev, self._end_rev, start_rev, end_rev) | |||
|
1030 | assert self._start_rev is None or ( | |||
|
1031 | end_rev < self._start_rev or end_rev > self._end_rev | |||
|
1032 | ), (self._start_rev, self._end_rev, start_rev, end_rev) | |||
|
1033 | cache = self.snapshots | |||
|
1034 | if util.safehasattr(revlog.index, b'findsnapshots'): | |||
|
1035 | revlog.index.findsnapshots(cache, start_rev, end_rev) | |||
|
1036 | else: | |||
|
1037 | deltaparent = revlog.deltaparent | |||
|
1038 | issnapshot = revlog.issnapshot | |||
|
1039 | for rev in revlog.revs(start_rev, end_rev): | |||
|
1040 | if issnapshot(rev): | |||
|
1041 | cache[deltaparent(rev)].append(rev) | |||
|
1042 | ||||
|
1043 | ||||
1000 | class deltacomputer: |
|
1044 | class deltacomputer: | |
1001 | def __init__( |
|
1045 | def __init__( | |
1002 | self, |
|
1046 | self, |
@@ -1,7 +1,6 b'' | |||||
1 | # test revlog interaction about raw data (flagprocessor) |
|
1 | # test revlog interaction about raw data (flagprocessor) | |
2 |
|
2 | |||
3 |
|
3 | |||
4 | import collections |
|
|||
5 | import hashlib |
|
4 | import hashlib | |
6 | import sys |
|
5 | import sys | |
7 |
|
6 | |||
@@ -472,16 +471,16 b' snapshotmap15 = {0: [17, 19, 25], 8: [21' | |||||
472 |
|
471 | |||
473 |
|
472 | |||
474 | def findsnapshottest(rlog): |
|
473 | def findsnapshottest(rlog): | |
475 | resultall = collections.defaultdict(list) |
|
474 | cache = deltas.SnapshotCache() | |
476 | deltas._findsnapshots(rlog, resultall, 0) |
|
475 | cache.update(rlog) | |
477 |
resultall = dict( |
|
476 | resultall = dict(cache.snapshots) | |
478 | if resultall != snapshotmapall: |
|
477 | if resultall != snapshotmapall: | |
479 | print('snapshot map differ:') |
|
478 | print('snapshot map differ:') | |
480 | print(' expected: %s' % snapshotmapall) |
|
479 | print(' expected: %s' % snapshotmapall) | |
481 | print(' got: %s' % resultall) |
|
480 | print(' got: %s' % resultall) | |
482 | result15 = collections.defaultdict(list) |
|
481 | cache15 = deltas.SnapshotCache() | |
483 | deltas._findsnapshots(rlog, result15, 15) |
|
482 | cache15.update(rlog, 15) | |
484 |
result15 = dict( |
|
483 | result15 = dict(cache15.snapshots) | |
485 | if result15 != snapshotmap15: |
|
484 | if result15 != snapshotmap15: | |
486 | print('snapshot map differ:') |
|
485 | print('snapshot map differ:') | |
487 | print(' expected: %s' % snapshotmap15) |
|
486 | print(' expected: %s' % snapshotmap15) |
General Comments 0
You need to be logged in to leave comments.
Login now