9090use core:: borrow:: Borrow ;
9191use core:: hash:: { Hash , Hasher } ;
9292use core:: marker:: PhantomData ;
93+ use core:: ops:: { Deref , DerefMut } ;
9394use core:: { cmp, fmt} ;
9495
9596use alloc:: vec:: Vec ;
9697
9798mod sealed {
98- use super :: Features ;
99-
100- use alloc:: vec:: Vec ;
99+ use super :: { FeatureFlags , Features } ;
101100
102101 /// The context in which [`Features`] are applicable. Defines which features are known to the
103102 /// implementation, though specification of them as required or optional is up to the code
@@ -297,21 +296,21 @@ mod sealed {
297296
298297 /// Returns whether the feature is required by the given flags.
299298 #[ inline]
300- fn requires_feature( flags: & Vec < u8 > ) -> bool {
299+ fn requires_feature( flags: & [ u8 ] ) -> bool {
301300 flags. len( ) > Self :: BYTE_OFFSET &&
302301 ( flags[ Self :: BYTE_OFFSET ] & Self :: REQUIRED_MASK ) != 0
303302 }
304303
305304 /// Returns whether the feature is supported by the given flags.
306305 #[ inline]
307- fn supports_feature( flags: & Vec < u8 > ) -> bool {
306+ fn supports_feature( flags: & [ u8 ] ) -> bool {
308307 flags. len( ) > Self :: BYTE_OFFSET &&
309308 ( flags[ Self :: BYTE_OFFSET ] & ( Self :: REQUIRED_MASK | Self :: OPTIONAL_MASK ) ) != 0
310309 }
311310
312311 /// Sets the feature's required (even) bit in the given flags.
313312 #[ inline]
314- fn set_required_bit( flags: & mut Vec < u8 > ) {
313+ fn set_required_bit( flags: & mut FeatureFlags ) {
315314 if flags. len( ) <= Self :: BYTE_OFFSET {
316315 flags. resize( Self :: BYTE_OFFSET + 1 , 0u8 ) ;
317316 }
@@ -322,7 +321,7 @@ mod sealed {
322321
323322 /// Sets the feature's optional (odd) bit in the given flags.
324323 #[ inline]
325- fn set_optional_bit( flags: & mut Vec < u8 > ) {
324+ fn set_optional_bit( flags: & mut FeatureFlags ) {
326325 if flags. len( ) <= Self :: BYTE_OFFSET {
327326 flags. resize( Self :: BYTE_OFFSET + 1 , 0u8 ) ;
328327 }
@@ -333,7 +332,7 @@ mod sealed {
333332 /// Clears the feature's required (even) and optional (odd) bits from the given
334333 /// flags.
335334 #[ inline]
336- fn clear_bits( flags: & mut Vec < u8 > ) {
335+ fn clear_bits( flags: & mut FeatureFlags ) {
337336 if flags. len( ) > Self :: BYTE_OFFSET {
338337 flags[ Self :: BYTE_OFFSET ] &= !Self :: REQUIRED_MASK ;
339338 flags[ Self :: BYTE_OFFSET ] &= !Self :: OPTIONAL_MASK ;
@@ -661,6 +660,9 @@ mod sealed {
661660 supports_trampoline_routing,
662661 requires_trampoline_routing
663662 ) ;
663+ // By default, allocate enough bytes to cover up to Trampoline. Update this as new features are
664+ // added which we expect to appear commonly across contexts.
665+ pub ( super ) const MIN_FEATURES_ALLOCATION_BYTES : usize = ( 57 + 7 ) / 8 ;
664666 define_feature ! (
665667 259 ,
666668 DnsResolver ,
@@ -700,14 +702,131 @@ mod sealed {
700702const ANY_REQUIRED_FEATURES_MASK : u8 = 0b01_01_01_01 ;
701703const ANY_OPTIONAL_FEATURES_MASK : u8 = 0b10_10_10_10 ;
702704
705+ // Vecs are always 3 pointers long, so `FeatureFlags` is never shorter than 24 bytes on 64-bit
706+ // platforms no matter what we do.
707+ //
708+ // Luckily, because `Vec` uses a `NonNull` pointer to its buffer, the two-variant enum is free
709+ // space-wise, but we only get the remaining 2 usizes in length available for our own stuff (as any
710+ // other value is interpreted as the `Heap` variant).
711+ //
712+ // Thus, as long as we never use more than 15 bytes for our Held variant `FeatureFlags` is the same
713+ // length as a `Vec` in memory.
714+ const DIRECT_ALLOC_BYTES : usize = if sealed:: MIN_FEATURES_ALLOCATION_BYTES > 8 * 2 - 1 {
715+ sealed:: MIN_FEATURES_ALLOCATION_BYTES
716+ } else {
717+ 8 * 2 - 1
718+ } ;
719+ const _ASSERT: ( ) = assert ! ( DIRECT_ALLOC_BYTES <= u8 :: MAX as usize ) ;
720+
721+ /// The internal storage for feature flags. Public only for the [`sealed`] feature flag traits but
722+ /// generally should never be used directly.
723+ #[ derive( Clone , PartialEq , Eq ) ]
724+ #[ doc( hidden) ]
725+ pub enum FeatureFlags {
726+ Held { bytes : [ u8 ; DIRECT_ALLOC_BYTES ] , len : u8 } ,
727+ Heap ( Vec < u8 > ) ,
728+ }
729+
730+ impl FeatureFlags {
731+ fn empty ( ) -> Self {
732+ Self :: Held { bytes : [ 0 ; DIRECT_ALLOC_BYTES ] , len : 0 }
733+ }
734+
735+ fn from ( vec : Vec < u8 > ) -> Self {
736+ if vec. len ( ) <= DIRECT_ALLOC_BYTES {
737+ let mut bytes = [ 0 ; DIRECT_ALLOC_BYTES ] ;
738+ bytes[ ..vec. len ( ) ] . copy_from_slice ( & vec) ;
739+ Self :: Held { bytes, len : vec. len ( ) as u8 }
740+ } else {
741+ Self :: Heap ( vec)
742+ }
743+ }
744+
745+ fn resize ( & mut self , new_len : usize , default : u8 ) {
746+ match self {
747+ Self :: Held { bytes, len } => {
748+ let start_len = * len as usize ;
749+ if new_len <= DIRECT_ALLOC_BYTES {
750+ bytes[ start_len..] . copy_from_slice ( & [ default; DIRECT_ALLOC_BYTES ] [ start_len..] ) ;
751+ * len = new_len as u8 ;
752+ } else {
753+ let mut vec = Vec :: new ( ) ;
754+ vec. resize ( new_len, default) ;
755+ vec[ ..start_len] . copy_from_slice ( & bytes[ ..start_len] ) ;
756+ * self = Self :: Heap ( vec) ;
757+ }
758+ } ,
759+ Self :: Heap ( vec) => {
760+ vec. resize ( new_len, default) ;
761+ if new_len <= DIRECT_ALLOC_BYTES {
762+ let mut bytes = [ 0 ; DIRECT_ALLOC_BYTES ] ;
763+ bytes. copy_from_slice ( & vec) ;
764+ * self = Self :: Held { bytes, len : new_len as u8 } ;
765+ }
766+ } ,
767+ }
768+ }
769+
770+ fn len ( & self ) -> usize {
771+ self . deref ( ) . len ( )
772+ }
773+
774+ fn iter ( & self ) -> ( impl ExactSizeIterator < Item = & u8 > + DoubleEndedIterator < Item = & u8 > ) {
775+ let slice = self . deref ( ) ;
776+ slice. iter ( )
777+ }
778+
779+ fn iter_mut (
780+ & mut self ,
781+ ) -> ( impl ExactSizeIterator < Item = & mut u8 > + DoubleEndedIterator < Item = & mut u8 > ) {
782+ let slice = self . deref_mut ( ) ;
783+ slice. iter_mut ( )
784+ }
785+ }
786+
787+ impl Deref for FeatureFlags {
788+ type Target = [ u8 ] ;
789+ fn deref ( & self ) -> & [ u8 ] {
790+ match self {
791+ FeatureFlags :: Held { bytes, len } => & bytes[ ..* len as usize ] ,
792+ FeatureFlags :: Heap ( vec) => & vec,
793+ }
794+ }
795+ }
796+
797+ impl DerefMut for FeatureFlags {
798+ fn deref_mut ( & mut self ) -> & mut [ u8 ] {
799+ match self {
800+ FeatureFlags :: Held { bytes, len } => & mut bytes[ ..* len as usize ] ,
801+ FeatureFlags :: Heap ( vec) => & mut vec[ ..] ,
802+ }
803+ }
804+ }
805+
806+ impl PartialOrd for FeatureFlags {
807+ fn partial_cmp ( & self , other : & Self ) -> Option < cmp:: Ordering > {
808+ self . deref ( ) . partial_cmp ( other. deref ( ) )
809+ }
810+ }
811+ impl Ord for FeatureFlags {
812+ fn cmp ( & self , other : & Self ) -> cmp:: Ordering {
813+ self . deref ( ) . cmp ( other. deref ( ) )
814+ }
815+ }
816+ impl fmt:: Debug for FeatureFlags {
817+ fn fmt ( & self , fmt : & mut fmt:: Formatter ) -> Result < ( ) , fmt:: Error > {
818+ self . deref ( ) . fmt ( fmt)
819+ }
820+ }
821+
703822/// Tracks the set of features which a node implements, templated by the context in which it
704823/// appears.
705824///
706825/// This is not exported to bindings users as we map the concrete feature types below directly instead
707826#[ derive( Eq ) ]
708827pub struct Features < T : sealed:: Context > {
709828 /// Note that, for convenience, flags is LITTLE endian (despite being big-endian on the wire)
710- flags : Vec < u8 > ,
829+ flags : FeatureFlags ,
711830 mark : PhantomData < T > ,
712831}
713832
@@ -897,20 +1016,21 @@ impl ChannelTypeFeatures {
8971016impl < T : sealed:: Context > Features < T > {
8981017 /// Create a blank Features with no features set
8991018 pub fn empty ( ) -> Self {
900- Features { flags : Vec :: new ( ) , mark : PhantomData }
1019+ Features { flags : FeatureFlags :: empty ( ) , mark : PhantomData }
9011020 }
9021021
9031022 /// Converts `Features<T>` to `Features<C>`. Only known `T` features relevant to context `C` are
9041023 /// included in the result.
9051024 fn to_context_internal < C : sealed:: Context > ( & self ) -> Features < C > {
9061025 let from_byte_count = T :: KNOWN_FEATURE_MASK . len ( ) ;
9071026 let to_byte_count = C :: KNOWN_FEATURE_MASK . len ( ) ;
908- let mut flags = Vec :: new ( ) ;
1027+ let mut flags = FeatureFlags :: empty ( ) ;
1028+ flags. resize ( self . flags . len ( ) , 0 ) ;
9091029 for ( i, byte) in self . flags . iter ( ) . enumerate ( ) {
9101030 if i < from_byte_count && i < to_byte_count {
9111031 let from_known_features = T :: KNOWN_FEATURE_MASK [ i] ;
9121032 let to_known_features = C :: KNOWN_FEATURE_MASK [ i] ;
913- flags. push ( byte & from_known_features & to_known_features) ;
1033+ flags[ i ] = byte & from_known_features & to_known_features;
9141034 }
9151035 }
9161036 Features :: < C > { flags, mark : PhantomData }
@@ -921,7 +1041,7 @@ impl<T: sealed::Context> Features<T> {
9211041 ///
9221042 /// This is not exported to bindings users as we don't support export across multiple T
9231043 pub fn from_le_bytes ( flags : Vec < u8 > ) -> Features < T > {
924- Features { flags, mark : PhantomData }
1044+ Features { flags : FeatureFlags :: from ( flags ) , mark : PhantomData }
9251045 }
9261046
9271047 /// Returns the feature set as a list of bytes, in little-endian. This is in reverse byte order
@@ -936,7 +1056,7 @@ impl<T: sealed::Context> Features<T> {
9361056 /// This is not exported to bindings users as we don't support export across multiple T
9371057 pub fn from_be_bytes ( mut flags : Vec < u8 > ) -> Features < T > {
9381058 flags. reverse ( ) ; // Swap to little-endian
939- Self { flags, mark : PhantomData }
1059+ Self { flags : FeatureFlags :: from ( flags ) , mark : PhantomData }
9401060 }
9411061
9421062 /// Returns true if this `Features` has any optional flags set
0 commit comments