use std::sync::Arc;
use super::PhysicalRow;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RowLockOrigin {
pub qualifier: Arc<str>,
pub scan_qualifier: Arc<str>,
pub storage_name: Arc<str>,
pub doc_id: uqa_core::DocId,
}
impl RowLockOrigin {
#[must_use]
pub fn new(
qualifier: impl Into<String>,
storage_name: impl Into<String>,
doc_id: uqa_core::DocId,
) -> Self {
Self::from_shared(
Arc::<str>::from(qualifier.into()),
Arc::<str>::from(storage_name.into()),
doc_id,
)
}
#[must_use]
pub fn from_shared(
qualifier: Arc<str>,
storage_name: Arc<str>,
doc_id: uqa_core::DocId,
) -> Self {
Self {
scan_qualifier: Arc::clone(&qualifier),
qualifier,
storage_name,
doc_id,
}
}
}
pub(super) fn concat_lock_origins(
left: Option<&Arc<Vec<RowLockOrigin>>>,
right: Option<&Arc<Vec<RowLockOrigin>>>,
) -> Option<Arc<Vec<RowLockOrigin>>> {
match (left, right) {
(None, None) => None,
(Some(origins), None) | (None, Some(origins)) => Some(Arc::clone(origins)),
(Some(left), Some(right)) => {
let mut origins = Vec::with_capacity(left.len() + right.len());
origins.extend(left.iter().cloned());
origins.extend(right.iter().cloned());
Some(Arc::new(origins))
}
}
}
impl PhysicalRow {
#[must_use]
pub fn with_lock_origin(mut self, origin: RowLockOrigin) -> Self {
self.lock_origins = match self.lock_origins.take() {
None => Some(Arc::new(vec![origin])),
Some(existing) => {
let mut origins = Vec::with_capacity(existing.len() + 1);
origins.extend(existing.iter().cloned());
origins.push(origin);
Some(Arc::new(origins))
}
};
self
}
#[must_use]
pub fn with_lock_origins(mut self, origins: impl IntoIterator<Item = RowLockOrigin>) -> Self {
let origins = origins.into_iter().collect::<Vec<_>>();
if origins.is_empty() {
return self;
}
self.lock_origins = match self.lock_origins.take() {
None => Some(Arc::new(origins)),
Some(existing) => {
let mut combined = Vec::with_capacity(existing.len() + origins.len());
combined.extend(existing.iter().cloned());
combined.extend(origins);
Some(Arc::new(combined))
}
};
self
}
#[must_use]
pub fn lock_origins(&self) -> &[RowLockOrigin] {
self.lock_origins
.as_deref()
.map_or(&[], std::vec::Vec::as_slice)
}
#[must_use]
pub fn without_lock_origins(mut self) -> Self {
self.lock_origins = None;
self
}
pub fn discard_lock_origins_mut(&mut self) {
self.lock_origins = None;
}
#[must_use]
pub fn rebind_lock_origin_qualifiers(mut self, qualifier: impl Into<Arc<str>>) -> Self {
self.rebind_lock_origin_qualifiers_mut(qualifier.into());
self
}
pub fn rebind_lock_origin_qualifiers_mut(&mut self, qualifier: Arc<str>) {
let Some(origins) = self.lock_origins.as_mut() else {
return;
};
for origin in Arc::make_mut(origins) {
origin.qualifier = Arc::clone(&qualifier);
}
}
}