File indexing completed on 2025-03-09 05:11:45
0001 /* 0002 SPDX-FileCopyrightText: 2021 Hamed Masafi <hamed.masfi@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-3.0-or-later 0005 */ 0006 0007 #include "solution.h" 0008 0009 namespace Diff 0010 { 0011 0012 SolutionIterator::Result::Result() 0013 : oldStart(0) 0014 , oldSize(0) 0015 , newStart(0) 0016 , newSize(0) 0017 , success(false) 0018 , type(SegmentType::DifferentOnBoth) 0019 { 0020 } 0021 0022 SolutionIterator::Result::Result(int oldStart, int oldSize, int newStart, int newSize, bool success, SegmentType type) 0023 : oldStart(oldStart) 0024 , oldSize(oldSize) 0025 , newStart(newStart) 0026 , newSize(newSize) 0027 , success(success) 0028 , type(type) 0029 { 0030 } 0031 0032 SolutionIterator::SolutionIterator(const Solution &solution, int firstSize, int secondSize) 0033 : _solution(solution) 0034 , i(_solution.begin()) 0035 , _firstSize{firstSize} 0036 , _secondSize{secondSize} 0037 { 0038 } 0039 0040 void SolutionIterator::begin() 0041 { 0042 _firstIndex = _secondIndex = 0; 0043 i = _solution.begin(); 0044 _ended = false; 0045 } 0046 0047 SolutionIterator::Result SolutionIterator::pick() 0048 { 0049 if (i == _solution.end()) { 0050 if (_ended) 0051 return {}; 0052 else { 0053 Result r{_firstIndex, _firstSize - _firstIndex, _firstIndex, _secondSize - _secondIndex, true, SegmentType::SameOnBoth}; 0054 if (r.newSize && r.oldSize) 0055 r.type = SegmentType::DifferentOnBoth; 0056 else if (r.newSize) 0057 r.type = SegmentType::OnlyOnRight; 0058 else 0059 r.type = SegmentType::OnlyOnLeft; 0060 r.success = true; 0061 _ended = true; 0062 return r; 0063 } 0064 } 0065 0066 if ((i->first == _firstIndex && i->second == _secondIndex)) { 0067 auto fi = _firstIndex; 0068 auto si = _secondIndex; 0069 do { 0070 _firstIndex++; 0071 _secondIndex++; 0072 ++i; 0073 } while (i != _solution.end() && i->first == _firstIndex && i->second == _secondIndex); 0074 0075 return {fi, _firstIndex - fi, si, _secondIndex - si, true, SegmentType::SameOnBoth}; 0076 0077 } else { 0078 Result r{_firstIndex, i->first - _firstIndex, _secondIndex, i->second - _secondIndex, true, SegmentType::DifferentOnBoth}; 0079 _firstIndex = i->first; 0080 _secondIndex = i->second; 0081 0082 if (r.newSize && r.oldSize) 0083 r.type = SegmentType::DifferentOnBoth; 0084 else if (r.newSize) 0085 r.type = SegmentType::OnlyOnRight; 0086 else 0087 r.type = SegmentType::OnlyOnLeft; 0088 r.success = true; 0089 return r; 0090 } 0091 0092 return {}; 0093 } 0094 QDebug &operator<<(QDebug &stream, const Diff::Solution &sln) 0095 { 0096 for (auto i = sln.begin(); i != sln.end(); ++i) 0097 stream << "(" << i->first << ", " << i->second << ")"; 0098 return stream; 0099 } 0100 0101 QDebug operator<<(QDebug d, const SolutionIterator::Result &r) 0102 { 0103 d.noquote() << "(Old: " << r.oldStart << " size=" << r.oldSize << ", New: " << r.newStart << " size=" << r.newSize << ")"; 0104 return d; 0105 } 0106 0107 SolutionIterator3::SolutionIterator3(const Solution3 &solution) 0108 : _solution(solution) 0109 , i(_solution.begin()) 0110 { 0111 } 0112 0113 void SolutionIterator3::begin() 0114 { 0115 _firstIndex = _secondIndex = _thirdIndex = -1; 0116 i = _solution.begin(); 0117 } 0118 0119 Diff::SolutionIterator3::Result Diff::SolutionIterator3::pick() 0120 { 0121 if (i == _solution.end()) 0122 return {}; 0123 0124 if ((i->first == _firstIndex && i->second == _secondIndex && i->third == _thirdIndex)) { 0125 auto fi = _firstIndex; 0126 auto si = _secondIndex; 0127 auto ti = _thirdIndex; 0128 do { 0129 _firstIndex++; 0130 _secondIndex++; 0131 _thirdIndex++; 0132 ++i; 0133 } while (i != _solution.end() && i->first == _firstIndex && i->second == _secondIndex); 0134 0135 return {{fi, _firstIndex - fi}, {si, _secondIndex - si}, {ti, _thirdIndex - ti}, SegmentType::SameOnBoth}; 0136 0137 } else { 0138 Result r{{_firstIndex, i->first - _firstIndex}, 0139 {_secondIndex, i->second - _secondIndex}, 0140 {_thirdIndex, i->third - _thirdIndex}, 0141 SegmentType::DifferentOnBoth}; 0142 _firstIndex = i->first; 0143 _secondIndex = i->second; 0144 _thirdIndex = i->third; 0145 0146 if (r.local.size && r.remote.size) 0147 r.type = SegmentType::DifferentOnBoth; 0148 else if (r.remote.size) 0149 r.type = SegmentType::OnlyOnRight; 0150 else 0151 r.type = SegmentType::OnlyOnLeft; 0152 r.success = true; 0153 return r; 0154 } 0155 0156 return {}; 0157 } 0158 0159 SolutionIterator3::Result::Result() 0160 : base{} 0161 , local{} 0162 , remote{} 0163 , success{false} 0164 , type{} 0165 { 0166 } 0167 0168 Diff::SolutionIterator3::Result::Result(Range base, Range local, Range remote, SegmentType type) 0169 : base{base} 0170 , local{local} 0171 , remote{remote} 0172 , success{true} 0173 , type{type} 0174 { 0175 } 0176 0177 Range::Range() 0178 : begin{-1} 0179 , size{-1} 0180 { 0181 } 0182 0183 Range::Range(int begin, int size) 0184 : begin{begin} 0185 , size{size} 0186 { 0187 } 0188 }