##// END OF EJS Templates
changegroup: capture revision delta in a data structure...
Gregory Szorc -
r38929:23d582ca default
parent child Browse files
Show More
@@ -19,6 +19,10 b' from .node import ('
19 short,
19 short,
20 )
20 )
21
21
22 from .thirdparty import (
23 attr,
24 )
25
22 from . import (
26 from . import (
23 dagutil,
27 dagutil,
24 error,
28 error,
@@ -494,6 +498,26 b' class headerlessfixup(object):'
494 return d
498 return d
495 return readexactly(self._fh, n)
499 return readexactly(self._fh, n)
496
500
501 @attr.s(slots=True, frozen=True)
502 class revisiondelta(object):
503 """Describes a delta entry in a changegroup.
504
505 Captured data is sufficient to serialize the delta into multiple
506 formats.
507 """
508 # 20 byte node of this revision.
509 node = attr.ib()
510 # 20 byte nodes of parent revisions.
511 p1node = attr.ib()
512 p2node = attr.ib()
513 # 20 byte node of node this delta is against.
514 basenode = attr.ib()
515 # 20 byte node of changeset revision this delta is associated with.
516 linknode = attr.ib()
517 # 2 bytes of flags to apply to revision data.
518 flags = attr.ib()
519 # Iterable of chunks holding raw delta data.
520 deltachunks = attr.ib()
497
521
498 class cg1packer(object):
522 class cg1packer(object):
499 deltaheader = _CHANGEGROUPV1_DELTA_HEADER
523 deltaheader = _CHANGEGROUPV1_DELTA_HEADER
@@ -899,13 +923,25 b' class cg1packer(object):'
899
923
900 def revchunk(self, store, rev, prev, linknode):
924 def revchunk(self, store, rev, prev, linknode):
901 if util.safehasattr(self, 'full_nodes'):
925 if util.safehasattr(self, 'full_nodes'):
902 fn = self._revchunknarrow
926 fn = self._revisiondeltanarrow
903 else:
927 else:
904 fn = self._revchunknormal
928 fn = self._revisiondeltanormal
929
930 delta = fn(store, rev, prev, linknode)
931 if not delta:
932 return
905
933
906 return fn(store, rev, prev, linknode)
934 meta = self.builddeltaheader(delta.node, delta.p1node, delta.p2node,
935 delta.basenode, delta.linknode,
936 delta.flags)
937 l = len(meta) + sum(len(x) for x in delta.deltachunks)
907
938
908 def _revchunknormal(self, store, rev, prev, linknode):
939 yield chunkheader(l)
940 yield meta
941 for x in delta.deltachunks:
942 yield x
943
944 def _revisiondeltanormal(self, store, rev, prev, linknode):
909 node = store.node(rev)
945 node = store.node(rev)
910 p1, p2 = store.parentrevs(rev)
946 p1, p2 = store.parentrevs(rev)
911 base = self.deltaparent(store, rev, p1, p2, prev)
947 base = self.deltaparent(store, rev, p1, p2, prev)
@@ -927,16 +963,18 b' class cg1packer(object):'
927 else:
963 else:
928 delta = store.revdiff(base, rev)
964 delta = store.revdiff(base, rev)
929 p1n, p2n = store.parents(node)
965 p1n, p2n = store.parents(node)
930 basenode = store.node(base)
931 flags = store.flags(rev)
932 meta = self.builddeltaheader(node, p1n, p2n, basenode, linknode, flags)
933 meta += prefix
934 l = len(meta) + len(delta)
935 yield chunkheader(l)
936 yield meta
937 yield delta
938
966
939 def _revchunknarrow(self, store, rev, prev, linknode):
967 return revisiondelta(
968 node=node,
969 p1node=p1n,
970 p2node=p2n,
971 basenode=store.node(base),
972 linknode=linknode,
973 flags=store.flags(rev),
974 deltachunks=(prefix, delta),
975 )
976
977 def _revisiondeltanarrow(self, store, rev, prev, linknode):
940 # build up some mapping information that's useful later. See
978 # build up some mapping information that's useful later. See
941 # the local() nested function below.
979 # the local() nested function below.
942 if not self.changelog_done:
980 if not self.changelog_done:
@@ -950,9 +988,7 b' class cg1packer(object):'
950 # This is a node to send in full, because the changeset it
988 # This is a node to send in full, because the changeset it
951 # corresponds to was a full changeset.
989 # corresponds to was a full changeset.
952 if linknode in self.full_nodes:
990 if linknode in self.full_nodes:
953 for x in self._revchunknormal(store, rev, prev, linknode):
991 return self._revisiondeltanormal(store, rev, prev, linknode)
954 yield x
955 return
956
992
957 # At this point, a node can either be one we should skip or an
993 # At this point, a node can either be one we should skip or an
958 # ellipsis. If it's not an ellipsis, bail immediately.
994 # ellipsis. If it's not an ellipsis, bail immediately.
@@ -1043,16 +1079,20 b' class cg1packer(object):'
1043 p1n, p2n = store.node(p1), store.node(p2)
1079 p1n, p2n = store.node(p1), store.node(p2)
1044 flags = store.flags(rev)
1080 flags = store.flags(rev)
1045 flags |= revlog.REVIDX_ELLIPSIS
1081 flags |= revlog.REVIDX_ELLIPSIS
1046 meta = self.builddeltaheader(
1082
1047 n, p1n, p2n, nullid, linknode, flags)
1048 # TODO: try and actually send deltas for ellipsis data blocks
1083 # TODO: try and actually send deltas for ellipsis data blocks
1049 data = store.revision(n)
1084 data = store.revision(n)
1050 diffheader = mdiff.trivialdiffheader(len(data))
1085 diffheader = mdiff.trivialdiffheader(len(data))
1051 l = len(meta) + len(diffheader) + len(data)
1086
1052 yield ''.join((chunkheader(l),
1087 return revisiondelta(
1053 meta,
1088 node=n,
1054 diffheader,
1089 p1node=p1n,
1055 data))
1090 p2node=p2n,
1091 basenode=nullid,
1092 linknode=linknode,
1093 flags=flags,
1094 deltachunks=(diffheader, data),
1095 )
1056
1096
1057 def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags):
1097 def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags):
1058 # do nothing with basenode, it is implicitly the previous one in HG10
1098 # do nothing with basenode, it is implicitly the previous one in HG10
General Comments 0
You need to be logged in to leave comments. Login now