Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-utils/src/arena.rs
8424 views
1
#[cfg(feature = "ir_serde")]
2
use serde::{Deserialize, Serialize};
3
4
use crate::error::*;
5
use crate::relaxed_cell::RelaxedCell;
6
7
unsafe fn index_of_unchecked<T>(slice: &[T], item: &T) -> usize {
8
(item as *const _ as usize - slice.as_ptr() as usize) / size_of::<T>()
9
}
10
11
fn index_of<T>(slice: &[T], item: &T) -> Option<usize> {
12
debug_assert!(size_of::<T>() > 0);
13
let ptr = item as *const T;
14
unsafe {
15
if slice.as_ptr() < ptr && slice.as_ptr().add(slice.len()) > ptr {
16
Some(index_of_unchecked(slice, item))
17
} else {
18
None
19
}
20
}
21
}
22
23
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
24
#[repr(transparent)]
25
#[cfg_attr(feature = "ir_serde", derive(Serialize, Deserialize))]
26
pub struct Node(pub usize);
27
28
impl Default for Node {
29
fn default() -> Self {
30
Node(usize::MAX)
31
}
32
}
33
34
static ARENA_VERSION: RelaxedCell<u32> = RelaxedCell::new_u32(0);
35
36
#[derive(Debug, Clone)]
37
#[cfg_attr(feature = "ir_serde", derive(Serialize, Deserialize))]
38
pub struct Arena<T> {
39
version: u32,
40
items: Vec<T>,
41
}
42
43
impl<T> Default for Arena<T> {
44
fn default() -> Self {
45
Self::new()
46
}
47
}
48
49
/// Simple Arena implementation
50
/// Allocates memory and stores item in a Vec. Only deallocates when being dropped itself.
51
impl<T> Arena<T> {
52
#[inline]
53
pub fn version(&self) -> u32 {
54
self.version
55
}
56
57
pub fn add(&mut self, val: T) -> Node {
58
let idx = self.items.len();
59
self.items.push(val);
60
Node(idx)
61
}
62
63
pub fn pop(&mut self) -> Option<T> {
64
self.items.pop()
65
}
66
67
pub fn last_node(&mut self) -> Option<Node> {
68
if self.is_empty() {
69
None
70
} else {
71
Some(Node(self.items.len() - 1))
72
}
73
}
74
75
pub fn len(&self) -> usize {
76
self.items.len()
77
}
78
79
pub fn is_empty(&self) -> bool {
80
self.items.is_empty()
81
}
82
83
pub fn new() -> Self {
84
Arena {
85
items: vec![],
86
version: ARENA_VERSION.fetch_add(1),
87
}
88
}
89
90
pub fn with_capacity(cap: usize) -> Self {
91
Arena {
92
items: Vec::with_capacity(cap),
93
version: ARENA_VERSION.fetch_add(1),
94
}
95
}
96
97
pub fn get_node(&self, val: &T) -> Option<Node> {
98
index_of(&self.items, val).map(Node)
99
}
100
101
pub fn swap(&mut self, idx_a: Node, idx_b: Node) {
102
self.items.swap(idx_a.0, idx_b.0)
103
}
104
105
#[inline]
106
pub fn get(&self, idx: Node) -> &T {
107
self.items.get(idx.0).unwrap()
108
}
109
110
/// # Safety
111
/// Doesn't do any bound checks
112
#[inline]
113
pub unsafe fn get_unchecked(&self, idx: Node) -> &T {
114
unsafe { self.items.get_unchecked(idx.0) }
115
}
116
117
#[inline]
118
pub fn get_mut(&mut self, idx: Node) -> &mut T {
119
self.items.get_mut(idx.0).unwrap()
120
}
121
122
/// Get mutable references to multiple disjoint items of the Arena.
123
///
124
/// # Panics
125
/// Panics if indices are out of bounds or overlapping.
126
#[inline]
127
pub fn get_disjoint_mut<const N: usize>(&mut self, nodes: [Node; N]) -> [&mut T; N] {
128
self.items.get_disjoint_mut(nodes.map(|n| n.0)).unwrap()
129
}
130
131
#[inline]
132
pub fn replace(&mut self, idx: Node, val: T) -> T {
133
let x = self.get_mut(idx);
134
std::mem::replace(x, val)
135
}
136
137
pub fn clear(&mut self) {
138
self.items.clear();
139
self.version = ARENA_VERSION.fetch_add(1);
140
}
141
}
142
143
impl<T: Clone> Arena<T> {
144
pub fn duplicate(&mut self, node: Node) -> Node {
145
let item = self.items[node.0].clone();
146
self.add(item)
147
}
148
}
149
150
impl<T: Default> Arena<T> {
151
#[inline]
152
pub fn take(&mut self, idx: Node) -> T {
153
std::mem::take(self.get_mut(idx))
154
}
155
156
pub fn replace_with<F>(&mut self, idx: Node, f: F)
157
where
158
F: FnOnce(T) -> T,
159
{
160
let val = self.take(idx);
161
self.replace(idx, f(val));
162
}
163
164
pub fn try_replace_with<F>(&mut self, idx: Node, mut f: F) -> Result<()>
165
where
166
F: FnMut(T) -> Result<T>,
167
{
168
let val = self.take(idx);
169
self.replace(idx, f(val)?);
170
Ok(())
171
}
172
}
173
174