def _setitem_partial_overlap(self, i: int, key: oir.Interval, value: Any) -> None: start = self.interval_starts[i] if key.start < start: if self.values[i] is value: self.interval_starts[i] = key.start else: self.interval_starts[i] = key.end self.interval_starts.insert(i, key.start) self.interval_ends.insert(i, key.end) self.values.insert(i, value) else: # key.end > end if self.values[i] is value: self.interval_ends[i] = key.end nextidx = i + 1 else: self.interval_ends[i] = key.start self.interval_starts.insert(i + 1, key.start) self.interval_ends.insert(i + 1, key.end) self.values.insert(i + 1, value) nextidx = i + 2 if nextidx < len(self.interval_starts) and ( key.intersects( oir.Interval(start=self.interval_starts[nextidx], end=self.interval_ends[nextidx])) or self.interval_starts[nextidx] == key.end): if self.values[nextidx] is value: self.interval_ends[nextidx - 1] = self.interval_ends[nextidx] del self.interval_starts[nextidx] del self.interval_ends[nextidx] del self.values[nextidx] else: self.interval_starts[nextidx] = key.end
def __getitem__(self, key: oir.Interval) -> List[Any]: if not isinstance(key, oir.Interval): raise TypeError("Only OIR intervals supported for keys of IntervalMapping.") res = [] for start, end, value in zip(self.interval_starts, self.interval_ends, self.values): if key.intersects(oir.Interval(start=start, end=end)): res.append(value) return res
def __setitem__(self, key: oir.Interval, value: Any) -> None: if not isinstance(key, oir.Interval): raise TypeError( "Only OIR intervals supported for method add of IntervalSet.") key = oir.UnboundedInterval(start=key.start, end=key.end) delete = list() for i, (start, end) in enumerate(zip(self.interval_starts, self.interval_ends)): if key.covers(oir.UnboundedInterval(start=start, end=end)): delete.append(i) for i in reversed(delete): # so indices keep validity while deleting del self.interval_starts[i] del self.interval_ends[i] del self.values[i] if len(self.interval_starts) == 0: self.interval_starts.append(key.start) self.interval_ends.append(key.end) self.values.append(value) return for i, (start, end) in enumerate(zip(self.interval_starts, self.interval_ends)): if oir.UnboundedInterval(start=start, end=end).covers(key): self._setitem_subset_of_existing(i, key, value) return for i, (start, end) in enumerate(zip(self.interval_starts, self.interval_ends)): if (key.intersects(oir.UnboundedInterval(start=start, end=end)) or start == key.end or end == key.start): self._setitem_partial_overlap(i, key, value) return for i, start in enumerate(self.interval_starts): if start > key.start: self.interval_starts.insert(i, key.start) self.interval_ends.insert(i, key.end) self.values.insert(i, value) return self.interval_starts.append(key.start) self.interval_ends.append(key.end) self.values.append(value) return