@@ -7,6 +7,7 @@ use core::{cmp, fmt, hash, isize, slice, usize};
7
7
use alloc:: {
8
8
borrow:: { Borrow , BorrowMut } ,
9
9
boxed:: Box ,
10
+ collections:: TryReserveError ,
10
11
string:: String ,
11
12
vec,
12
13
vec:: Vec ,
@@ -588,22 +589,87 @@ impl BytesMut {
588
589
/// Panics if the new capacity overflows `usize`.
589
590
#[ inline]
590
591
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 > {
591
651
let len = self . len ( ) ;
592
652
let rem = self . capacity ( ) - len;
593
653
594
654
if additional <= rem {
595
655
// The handle can already store at least `additional` more bytes, so
596
656
// there is no further work needed to be done.
597
- return ;
657
+ return Ok ( ( ) ) ;
598
658
}
599
659
600
- // will always succeed
601
- let _ = self . reserve_inner ( additional, true ) ;
660
+ self . reserve_inner ( additional, true ) . map (
661
+ // will always succeed
662
+ |_| ( ) ,
663
+ )
602
664
}
603
665
604
666
// In separate function to allow the short-circuits in `reserve` and `try_reclaim` to
605
667
// 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 > {
607
673
let len = self . len ( ) ;
608
674
let kind = self . kind ( ) ;
609
675
@@ -649,21 +715,21 @@ impl BytesMut {
649
715
self . cap += off;
650
716
} else {
651
717
if !allocate {
652
- return false ;
718
+ return Ok ( false ) ;
653
719
}
654
720
// Not enough space, or reusing might be too much overhead:
655
721
// allocate more space!
656
722
let mut v =
657
723
ManuallyDrop :: new ( rebuild_vec ( self . ptr . as_ptr ( ) , self . len , self . cap , off) ) ;
658
- v. reserve ( additional) ;
724
+ v. try_reserve ( additional) ? ;
659
725
660
726
// Update the info
661
727
self . ptr = vptr ( v. as_mut_ptr ( ) . add ( off) ) ;
662
728
self . cap = v. capacity ( ) - off;
663
729
debug_assert_eq ! ( self . len, v. len( ) - off) ;
664
730
}
665
731
666
- return true ;
732
+ return Ok ( true ) ;
667
733
}
668
734
}
669
735
@@ -676,7 +742,7 @@ impl BytesMut {
676
742
// Compute the new capacity
677
743
let mut new_cap = match len. checked_add ( additional) {
678
744
Some ( new_cap) => new_cap,
679
- None if !allocate => return false ,
745
+ None if !allocate => return Ok ( false ) ,
680
746
None => panic ! ( "overflow" ) ,
681
747
} ;
682
748
@@ -710,7 +776,7 @@ impl BytesMut {
710
776
self . cap = v. capacity ( ) ;
711
777
} else {
712
778
if !allocate {
713
- return false ;
779
+ return Ok ( false ) ;
714
780
}
715
781
// calculate offset
716
782
let off = ( self . ptr . as_ptr ( ) as usize ) - ( v. as_ptr ( ) as usize ) ;
@@ -743,18 +809,18 @@ impl BytesMut {
743
809
// care about in the unused capacity before calling `reserve`.
744
810
debug_assert ! ( off + len <= v. capacity( ) ) ;
745
811
v. set_len ( off + len) ;
746
- v. reserve ( new_cap - v. len ( ) ) ;
812
+ v. try_reserve ( new_cap - v. len ( ) ) ? ;
747
813
748
814
// Update the info
749
815
self . ptr = vptr ( v. as_mut_ptr ( ) . add ( off) ) ;
750
816
self . cap = v. capacity ( ) - off;
751
817
}
752
818
753
- return true ;
819
+ return Ok ( true ) ;
754
820
}
755
821
}
756
822
if !allocate {
757
- return false ;
823
+ return Ok ( false ) ;
758
824
}
759
825
760
826
let original_capacity_repr = unsafe { ( * shared) . original_capacity_repr } ;
@@ -763,7 +829,9 @@ impl BytesMut {
763
829
new_cap = cmp:: max ( new_cap, original_capacity) ;
764
830
765
831
// 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) ;
767
835
768
836
// Copy the bytes
769
837
v. extend_from_slice ( self . as_ref ( ) ) ;
@@ -778,7 +846,7 @@ impl BytesMut {
778
846
self . ptr = vptr ( v. as_mut_ptr ( ) ) ;
779
847
self . cap = v. capacity ( ) ;
780
848
debug_assert_eq ! ( self . len, v. len( ) ) ;
781
- return true ;
849
+ Ok ( true )
782
850
}
783
851
784
852
/// Attempts to cheaply reclaim already allocated capacity for at least `additional` more
@@ -838,7 +906,10 @@ impl BytesMut {
838
906
return true ;
839
907
}
840
908
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
+ }
842
913
}
843
914
844
915
/// Appends given bytes to this `BytesMut`.
0 commit comments