Fix search for first block in load_blocks
commit83f51a2452a44917a3e2678f9beb16922e06d14b
authorPetr Tesarik <petr@tesarici.cz>
Wed, 3 Oct 2012 07:30:26 +0000 (3 09:30 +0200)
committerPetr Tesarik <petr@tesarici.cz>
Wed, 3 Oct 2012 07:30:26 +0000 (3 09:30 +0200)
treed3b05b89f0a34a4e0a8b4e361d8fe423443d0a7f
parenta020da28a01538d64e12af24909a4a9ef397037e
Fix search for first block in load_blocks

The intention was to find the first block that intersects the loaded
segment, but the first attempt somehow got it utterly wrong. The
assertion in replace_chunk() was added to spot such bugs earlier,
because the old code initially seemed to work by creating a virtual
block with a "negative" length.

The logic is now thus:
1. The starting point is always inside the loaded segment (because it
   was used to compute the segment boundaries in the first place).
2. There may be more blocks preceding this one that can benefit from
   the loaded data.
3. Any such block must contain at least one byte with a physical offset
   greater or equal to the beginning of the loaded segment.

As an optimization, I'm not comparing the physical position of the last
byte, but rather the physical position of the first byte beyond this
block, and then it must be greater than the segment beginning.

The initial block offset must also be computed more carefully, because
there are two possible situations:

A. A block crosses the segment boundary:

                     I segment ...
  +------+-----------I-----+-----+
  \      | pos.block I     |     /
  /      |           I     |     \
  +------+-----------I-----+-----+
         |<--------->I
            pos.off

B. The segment boundary is inside an erased region:

             I segment ...
  +------+   I    +-----------+----+
  \      |   I    | pos.block |    /
  /      |   I    |           |    \
  +------+   I    +-----------+-----+
             I    pos.off = 0
libhed/file.c