use std::{fmt, sync::Arc};
use windex::HashIndex;
const DEFAULT_TXN_BUCKETS: usize = 1024;
pub struct TxnLockTable {
loader: Arc<dyn Fn() -> Arc<HashIndex> + Send + Sync>,
}
impl Clone for TxnLockTable {
#[inline]
fn clone(&self) -> Self {
Self {
loader: Arc::clone(&self.loader),
}
}
}
impl Default for TxnLockTable {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl fmt::Debug for TxnLockTable {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("TxnLockTable")
.field("bucket_count", &self.pin().size)
.finish()
}
}
impl TxnLockTable {
#[inline]
pub fn new() -> Self {
let index = Arc::new(
HashIndex::new(DEFAULT_TXN_BUCKETS)
.expect("DEFAULT_TXN_BUCKETS 为合法 2 的幂,HashIndex 构造恒成功"),
);
Self {
loader: Arc::new(move || Arc::clone(&index)),
}
}
#[inline]
pub fn from_loader(loader: impl Fn() -> Arc<HashIndex> + Send + Sync + 'static) -> Self {
Self {
loader: Arc::new(loader),
}
}
#[inline]
pub fn pin(&self) -> Arc<HashIndex> {
(self.loader)()
}
#[inline]
pub fn bucket_index_for_hash(&self, key_hash: i64) -> usize {
self.pin().bucket_index_for_hash(key_hash as u64)
}
#[inline]
pub fn try_lock_shared(&self, bucket: usize) -> bool {
self.pin().bucket(bucket).try_lock_shared()
}
#[inline]
pub fn try_lock_exclusive(&self, bucket: usize) -> bool {
self.pin().bucket(bucket).try_lock_exclusive()
}
#[inline]
pub fn unlock_shared(&self, bucket: usize) {
self.pin().bucket(bucket).unlock_shared();
}
#[inline]
pub fn unlock_exclusive(&self, bucket: usize) {
self.pin().bucket(bucket).unlock_exclusive();
}
}