3 //! Implements a map from integer indices to data.
4 //! Rather than storing data for every index, internally, this maps entire ranges to the data.
5 //! To this end, the APIs all work on ranges, not on individual integers. Ranges are split as
6 //! necessary (e.g. when [0,5) is first associated with X, and then [1,2) is mutated).
7 //! Users must not depend on whether a range is coalesced or not, even though this is observable
8 //! via the iteration APIs.
9 use std::collections::BTreeMap;
12 use rustc::ty::layout::Size;
14 #[derive(Clone, Debug, PartialEq, Eq)]
15 pub struct RangeMap<T> {
16 map: BTreeMap<Range, T>,
19 impl<T> Default for RangeMap<T> {
21 fn default() -> Self {
26 // The derived `Ord` impl sorts first by the first field, then, if the fields are the same,
27 // by the second field.
28 // This is exactly what we need for our purposes, since a range query on a BTReeSet/BTreeMap will give us all
29 // `MemoryRange`s whose `start` is <= than the one we're looking for, but not > the end of the range we're checking.
30 // At the same time the `end` is irrelevant for the sorting and range searching, but used for the check.
31 // This kind of search breaks, if `end < start`, so don't do that!
32 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
35 end: u64, // Invariant: end > start
39 /// Compute a range of ranges that contains all ranges overlaping with [offset, offset+len)
40 fn range(offset: u64, len: u64) -> ops::Range<Range> {
42 // We can produce an empty range, nothing overlaps with this.
43 let r = Range { start: 0, end: 1 };
46 // We select all elements that are within
47 // the range given by the offset into the allocation and the length.
48 // This is sound if all ranges that intersect with the argument range, are in the
49 // resulting range of ranges.
51 // lowest range to include `offset`
56 // lowest (valid) range not to include `offset+len`
58 end: offset + len + 1,
63 /// Tests if any element of [offset, offset+len) is contained in this range.
65 fn overlaps(&self, offset: u64, len: u64) -> bool {
67 // `offset` totally does not matter, we cannot overlap with an empty interval
70 offset < self.end && offset.checked_add(len).unwrap() >= self.start
77 pub fn new() -> RangeMap<T> {
78 RangeMap { map: BTreeMap::new() }
81 fn iter_with_range<'a>(
85 ) -> impl Iterator<Item = (&'a Range, &'a T)> + 'a {
86 self.map.range(Range::range(offset, len)).filter_map(
87 move |(range, data)| {
88 debug_assert!(len > 0);
89 if range.overlaps(offset, len) {
98 pub fn iter<'a>(&'a self, offset: Size, len: Size) -> impl Iterator<Item = &'a T> + 'a {
99 self.iter_with_range(offset.bytes(), len.bytes()).map(|(_, data)| data)
102 fn split_entry_at(&mut self, offset: u64)
106 let range = match self.iter_with_range(offset, 1).next() {
107 Some((&range, _)) => range,
111 range.start <= offset && range.end > offset,
112 "We got a range that doesn't even contain what we asked for."
114 // There is an entry overlapping this position, see if we have to split it
115 if range.start < offset {
116 let data = self.map.remove(&range).unwrap();
117 let old = self.map.insert(
124 assert!(old.is_none());
125 let old = self.map.insert(
132 assert!(old.is_none());
136 /// Provide mutable iteration over everything in the given range. As a side-effect,
137 /// this will split entries in the map that are only partially hit by the given range,
138 /// to make sure that when they are mutated, the effect is constrained to the given range.
139 /// If there are gaps, leave them be.
140 pub fn iter_mut_with_gaps<'a>(
144 ) -> impl Iterator<Item = &'a mut T> + 'a
148 let offset = offset.bytes();
149 let len = len.bytes();
152 // Preparation: Split first and last entry as needed.
153 self.split_entry_at(offset);
154 self.split_entry_at(offset + len);
156 // Now we can provide a mutable iterator
157 self.map.range_mut(Range::range(offset, len)).filter_map(
158 move |(&range, data)| {
159 debug_assert!(len > 0);
160 if range.overlaps(offset, len) {
162 offset <= range.start && offset + len >= range.end,
163 "The splitting went wrong"
174 /// Provide a mutable iterator over everything in the given range, with the same side-effects as
175 /// iter_mut_with_gaps. Furthermore, if there are gaps between ranges, fill them with the given default
176 /// before yielding them in the iterator.
177 /// This is also how you insert.
178 pub fn iter_mut<'a>(&'a mut self, offset: Size, len: Size) -> impl Iterator<Item = &'a mut T> + 'a
183 let offset = offset.bytes();
184 let len = len.bytes();
186 // Do a first iteration to collect the gaps
187 let mut gaps = Vec::new();
188 let mut last_end = offset;
189 for (range, _) in self.iter_with_range(offset, len) {
190 if last_end < range.start {
196 last_end = range.end;
198 if last_end < offset + len {
205 // Add default for all gaps
207 let old = self.map.insert(gap, Default::default());
208 assert!(old.is_none());
212 // Now provide mutable iteration
213 self.iter_mut_with_gaps(offset, len)
216 pub fn retain<F>(&mut self, mut f: F)
218 F: FnMut(&T) -> bool,
220 let mut remove = Vec::new();
221 for (range, data) in &self.map {
227 for range in remove {
228 self.map.remove(&range);
237 /// Query the map at every offset in the range and collect the results.
238 fn to_vec<T: Copy>(map: &RangeMap<T>, offset: u64, len: u64, default: Option<T>) -> Vec<T> {
239 (offset..offset + len)
242 .iter(Size::from_bytes(i), Size::from_bytes(1))
253 let mut map = RangeMap::<i32>::new();
255 for x in map.iter_mut(Size::from_bytes(10), Size::from_bytes(1)) {
259 assert_eq!(to_vec(&map, 10, 1, None), vec![42]);
261 // Insert with size 0
262 for x in map.iter_mut(Size::from_bytes(10), Size::from_bytes(0)) {
265 for x in map.iter_mut(Size::from_bytes(11), Size::from_bytes(0)) {
268 assert_eq!(to_vec(&map, 10, 2, Some(-1)), vec![42, -1]);
273 let mut map = RangeMap::<i32>::new();
274 for x in map.iter_mut(Size::from_bytes(11), Size::from_bytes(1)) {
277 for x in map.iter_mut(Size::from_bytes(15), Size::from_bytes(1)) {
281 to_vec(&map, 10, 10, Some(-1)),
282 vec![-1, 42, -1, -1, -1, 43, -1, -1, -1, -1]
285 // Now request a range that needs three gaps filled
286 for x in map.iter_mut(Size::from_bytes(10), Size::from_bytes(10)) {
293 to_vec(&map, 10, 10, None),
294 vec![23, 42, 23, 23, 23, 43, 23, 23, 23, 23]
296 assert_eq!(to_vec(&map, 13, 5, None), vec![23, 23, 43, 23, 23]);