// Copyright (c) 2022-2025 Alex Chi Z // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #![allow(unused_variables)] // TODO(you): remove this lint after implementing this mod #![allow(dead_code)] // TODO(you): remove this lint after implementing this mod pub mod txn; pub mod watermark; use std::{ collections::{BTreeMap, HashSet}, sync::{Arc, atomic::AtomicBool}, }; use crossbeam_skiplist::SkipMap; use parking_lot::Mutex; use crate::lsm_storage::LsmStorageInner; use self::{txn::Transaction, watermark::Watermark}; pub(crate) struct CommittedTxnData { pub(crate) key_hashes: HashSet, #[allow(dead_code)] pub(crate) read_ts: u64, #[allow(dead_code)] pub(crate) commit_ts: u64, } pub(crate) struct LsmMvccInner { pub(crate) write_lock: Mutex<()>, pub(crate) commit_lock: Mutex<()>, pub(crate) ts: Arc>, pub(crate) committed_txns: Arc>>, } impl LsmMvccInner { pub fn new(initial_ts: u64) -> Self { Self { write_lock: Mutex::new(()), commit_lock: Mutex::new(()), ts: Arc::new(Mutex::new((initial_ts, Watermark::new()))), committed_txns: Arc::new(Mutex::new(BTreeMap::new())), } } pub fn latest_commit_ts(&self) -> u64 { self.ts.lock().0 } pub fn update_commit_ts(&self, ts: u64) { self.ts.lock().0 = ts; } /// All ts (strictly) below this ts can be garbage collected. pub fn watermark(&self) -> u64 { let ts = self.ts.lock(); ts.1.watermark().unwrap_or(ts.0) } pub fn new_txn(&self, inner: Arc, serializable: bool) -> Arc { let mut ts = self.ts.lock(); let read_ts = ts.0; ts.1.add_reader(read_ts); Arc::new(Transaction { inner, read_ts, local_storage: Arc::new(SkipMap::new()), committed: Arc::new(AtomicBool::new(false)), key_hashes: if serializable { Some(Mutex::new((HashSet::new(), HashSet::new()))) } else { None }, }) } }