Skip to main content

rocketmq_model/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
22/// Message storage metadata
23///
24/// Contains indexing and location information for messages in the Broker storage engine.
25#[derive(Clone, Debug, PartialEq, Eq)]
26pub struct StorageMetadata {
27    broker_name: CheetahString,
28    queue_id: i32,
29    queue_offset: i64,
30    commit_log_offset: i64,
31    store_timestamp: i64,
32    store_host: SocketAddr,
33    store_size: i32,
34}
35
36impl StorageMetadata {
37    /// Creates new storage metadata
38    #[allow(clippy::too_many_arguments)]
39    pub fn new(
40        broker_name: CheetahString,
41        queue_id: i32,
42        queue_offset: i64,
43        commit_log_offset: i64,
44        store_timestamp: i64,
45        store_host: SocketAddr,
46        store_size: i32,
47    ) -> Self {
48        Self {
49            broker_name,
50            queue_id,
51            queue_offset,
52            commit_log_offset,
53            store_timestamp,
54            store_host,
55            store_size,
56        }
57    }
58
59    /// Gets the broker name
60    #[inline]
61    pub fn broker_name(&self) -> &str {
62        self.broker_name.as_str()
63    }
64
65    /// Gets the queue ID
66    #[inline]
67    pub fn queue_id(&self) -> i32 {
68        self.queue_id
69    }
70
71    /// Gets the queue logical offset
72    #[inline]
73    pub fn queue_offset(&self) -> i64 {
74        self.queue_offset
75    }
76
77    /// Gets the CommitLog physical offset
78    #[inline]
79    pub fn commit_log_offset(&self) -> i64 {
80        self.commit_log_offset
81    }
82
83    /// Gets the storage timestamp
84    #[inline]
85    pub fn store_timestamp(&self) -> i64 {
86        self.store_timestamp
87    }
88
89    /// Gets the storage host address
90    #[inline]
91    pub fn store_host(&self) -> SocketAddr {
92        self.store_host
93    }
94
95    /// Gets the storage size in bytes
96    #[inline]
97    pub fn store_size(&self) -> i32 {
98        self.store_size
99    }
100
101    /// Serializes store_host to bytes
102    pub fn store_host_bytes(&self) -> Bytes {
103        Self::socket_addr_to_bytes(&self.store_host)
104    }
105
106    fn socket_addr_to_bytes(addr: &SocketAddr) -> Bytes {
107        match addr {
108            SocketAddr::V4(v4) => {
109                let mut buf = BytesMut::with_capacity(8);
110                buf.put_slice(&v4.ip().octets());
111                buf.put_i32(v4.port() as i32);
112                buf.freeze()
113            }
114            SocketAddr::V6(v6) => {
115                let mut buf = BytesMut::with_capacity(20);
116                buf.put_slice(&v6.ip().octets());
117                buf.put_i32(v6.port() as i32);
118                buf.freeze()
119            }
120        }
121    }
122}
123
124impl Default for StorageMetadata {
125    fn default() -> Self {
126        Self {
127            broker_name: CheetahString::new(),
128            queue_id: 0,
129            queue_offset: 0,
130            commit_log_offset: 0,
131            store_timestamp: 0,
132            store_host: SocketAddr::from(([127, 0, 0, 1], 10911)),
133            store_size: 0,
134        }
135    }
136}
137
138#[cfg(test)]
139mod tests {
140    use super::*;
141
142    #[test]
143    fn test_storage_metadata_creation() {
144        let addr: SocketAddr = "192.168.1.100:10911".parse().unwrap();
145        let metadata = StorageMetadata::new(
146            CheetahString::from_static_str("broker-a"),
147            0,
148            1000,
149            50000,
150            1234567890,
151            addr,
152            1024,
153        );
154
155        assert_eq!(metadata.broker_name(), "broker-a");
156        assert_eq!(metadata.queue_id(), 0);
157        assert_eq!(metadata.queue_offset(), 1000);
158        assert_eq!(metadata.commit_log_offset(), 50000);
159        assert_eq!(metadata.store_timestamp(), 1234567890);
160        assert_eq!(metadata.store_host(), addr);
161        assert_eq!(metadata.store_size(), 1024);
162    }
163
164    #[test]
165    fn test_store_host_bytes_v4() {
166        let addr: SocketAddr = "192.168.1.100:10911".parse().unwrap();
167        let metadata = StorageMetadata::new(CheetahString::new(), 0, 0, 0, 0, addr, 0);
168
169        let bytes = metadata.store_host_bytes();
170        assert_eq!(bytes.len(), 8);
171    }
172
173    #[test]
174    fn test_store_host_bytes_v6() {
175        let addr: SocketAddr = "[::1]:10911".parse().unwrap();
176        let metadata = StorageMetadata::new(CheetahString::new(), 0, 0, 0, 0, addr, 0);
177
178        let bytes = metadata.store_host_bytes();
179        assert_eq!(bytes.len(), 20);
180    }
181
182    #[test]
183    fn test_default() {
184        let metadata = StorageMetadata::default();
185        assert_eq!(metadata.broker_name(), "");
186        assert_eq!(metadata.queue_id(), 0);
187        assert_eq!(metadata.queue_offset(), 0);
188        assert_eq!(metadata.commit_log_offset(), 0);
189        assert_eq!(metadata.store_size(), 0);
190    }
191
192    #[test]
193    fn test_clone_and_eq_keep_broker_name_contract() {
194        let addr: SocketAddr = "192.168.1.100:10911".parse().unwrap();
195        let metadata = StorageMetadata::new(
196            CheetahString::from_string(format!("broker-{}", "x".repeat(64))),
197            1,
198            100,
199            5000,
200            999999,
201            addr,
202            2048,
203        );
204
205        let cloned = metadata.clone();
206
207        assert_eq!(cloned, metadata);
208        assert_eq!(cloned.broker_name(), metadata.broker_name());
209    }
210}