##// 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 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 snapshots,
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 _findsnapshots(revlog, snapshots, good + 1)
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, snapshots=None):
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 snapshots is None:
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 _findsnapshots(revlog, snapshots, snapfloor)
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(resultall.items())
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(result15.items())
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