From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- .../rustc_data_structures/src/snapshot_map/mod.rs | 143 +++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 compiler/rustc_data_structures/src/snapshot_map/mod.rs (limited to 'compiler/rustc_data_structures/src/snapshot_map/mod.rs') diff --git a/compiler/rustc_data_structures/src/snapshot_map/mod.rs b/compiler/rustc_data_structures/src/snapshot_map/mod.rs new file mode 100644 index 000000000..8a50179cd --- /dev/null +++ b/compiler/rustc_data_structures/src/snapshot_map/mod.rs @@ -0,0 +1,143 @@ +use crate::fx::FxHashMap; +use crate::undo_log::{Rollback, Snapshots, UndoLogs, VecLog}; +use std::borrow::{Borrow, BorrowMut}; +use std::hash::Hash; +use std::marker::PhantomData; +use std::ops; + +pub use crate::undo_log::Snapshot; + +#[cfg(test)] +mod tests; + +pub type SnapshotMapStorage = SnapshotMap, ()>; +pub type SnapshotMapRef<'a, K, V, L> = SnapshotMap, &'a mut L>; + +#[derive(Clone)] +pub struct SnapshotMap, L = VecLog>> { + map: M, + undo_log: L, + _marker: PhantomData<(K, V)>, +} + +// HACK(eddyb) manual impl avoids `Default` bounds on `K` and `V`. +impl Default for SnapshotMap +where + M: Default, + L: Default, +{ + fn default() -> Self { + SnapshotMap { map: Default::default(), undo_log: Default::default(), _marker: PhantomData } + } +} + +#[derive(Clone)] +pub enum UndoLog { + Inserted(K), + Overwrite(K, V), + Purged, +} + +impl SnapshotMap { + #[inline] + pub fn with_log(&mut self, undo_log: L2) -> SnapshotMap { + SnapshotMap { map: &mut self.map, undo_log, _marker: PhantomData } + } +} + +impl SnapshotMap +where + K: Hash + Clone + Eq, + M: BorrowMut> + Borrow>, + L: UndoLogs>, +{ + pub fn clear(&mut self) { + self.map.borrow_mut().clear(); + self.undo_log.clear(); + } + + pub fn insert(&mut self, key: K, value: V) -> bool { + match self.map.borrow_mut().insert(key.clone(), value) { + None => { + self.undo_log.push(UndoLog::Inserted(key)); + true + } + Some(old_value) => { + self.undo_log.push(UndoLog::Overwrite(key, old_value)); + false + } + } + } + + pub fn remove(&mut self, key: K) -> bool { + match self.map.borrow_mut().remove(&key) { + Some(old_value) => { + self.undo_log.push(UndoLog::Overwrite(key, old_value)); + true + } + None => false, + } + } + + pub fn get(&self, key: &K) -> Option<&V> { + self.map.borrow().get(key) + } +} + +impl SnapshotMap +where + K: Hash + Clone + Eq, +{ + pub fn snapshot(&mut self) -> Snapshot { + self.undo_log.start_snapshot() + } + + pub fn commit(&mut self, snapshot: Snapshot) { + self.undo_log.commit(snapshot) + } + + pub fn rollback_to(&mut self, snapshot: Snapshot) { + let map = &mut self.map; + self.undo_log.rollback_to(|| map, snapshot) + } +} + +impl<'k, K, V, M, L> ops::Index<&'k K> for SnapshotMap +where + K: Hash + Clone + Eq, + M: Borrow>, +{ + type Output = V; + fn index(&self, key: &'k K) -> &V { + &self.map.borrow()[key] + } +} + +impl Rollback> for SnapshotMap +where + K: Eq + Hash, + M: Rollback>, +{ + fn reverse(&mut self, undo: UndoLog) { + self.map.reverse(undo) + } +} + +impl Rollback> for FxHashMap +where + K: Eq + Hash, +{ + fn reverse(&mut self, undo: UndoLog) { + match undo { + UndoLog::Inserted(key) => { + self.remove(&key); + } + + UndoLog::Overwrite(key, old_value) => { + self.insert(key, old_value); + } + + UndoLog::Purged => {} + } + } +} -- cgit v1.2.3