##// END OF EJS Templates
delta-find: use a smarter object for snapshot caching...
marmoute -
r50573:efbbc2f9 default
parent child Browse files
Show More
@@ -20,7 +20,7 b' for inline in (True, False):'
20 20 index, cache = parsers.parse_index2(data, inline)
21 21 index.slicechunktodensity(list(range(len(index))), 0.5, 262144)
22 22 index.stats()
23 index.findsnapshots({}, 0)
23 index.findsnapshots({}, 0, len(index) - 1)
24 24 10 in index
25 25 for rev in range(len(index)):
26 26 index.reachableroots(0, [len(index)-1], [rev])
@@ -1446,16 +1446,25 b' static PyObject *index_issnapshot(indexO'
1446 1446 static PyObject *index_findsnapshots(indexObject *self, PyObject *args)
1447 1447 {
1448 1448 Py_ssize_t start_rev;
1449 Py_ssize_t end_rev;
1449 1450 PyObject *cache;
1450 1451 Py_ssize_t base;
1451 1452 Py_ssize_t rev;
1452 1453 PyObject *key = NULL;
1453 1454 PyObject *value = NULL;
1454 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 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 1468 int issnap;
1460 1469 PyObject *allvalues = NULL;
1461 1470 issnap = index_issnapshotrev(self, rev);
@@ -799,18 +799,6 b' def _candidategroups('
799 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 802 def _refinedgroups(revlog, p1, p2, cachedelta):
815 803 good = None
816 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 820 yield None
833 821 return
834 822 # XXX cache me higher
835 snapshots = collections.defaultdict(list)
823 snapshot_cache = SnapshotCache()
836 824 groups = _rawgroups(
837 825 revlog,
838 826 p1,
839 827 p2,
840 828 cachedelta,
841 snapshots,
829 snapshot_cache,
842 830 )
843 831 for candidates in groups:
844 832 good = yield candidates
@@ -861,12 +849,12 b' def _refinedgroups(revlog, p1, p2, cache'
861 849 break
862 850 good = yield (base,)
863 851 # refine snapshot up
864 if not snapshots:
865 _findsnapshots(revlog, snapshots, good + 1)
852 if not snapshot_cache.snapshots:
853 snapshot_cache.update(revlog, good + 1)
866 854 previous = None
867 855 while good != previous:
868 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 858 good = yield children
871 859
872 860 if debug_info is not None:
@@ -876,7 +864,7 b' def _refinedgroups(revlog, p1, p2, cache'
876 864 yield None
877 865
878 866
879 def _rawgroups(revlog, p1, p2, cachedelta, snapshots=None):
867 def _rawgroups(revlog, p1, p2, cachedelta, snapshot_cache=None):
880 868 """Provides group of revision to be tested as delta base
881 869
882 870 This lower level function focus on emitting delta theorically interresting
@@ -907,9 +895,9 b' def _rawgroups(revlog, p1, p2, cachedelt'
907 895 yield parents
908 896
909 897 if sparse and parents:
910 if snapshots is None:
898 if snapshot_cache is None:
911 899 # map: base-rev: [snapshot-revs]
912 snapshots = collections.defaultdict(list)
900 snapshot_cache = SnapshotCache()
913 901 # See if we can use an existing snapshot in the parent chains to use as
914 902 # a base for a new intermediate-snapshot
915 903 #
@@ -923,7 +911,7 b' def _rawgroups(revlog, p1, p2, cachedelt'
923 911 break
924 912 parents_snaps[idx].add(s)
925 913 snapfloor = min(parents_snaps[0]) + 1
926 _findsnapshots(revlog, snapshots, snapfloor)
914 snapshot_cache.update(revlog, snapfloor)
927 915 # search for the highest "unrelated" revision
928 916 #
929 917 # Adding snapshots used by "unrelated" revision increase the odd we
@@ -961,7 +949,7 b' def _rawgroups(revlog, p1, p2, cachedelt'
961 949 for idx, snaps in sorted(parents_snaps.items(), reverse=True):
962 950 siblings = set()
963 951 for s in snaps:
964 siblings.update(snapshots[s])
952 siblings.update(snapshot_cache.snapshots[s])
965 953 # Before considering making a new intermediate snapshot, we check
966 954 # if an existing snapshot, children of base we consider, would be
967 955 # suitable.
@@ -989,7 +977,7 b' def _rawgroups(revlog, p1, p2, cachedelt'
989 977 # revisions instead of starting our own. Without such re-use,
990 978 # topological branches would keep reopening new full chains. Creating
991 979 # more and more snapshot as the repository grow.
992 yield tuple(snapshots[nullrev])
980 yield tuple(snapshot_cache.snapshots[nullrev])
993 981
994 982 if not sparse:
995 983 # other approach failed try against prev to hopefully save us a
@@ -997,6 +985,62 b' def _rawgroups(revlog, p1, p2, cachedelt'
997 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 1044 class deltacomputer:
1001 1045 def __init__(
1002 1046 self,
@@ -1,7 +1,6 b''
1 1 # test revlog interaction about raw data (flagprocessor)
2 2
3 3
4 import collections
5 4 import hashlib
6 5 import sys
7 6
@@ -472,16 +471,16 b' snapshotmap15 = {0: [17, 19, 25], 8: [21'
472 471
473 472
474 473 def findsnapshottest(rlog):
475 resultall = collections.defaultdict(list)
476 deltas._findsnapshots(rlog, resultall, 0)
477 resultall = dict(resultall.items())
474 cache = deltas.SnapshotCache()
475 cache.update(rlog)
476 resultall = dict(cache.snapshots)
478 477 if resultall != snapshotmapall:
479 478 print('snapshot map differ:')
480 479 print(' expected: %s' % snapshotmapall)
481 480 print(' got: %s' % resultall)
482 result15 = collections.defaultdict(list)
483 deltas._findsnapshots(rlog, result15, 15)
484 result15 = dict(result15.items())
481 cache15 = deltas.SnapshotCache()
482 cache15.update(rlog, 15)
483 result15 = dict(cache15.snapshots)
485 484 if result15 != snapshotmap15:
486 485 print('snapshot map differ:')
487 486 print(' expected: %s' % snapshotmap15)
General Comments 0
You need to be logged in to leave comments. Login now