summaryrefslogtreecommitdiff
path: root/xdelta3/testing/file.h
diff options
context:
space:
mode:
authorjosh.macdonald <jmacd@users.noreply.github.com>2008-07-09 06:56:30 +0000
committerjosh.macdonald <jmacd@users.noreply.github.com>2008-07-09 06:56:30 +0000
commitbd594c150533173d0340df8204824c9d6f00966b (patch)
treea56e040c0b7e1cf13062401e06ed2c40049c5f41 /xdelta3/testing/file.h
parentd0c5ff7a1847558a9264d9485e336f549b66dd38 (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.h57
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
116private: 118private:
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
249inline void FileSpec::PrintData() const { 251inline 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]); 259inline 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}