Skip to main content

reifydb_transaction/multi/
types.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use std::{cmp, cmp::Reverse};
5
6use reifydb_codec::row::bytes::EncodedBytes;
7use reifydb_core::{common::CommitVersion, delta::Delta, interface::store::MultiVersionRow, key::any::TaggedKey};
8use reifydb_value::util::cowvec::CowVec;
9
10pub enum TransactionValue {
11	Pending(DeltaEntry),
12	Committed(Committed),
13}
14
15impl From<MultiVersionRow<TaggedKey>> for TransactionValue {
16	fn from(value: MultiVersionRow<TaggedKey>) -> Self {
17		Self::Committed(Committed {
18			key: value.key,
19			bytes: value.bytes,
20			version: value.version,
21		})
22	}
23}
24
25impl core::fmt::Debug for TransactionValue {
26	fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
27		let mut out = f.debug_struct("TransactionValue");
28		match self {
29			Self::Pending(item) => out.field("key", item.key()),
30			Self::Committed(item) => out.field("key", item.key()),
31		};
32		out.field("version", &self.version()).field("value", &self.bytes()).finish()
33	}
34}
35
36impl Clone for TransactionValue {
37	fn clone(&self) -> Self {
38		match self {
39			Self::Committed(item) => Self::Committed(item.clone()),
40			Self::Pending(delta) => Self::Pending(delta.clone()),
41		}
42	}
43}
44
45impl TransactionValue {
46	pub fn version(&self) -> CommitVersion {
47		match self {
48			Self::Pending(item) => item.version(),
49			Self::Committed(item) => item.version(),
50		}
51	}
52
53	pub fn bytes(&self) -> &EncodedBytes {
54		match self {
55			Self::Pending(item) => item.bytes().expect("encoded of pending cannot be `None`"),
56			Self::Committed(item) => &item.bytes,
57		}
58	}
59
60	pub fn is_committed(&self) -> bool {
61		matches!(self, Self::Committed(_))
62	}
63
64	pub fn into_multi_version_row(self) -> MultiVersionRow<TaggedKey> {
65		match self {
66			Self::Pending(item) => match item.delta {
67				Delta::Set {
68					key,
69					bytes,
70				} => MultiVersionRow {
71					key,
72					bytes,
73					version: item.version,
74				},
75				Delta::Remove {
76					key,
77					..
78				} => MultiVersionRow {
79					key,
80					bytes: EncodedBytes(CowVec::default()),
81					version: item.version,
82				},
83			},
84			Self::Committed(item) => MultiVersionRow {
85				key: item.key,
86				bytes: item.bytes,
87				version: item.version,
88			},
89		}
90	}
91}
92
93impl From<DeltaEntry> for TransactionValue {
94	fn from(pending: DeltaEntry) -> Self {
95		Self::Pending(pending)
96	}
97}
98
99impl From<Committed> for TransactionValue {
100	fn from(item: Committed) -> Self {
101		Self::Committed(item)
102	}
103}
104
105#[derive(Clone, Debug)]
106pub struct Committed {
107	pub(crate) key: TaggedKey,
108	pub(crate) bytes: EncodedBytes,
109	pub(crate) version: CommitVersion,
110}
111
112impl From<MultiVersionRow<TaggedKey>> for Committed {
113	fn from(value: MultiVersionRow<TaggedKey>) -> Self {
114		Self {
115			key: value.key,
116			bytes: value.bytes,
117			version: value.version,
118		}
119	}
120}
121
122impl Committed {
123	pub fn key(&self) -> &TaggedKey {
124		&self.key
125	}
126
127	pub fn bytes(&self) -> &EncodedBytes {
128		&self.bytes
129	}
130
131	pub fn version(&self) -> CommitVersion {
132		self.version
133	}
134}
135
136#[derive(Debug, PartialEq, Eq)]
137pub struct DeltaEntry {
138	pub delta: Delta,
139	pub version: CommitVersion,
140}
141
142impl PartialOrd for DeltaEntry {
143	fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
144		Some(self.cmp(other))
145	}
146}
147
148impl Ord for DeltaEntry {
149	fn cmp(&self, other: &Self) -> cmp::Ordering {
150		self.delta.key().cmp(other.delta.key()).then_with(|| Reverse(self.version).cmp(&Reverse(other.version)))
151	}
152}
153
154impl Clone for DeltaEntry {
155	fn clone(&self) -> Self {
156		Self {
157			version: self.version,
158			delta: self.delta.clone(),
159		}
160	}
161}
162
163impl DeltaEntry {
164	pub fn delta(&self) -> &Delta {
165		&self.delta
166	}
167
168	pub fn version(&self) -> CommitVersion {
169		self.version
170	}
171
172	pub fn into_components(self) -> (CommitVersion, Delta) {
173		(self.version, self.delta)
174	}
175
176	pub fn key(&self) -> &TaggedKey {
177		self.delta.key()
178	}
179
180	pub fn bytes(&self) -> Option<&EncodedBytes> {
181		self.delta.bytes()
182	}
183
184	pub fn was_removed(&self) -> bool {
185		matches!(self.delta, Delta::Remove { .. })
186	}
187}