817
817
return SVN_NO_ERROR;
820
/* Either remove any overlapping ranges described by ERASER from
821
WHITEBOARD (when DO_REMOVE is TRUE), or capture the overlap, and
822
place the remaining or overlapping ranges in OUTPUT. */
823
/* ### FIXME: Some variables names and inline comments for this method
824
### are legacy from when it was solely the remove() impl. */
821
svn_rangelist__set_inheritance(apr_array_header_t *rangelist,
822
svn_boolean_t inheritable)
827
svn_merge_range_t *range;
829
for (i = 0; i < rangelist->nelts; i++)
831
range = APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *);
832
range->inheritable = inheritable;
838
/* If DO_REMOVE is true, then remove any overlapping ranges described by
839
RANGELIST1 from RANGELIST2 and place the results in *OUTPUT. When
840
DO_REMOVE is true, RANGELIST1 is effectively the "eraser" and RANGELIST2
843
If DO_REMOVE is false, then capture the intersection between RANGELIST1
844
and RANGELIST2 and place the results in *OUTPUT. The ordering of
845
RANGELIST1 and RANGELIST2 doesn't matter when DO_REMOVE is false.
847
If CONSIDER_INHERITANCE is true, then take the inheritance of the
848
ranges in RANGELIST1 and RANGELIST2 into account when comparing them
849
for intersection, see the doc string for svn_rangelist_intersection().
851
If CONSIDER_INHERITANCE is true, then ranges with differing inheritance
852
may intersect, but the resulting intersection is non-inheritable only
853
if both ranges were non-inheritable, e.g.:
855
RANGELIST1 RANGELIST2 CONSIDER DO_REMOVE *OUTPUT
857
---------- ------ ----------- --------- -------
859
90-420* 1-100 TRUE FALSE Empty Rangelist
860
90-420 1-100* TRUE FALSE Empty Rangelist
861
90-420 1-100 TRUE FALSE 90-100
862
90-420* 1-100* TRUE FALSE 90-100*
864
90-420* 1-100 FALSE FALSE 90-100
865
90-420 1-100* FALSE FALSE 90-100
866
90-420 1-100 FALSE FALSE 90-100
867
90-420* 1-100* FALSE FALSE 90-100*
869
Allocate the contents of *OUTPUT in POOL. */
825
870
static svn_error_t *
826
871
rangelist_intersect_or_remove(apr_array_header_t **output,
827
apr_array_header_t *eraser,
828
apr_array_header_t *whiteboard,
872
const apr_array_header_t *rangelist1,
873
const apr_array_header_t *rangelist2,
829
874
svn_boolean_t do_remove,
830
875
svn_boolean_t consider_inheritance,
831
876
apr_pool_t *pool)
841
886
lasti = -1; /* Initialized to a value that "i" will never be. */
843
while (i < whiteboard->nelts && j < eraser->nelts)
888
while (i < rangelist2->nelts && j < rangelist1->nelts)
845
890
svn_merge_range_t *elt1, *elt2;
847
elt2 = APR_ARRAY_IDX(eraser, j, svn_merge_range_t *);
892
elt2 = APR_ARRAY_IDX(rangelist1, j, svn_merge_range_t *);
849
/* Instead of making a copy of the entire array of whiteboard
850
elements, we just keep a copy of the current whiteboard element
894
/* Instead of making a copy of the entire array of rangelist2
895
elements, we just keep a copy of the current rangelist2 element
851
896
that needs to be used, and modify our copy if necessary. */
854
wboardelt = *(APR_ARRAY_IDX(whiteboard, i, svn_merge_range_t *));
899
wboardelt = *(APR_ARRAY_IDX(rangelist2, i, svn_merge_range_t *));
858
903
elt1 = &wboardelt;
860
/* If the whiteboard range is contained completely in the
861
eraser, we increment the whiteboard.
905
/* If the rangelist2 range is contained completely in the
906
rangelist1, we increment the rangelist2.
862
907
If the ranges intersect, and match exactly, we increment both
863
eraser and whiteboard.
908
rangelist1 and rangelist2.
864
909
Otherwise, we have to generate a range for the left part of
865
the removal of eraser from whiteboard, and possibly change
866
the whiteboard to the remaining portion of the right part of
910
the removal of rangelist1 from rangelist2, and possibly change
911
the rangelist2 to the remaining portion of the right part of
867
912
the removal, to test against. */
868
913
if (range_contains(elt2, elt1, consider_inheritance))
871
SVN_ERR(combine_with_lastrange(&lastrange, elt1, *output,
872
consider_inheritance, pool,
917
svn_merge_range_t tmp_range;
918
tmp_range.start = elt1->start;
919
tmp_range.end = elt1->end;
920
/* The intersection of two ranges is non-inheritable only
921
if both ranges are non-inheritable. */
922
tmp_range.inheritable =
923
(elt1->inheritable || elt2->inheritable);
924
SVN_ERR(combine_with_lastrange(&lastrange, &tmp_range, *output,
925
consider_inheritance, pool,
882
936
if (elt1->start < elt2->start)
884
/* The whiteboard range starts before the eraser range. */
938
/* The rangelist2 range starts before the rangelist1 range. */
885
939
svn_merge_range_t tmp_range;
886
tmp_range.inheritable = elt1->inheritable;
889
/* Retain the range that falls before the eraser start. */
942
/* Retain the range that falls before the rangelist1
890
944
tmp_range.start = elt1->start;
891
945
tmp_range.end = elt2->start;
946
tmp_range.inheritable = elt1->inheritable;
895
/* Retain the range that falls between the eraser
896
start and whiteboard end. */
950
/* Retain the range that falls between the rangelist1
951
start and rangelist2 end. */
897
952
tmp_range.start = elt2->start;
898
953
tmp_range.end = MIN(elt1->end, elt2->end);
954
/* The intersection of two ranges is non-inheritable only
955
if both ranges are non-inheritable. */
956
tmp_range.inheritable =
957
(elt1->inheritable || elt2->inheritable);
901
960
SVN_ERR(combine_with_lastrange(&lastrange, &tmp_range,
906
/* Set up the rest of the whiteboard range for further
965
/* Set up the rest of the rangelist2 range for further
908
967
if (elt1->end > elt2->end)
910
/* The whiteboard range ends after the eraser range. */
969
/* The rangelist2 range ends after the rangelist1 range. */
913
972
/* Partial overlap. */
914
973
svn_merge_range_t tmp_range;
915
974
tmp_range.start = MAX(elt1->start, elt2->start);
916
975
tmp_range.end = elt2->end;
917
tmp_range.inheritable = elt1->inheritable;
976
/* The intersection of two ranges is non-inheritable only
977
if both ranges are non-inheritable. */
978
tmp_range.inheritable =
979
(elt1->inheritable || elt2->inheritable);
918
980
SVN_ERR(combine_with_lastrange(&lastrange, &tmp_range,
920
982
consider_inheritance,
930
992
else /* ranges don't intersect */
932
/* See which side of the whiteboard the eraser is on. If it
933
is on the left side, we need to move the eraser.
994
/* See which side of the rangelist2 the rangelist1 is on. If it
995
is on the left side, we need to move the rangelist1.
935
If it is on past the whiteboard on the right side, we
936
need to output the whiteboard and increment the
997
If it is on past the rangelist2 on the right side, we
998
need to output the rangelist2 and increment the
938
1000
if (svn_sort_compare_ranges(&elt2, &elt1) < 0)
956
/* Copy the current whiteboard element if we didn't hit the end
957
of the whiteboard, and we still had it around. This element
958
may have been touched, so we can't just walk the whiteboard
1018
/* Copy the current rangelist2 element if we didn't hit the end
1019
of the rangelist2, and we still had it around. This element
1020
may have been touched, so we can't just walk the rangelist2
959
1021
array, we have to use our copy. This case only happens when
960
we ran out of eraser before whiteboard, *and* we had changed
961
the whiteboard element. */
962
if (i == lasti && i < whiteboard->nelts)
1022
we ran out of rangelist1 before rangelist2, *and* we had changed
1023
the rangelist2 element. */
1024
if (i == lasti && i < rangelist2->nelts)
964
1026
SVN_ERR(combine_with_lastrange(&lastrange, &wboardelt, *output,
965
1027
consider_inheritance, pool, pool));
969
/* Copy any other remaining untouched whiteboard elements. */
970
for (; i < whiteboard->nelts; i++)
1031
/* Copy any other remaining untouched rangelist2 elements. */
1032
for (; i < rangelist2->nelts; i++)
972
svn_merge_range_t *elt = APR_ARRAY_IDX(whiteboard, i,
1034
svn_merge_range_t *elt = APR_ARRAY_IDX(rangelist2, i,
973
1035
svn_merge_range_t *);
975
1037
SVN_ERR(combine_with_lastrange(&lastrange, elt, *output,