1#![allow(clippy::missing_safety_doc)]
5
6use std::fmt::Debug;
8use std::marker;
9use std::marker::PhantomPinned;
10use std::pin::Pin;
11use std::ptr::NonNull;
12
13pub use metrics::*;
14pub use root::DeleteResult;
15
16pub use rle::{SplitAndJoinSpan, RleRun, ReverseSpan, Single};
18
19mod unsafe_cursor;
21mod root;
22mod leaf;
23mod internal;
24mod mutations;
25mod metrics;
26mod safe_cursor;
27pub mod testrange;
28mod iter;
29mod debug;
30
31#[cfg(debug_assertions)]
34pub const DEFAULT_IE: usize = 8; #[cfg(not(debug_assertions))]
36pub const DEFAULT_IE: usize = 10;
37
38#[cfg(debug_assertions)]
40pub const DEFAULT_LE: usize = 4;
41#[cfg(not(debug_assertions))]
42pub const DEFAULT_LE: usize = 32;
43
44pub trait ContentTraits: SplitAndJoinSpan + Copy + Debug + Default {}
46impl<T: SplitAndJoinSpan + Copy + Debug + Default> ContentTraits for T {}
47
48pub struct ContentTreeRaw<E: ContentTraits, I: TreeMetrics<E>, const INT_ENTRIES: usize = DEFAULT_IE, const LEAF_ENTRIES: usize = DEFAULT_LE> {
64 count: I::Value,
65
66 root: Node<E, I, INT_ENTRIES, LEAF_ENTRIES>,
69
70 _pin: marker::PhantomPinned,
76}
77
78pub trait Cursors {
79 type UnsafeCursor;
80 type Cursor;
81 type MutCursor;
82}
83
84impl<'a, E: ContentTraits, I: TreeMetrics<E>, const IE: usize, const LE: usize> Cursors for &'a ContentTreeRaw<E, I, IE, LE> {
86 type UnsafeCursor = UnsafeCursor<E, I, IE, LE>;
87 type Cursor = Cursor<'a, E, I, IE, LE>;
88 type MutCursor = MutCursor<'a, E, I, IE, LE>;
89}
90impl<'a, E: ContentTraits, I: TreeMetrics<E>, const IE: usize, const LE: usize> Cursors for &'a Pin<Box<ContentTreeRaw<E, I, IE, LE>>> {
91 type UnsafeCursor = UnsafeCursor<E, I, IE, LE>;
92 type Cursor = Cursor<'a, E, I, IE, LE>;
93 type MutCursor = MutCursor<'a, E, I, IE, LE>;
94}
95
96#[deprecated]
98pub type ContentTreeWithIndex<E, I> = ContentTreeRaw<E, I, DEFAULT_IE, DEFAULT_LE>;
99pub type ContentTree<E> = ContentTreeRaw<E, RawPositionMetricsU32, DEFAULT_IE, DEFAULT_LE>;
100
101#[derive(Debug)]
103pub(crate) struct NodeInternal<E: ContentTraits, I: TreeMetrics<E>, const INT_ENTRIES: usize, const LEAF_ENTRIES: usize> {
104 parent: ParentPtr<E, I, INT_ENTRIES, LEAF_ENTRIES>,
105 metrics: [I::Value; INT_ENTRIES],
109 children: [Option<Node<E, I, INT_ENTRIES, LEAF_ENTRIES>>; INT_ENTRIES],
110 _pin: PhantomPinned, }
112
113#[derive(Debug)]
121pub struct NodeLeaf<E: ContentTraits, I: TreeMetrics<E>, const INT_ENTRIES: usize = DEFAULT_IE, const LEAF_ENTRIES: usize = DEFAULT_LE> {
122 parent: ParentPtr<E, I, INT_ENTRIES, LEAF_ENTRIES>,
123 num_entries: u8, data: [E; LEAF_ENTRIES],
125 _pin: PhantomPinned, next: Option<NonNull<Self>>,
128}
129
130#[derive(Debug)]
131pub(crate) enum Node<E: ContentTraits, I: TreeMetrics<E>, const IE: usize = DEFAULT_IE, const LE: usize = DEFAULT_LE> {
132 Internal(Pin<Box<NodeInternal<E, I, IE, LE>>>),
133 Leaf(Pin<Box<NodeLeaf<E, I, IE, LE>>>),
134}
135
136#[derive(Copy, Clone, Debug, PartialEq, Eq)]
138pub(crate) enum NodePtr<E: ContentTraits, I: TreeMetrics<E>, const IE: usize = DEFAULT_IE, const LE: usize = DEFAULT_LE> {
139 Internal(NonNull<NodeInternal<E, I, IE, LE>>),
140 Leaf(NonNull<NodeLeaf<E, I, IE, LE>>),
141}
142
143#[derive(Copy, Clone, Debug, Eq)]
145pub(crate) enum ParentPtr<E: ContentTraits, I: TreeMetrics<E>, const IE: usize = DEFAULT_IE, const LE: usize = DEFAULT_LE> {
146 Root(NonNull<ContentTreeRaw<E, I, IE, LE>>),
147 Internal(NonNull<NodeInternal<E, I, IE, LE>>)
148}
149
150#[derive(Clone, Debug)]
162pub struct UnsafeCursor<E: ContentTraits, I: TreeMetrics<E>, const IE: usize = DEFAULT_IE, const LE: usize = DEFAULT_LE> {
163 node: NonNull<NodeLeaf<E, I, IE, LE>>,
164 idx: usize,
165 pub offset: usize, }
167
168#[repr(transparent)]
169#[derive(Clone, Debug)]
170pub struct SafeCursor<R, E: ContentTraits, I: TreeMetrics<E>, const IE: usize = DEFAULT_IE, const LE: usize = DEFAULT_LE> {
171 pub inner: UnsafeCursor<E, I, IE, LE>,
172 marker: marker::PhantomData<R>
173}
174
175pub type Cursor<'a, E, I, const IE: usize = DEFAULT_IE, const LE: usize = DEFAULT_LE>
179 = SafeCursor<&'a ContentTreeRaw<E, I, IE, LE>, E, I, IE, LE>;
180
181pub type MutCursor<'a, E, I, const IE: usize, const LE: usize> = SafeCursor<&'a mut ContentTreeRaw<E, I, IE, LE>, E, I, IE, LE>;
186
187impl<E: ContentTraits, I: TreeMetrics<E>, const IE: usize, const LE: usize> PartialEq for ParentPtr<E, I, IE, LE> {
190 fn eq(&self, other: &Self) -> bool {
191 use ParentPtr::*;
192 match (self, other) {
193 (Root(a), Root(b)) => a == b,
194 (Internal(a), Internal(b)) => a == b,
195 _ => false
196 }
197 }
198}
199
200unsafe fn ref_to_nonnull<T>(val: &T) -> NonNull<T> {
202 NonNull::new_unchecked(val as *const _ as *mut _)
203}
204
205pub fn null_notify<E, Node>(_e: E, _node: Node) {}
207
208impl<E: ContentTraits, I: TreeMetrics<E>, const IE: usize, const LE: usize> Node<E, I, IE, LE> {
209 fn set_parent(&mut self, parent: ParentPtr<E, I, IE, LE>) {
218 unsafe {
219 match self {
220 Node::Leaf(l) => l.as_mut().get_unchecked_mut().parent = parent,
221 Node::Internal(i) => i.as_mut().get_unchecked_mut().parent = parent,
222 }
223 }
224 }
225
226 pub fn is_leaf(&self) -> bool {
234 match self {
235 Node::Leaf(_) => true,
236 Node::Internal(_) => false,
237 }
238 }
239
240 fn unwrap_leaf_mut(&mut self) -> Pin<&mut NodeLeaf<E, I, IE, LE>> {
255 match self {
256 Node::Leaf(l) => l.as_mut(),
257 Node::Internal(_) => panic!("Expected leaf - found internal node"),
258 }
259 }
260 fn unwrap_internal_mut(&mut self) -> Pin<&mut NodeInternal<E, I, IE, LE>> {
267 match self {
268 Node::Internal(n) => n.as_mut(),
269 Node::Leaf(_) => panic!("Expected internal node"),
270 }
271 }
272
273 unsafe fn as_ptr(&self) -> NodePtr<E, I, IE, LE> {
275 match self {
276 Node::Internal(n) => {
277 NodePtr::Internal(ref_to_nonnull(n.as_ref().get_ref()))
278 },
279 Node::Leaf(n) => {
280 NodePtr::Leaf(ref_to_nonnull(n.as_ref().get_ref()))
281 },
282 }
283 }
284
285 fn ptr_eq(&self, ptr: NodePtr<E, I, IE, LE>) -> bool {
286 match (self, ptr) {
287 (Node::Internal(n), NodePtr::Internal(ptr)) => {
288 std::ptr::eq(n.as_ref().get_ref(), ptr.as_ptr())
289 },
290 (Node::Leaf(n), NodePtr::Leaf(ptr)) => {
291 std::ptr::eq(n.as_ref().get_ref(), ptr.as_ptr())
292 },
293 _ => panic!("Pointer type does not match")
294 }
295 }
296}
297
298impl<E: ContentTraits, I: TreeMetrics<E>, const IE: usize, const LE: usize> NodePtr<E, I, IE, LE> {
299 fn unwrap_leaf(self) -> NonNull<NodeLeaf<E, I, IE, LE>> {
300 match self {
301 NodePtr::Leaf(l) => l,
302 NodePtr::Internal(_) => panic!("Expected leaf - found internal node"),
303 }
304 }
305
306 unsafe fn get_parent(&self) -> ParentPtr<E, I, IE, LE> {
307 match self {
308 NodePtr::Internal(n) => { n.as_ref().parent }
309 NodePtr::Leaf(n) => { n.as_ref().parent }
310 }
311 }
312}
313
314impl<E: ContentTraits, I: TreeMetrics<E>, const IE: usize, const LE: usize> ParentPtr<E, I, IE, LE> {
315 fn unwrap_internal(self) -> NonNull<NodeInternal<E, I, IE, LE>> {
316 match self {
317 ParentPtr::Root(_) => { panic!("Expected internal node"); }
318 ParentPtr::Internal(ptr) => { ptr }
319 }
320 }
321
322 fn is_root(&self) -> bool {
323 match self {
324 ParentPtr::Root(_) => { true }
325 ParentPtr::Internal(_) => { false }
326 }
327 }
328}
329
330#[cfg(test)]
331mod test {
332 use std::mem::size_of;
333 use super::*;
334 use crate::testrange::TestRange;
335
336#[test]
339 fn option_node_size_is_transparent() {
340 let node_size = size_of::<Node<TestRange, RawPositionMetricsU32, DEFAULT_IE, DEFAULT_LE>>();
341 let opt_node_size = size_of::<Option<Node<TestRange, RawPositionMetricsU32, DEFAULT_IE, DEFAULT_LE>>>();
342 assert_eq!(node_size, opt_node_size);
343
344 }
349}