uqa_execution/batch/
row_lock_origins.rs1use std::sync::Arc;
10
11use super::PhysicalRow;
12
13#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct RowLockOrigin {
18 pub qualifier: Arc<str>,
20 pub scan_qualifier: Arc<str>,
22 pub storage_name: Arc<str>,
23 pub doc_id: uqa_core::DocId,
24}
25
26impl RowLockOrigin {
27 #[must_use]
28 pub fn new(
29 qualifier: impl Into<String>,
30 storage_name: impl Into<String>,
31 doc_id: uqa_core::DocId,
32 ) -> Self {
33 Self::from_shared(
34 Arc::<str>::from(qualifier.into()),
35 Arc::<str>::from(storage_name.into()),
36 doc_id,
37 )
38 }
39
40 #[must_use]
42 pub fn from_shared(
43 qualifier: Arc<str>,
44 storage_name: Arc<str>,
45 doc_id: uqa_core::DocId,
46 ) -> Self {
47 Self {
48 scan_qualifier: Arc::clone(&qualifier),
49 qualifier,
50 storage_name,
51 doc_id,
52 }
53 }
54}
55
56pub(super) fn concat_lock_origins(
57 left: Option<&Arc<Vec<RowLockOrigin>>>,
58 right: Option<&Arc<Vec<RowLockOrigin>>>,
59) -> Option<Arc<Vec<RowLockOrigin>>> {
60 match (left, right) {
61 (None, None) => None,
62 (Some(origins), None) | (None, Some(origins)) => Some(Arc::clone(origins)),
63 (Some(left), Some(right)) => {
64 let mut origins = Vec::with_capacity(left.len() + right.len());
65 origins.extend(left.iter().cloned());
66 origins.extend(right.iter().cloned());
67 Some(Arc::new(origins))
68 }
69 }
70}
71
72impl PhysicalRow {
73 #[must_use]
74 pub fn with_lock_origin(mut self, origin: RowLockOrigin) -> Self {
75 self.lock_origins = match self.lock_origins.take() {
76 None => Some(Arc::new(vec![origin])),
77 Some(existing) => {
78 let mut origins = Vec::with_capacity(existing.len() + 1);
79 origins.extend(existing.iter().cloned());
80 origins.push(origin);
81 Some(Arc::new(origins))
82 }
83 };
84 self
85 }
86
87 #[must_use]
88 pub fn with_lock_origins(mut self, origins: impl IntoIterator<Item = RowLockOrigin>) -> Self {
89 let origins = origins.into_iter().collect::<Vec<_>>();
90 if origins.is_empty() {
91 return self;
92 }
93 self.lock_origins = match self.lock_origins.take() {
94 None => Some(Arc::new(origins)),
95 Some(existing) => {
96 let mut combined = Vec::with_capacity(existing.len() + origins.len());
97 combined.extend(existing.iter().cloned());
98 combined.extend(origins);
99 Some(Arc::new(combined))
100 }
101 };
102 self
103 }
104
105 #[must_use]
106 pub fn lock_origins(&self) -> &[RowLockOrigin] {
107 self.lock_origins
108 .as_deref()
109 .map_or(&[], std::vec::Vec::as_slice)
110 }
111
112 #[must_use]
114 pub fn without_lock_origins(mut self) -> Self {
115 self.lock_origins = None;
116 self
117 }
118
119 pub fn discard_lock_origins_mut(&mut self) {
121 self.lock_origins = None;
122 }
123
124 #[must_use]
126 pub fn rebind_lock_origin_qualifiers(mut self, qualifier: impl Into<Arc<str>>) -> Self {
127 self.rebind_lock_origin_qualifiers_mut(qualifier.into());
128 self
129 }
130
131 pub fn rebind_lock_origin_qualifiers_mut(&mut self, qualifier: Arc<str>) {
132 let Some(origins) = self.lock_origins.as_mut() else {
133 return;
134 };
135 for origin in Arc::make_mut(origins) {
136 origin.qualifier = Arc::clone(&qualifier);
137 }
138 }
139}