eta_algorithms/data_structs/
queue.rs1use crate::utils::{closest_pow2, rotate_inc};
2use std::alloc::{dealloc, realloc, Layout};
3use std::ptr;
4
5pub struct Queue<T>
6where
7 T: Copy + Sized,
8{
9 capacity: usize,
10 len: usize,
11 layout: Layout,
12 data: *mut T,
13 front: usize,
14 end: usize,
15}
16
17impl<T> Queue<T>
18where
19 T: Copy + Sized,
20{
21 pub fn new_pow2_sized(capacity: usize) -> Self {
22 let capacity = closest_pow2(capacity);
23 let layout = Layout::array::<T>(capacity).expect("Failed to create layout");
24 let data = unsafe { std::alloc::alloc(layout) as *mut T };
25 if data.is_null() {
26 panic!("Failed to allocate memory");
27 }
28
29 Queue {
30 capacity,
31 layout,
32 data,
33 len: 0,
34 front: 0,
35 end: 0,
36 }
37 }
38
39 #[inline(always)]
40 pub fn is_empty(&self) -> bool {
41 self.len == 0
42 }
43
44 pub fn extend_pow2_sized(&mut self, capacity_pow: usize) {
45 let new_capacity = closest_pow2(capacity_pow);
46 if new_capacity <= self.capacity {
47 panic!("New capacity is less than or equal to current capacity");
48 }
49
50 let new_layout = Layout::array::<T>(new_capacity).expect("Failed to create layout");
51 if self.front >= self.end && self.len > 0 {
53 let new_data = unsafe { std::alloc::alloc(new_layout) as *mut T };
54 if new_data.is_null() {
55 panic!("Failed to allocate memory");
56 }
57 let from_front_to_array_end_len = self.capacity() - self.front;
58 let from_start_to_end_len = self.front;
59 unsafe {
60 ptr::copy_nonoverlapping(
61 self.data.add(self.front),
62 new_data,
63 from_front_to_array_end_len,
64 )
65 }; unsafe {
67 ptr::copy_nonoverlapping(
68 self.data,
69 new_data.add(from_front_to_array_end_len),
70 from_start_to_end_len,
71 )
72 }; unsafe { dealloc(self.data as *mut u8, self.layout) };
75 self.capacity = new_capacity;
76 self.data = new_data;
77 self.front = 0;
78 self.end = from_front_to_array_end_len + from_start_to_end_len;
79 return;
80 }
81
82 unsafe {
83 self.data = realloc(self.data as *mut u8, new_layout, new_layout.size()) as *mut T;
84 if self.data.is_null() {
85 panic!("Failed to reallocate memory");
86 }
87 self.capacity = new_capacity;
88 }
89 }
90 #[inline(always)]
91 pub fn extend_pow2_sized_by(&mut self, capacity_pow: usize) {
92 if self.capacity < self.capacity + capacity_pow {
93 return;
94 }
95 let new_capacity = closest_pow2(self.capacity + capacity_pow);
96 self.extend_pow2_sized(new_capacity)
97 }
98 #[inline(always)]
99 pub fn capacity(&self) -> usize {
100 self.capacity
101 }
102 #[inline(always)]
103 pub fn len(&self) -> usize {
104 self.len
105 }
106
107 #[inline(always)]
108 pub fn push(&mut self, value: T) {
109 if self.len == self.capacity {
110 panic!("Queue is full");
111 }
112 unsafe {
113 self.data.add(self.end).write(value);
114 self.len += 1;
115 self.end = rotate_inc(self.end, self.capacity - 1);
116 }
117 }
118 #[inline(always)]
119 pub fn front(&self) -> Option<&T> {
120 if self.len == 0 {
121 return None;
122 }
123 unsafe { Some(self.data.add(self.front).as_ref().unwrap()) }
124 }
125 #[inline(always)]
126 pub fn front_mut(&mut self) -> Option<&mut T> {
127 if self.len == 0 {
128 return None;
129 }
130 unsafe { Some(self.data.add(self.front).as_mut().unwrap()) }
131 }
132 #[inline(always)]
133 pub fn dequeue(&mut self) -> Option<T> {
134 if self.len == 0 {
135 return None;
136 }
137 unsafe {
138 let result = Some(self.data.add(self.front).read());
139 self.len -= 1;
140 self.front = rotate_inc(self.front, self.capacity - 1);
141 result
142 }
143 }
144}
145
146impl<T> Drop for Queue<T>
147where
148 T: Copy + Sized,
149{
150 fn drop(&mut self) {
151 unsafe {
152 dealloc(self.data as *mut u8, self.layout);
153 }
154 }
155}