diff options
author | josh.macdonald <jmacd@users.noreply.github.com> | 2008-07-08 04:07:45 +0000 |
---|---|---|
committer | josh.macdonald <jmacd@users.noreply.github.com> | 2008-07-08 04:07:45 +0000 |
commit | d0c5ff7a1847558a9264d9485e336f549b66dd38 (patch) | |
tree | d19851cb1d698cb1d7ea6046ab5333ad0258323b /xdelta3/testing/modify.h | |
parent | 2f8593b1222a6e74c835a1b90e4195de0ba234d0 (diff) |
Add testing for move/copy mutators.
Diffstat (limited to 'xdelta3/testing/modify.h')
-rw-r--r-- | xdelta3/testing/modify.h | 119 |
1 files changed, 112 insertions, 7 deletions
diff --git a/xdelta3/testing/modify.h b/xdelta3/testing/modify.h index 2f3e752..ac2286a 100644 --- a/xdelta3/testing/modify.h +++ b/xdelta3/testing/modify.h | |||
@@ -14,8 +14,9 @@ public: | |||
14 | enum Kind { | 14 | enum Kind { |
15 | MODIFY = 1, | 15 | MODIFY = 1, |
16 | ADD = 2, | 16 | ADD = 2, |
17 | MOVE = 3, | 17 | DELETE = 3, |
18 | DELETE = 4, | 18 | MOVE = 4, |
19 | COPY = 5, | ||
19 | }; | 20 | }; |
20 | 21 | ||
21 | // Constructor for modify, add, delete. | 22 | // Constructor for modify, add, delete. |
@@ -23,15 +24,16 @@ public: | |||
23 | : kind(kind), | 24 | : kind(kind), |
24 | size(size), | 25 | size(size), |
25 | addr1(addr1) { | 26 | addr1(addr1) { |
26 | CHECK_NE(kind, MOVE); | 27 | CHECK(kind != MOVE && kind != COPY); |
27 | } | 28 | } |
28 | 29 | ||
29 | // Constructor for move | 30 | // Constructor for move |
30 | Change(Kind kind, xoff_t size, xoff_t addr1, xoff_t addr2) | 31 | Change(Kind kind, xoff_t size, xoff_t addr1, xoff_t addr2) |
31 | : kind(kind), | 32 | : kind(kind), |
32 | size(size), | 33 | size(size), |
33 | addr1(addr1) { | 34 | addr1(addr1), |
34 | CHECK_EQ(kind, MOVE); | 35 | addr2(addr2) { |
36 | CHECK(kind == MOVE || kind == COPY); | ||
35 | } | 37 | } |
36 | 38 | ||
37 | Kind kind; | 39 | Kind kind; |
@@ -78,6 +80,17 @@ public: | |||
78 | const SegmentMap *source_table, | 80 | const SegmentMap *source_table, |
79 | MTRandom *rand); | 81 | MTRandom *rand); |
80 | 82 | ||
83 | static void CopyChange(const Change &ch, | ||
84 | SegmentMap *table, | ||
85 | const SegmentMap *source_table, | ||
86 | MTRandom *rand); | ||
87 | |||
88 | static void AppendCopy(SegmentMap *table, | ||
89 | const SegmentMap *source_table, | ||
90 | xoff_t copy_offset, | ||
91 | xoff_t append_offset, | ||
92 | xoff_t length); | ||
93 | |||
81 | ChangeList* Changes() { | 94 | ChangeList* Changes() { |
82 | return &cl_; | 95 | return &cl_; |
83 | } | 96 | } |
@@ -119,11 +132,14 @@ void ChangeListMutator::Mutate(const Change &ch, | |||
119 | case Change::DELETE: | 132 | case Change::DELETE: |
120 | DeleteChange(ch, table, source_table, rand); | 133 | DeleteChange(ch, table, source_table, rand); |
121 | break; | 134 | break; |
135 | case Change::COPY: | ||
136 | CopyChange(ch, table, source_table, rand); | ||
137 | break; | ||
122 | case Change::MOVE: | 138 | case Change::MOVE: |
123 | //MoveChange(ch, table, source_table, rand); | 139 | MoveChange(ch, table, source_table, rand); |
124 | break; | 140 | break; |
125 | } | 141 | } |
126 | } | 142 | } |
127 | 143 | ||
128 | void ChangeListMutator::ModifyChange(const Change &ch, | 144 | void ChangeListMutator::ModifyChange(const Change &ch, |
129 | SegmentMap *table, | 145 | SegmentMap *table, |
@@ -258,6 +274,95 @@ void ChangeListMutator::DeleteChange(const Change &ch, | |||
258 | CHECK_LE(m_end, i_end); | 274 | CHECK_LE(m_end, i_end); |
259 | } | 275 | } |
260 | 276 | ||
277 | void ChangeListMutator::MoveChange(const Change &ch, | ||
278 | SegmentMap *table, | ||
279 | const SegmentMap *source_table, | ||
280 | MTRandom *rand) { | ||
281 | SegmentMap tmp; | ||
282 | CHECK_NE(ch.addr1, ch.addr2); | ||
283 | CopyChange(ch, &tmp, source_table, rand); | ||
284 | Change d(Change::DELETE, ch.size, | ||
285 | ch.addr1 < ch.addr2 ? ch.addr1 : ch.addr1 + ch.size); | ||
286 | DeleteChange(d, table, &tmp, rand); | ||
287 | } | ||
288 | |||
289 | void ChangeListMutator::CopyChange(const Change &ch, | ||
290 | SegmentMap *table, | ||
291 | const SegmentMap *source_table, | ||
292 | MTRandom *ignore) { | ||
293 | xoff_t m_start = ch.addr2; | ||
294 | xoff_t c_start = ch.addr1; | ||
295 | xoff_t i_start = 0; | ||
296 | xoff_t i_end = 0; | ||
297 | |||
298 | // Like AddChange() with AppendCopy instead of a random segment. | ||
299 | for (SegmentMap::const_iterator iter(source_table->begin()); | ||
300 | iter != source_table->end(); | ||
301 | ++iter) { | ||
302 | const Segment &seg = iter->second; | ||
303 | i_start = iter->first; | ||
304 | i_end = i_start + seg.length; | ||
305 | |||
306 | if (i_end <= m_start) { | ||
307 | table->insert(table->end(), make_pair(i_start, seg)); | ||
308 | continue; | ||
309 | } | ||
310 | |||
311 | if (i_start > m_start) { | ||
312 | table->insert(table->end(), make_pair(i_start + ch.size, seg)); | ||
313 | continue; | ||
314 | } | ||
315 | |||
316 | if (i_start < m_start) { | ||
317 | Segment before(seg.seed, m_start - i_start, seg.seed_offset); | ||
318 | table->insert(table->end(), make_pair(i_start, before)); | ||
319 | } | ||
320 | |||
321 | AppendCopy(table, source_table, c_start, m_start, ch.size); | ||
322 | |||
323 | if (m_start < i_end) { | ||
324 | Segment after(seg.seed, i_end - m_start, | ||
325 | seg.seed_offset + (m_start - i_start)); | ||
326 | table->insert(table->end(), make_pair(m_start + ch.size, after)); | ||
327 | } | ||
328 | } | ||
329 | |||
330 | CHECK_LE(m_start, i_end); | ||
331 | |||
332 | // Special case for copy to end-of-input. | ||
333 | if (m_start == i_end) { | ||
334 | AppendCopy(table, source_table, c_start, m_start, ch.size); | ||
335 | } | ||
336 | } | ||
337 | |||
338 | void ChangeListMutator::AppendCopy(SegmentMap *table, | ||
339 | const SegmentMap *source_table, | ||
340 | xoff_t copy_offset, | ||
341 | xoff_t append_offset, | ||
342 | xoff_t length) { | ||
343 | SegmentMap::const_iterator pos(source_table->upper_bound(copy_offset)); | ||
344 | --pos; | ||
345 | xoff_t got = 0; | ||
346 | |||
347 | while (got < length) { | ||
348 | size_t seg_offset = copy_offset - pos->first; | ||
349 | xoff_t skip = seg_offset + pos->second.seed_offset; | ||
350 | size_t advance = min(pos->second.length - seg_offset, | ||
351 | (size_t)(length - got)); | ||
352 | |||
353 | table->insert(table->end(), | ||
354 | make_pair(append_offset, | ||
355 | Segment(pos->second.seed, | ||
356 | advance, | ||
357 | skip))); | ||
358 | |||
359 | got += advance; | ||
360 | copy_offset += advance; | ||
361 | append_offset += advance; | ||
362 | ++pos; | ||
363 | } | ||
364 | } | ||
365 | |||
261 | class Modify1stByte : public Mutator { | 366 | class Modify1stByte : public Mutator { |
262 | public: | 367 | public: |
263 | void Mutate(SegmentMap *table, | 368 | void Mutate(SegmentMap *table, |