Skip to content

Commit d633ff5

Browse files
committed
Add examples to VecAllocExt and remove custom doubling strategy
1 parent c19e078 commit d633ff5

File tree

1 file changed

+42
-9
lines changed
  • datafusion/execution/src/memory_pool

1 file changed

+42
-9
lines changed

datafusion/execution/src/memory_pool/proxy.rs

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,25 @@ pub trait VecAllocExt {
2828
/// `accounting` by any newly allocated bytes.
2929
///
3030
/// Note that allocation counts capacity, not size
31+
///
32+
/// # Example:
33+
/// ```
34+
/// # use datafusion_execution::memory_pool::proxy::VecAllocExt;
35+
/// // use allocated to incrementally track how much memory is allocated in the vec
36+
/// let mut allocated = 0;
37+
/// let mut vec = Vec::new();
38+
/// // Push data into the vec and the accounting will be updated to reflect
39+
/// // memory allocation
40+
/// vec.push_accounted(1, &mut allocated);
41+
/// assert_eq!(allocated, 16); // space for 4 u32s
42+
/// vec.push_accounted(1, &mut allocated);
43+
/// assert_eq!(allocated, 16); // no new allocation needed
44+
///
45+
/// // push more data into the vec
46+
/// for _ in 0..10 { vec.push_accounted(1, &mut allocated); }
47+
/// assert_eq!(allocated, 64); // underlying vec has space for 10 u32s
48+
/// assert_eq!(vec.allocated_size(), 64);
49+
/// ```
3150
fn push_accounted(&mut self, x: Self::T, accounting: &mut usize);
3251

3352
/// Return the amount of memory allocated by this Vec to store elements
@@ -36,24 +55,37 @@ pub trait VecAllocExt {
3655
/// Note this calculation is not recursive, and does not include any heap
3756
/// allocations contained within the Vec's elements. Does not include the
3857
/// size of `self`
58+
///
59+
/// # Example:
60+
/// ```
61+
/// # use datafusion_execution::memory_pool::proxy::VecAllocExt;
62+
/// let mut vec = Vec::new();
63+
/// // Push data into the vec and the accounting will be updated to reflect
64+
/// // memory allocation
65+
/// vec.push(1);
66+
/// assert_eq!(vec.allocated_size(), 16); // space for 4 u32s
67+
/// vec.push(1);
68+
/// assert_eq!(vec.allocated_size(), 16); // no new allocation needed
69+
///
70+
/// // push more data into the vec
71+
/// for _ in 0..10 { vec.push(1); }
72+
/// assert_eq!(vec.allocated_size(), 64); // space for 64 now
73+
/// ```
3974
fn allocated_size(&self) -> usize;
4075
}
4176

4277
impl<T> VecAllocExt for Vec<T> {
4378
type T = T;
4479

4580
fn push_accounted(&mut self, x: Self::T, accounting: &mut usize) {
46-
if self.capacity() == self.len() {
47-
// allocate more
48-
49-
// growth factor: 2, but at least 2 elements
50-
let bump_elements = (self.capacity() * 2).max(2);
51-
let bump_size = std::mem::size_of::<u32>() * bump_elements;
52-
self.reserve(bump_elements);
81+
let prev_capacty = self.capacity();
82+
self.push(x);
83+
let new_capacity = self.capacity();
84+
if new_capacity > prev_capacty {
85+
// capacity changed, so we allocated more
86+
let bump_size = (new_capacity - prev_capacty) * std::mem::size_of::<T>();
5387
*accounting = (*accounting).checked_add(bump_size).expect("overflow");
5488
}
55-
56-
self.push(x);
5789
}
5890
fn allocated_size(&self) -> usize {
5991
std::mem::size_of::<T>() * self.capacity()
@@ -69,6 +101,7 @@ pub trait RawTableAllocExt {
69101
/// `accounting` by any newly allocated bytes.
70102
///
71103
/// Returns the bucket where the element was inserted.
104+
/// Note that allocation counts capacity, not size.
72105
fn insert_accounted(
73106
&mut self,
74107
x: Self::T,

0 commit comments

Comments
 (0)