Skip to main content

rocketmq_common/common/message/
storage_metadata.rs

1// Copyright 2023 The RocketMQ Rust Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::net::SocketAddr;
16
17use bytes::BufMut;
18use bytes::Bytes;
19use bytes::BytesMut;
20use cheetah_string::CheetahString;
21
22use crate::common::sys_flag::message_sys_flag::MessageSysFlag;
23
24/// Message storage metadata
25///
26/// Contains indexing and location information for messages in the Broker storage engine.
27#[derive(Clone, Debug, PartialEq, Eq)]
28pub struct StorageMetadata {
29    broker_name: CheetahString,
30    queue_id: i32,
31    queue_offset: i64,
32    commit_log_offset: i64,
33    store_timestamp: i64,
34    store_host: SocketAddr,
35    store_size: i32,
36}
37
38impl StorageMetadata {
39    /// Creates new storage metadata
40    #[allow(clippy::too_many_arguments)]
41    pub fn new(
42        broker_name: CheetahString,
43        queue_id: i32,
44        queue_offset: i64,
45        commit_log_offset: i64,
46        store_timestamp: i64,
47        store_host: SocketAddr,
48        store_size: i32,
49    ) -> Self {
50        Self {
51            broker_name,
52            queue_id,
53            queue_offset,
54            commit_log_offset,
55            store_timestamp,
56            store_host,
57            store_size,
58        }
59    }
60
61    /// Gets the broker name
62    #[inline]
63    pub fn broker_name(&self) -> &str {
64        &self.broker_name
65    }
66
67    /// Gets the queue ID
68    #[inline]
69    pub fn queue_id(&self) -> i32 {
70        self.queue_id
71    }
72
73    /// Gets the queue logical offset
74    #[inline]
75    pub fn queue_offset(&self) -> i64 {
76        self.queue_offset
77    }
78
79    /// Gets the CommitLog physical offset
80    #[inline]
81    pub fn commit_log_offset(&self) -> i64 {
82        self.commit_log_offset
83    }
84
85    /// Gets the storage timestamp
86    #[inline]
87    pub fn store_timestamp(&self) -> i64 {
88        self.store_timestamp
89    }
90
91    /// Gets the storage host address
92    #[inline]
93    pub fn store_host(&self) -> SocketAddr {
94        self.store_host
95    }
96
97    /// Gets the storage size in bytes
98    #[inline]
99    pub fn store_size(&self) -> i32 {
100        self.store_size
101    }
102
103    /// Sets the IPv6 flag for store_host (internal use)
104    #[inline]
105    pub(crate) fn with_store_host_v6_flag(&mut self, sys_flag: &mut i32) {
106        *sys_flag |= MessageSysFlag::STOREHOSTADDRESS_V6_FLAG;
107    }
108
109    /// Serializes store_host to bytes
110    pub fn store_host_bytes(&self) -> Bytes {
111        Self::socket_addr_to_bytes(&self.store_host)
112    }
113
114    fn socket_addr_to_bytes(addr: &SocketAddr) -> Bytes {
115        match addr {
116            SocketAddr::V4(v4) => {
117                let mut buf = BytesMut::with_capacity(8);
118                buf.put_slice(&v4.ip().octets());
119                buf.put_i32(v4.port() as i32);
120                buf.freeze()
121            }
122            SocketAddr::V6(v6) => {
123                let mut buf = BytesMut::with_capacity(20);
124                buf.put_slice(&v6.ip().octets());
125                buf.put_i32(v6.port() as i32);
126                buf.freeze()
127            }
128        }
129    }
130
131    /// Sets the broker name (internal use)
132    #[inline]
133    pub(crate) fn set_broker_name(&mut self, broker_name: CheetahString) {
134        self.broker_name = broker_name;
135    }
136
137    /// Sets the queue offset (internal use)
138    #[inline]
139    pub(crate) fn set_queue_offset(&mut self, queue_offset: i64) {
140        self.queue_offset = queue_offset;
141    }
142
143    /// Sets the CommitLog offset (internal use)
144    #[inline]
145    pub(crate) fn set_commit_log_offset(&mut self, commit_log_offset: i64) {
146        self.commit_log_offset = commit_log_offset;
147    }
148
149    /// Sets the store timestamp (internal use)
150    #[inline]
151    pub(crate) fn set_store_timestamp(&mut self, store_timestamp: i64) {
152        self.store_timestamp = store_timestamp;
153    }
154
155    /// Sets the store host (internal use)
156    #[inline]
157    pub(crate) fn set_store_host(&mut self, store_host: SocketAddr) {
158        self.store_host = store_host;
159    }
160
161    /// Sets the store size (internal use)
162    #[inline]
163    pub(crate) fn set_store_size(&mut self, store_size: i32) {
164        self.store_size = store_size;
165    }
166
167    /// Sets the queue ID (internal use)
168    #[inline]
169    pub(crate) fn set_queue_id(&mut self, queue_id: i32) {
170        self.queue_id = queue_id;
171    }
172}
173
174impl Default for StorageMetadata {
175    fn default() -> Self {
176        Self {
177            broker_name: CheetahString::new(),
178            queue_id: 0,
179            queue_offset: 0,
180            commit_log_offset: 0,
181            store_timestamp: 0,
182            store_host: SocketAddr::from(([127, 0, 0, 1], 10911)),
183            store_size: 0,
184        }
185    }
186}
187
188#[cfg(test)]
189mod tests {
190    use super::*;
191
192    #[test]
193    fn test_storage_metadata_creation() {
194        let addr: SocketAddr = "192.168.1.100:10911".parse().unwrap();
195        let metadata = StorageMetadata::new(
196            CheetahString::from_static_str("broker-a"),
197            0,
198            1000,
199            50000,
200            1234567890,
201            addr,
202            1024,
203        );
204
205        assert_eq!(metadata.broker_name(), "broker-a");
206        assert_eq!(metadata.queue_id(), 0);
207        assert_eq!(metadata.queue_offset(), 1000);
208        assert_eq!(metadata.commit_log_offset(), 50000);
209        assert_eq!(metadata.store_timestamp(), 1234567890);
210        assert_eq!(metadata.store_host(), addr);
211        assert_eq!(metadata.store_size(), 1024);
212    }
213
214    #[test]
215    fn test_store_host_bytes_v4() {
216        let addr: SocketAddr = "192.168.1.100:10911".parse().unwrap();
217        let metadata = StorageMetadata::new(CheetahString::new(), 0, 0, 0, 0, addr, 0);
218
219        let bytes = metadata.store_host_bytes();
220        assert_eq!(bytes.len(), 8);
221    }
222
223    #[test]
224    fn test_store_host_bytes_v6() {
225        let addr: SocketAddr = "[::1]:10911".parse().unwrap();
226        let metadata = StorageMetadata::new(CheetahString::new(), 0, 0, 0, 0, addr, 0);
227
228        let bytes = metadata.store_host_bytes();
229        assert_eq!(bytes.len(), 20);
230    }
231
232    #[test]
233    fn test_default() {
234        let metadata = StorageMetadata::default();
235        assert_eq!(metadata.broker_name(), "");
236        assert_eq!(metadata.queue_id(), 0);
237        assert_eq!(metadata.queue_offset(), 0);
238        assert_eq!(metadata.commit_log_offset(), 0);
239        assert_eq!(metadata.store_size(), 0);
240    }
241
242    #[test]
243    fn test_setters() {
244        let mut metadata = StorageMetadata::default();
245
246        metadata.set_broker_name(CheetahString::from_static_str("test-broker"));
247        metadata.set_queue_id(5);
248        metadata.set_queue_offset(100);
249        metadata.set_commit_log_offset(5000);
250        metadata.set_store_timestamp(999999);
251        metadata.set_store_size(2048);
252
253        assert_eq!(metadata.broker_name(), "test-broker");
254        assert_eq!(metadata.queue_id(), 5);
255        assert_eq!(metadata.queue_offset(), 100);
256        assert_eq!(metadata.commit_log_offset(), 5000);
257        assert_eq!(metadata.store_timestamp(), 999999);
258        assert_eq!(metadata.store_size(), 2048);
259    }
260}