1 // Copyright (c) 2023 Huawei Device Co., Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 //! This linked list does not have ownership of nodes, and it treats the 15 //! structure passed in by the user as a node for storage, so the `clear` 16 //! operation does not release memory, and the `remove` operation needs to 17 //! ensure that the node is in any linked list held by a caller to ensure the 18 //! memory validity of pointers within the node. Users need to manage the memory 19 //! of the instances associated with each node themselves. 20 21 use std::ptr::NonNull; 22 23 #[derive(Default)] 24 #[repr(C)] 25 pub(crate) struct Node<T> { 26 prev: Option<NonNull<T>>, 27 next: Option<NonNull<T>>, 28 } 29 30 impl<T> Node<T> { new() -> Node<T>31 pub(crate) fn new() -> Node<T> { 32 Node { 33 prev: None, 34 next: None, 35 } 36 } 37 } 38 39 impl<T: Link> Node<T> { remove_node(node: NonNull<T>) -> Option<NonNull<T>>40 unsafe fn remove_node(node: NonNull<T>) -> Option<NonNull<T>> { 41 let prev = T::node(node).as_ref().prev; 42 let next = T::node(node).as_ref().next; 43 match prev { 44 None => return None, 45 Some(prev) => T::node(prev).as_mut().next = next, 46 } 47 match next { 48 None => return None, 49 Some(next) => T::node(next).as_mut().prev = prev, 50 } 51 T::node(node).as_mut().prev = None; 52 T::node(node).as_mut().next = None; 53 Some(node) 54 } 55 } 56 57 unsafe impl<T: Send> Send for Node<T> {} 58 unsafe impl<T: Sync> Sync for Node<T> {} 59 60 pub(crate) struct LinkedList<L: Link + Default> { 61 head: NonNull<L>, 62 } 63 64 unsafe impl<L: Link + Default + Send> Send for LinkedList<L> {} 65 unsafe impl<L: Link + Default + Sync> Sync for LinkedList<L> {} 66 67 /// Defines the structure of a linked list node. 68 /// Provides methods for converting between nodes and instances. 69 /// 70 /// # Safety 71 /// 72 /// The implementation must ensure that the inserted data does not move in 73 /// memory. 74 pub(crate) unsafe trait Link { node(ptr: NonNull<Self>) -> NonNull<Node<Self>> where Self: Sized75 unsafe fn node(ptr: NonNull<Self>) -> NonNull<Node<Self>> 76 where 77 Self: Sized; 78 } 79 80 impl<L: Link + Default> LinkedList<L> { 81 /// Constructs a new linked list. new() -> LinkedList<L>82 pub(crate) fn new() -> LinkedList<L> { 83 let head = Box::<L>::default(); 84 let head_ptr = unsafe { NonNull::new_unchecked(Box::into_raw(head)) }; 85 let node = unsafe { L::node(head_ptr).as_mut() }; 86 node.prev = Some(head_ptr); 87 node.next = Some(head_ptr); 88 LinkedList { head: head_ptr } 89 } 90 91 /// Inserts an element to the front of the list. push_front(&mut self, val: NonNull<L>)92 pub(crate) fn push_front(&mut self, val: NonNull<L>) { 93 unsafe { 94 let head = L::node(self.head).as_mut(); 95 L::node(val).as_mut().next = head.next; 96 L::node(val).as_mut().prev = Some(self.head); 97 98 let node = Some(val); 99 if let Some(first) = head.next { 100 L::node(first).as_mut().prev = node; 101 } 102 head.next = node; 103 } 104 } 105 106 /// Pops an element from the back of the list. 107 #[cfg(feature = "time")] pop_back(&mut self) -> Option<NonNull<L>>108 pub(crate) fn pop_back(&mut self) -> Option<NonNull<L>> { 109 unsafe { 110 let head = L::node(self.head).as_mut(); 111 if head.prev != Some(self.head) { 112 let node = head.prev.take().unwrap(); 113 Node::remove_node(node); 114 Some(node) 115 } else { 116 None 117 } 118 } 119 } 120 121 /// Deletes an element in list. 122 /// 123 /// # Safety 124 /// 125 /// This method can be safely used when the node is in a guarded linked list 126 /// that the caller has unique access to or the node is not in any 127 /// linked list. remove(&mut self, node: NonNull<L>) -> Option<NonNull<L>>128 pub(crate) unsafe fn remove(&mut self, node: NonNull<L>) -> Option<NonNull<L>> { 129 Node::remove_node(node) 130 } 131 132 /// Checks whether the list is empty. 133 #[cfg(feature = "time")] is_empty(&self) -> bool134 pub(crate) fn is_empty(&self) -> bool { 135 unsafe { L::node(self.head).as_ref().next == Some(self.head) } 136 } 137 138 /// Traverses the list and execute the closure. 139 #[cfg(feature = "net")] for_each_mut<F>(&mut self, mut f: F) where F: FnMut(&mut L),140 pub(crate) fn for_each_mut<F>(&mut self, mut f: F) 141 where 142 F: FnMut(&mut L), 143 { 144 unsafe { 145 let head = L::node(self.head).as_ref(); 146 let mut p = head.next; 147 while p != Some(self.head) { 148 let node = p.unwrap(); 149 f(&mut *node.as_ptr()); 150 p = L::node(node).as_ref().next; 151 } 152 } 153 } 154 } 155 156 impl<L: Link + Default> Default for LinkedList<L> { default() -> Self157 fn default() -> Self { 158 LinkedList::new() 159 } 160 } 161 162 impl<L: Link + Default> Drop for LinkedList<L> { drop(&mut self)163 fn drop(&mut self) { 164 let _ = unsafe { Box::from_raw(self.head.as_ptr()) }; 165 } 166 } 167 168 #[cfg(test)] 169 mod tests { 170 use std::ptr::{addr_of_mut, NonNull}; 171 172 use crate::util::linked_list::{Link, LinkedList, Node}; 173 174 #[derive(Default)] 175 struct Entry { 176 val: usize, 177 node: Node<Entry>, 178 } 179 180 impl Entry { new(val: usize) -> Entry181 fn new(val: usize) -> Entry { 182 Entry { 183 val, 184 node: Node::new(), 185 } 186 } 187 get_ptr(&self) -> NonNull<Self>188 fn get_ptr(&self) -> NonNull<Self> { 189 NonNull::from(self) 190 } 191 } 192 address_of_node(mut ptr: NonNull<Entry>) -> NonNull<Node<Entry>>193 unsafe fn address_of_node(mut ptr: NonNull<Entry>) -> NonNull<Node<Entry>> { 194 let node_ptr = addr_of_mut!(ptr.as_mut().node); 195 NonNull::new_unchecked(node_ptr) 196 } 197 get_val(ptr: NonNull<Entry>) -> usize198 fn get_val(ptr: NonNull<Entry>) -> usize { 199 unsafe { ptr.as_ref().val } 200 } 201 202 unsafe impl Link for Entry { node(ptr: NonNull<Self>) -> NonNull<Node<Self>>203 unsafe fn node(ptr: NonNull<Self>) -> NonNull<Node<Self>> { 204 address_of_node(ptr) 205 } 206 } 207 208 /// UT test cases for `is_empty()` and `clear()`. 209 /// 210 /// # Brief 211 /// 1. Create a linked list. 212 /// 2. Check if the list is empty before and after pushing nodes into the 213 /// list. 214 /// 3. Check if the list is empty before and after clear the list. 215 #[test] ut_link_list_is_empty()216 fn ut_link_list_is_empty() { 217 let mut list = LinkedList::<Entry>::new(); 218 assert!(list.is_empty()); 219 let node1 = Entry::new(1); 220 let node1 = node1.get_ptr(); 221 list.push_front(node1); 222 assert!(!list.is_empty()); 223 } 224 225 /// UT test cases for `push_front()` and `pop_back()`. 226 /// 227 /// # Brief 228 /// 1. Create a linked list. 229 /// 2. Push nodes into the list. 230 /// 3. Pop nodes from the list and check the value. 231 #[test] ut_link_list_push_and_pop()232 fn ut_link_list_push_and_pop() { 233 let mut list = LinkedList::<Entry>::new(); 234 assert!(list.is_empty()); 235 let node1 = Entry::new(1); 236 let node1 = node1.get_ptr(); 237 let node2 = Entry::new(2); 238 let node2 = node2.get_ptr(); 239 let node3 = Entry::new(3); 240 let node3 = node3.get_ptr(); 241 list.push_front(node1); 242 assert!(!list.is_empty()); 243 list.push_front(node2); 244 list.push_front(node3); 245 assert_eq!(1, get_val(list.pop_back().unwrap())); 246 assert_eq!(2, get_val(list.pop_back().unwrap())); 247 assert_eq!(3, get_val(list.pop_back().unwrap())); 248 assert!(list.pop_back().is_none()); 249 assert!(list.is_empty()); 250 } 251 252 /// UT test cases for `push_front()` and `remove()`. 253 /// 254 /// # Brief 255 /// 1. Create a linked list. 256 /// 2. Push nodes into the list. 257 /// 3. Remove the first node from the list and check the list. 258 /// 4. Remove the second node from the list and check the list. 259 /// 5. Remove the third node from the list and check the list. 260 #[test] ut_link_list_remove()261 fn ut_link_list_remove() { 262 let mut list = LinkedList::<Entry>::new(); 263 assert!(list.is_empty()); 264 let node1 = Entry::new(1); 265 let node1_ptr = node1.get_ptr(); 266 let node2 = Entry::new(2); 267 let node2_ptr = node2.get_ptr(); 268 let node3 = Entry::new(3); 269 let node3_ptr = node3.get_ptr(); 270 list.push_front(node1_ptr); 271 assert!(!list.is_empty()); 272 list.push_front(node2_ptr); 273 list.push_front(node3_ptr); 274 unsafe { 275 assert!(list.remove(node1_ptr).is_some()); 276 assert!(list.remove(node1_ptr).is_none()); 277 assert_eq!(Some(node2_ptr), node3.node.next); 278 assert_eq!(Some(node3_ptr), node2.node.prev); 279 assert!(list.remove(node2_ptr).is_some()); 280 assert!(list.remove(node2_ptr).is_none()); 281 assert!(list.remove(node3_ptr).is_some()); 282 assert!(list.remove(node3_ptr).is_none()); 283 } 284 285 list.push_front(node1_ptr); 286 list.push_front(node2_ptr); 287 list.push_front(node3_ptr); 288 unsafe { 289 assert!(list.remove(node2_ptr).is_some()); 290 assert!(list.remove(node2_ptr).is_none()); 291 assert_eq!(Some(node1_ptr), node3.node.next); 292 assert_eq!(Some(node3_ptr), node1.node.prev); 293 assert!(list.remove(node1_ptr).is_some()); 294 assert!(list.remove(node1_ptr).is_none()); 295 assert!(list.remove(node3_ptr).is_some()); 296 assert!(list.remove(node3_ptr).is_none()); 297 } 298 299 list.push_front(node1_ptr); 300 list.push_front(node2_ptr); 301 list.push_front(node3_ptr); 302 unsafe { 303 assert!(list.remove(node3_ptr).is_some()); 304 assert!(list.remove(node3_ptr).is_none()); 305 assert_eq!(Some(node1_ptr), node2.node.next); 306 assert_eq!(Some(node2_ptr), node1.node.prev); 307 assert!(list.remove(node1_ptr).is_some()); 308 assert!(list.remove(node1_ptr).is_none()); 309 assert!(list.remove(node2_ptr).is_some()); 310 assert!(list.remove(node2_ptr).is_none()); 311 } 312 assert!(list.is_empty()); 313 } 314 315 /// UT test cases for `for_each_mut()`. 316 /// 317 /// # Brief 318 /// 1. Create a linked list. 319 /// 2. Push nodes into the list. 320 /// 3. Check the value in node after traversing the list. 321 #[test] ut_link_list_for_each_mut()322 fn ut_link_list_for_each_mut() { 323 let mut list = LinkedList::<Entry>::new(); 324 assert!(list.is_empty()); 325 let node1 = Entry::new(1); 326 let node1 = node1.get_ptr(); 327 let node2 = Entry::new(2); 328 let node2 = node2.get_ptr(); 329 let node3 = Entry::new(3); 330 let node3 = node3.get_ptr(); 331 list.push_front(node1); 332 list.push_front(node2); 333 list.push_front(node3); 334 list.for_each_mut(|entry| { 335 entry.val += 1; 336 }); 337 assert_eq!(2, get_val(list.pop_back().unwrap())); 338 assert_eq!(3, get_val(list.pop_back().unwrap())); 339 assert_eq!(4, get_val(list.pop_back().unwrap())); 340 assert!(list.pop_back().is_none()); 341 assert!(list.is_empty()); 342 } 343 } 344