@@ -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
4277impl < 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