File tree Expand file tree Collapse file tree 2 files changed +34
-5
lines changed Expand file tree Collapse file tree 2 files changed +34
-5
lines changed Original file line number Diff line number Diff line change @@ -1201,11 +1201,21 @@ unsafe impl BufMut for BytesMut {
12011201 where
12021202 Self : Sized ,
12031203 {
1204- while src. has_remaining ( ) {
1205- let s = src. chunk ( ) ;
1206- let l = s. len ( ) ;
1207- self . extend_from_slice ( s) ;
1208- src. advance ( l) ;
1204+ // When capacity is zero, try reusing allocation of `src`.
1205+ if self . capacity ( ) == 0 {
1206+ let src_copy = src. copy_to_bytes ( src. remaining ( ) ) ;
1207+ drop ( src) ;
1208+ match src_copy. try_into_mut ( ) {
1209+ Ok ( bytes_mut) => * self = bytes_mut,
1210+ Err ( bytes) => self . extend_from_slice ( & bytes) ,
1211+ }
1212+ } else {
1213+ while src. has_remaining ( ) {
1214+ let s = src. chunk ( ) ;
1215+ let l = s. len ( ) ;
1216+ self . extend_from_slice ( s) ;
1217+ src. advance ( l) ;
1218+ }
12091219 }
12101220 }
12111221
Original file line number Diff line number Diff line change @@ -1688,3 +1688,22 @@ fn owned_safe_drop_on_as_ref_panic() {
16881688 assert ! ( result. is_err( ) ) ;
16891689 assert_eq ! ( drop_counter. get( ) , 1 ) ;
16901690}
1691+
1692+ /// Test `BytesMut::put` reuses allocation of `Bytes`.
1693+ #[ test]
1694+ fn bytes_mut_put_bytes_specialization ( ) {
1695+ let mut vec = Vec :: with_capacity ( 1234 ) ;
1696+ vec. push ( 10 ) ;
1697+ let capacity = vec. capacity ( ) ;
1698+ assert ! ( capacity >= 1234 ) ;
1699+
1700+ // Make `Bytes` backed by `Vec`.
1701+ let bytes = Bytes :: from ( vec) ;
1702+ let mut bytes_mut = BytesMut :: new ( ) ;
1703+ bytes_mut. put ( bytes) ;
1704+
1705+ // Check contents is correct.
1706+ assert_eq ! ( & [ 10 ] , bytes_mut. as_ref( ) ) ;
1707+ // If allocation is reused, capacity should be equal to original vec capacity.
1708+ assert_eq ! ( bytes_mut. capacity( ) , capacity) ;
1709+ }
You can’t perform that action at this time.
0 commit comments