Skip to content

Commit f00791c

Browse files
authored
[ISSUE #401]🎨Implement UtilAll method (#402)
* add * [ISSUE #401]🎨Implement UtilAll method
1 parent fb312a3 commit f00791c

File tree

2 files changed

+222
-60
lines changed

2 files changed

+222
-60
lines changed

rocketmq-common/src/utils/crc32_utils.rs

+46-6
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,63 @@ pub fn crc32(buf: &[u8]) -> u32 {
2222
//crc32fast::hash(buf)
2323
let mut hasher = Hasher::new();
2424
hasher.update(buf);
25-
let checksum = hasher.finalize();
26-
checksum & 0x7FFFFFFF
25+
hasher.finalize()
26+
}
27+
28+
pub fn crc32_bytes_offset(array: &[u8], offset: usize, length: usize) -> u32 {
29+
if !array.is_empty() && offset < array.len() && offset + length <= array.len() {
30+
let mut hasher = Hasher::new();
31+
hasher.update(&array[offset..offset + length]);
32+
return hasher.finalize();
33+
}
34+
0
35+
}
36+
37+
pub fn crc32_bytebuffer(byte_buffer: &mut Vec<u8>) -> u32 {
38+
let mut hasher = Hasher::new();
39+
hasher.update(byte_buffer.as_slice());
40+
hasher.finalize()
41+
}
42+
43+
pub fn crc32_bytebuffers(byte_buffers: &mut Vec<Vec<u8>>) -> u32 {
44+
let mut hasher = Hasher::new();
45+
for buffer in byte_buffers {
46+
hasher.update(buffer.as_slice());
47+
}
48+
hasher.finalize()
2749
}
2850

2951
#[cfg(test)]
3052
mod tests {
3153
use super::*;
3254

3355
#[test]
34-
fn test_crc32_negative() {
56+
fn crc32_calculates_correct_checksum() {
3557
let buf = [1, 2, 3, 4, 5];
36-
assert_ne!(crc32(&buf), 0xFFFFFFFF);
58+
assert_eq!(crc32(&buf), 1191942644);
3759
}
3860

3961
#[test]
40-
fn test_crc32_empty_buffer() {
62+
fn crc32_bytes_offset_calculates_correct_checksum() {
63+
let buf = [1, 2, 3, 4, 5];
64+
assert_eq!(crc32_bytes_offset(&buf, 1, 3), 3498416806);
65+
}
66+
67+
#[test]
68+
fn crc32_bytes_offset_returns_zero_for_empty_array() {
4169
let buf: [u8; 0] = [];
42-
assert_eq!(crc32(&buf), 0);
70+
assert_eq!(crc32_bytes_offset(&buf, 0, 0), 0);
71+
}
72+
73+
#[test]
74+
fn crc32_bytebuffer_calculates_correct_checksum() {
75+
let mut buf = vec![1, 2, 3, 4, 5];
76+
assert_eq!(crc32_bytebuffer(&mut buf), 1191942644);
77+
}
78+
79+
#[test]
80+
fn crc32_bytebuffers_calculates_correct_checksum() {
81+
let mut bufs = vec![vec![1, 2, 3], vec![4, 5]];
82+
assert_eq!(crc32_bytebuffers(&mut bufs), 1191942644);
4383
}
4484
}

rocketmq-common/src/utils/util_all.rs

+176-54
Original file line numberDiff line numberDiff line change
@@ -18,52 +18,36 @@
1818
use std::{
1919
env, fs,
2020
path::{Path, PathBuf},
21+
time::Instant,
2122
};
2223

23-
use chrono::{DateTime, Datelike, TimeZone, Timelike, Utc};
24+
use chrono::{DateTime, Datelike, Local, TimeZone, Timelike, Utc};
2425
use once_cell::sync::Lazy;
25-
use tracing::info;
26+
use tracing::{error, info};
2627

2728
use crate::common::mix_all::MULTI_PATH_SPLITTER;
2829

2930
const HEX_ARRAY: [char; 16] = [
3031
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
3132
];
3233

33-
pub fn bytes_to_string(src: &[u8]) -> String {
34-
let mut hex_chars = Vec::with_capacity(src.len() * 2);
35-
for &byte in src {
36-
let v = byte as usize;
37-
hex_chars.push(HEX_ARRAY[v >> 4]);
38-
hex_chars.push(HEX_ARRAY[v & 0x0F]);
39-
}
40-
hex_chars.into_iter().collect()
34+
pub fn compute_elapsed_time_milliseconds(begin_time: Instant) -> u64 {
35+
let elapsed = begin_time.elapsed();
36+
elapsed.as_millis() as u64
4137
}
4238

43-
fn string_to_bytes(hex_string: impl Into<String>) -> Option<Vec<u8>> {
44-
let hex_string = hex_string.into();
45-
if hex_string.is_empty() {
46-
return None;
47-
}
48-
49-
let hex_string = hex_string.to_uppercase();
50-
let length = hex_string.len() / 2;
51-
let mut bytes = Vec::<u8>::with_capacity(length);
52-
53-
for i in 0..length {
54-
let pos = i * 2;
55-
let byte = char_to_byte(hex_string.chars().nth(pos)?) << 4
56-
| char_to_byte(hex_string.chars().nth(pos + 1)?);
57-
58-
bytes.push(byte);
39+
pub fn is_it_time_to_do(when: &str) -> bool {
40+
let hours: Vec<&str> = when.split(";").collect();
41+
if !hours.is_empty() {
42+
let now = Local::now();
43+
for hour in hours {
44+
let now_hour: i32 = hour.parse().unwrap_or(0);
45+
if now_hour == now.hour() as i32 {
46+
return true;
47+
}
48+
}
5949
}
60-
61-
Some(bytes)
62-
}
63-
64-
fn char_to_byte(c: char) -> u8 {
65-
let hex_chars = "0123456789ABCDEF";
66-
hex_chars.find(c).unwrap_or(0) as u8
50+
false
6751
}
6852

6953
pub fn time_millis_to_human_string2(t: i64) -> String {
@@ -98,6 +82,120 @@ pub fn time_millis_to_human_string(t: i64) -> String {
9882
dt.as_ref().unwrap().format("%Y%m%d%H%M%S%3f").to_string()
9983
}
10084

85+
pub fn is_path_exists(path: &str) -> bool {
86+
Path::new(path).exists()
87+
}
88+
89+
pub fn get_disk_partition_space_used_percent(path: &str) -> f64 {
90+
if path.is_empty() {
91+
error!(
92+
"Error when measuring disk space usage, path is null or empty, path: {}",
93+
path
94+
);
95+
return -1.0;
96+
}
97+
98+
let path = Path::new(path);
99+
if !path.exists() {
100+
error!(
101+
"Error when measuring disk space usage, file doesn't exist on this path: {}",
102+
path.to_string_lossy()
103+
);
104+
return -1.0;
105+
}
106+
107+
match fs::metadata(path) {
108+
Ok(metadata) => {
109+
let total_space = metadata.len();
110+
if total_space > 0 {
111+
match (fs::metadata(path), fs::metadata(path)) {
112+
(Ok(metadata1), Ok(metadata2)) => {
113+
let free_space = metadata1.len();
114+
let usable_space = metadata2.len();
115+
let used_space = total_space.saturating_sub(free_space);
116+
let entire_space = used_space + usable_space;
117+
let round_num = if used_space * 100 % entire_space != 0 {
118+
1
119+
} else {
120+
0
121+
};
122+
let result = used_space * 100 / entire_space + round_num;
123+
return result as f64 / 100.0;
124+
}
125+
(Err(e), _) | (_, Err(e)) => {
126+
error!(
127+
"Error when measuring disk space usage, got exception: {:?}",
128+
e
129+
);
130+
return -1.0;
131+
}
132+
}
133+
}
134+
}
135+
Err(e) => {
136+
error!(
137+
"Error when measuring disk space usage, got exception: {:?}",
138+
e
139+
);
140+
return -1.0;
141+
}
142+
}
143+
144+
-1.0
145+
}
146+
147+
pub fn bytes_to_string(src: &[u8]) -> String {
148+
let mut hex_chars = Vec::with_capacity(src.len() * 2);
149+
for &byte in src {
150+
let v = byte as usize;
151+
hex_chars.push(HEX_ARRAY[v >> 4]);
152+
hex_chars.push(HEX_ARRAY[v & 0x0F]);
153+
}
154+
hex_chars.into_iter().collect()
155+
}
156+
157+
pub fn write_int(buffer: &mut [char], pos: usize, value: i32) {
158+
let value_str = format!("{:X}", value);
159+
let value_chars: Vec<char> = value_str.chars().collect();
160+
for (i, &c) in value_chars.iter().enumerate() {
161+
buffer[pos + i] = c;
162+
}
163+
}
164+
165+
pub fn write_short(buffer: &mut [char], pos: usize, value: i16) {
166+
let value_str = format!("{:X}", value);
167+
let value_chars: Vec<char> = value_str.chars().collect();
168+
for (i, &c) in value_chars.iter().enumerate() {
169+
buffer[pos + i] = c;
170+
}
171+
}
172+
173+
fn string_to_bytes(hex_string: impl Into<String>) -> Option<Vec<u8>> {
174+
let hex_string = hex_string.into();
175+
if hex_string.is_empty() {
176+
return None;
177+
}
178+
179+
let hex_string = hex_string.to_uppercase();
180+
let length = hex_string.len() / 2;
181+
let mut bytes = Vec::<u8>::with_capacity(length);
182+
183+
for i in 0..length {
184+
let pos = i * 2;
185+
let byte = char_to_byte(hex_string.chars().nth(pos)?) << 4
186+
| char_to_byte(hex_string.chars().nth(pos + 1)?);
187+
188+
bytes.push(byte);
189+
}
190+
191+
Some(bytes)
192+
}
193+
194+
fn char_to_byte(c: char) -> u8 {
195+
let hex_chars = "0123456789ABCDEF";
196+
hex_chars.find(c).unwrap_or(0) as u8
197+
}
198+
101199
pub fn offset_to_file_name(offset: u64) -> String {
102200
format!("{:020}", offset)
103201
}
@@ -126,38 +224,62 @@ fn create_dir_if_not_exist(dir_name: &str) {
126224
}
127225
#[cfg(test)]
128226
mod tests {
227+
use std::time::Instant;
228+
129229
use super::*;
130230

131231
#[test]
132-
fn test_bytes_to_string() {
133-
let src = b"hello";
134-
let expected = "68656C6C6F";
135-
let result = bytes_to_string(src);
136-
assert_eq!(result, String::from(expected));
232+
fn compute_elapsed_time_milliseconds_returns_correct_duration() {
233+
let start = Instant::now();
234+
std::thread::sleep(std::time::Duration::from_millis(100));
235+
let elapsed = compute_elapsed_time_milliseconds(start);
236+
assert!(elapsed >= 100);
137237
}
138238

139239
#[test]
140-
fn test_bytes_to_string_empty() {
141-
let src = &[];
142-
let expected = "";
143-
let result = bytes_to_string(src);
144-
assert_eq!(result, String::from(expected));
240+
fn is_it_time_to_do_returns_true_when_current_hour_is_in_input() {
241+
let current_hour = Local::now().hour();
242+
assert_eq!(is_it_time_to_do(&current_hour.to_string()), true);
145243
}
146244

147245
#[test]
148-
fn test_bytes_to_string_large() {
149-
let src = b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
150-
let expected = "6162636465666768696A6B6C6D6E6F707172737475767778797A4142434445464748494A4B4C4D4E4F505152535455565758595A";
151-
let result = bytes_to_string(src);
152-
assert_eq!(result, String::from(expected));
246+
fn is_it_time_to_do_returns_false_when_current_hour_is_not_in_input() {
247+
let current_hour = (Local::now().hour() + 1) % 24;
248+
assert_eq!(is_it_time_to_do(&current_hour.to_string()), false);
153249
}
154250

155251
#[test]
156-
fn test_offset_to_file_name() {
157-
assert_eq!(offset_to_file_name(0), "00000000000000000000");
158-
assert_eq!(
159-
offset_to_file_name(2000000000000000000),
160-
"02000000000000000000"
161-
);
252+
fn time_millis_to_human_string_formats_correctly() {
253+
let timestamp = 1625140800000; // 2021-07-01T12:00:00Z
254+
assert_eq!(time_millis_to_human_string(timestamp), "20210701120000000");
255+
}
256+
257+
#[test]
258+
fn is_path_exists_returns_true_for_existing_path() {
259+
assert_eq!(is_path_exists("."), true);
260+
}
261+
262+
#[test]
263+
fn is_path_exists_returns_false_for_non_existing_path() {
264+
assert_eq!(is_path_exists("./non_existing_path"), false);
265+
}
266+
267+
#[test]
268+
fn bytes_to_string_converts_correctly() {
269+
let bytes = [0x41, 0x42, 0x43];
270+
assert_eq!(bytes_to_string(&bytes), "414243");
271+
}
272+
273+
#[test]
274+
fn offset_to_file_name_formats_correctly() {
275+
assert_eq!(offset_to_file_name(123), "00000000000000000123");
276+
}
277+
278+
#[test]
279+
fn ensure_dir_ok_creates_directory_if_not_exists() {
280+
let dir_name = "./test_dir";
281+
ensure_dir_ok(dir_name);
282+
assert_eq!(is_path_exists(dir_name), true);
283+
std::fs::remove_dir(dir_name).unwrap();
162284
}
163285
}

0 commit comments

Comments
 (0)