reifydb_catalog/store/ringbuffer/
update.rs

1// Copyright (c) reifydb.com 2025
2// This file is licensed under the AGPL-3.0-or-later, see license.md file
3
4use reifydb_core::interface::{CommandTransaction, RingBufferMetadata, RingBufferMetadataKey};
5
6use crate::{CatalogStore, store::ringbuffer::layout::ringbuffer_metadata};
7
8impl CatalogStore {
9	pub async fn update_ringbuffer_metadata(
10		txn: &mut impl CommandTransaction,
11		metadata: RingBufferMetadata,
12	) -> crate::Result<()> {
13		let mut row = ringbuffer_metadata::LAYOUT.allocate();
14		ringbuffer_metadata::LAYOUT.set_u64(&mut row, ringbuffer_metadata::ID, metadata.id);
15		ringbuffer_metadata::LAYOUT.set_u64(&mut row, ringbuffer_metadata::CAPACITY, metadata.capacity);
16		ringbuffer_metadata::LAYOUT.set_u64(&mut row, ringbuffer_metadata::HEAD, metadata.head);
17		ringbuffer_metadata::LAYOUT.set_u64(&mut row, ringbuffer_metadata::TAIL, metadata.tail);
18		ringbuffer_metadata::LAYOUT.set_u64(&mut row, ringbuffer_metadata::COUNT, metadata.count);
19
20		txn.set(&RingBufferMetadataKey::encoded(metadata.id), row).await?;
21
22		Ok(())
23	}
24}
25
26#[cfg(test)]
27mod tests {
28	use reifydb_engine::test_utils::create_test_command_transaction;
29
30	use super::*;
31	use crate::test_utils::ensure_test_ringbuffer;
32
33	#[tokio::test]
34	async fn test_update_ringbuffer_metadata() {
35		let mut txn = create_test_command_transaction().await;
36		let ringbuffer = ensure_test_ringbuffer(&mut txn).await;
37
38		// Get initial metadata
39		let mut metadata = CatalogStore::find_ringbuffer_metadata(&mut txn, ringbuffer.id)
40			.await
41			.unwrap()
42			.expect("Metadata should exist");
43
44		assert_eq!(metadata.count, 0);
45		assert_eq!(metadata.head, 0);
46		assert_eq!(metadata.tail, 0);
47
48		// Update metadata
49		metadata.count = 5;
50		metadata.head = 2;
51		metadata.tail = 7;
52
53		CatalogStore::update_ringbuffer_metadata(&mut txn, metadata.clone()).await.unwrap();
54
55		// Verify update
56		let updated = CatalogStore::find_ringbuffer_metadata(&mut txn, ringbuffer.id)
57			.await
58			.unwrap()
59			.expect("Metadata should exist");
60
61		assert_eq!(updated.count, 5);
62		assert_eq!(updated.head, 2);
63		assert_eq!(updated.tail, 7);
64		assert_eq!(updated.capacity, metadata.capacity);
65	}
66
67	#[tokio::test]
68	async fn test_update_ringbuffer_metadata_wrap_around() {
69		let mut txn = create_test_command_transaction().await;
70		let ringbuffer = ensure_test_ringbuffer(&mut txn).await;
71
72		let mut metadata = CatalogStore::find_ringbuffer_metadata(&mut txn, ringbuffer.id)
73			.await
74			.unwrap()
75			.expect("Metadata should exist");
76
77		// Simulate wrap-around scenario
78		metadata.count = metadata.capacity;
79		metadata.head = metadata.capacity - 1;
80		metadata.tail = 0;
81
82		CatalogStore::update_ringbuffer_metadata(&mut txn, metadata.clone()).await.unwrap();
83
84		let updated = CatalogStore::find_ringbuffer_metadata(&mut txn, ringbuffer.id)
85			.await
86			.unwrap()
87			.expect("Metadata should exist");
88
89		assert_eq!(updated.count, metadata.capacity);
90		assert_eq!(updated.head, metadata.capacity - 1);
91		assert_eq!(updated.tail, 0);
92	}
93}