@@ -783,6 +783,7 @@ impl ProbabilisticScoringDecayParameters {
783783/// Direction is defined in terms of [`NodeId`] partial ordering, where the source node is the
784784/// first node in the ordering of the channel's counterparties. Thus, swapping the two liquidity
785785/// offset fields gives the opposite direction.
786+ #[ repr( C ) ] // Force the fields in memory to be in the order we specify
786787struct ChannelLiquidity {
787788 /// Lower channel liquidity bound in terms of an offset from zero.
788789 min_liquidity_offset_msat : u64 ,
@@ -800,6 +801,16 @@ struct ChannelLiquidity {
800801 offset_history_last_updated : Duration ,
801802}
802803
804+ // Check that the liquidity HashMap's entries sit on round cache lines.
805+ //
806+ // Specifically, the first cache line will have the key, the liquidity offsets, and the total
807+ // points tracked in the historical tracker.
808+ //
809+ // The next two cache lines will have the historical points, which we only access last during
810+ // scoring, followed by the last_updated `Duration`s (which we do not need during scoring).
811+ const _LIQUIDITY_MAP_SIZING_CHECK: usize = 192 - :: core:: mem:: size_of :: < ( u64 , ChannelLiquidity ) > ( ) ;
812+ const _LIQUIDITY_MAP_SIZING_CHECK_2: usize = :: core:: mem:: size_of :: < ( u64 , ChannelLiquidity ) > ( ) - 192 ;
813+
803814/// A snapshot of [`ChannelLiquidity`] in one direction assuming a certain channel capacity.
804815struct DirectedChannelLiquidity < L : Deref < Target = u64 > , HT : Deref < Target = HistoricalLiquidityTracker > , T : Deref < Target = Duration > > {
805816 min_liquidity_offset_msat : L ,
@@ -1490,10 +1501,24 @@ mod bucketed_history {
14901501 // between the 12,000th sat and 24,000th sat, while only needing to store and operate on 32
14911502 // buckets in total.
14921503
1493- const BUCKET_START_POS : [ u16 ; 33 ] = [
1494- 0 , 1 , 2 , 4 , 8 , 16 , 32 , 64 , 128 , 256 , 512 , 1024 , 2048 , 3072 , 4096 , 6144 , 8192 , 10240 , 12288 ,
1495- 13312 , 14336 , 15360 , 15872 , 16128 , 16256 , 16320 , 16352 , 16368 , 16376 , 16380 , 16382 , 16383 , 16384 ,
1496- ] ;
1504+ // By default u16s may not be cache-aligned, but we'd rather not have to read a third cache
1505+ // line just to access it
1506+ #[ repr( align( 128 ) ) ]
1507+ struct BucketStartPos ( [ u16 ; 33 ] ) ;
1508+ impl BucketStartPos {
1509+ const fn new ( ) -> Self {
1510+ Self ( [
1511+ 0 , 1 , 2 , 4 , 8 , 16 , 32 , 64 , 128 , 256 , 512 , 1024 , 2048 , 3072 , 4096 , 6144 , 8192 , 10240 , 12288 ,
1512+ 13312 , 14336 , 15360 , 15872 , 16128 , 16256 , 16320 , 16352 , 16368 , 16376 , 16380 , 16382 , 16383 , 16384 ,
1513+ ] )
1514+ }
1515+ }
1516+ impl core:: ops:: Index < usize > for BucketStartPos {
1517+ type Output = u16 ;
1518+ #[ inline( always) ]
1519+ fn index ( & self , index : usize ) -> & u16 { & self . 0 [ index] }
1520+ }
1521+ const BUCKET_START_POS : BucketStartPos = BucketStartPos :: new ( ) ;
14971522
14981523 const LEGACY_TO_BUCKET_RANGE : [ ( u8 , u8 ) ; 8 ] = [
14991524 ( 0 , 12 ) , ( 12 , 14 ) , ( 14 , 15 ) , ( 15 , 16 ) , ( 16 , 17 ) , ( 17 , 18 ) , ( 18 , 20 ) , ( 20 , 32 )
@@ -1631,10 +1656,11 @@ mod bucketed_history {
16311656 impl_writeable_tlv_based ! ( LegacyHistoricalBucketRangeTracker , { ( 0 , buckets, required) } ) ;
16321657
16331658 #[ derive( Clone , Copy ) ]
1659+ #[ repr( C ) ] // Force the fields in memory to be in the order we specify.
16341660 pub ( super ) struct HistoricalLiquidityTracker {
1661+ total_valid_points_tracked : u64 ,
16351662 min_liquidity_offset_history : HistoricalBucketRangeTracker ,
16361663 max_liquidity_offset_history : HistoricalBucketRangeTracker ,
1637- total_valid_points_tracked : u64 ,
16381664 }
16391665
16401666 impl HistoricalLiquidityTracker {
0 commit comments