diff --git a/src/util/arena.rs b/src/util/arena.rs index d9b3f9585e08ce4771a73d2cd8960a8555f0600e..611053b5857101b48ef6e2666fa008335fc84bdf 100644 --- a/src/util/arena.rs +++ b/src/util/arena.rs @@ -73,12 +73,10 @@ impl Arena { self.alloc_bytes_remaining = ARENA_BLOCK_SIZE - bytes; let layout = Layout::from_size_align_unchecked(ARENA_BLOCK_SIZE, align); let new_block = self.allocate_new_block(layout); - unsafe { - let ptr = new_block.as_ptr() as *mut u8; - let result = slice::from_raw_parts_mut(ptr, bytes); - self.alloc_ptr = Some(NonNull::new_unchecked(ptr.offset(bytes as isize))); - result - } + let ptr = new_block.as_ptr() as *mut u8; + let result = slice::from_raw_parts_mut(ptr, bytes); + self.alloc_ptr = Some(NonNull::new_unchecked(ptr.offset(bytes as isize))); + result } } diff --git a/src/util/slice.rs b/src/util/slice.rs index 6f07e61469ccf2666bd2c2f1d3c94e55aca0c29b..7616c134dc7191a61ba52a24406194f08176edcf 100644 --- a/src/util/slice.rs +++ b/src/util/slice.rs @@ -22,6 +22,14 @@ impl Default for Slice { } impl Slice { + /// 从 &mut [u8] 转到 Slice + /// # Unsafe + /// 这里目前存在内存泄漏和double free问题, 先别用 + pub unsafe fn from_buf(buf: &mut [u8]) -> Self { + Self { + data: Vec::from_raw_parts(buf.as_mut_ptr(), buf.len(), buf.len()) + } + } /// 获取 slice 长度 #[inline] pub fn size(&self) -> usize { @@ -59,6 +67,20 @@ impl Slice { other.size()) == 0 }; } + + pub fn merge(&mut self, mut other: Self, joiner: Option) { + if other.empty() { + return; + } + match joiner { + None => self.data.append(&mut other.data), + Some(mut j) => unsafe { + self.data.append(j.as_mut_vec()); + self.data.append(&mut other.data); + } + } + } + } impl<'a> Slice { diff --git a/src/util/slice_test.rs b/src/util/slice_test.rs index 9eabf5957b93857008ac218e34c8ed4b7d0e3637..06591c98ac4cb9155e2dbaf54f33e54f6938f984 100644 --- a/src/util/slice_test.rs +++ b/src/util/slice_test.rs @@ -1,5 +1,6 @@ mod test { use std::cmp::Ordering; + use std::mem::ManuallyDrop; use crate::util::slice::Slice; #[test] @@ -10,6 +11,11 @@ mod test { // from String let a1 = Slice::from(String::from("123")); assert_eq!(String::from("123"), String::from(a1)); + // from buf + // let mut data = ManuallyDrop::new([48_u8, 49, 50]); + // let slice = data.as_mut_slice(); + // let a2 = Slice::from_buf(slice); + // assert_eq!(String::from("012"), String::from(a2)); } #[test] @@ -67,6 +73,38 @@ mod test { } #[test] + fn test_merge() { + let mut a0 = Slice::from("123"); + let a1 = Slice::default(); + a0.merge(a1, None); + assert_eq!(String::from("123"), String::from(a0)); + } + + #[test] + fn test_merge1() { + let mut a0 = Slice::from("123"); + let a1 = Slice::default(); + a0.merge(a1, Some(String::from("ok"))); + assert_eq!(String::from("123"), String::from(a0)); + } + + #[test] + fn test_merge2() { + let mut a0 = Slice::from("123"); + let mut a2 = Slice::from("456"); + a0.merge(a2, None); + assert_eq!(String::from("123456"), String::from(a0)); + } + + #[test] + fn test_merge3() { + let mut a0 = Slice::from("123"); + let a2 = Slice::from("456"); + a0.merge(a2, Some(String::from("ok"))); + assert_eq!(String::from("123ok456"), String::from(a0)); + } + + // #[test] fn test_memory_leak() { // 申请 100G 内存, 查看是否内存泄漏。如果内存泄漏,程序会OOM (0..100_000_000).for_each(|_| { @@ -84,7 +122,7 @@ mod test { 301230123012301230123012301230123012301230123012301230123012301230123012301230123012\ 301230123012301230123012301230123012301230123012301230123012301230123012301230123012\ 301230123012301230123012301230123"; - let _: Slice = str.into(); + let _: Slice = Slice::from(str); }) } } \ No newline at end of file