aboutsummaryrefslogtreecommitdiff
path: root/equivalence_map.h
diff options
context:
space:
mode:
Diffstat (limited to 'equivalence_map.h')
-rw-r--r--equivalence_map.h42
1 files changed, 33 insertions, 9 deletions
diff --git a/equivalence_map.h b/equivalence_map.h
index 91b215c..2ae8801 100644
--- a/equivalence_map.h
+++ b/equivalence_map.h
@@ -84,26 +84,46 @@ class OffsetMapper {
public:
using const_iterator = std::vector<Equivalence>::const_iterator;
- // Constructors for various data sources.
+ // Constructors for various data sources. "Old" and "new" image sizes are
+ // needed for bounds checks and to handle dangling targets.
// - From a list of |equivalences|, already sorted (by |src_offset|) and
// pruned, useful for tests.
- explicit OffsetMapper(std::vector<Equivalence>&& equivalences);
+ OffsetMapper(std::vector<Equivalence>&& equivalences,
+ size_t old_image_size,
+ size_t new_image_size);
// - From a generator, useful for Zucchini-apply.
- explicit OffsetMapper(EquivalenceSource&& equivalence_source);
+ OffsetMapper(EquivalenceSource&& equivalence_source,
+ size_t old_image_size,
+ size_t new_image_size);
// - From an EquivalenceMap that needs to be processed, useful for
// Zucchini-gen.
- explicit OffsetMapper(const EquivalenceMap& equivalence_map);
+ OffsetMapper(const EquivalenceMap& equivalence_map,
+ size_t old_image_size,
+ size_t new_image_size);
~OffsetMapper();
size_t size() const { return equivalences_.size(); }
const_iterator begin() const { return equivalences_.begin(); }
const_iterator end() const { return equivalences_.end(); }
+ // Returns naive extended forward-projection of "old" |offset| that follows
+ // |eq|'s delta. |eq| needs not cover |offset|.
+ // - Averts underflow / overflow by clamping to |[0, new_image_size_)|.
+ // - However, |offset| is *not* restricted to |[0, old_image_size_)|; the
+ // caller must to make the check (hence "naive").
+ offset_t NaiveExtendedForwardProject(const Equivalence& unit,
+ offset_t offset) const;
+
// Returns an offset in |new_image| corresponding to |offset| in |old_image|.
- // If |offset| is not part of an equivalence, the equivalence nearest to
- // |offset| is used as if it contained |offset|. This assumes |equivalences_|
- // is not empty.
- offset_t ForwardProject(offset_t offset) const;
+ // Assumes |equivalences_| to be non-empty. Cases:
+ // - If |offset| is covered (i.e., in an "old" block), then use the delta of
+ // the (unique) equivalence unit that covers |offset|.
+ // - If |offset| is non-covered, but in |[0, old_image_size_)|, then find the
+ // nearest "old" block, use its delta, and avert underflow / overflow by
+ // clamping the result to |[0, new_image_size_)|.
+ // - If |offset| is >= |new_image_size_| (a "fake offset"), then use
+ // |new_image_size_ - old_image_size_| as the delta.
+ offset_t ExtendedForwardProject(offset_t offset) const;
// Given sorted |offsets|, applies a projection in-place of all offsets that
// are part of a pruned equivalence from |old_image| to |new_image|. Other
@@ -123,7 +143,11 @@ class OffsetMapper {
std::vector<Equivalence>* equivalences);
private:
- std::vector<Equivalence> equivalences_;
+ // |equivalences_| is pruned, i.e., no "old" blocks overlap (and no "new"
+ // block overlaps). Also, it is sorted by "old" offsets.
+ std::vector<Equivalence> equivalences_; // P
+ const size_t old_image_size_;
+ const size_t new_image_size_;
};
// Container of equivalences between |old_image_index| and |new_image_index|,