diff options
author | josh.macdonald <jmacd@users.noreply.github.com> | 2008-07-09 06:56:30 +0000 |
---|---|---|
committer | josh.macdonald <jmacd@users.noreply.github.com> | 2008-07-09 06:56:30 +0000 |
commit | bd594c150533173d0340df8204824c9d6f00966b (patch) | |
tree | a56e040c0b7e1cf13062401e06ed2c40049c5f41 /xdelta3/testing/file.h | |
parent | d0c5ff7a1847558a9264d9485e336f549b66dd38 (diff) |
Attempting to reproduce the non-blocking bug which caused an
infinite loop due to hash collision in a recently reported issue.
Having trouble, but this refactoring allows Segment to use fixed data.
Diffstat (limited to 'xdelta3/testing/file.h')
-rw-r--r-- | xdelta3/testing/file.h | 57 |
1 files changed, 31 insertions, 26 deletions
diff --git a/xdelta3/testing/file.h b/xdelta3/testing/file.h index 38aa463..d38a720 100644 --- a/xdelta3/testing/file.h +++ b/xdelta3/testing/file.h | |||
@@ -16,7 +16,7 @@ class FileSpec { | |||
16 | 16 | ||
17 | for (xoff_t p = 0; p < size; ) { | 17 | for (xoff_t p = 0; p < size; ) { |
18 | xoff_t t = min(Constants::BLOCK_SIZE, size - p); | 18 | xoff_t t = min(Constants::BLOCK_SIZE, size - p); |
19 | table_.insert(make_pair(p, Segment(rand_->Rand32(), t))); | 19 | table_.insert(make_pair(p, Segment(t, rand_))); |
20 | p += t; | 20 | p += t; |
21 | } | 21 | } |
22 | } | 22 | } |
@@ -32,7 +32,7 @@ class FileSpec { | |||
32 | return 0; | 32 | return 0; |
33 | } | 33 | } |
34 | SegmentMap::const_iterator i = --table_.end(); | 34 | SegmentMap::const_iterator i = --table_.end(); |
35 | return i->first + i->second.length; | 35 | return i->first + i->second.Size(); |
36 | } | 36 | } |
37 | 37 | ||
38 | // Returns the number of blocks | 38 | // Returns the number of blocks |
@@ -63,8 +63,8 @@ class FileSpec { | |||
63 | for (SegmentMap::const_iterator iter(table_.begin()); | 63 | for (SegmentMap::const_iterator iter(table_.begin()); |
64 | iter != table_.end(); | 64 | iter != table_.end(); |
65 | ++iter) { | 65 | ++iter) { |
66 | cerr << "Segment at " << iter->first << " (" << iter->second.seed | 66 | const Segment &seg = iter->second; |
67 | << "," << iter->second.length << "," << iter->second.seed_offset << ")" << endl; | 67 | cerr << "Segment at " << iter->first << " (" << seg << ")" << endl; |
68 | } | 68 | } |
69 | } | 69 | } |
70 | 70 | ||
@@ -113,6 +113,8 @@ public: | |||
113 | size_ = 0; | 113 | size_ = 0; |
114 | } | 114 | } |
115 | 115 | ||
116 | void Block::Print() const; | ||
117 | |||
116 | private: | 118 | private: |
117 | void SetSize(size_t size) { | 119 | void SetSize(size_t size) { |
118 | size_ = size; | 120 | size_ = size; |
@@ -158,6 +160,10 @@ public: | |||
158 | return blkno_; | 160 | return blkno_; |
159 | } | 161 | } |
160 | 162 | ||
163 | xoff_t Offset() const { | ||
164 | return blkno_ * blksize_; | ||
165 | } | ||
166 | |||
161 | void SetBlock(xoff_t blkno) { | 167 | void SetBlock(xoff_t blkno) { |
162 | blkno_ = blkno; | 168 | blkno_ = blkno; |
163 | } | 169 | } |
@@ -203,23 +209,19 @@ inline void BlockIterator::Get(Block *block) const { | |||
203 | CHECK(pos != table.end()); | 209 | CHECK(pos != table.end()); |
204 | CHECK_GE(offset, pos->first); | 210 | CHECK_GE(offset, pos->first); |
205 | 211 | ||
212 | const Segment &seg = pos->second; | ||
213 | |||
206 | // The position of this segment may start before this block starts, | 214 | // The position of this segment may start before this block starts, |
207 | // and then the position of the data may be offset from the seeding | 215 | // and then the position of the data may be offset from the seeding |
208 | // position. | 216 | // position. |
209 | size_t seg_offset = offset - pos->first; | 217 | size_t seg_offset = offset - pos->first; |
210 | xoff_t skip = seg_offset + pos->second.seed_offset; | 218 | size_t advance = min(seg.Size() - seg_offset, |
211 | MTRandom gen(pos->second.seed); | ||
212 | MTRandom8 gen8(&gen); | ||
213 | while (skip--) { | ||
214 | gen8.Rand8(); | ||
215 | } | ||
216 | size_t advance = min(pos->second.length - seg_offset, | ||
217 | blksize_ - got); | 219 | blksize_ - got); |
218 | for (size_t i = 0; i < advance; i++) { | ||
219 | block->data_[got++] = gen8.Rand8(); | ||
220 | } | ||
221 | 220 | ||
222 | offset += (pos->second.length - seg_offset); | 221 | seg.Fill(seg_offset, advance, block->data_ + got); |
222 | |||
223 | got += advance; | ||
224 | offset += advance; | ||
223 | ++pos; | 225 | ++pos; |
224 | } | 226 | } |
225 | } | 227 | } |
@@ -248,20 +250,23 @@ inline void Block::Append(const uint8_t *data, size_t size) { | |||
248 | 250 | ||
249 | inline void FileSpec::PrintData() const { | 251 | inline void FileSpec::PrintData() const { |
250 | Block block; | 252 | Block block; |
251 | xoff_t pos = 0; | ||
252 | |||
253 | for (BlockIterator iter(*this); !iter.Done(); iter.Next()) { | 253 | for (BlockIterator iter(*this); !iter.Done(); iter.Next()) { |
254 | iter.Get(&block); | 254 | iter.Get(&block); |
255 | for (size_t i = 0; i < block.Size(); i++) { | 255 | block.Print(); |
256 | if (pos % 16 == 0) { | 256 | } |
257 | DP(RINT "%5"Q"x: ", pos); | 257 | } |
258 | } | 258 | |
259 | DP(RINT "%02x ", block[i]); | 259 | inline void Block::Print() const { |
260 | if (pos % 16 == 15) { | 260 | xoff_t pos = 0; |
261 | DP(RINT "\n"); | 261 | for (size_t i = 0; i < Size(); i++) { |
262 | } | 262 | if (pos % 16 == 0) { |
263 | pos++; | 263 | DP(RINT "%5"Q"x: ", pos); |
264 | } | ||
265 | DP(RINT "%02x ", (*this)[i]); | ||
266 | if (pos % 16 == 15) { | ||
267 | DP(RINT "\n"); | ||
264 | } | 268 | } |
269 | pos++; | ||
265 | } | 270 | } |
266 | DP(RINT "\n"); | 271 | DP(RINT "\n"); |
267 | } | 272 | } |