@@ -7,6 +7,7 @@ use core::{cmp, fmt, hash, isize, slice, usize};
77use alloc:: {
88 borrow:: { Borrow , BorrowMut } ,
99 boxed:: Box ,
10+ collections:: TryReserveError ,
1011 string:: String ,
1112 vec,
1213 vec:: Vec ,
@@ -588,22 +589,87 @@ impl BytesMut {
588589 /// Panics if the new capacity overflows `usize`.
589590 #[ inline]
590591 pub fn reserve ( & mut self , additional : usize ) {
592+ match self . try_reserve ( additional) {
593+ Err ( err) => panic ! ( "fail to reserve: {}" , err) ,
594+ Ok ( _) => { }
595+ }
596+ }
597+
598+ /// Tries to reserves capacity for at least `additional` more bytes to be inserted
599+ /// into the given `BytesMut`.
600+ ///
601+ /// More than `additional` bytes may be reserved in order to avoid frequent
602+ /// reallocations. A call to `try_reserve` may result in an allocation.
603+ ///
604+ /// Before allocating new buffer space, the function will attempt to reclaim
605+ /// space in the existing buffer. If the current handle references a small
606+ /// view in the original buffer and all other handles have been dropped,
607+ /// and the requested capacity is less than or equal to the existing
608+ /// buffer's capacity, then the current view will be copied to the front of
609+ /// the buffer and the handle will take ownership of the full buffer.
610+ ///
611+ /// # Errors
612+ ///
613+ /// If the capacity overflows, or the allocator reports a failure, then an error is returned.
614+ ///
615+ /// # Examples
616+ ///
617+ /// In the following example, a new buffer is allocated.
618+ ///
619+ /// ```
620+ /// use bytes::BytesMut;
621+ ///
622+ /// let mut buf = BytesMut::from(&b"hello"[..]);
623+ /// let res = buf.try_reserve(64);
624+ /// assert!(res.is_ok());
625+ /// assert!(buf.capacity() >= 69);
626+ /// ```
627+ ///
628+ /// In the following example, the existing buffer is reclaimed.
629+ ///
630+ /// ```
631+ /// use bytes::{BytesMut, BufMut};
632+ ///
633+ /// let mut buf = BytesMut::with_capacity(128);
634+ /// buf.put(&[0; 64][..]);
635+ ///
636+ /// let ptr = buf.as_ptr();
637+ /// let other = buf.split();
638+ ///
639+ /// assert!(buf.is_empty());
640+ /// assert_eq!(buf.capacity(), 64);
641+ ///
642+ /// drop(other);
643+ /// let res = buf.try_reserve(128);
644+ ///
645+ /// assert!(res.is_ok());
646+ /// assert_eq!(buf.capacity(), 128);
647+ /// assert_eq!(buf.as_ptr(), ptr);
648+ /// ```
649+ #[ inline]
650+ pub fn try_reserve ( & mut self , additional : usize ) -> Result < ( ) , TryReserveError > {
591651 let len = self . len ( ) ;
592652 let rem = self . capacity ( ) - len;
593653
594654 if additional <= rem {
595655 // The handle can already store at least `additional` more bytes, so
596656 // there is no further work needed to be done.
597- return ;
657+ return Ok ( ( ) ) ;
598658 }
599659
600- // will always succeed
601- let _ = self . reserve_inner ( additional, true ) ;
660+ self . reserve_inner ( additional, true ) . map (
661+ // will always succeed
662+ |_| ( ) ,
663+ )
602664 }
603665
604666 // In separate function to allow the short-circuits in `reserve` and `try_reclaim` to
605667 // be inline-able. Significantly helps performance. Returns false if it did not succeed.
606- fn reserve_inner ( & mut self , additional : usize , allocate : bool ) -> bool {
668+ fn reserve_inner (
669+ & mut self ,
670+ additional : usize ,
671+ allocate : bool ,
672+ ) -> Result < bool , TryReserveError > {
607673 let len = self . len ( ) ;
608674 let kind = self . kind ( ) ;
609675
@@ -649,21 +715,21 @@ impl BytesMut {
649715 self . cap += off;
650716 } else {
651717 if !allocate {
652- return false ;
718+ return Ok ( false ) ;
653719 }
654720 // Not enough space, or reusing might be too much overhead:
655721 // allocate more space!
656722 let mut v =
657723 ManuallyDrop :: new ( rebuild_vec ( self . ptr . as_ptr ( ) , self . len , self . cap , off) ) ;
658- v. reserve ( additional) ;
724+ v. try_reserve ( additional) ? ;
659725
660726 // Update the info
661727 self . ptr = vptr ( v. as_mut_ptr ( ) . add ( off) ) ;
662728 self . cap = v. capacity ( ) - off;
663729 debug_assert_eq ! ( self . len, v. len( ) - off) ;
664730 }
665731
666- return true ;
732+ return Ok ( true ) ;
667733 }
668734 }
669735
@@ -676,7 +742,7 @@ impl BytesMut {
676742 // Compute the new capacity
677743 let mut new_cap = match len. checked_add ( additional) {
678744 Some ( new_cap) => new_cap,
679- None if !allocate => return false ,
745+ None if !allocate => return Ok ( false ) ,
680746 None => panic ! ( "overflow" ) ,
681747 } ;
682748
@@ -710,7 +776,7 @@ impl BytesMut {
710776 self . cap = v. capacity ( ) ;
711777 } else {
712778 if !allocate {
713- return false ;
779+ return Ok ( false ) ;
714780 }
715781 // calculate offset
716782 let off = ( self . ptr . as_ptr ( ) as usize ) - ( v. as_ptr ( ) as usize ) ;
@@ -743,18 +809,18 @@ impl BytesMut {
743809 // care about in the unused capacity before calling `reserve`.
744810 debug_assert ! ( off + len <= v. capacity( ) ) ;
745811 v. set_len ( off + len) ;
746- v. reserve ( new_cap - v. len ( ) ) ;
812+ v. try_reserve ( new_cap - v. len ( ) ) ? ;
747813
748814 // Update the info
749815 self . ptr = vptr ( v. as_mut_ptr ( ) . add ( off) ) ;
750816 self . cap = v. capacity ( ) - off;
751817 }
752818
753- return true ;
819+ return Ok ( true ) ;
754820 }
755821 }
756822 if !allocate {
757- return false ;
823+ return Ok ( false ) ;
758824 }
759825
760826 let original_capacity_repr = unsafe { ( * shared) . original_capacity_repr } ;
@@ -763,7 +829,9 @@ impl BytesMut {
763829 new_cap = cmp:: max ( new_cap, original_capacity) ;
764830
765831 // Create a new vector to store the data
766- let mut v = ManuallyDrop :: new ( Vec :: with_capacity ( new_cap) ) ;
832+ let mut v = Vec :: new ( ) ;
833+ v. try_reserve ( new_cap) ?;
834+ let mut v = ManuallyDrop :: new ( v) ;
767835
768836 // Copy the bytes
769837 v. extend_from_slice ( self . as_ref ( ) ) ;
@@ -778,7 +846,7 @@ impl BytesMut {
778846 self . ptr = vptr ( v. as_mut_ptr ( ) ) ;
779847 self . cap = v. capacity ( ) ;
780848 debug_assert_eq ! ( self . len, v. len( ) ) ;
781- return true ;
849+ Ok ( true )
782850 }
783851
784852 /// Attempts to cheaply reclaim already allocated capacity for at least `additional` more
@@ -838,7 +906,10 @@ impl BytesMut {
838906 return true ;
839907 }
840908
841- self . reserve_inner ( additional, false )
909+ match self . reserve_inner ( additional, false ) {
910+ Err ( err) => panic ! ( "fail to reserve: {}" , err) ,
911+ Ok ( r) => r,
912+ }
842913 }
843914
844915 /// Appends given bytes to this `BytesMut`.
0 commit comments