@@ -96,31 +96,35 @@ pub struct ReflectAccessId {
96
96
97
97
impl AccessMapKey for ReflectAccessId {
98
98
fn as_index ( & self ) -> u64 {
99
- // project two linear non-negative ranges to a single linear non-negative range, offset by 1 to avoid 0
100
- // y1 = 2x - 0 + 1
101
- // y2 = 2x - 1 + 1
99
+ // project two linear non-negative ranges [0,inf] to a single linear non-negative range, offset by 1 to avoid 0
100
+ // y1 = 2x - 0 + 2 = 2x + 2
101
+ // y2 = 2x - 1 + 2 = 2x + 1
102
102
match self . kind {
103
- ReflectAccessKind :: ComponentOrResource => ( self . id * 2 ) + 1 ,
103
+ ReflectAccessKind :: ComponentOrResource => ( self . id * 2 ) + 2 ,
104
104
ReflectAccessKind :: Allocation => ( self . id * 2 ) + 1 ,
105
105
ReflectAccessKind :: Global => 0 ,
106
106
}
107
107
}
108
108
109
109
fn from_index ( value : u64 ) -> Self {
110
- // retrieve the kind of range based on if the value is odd or even
111
- // y1 if even, y2 if odd
112
- // to retrieve value of x:
113
- // x1 = (y / 2) - 1
114
- // x2 = ((y - 1) / 2) - 1
115
-
116
- let ( kind, id) = if value == 0 {
117
- ( ReflectAccessKind :: Global , 0 )
118
- } else if value % 2 == 0 {
119
- ( ReflectAccessKind :: ComponentOrResource , ( value / 2 ) - 1 )
120
- } else {
121
- ( ReflectAccessKind :: Allocation , ( ( value - 1 ) / 2 ) - 1 )
122
- } ;
123
- Self { kind, id }
110
+ // reverse the projection
111
+ // x1 = (y1 - 2) / 2
112
+ // x2 = (y2 - 1) / 2
113
+
114
+ match value {
115
+ 0 => ReflectAccessId {
116
+ kind : ReflectAccessKind :: Global ,
117
+ id : 0 ,
118
+ } ,
119
+ v if v % 2 == 0 => ReflectAccessId {
120
+ kind : ReflectAccessKind :: ComponentOrResource ,
121
+ id : ( v - 2 ) / 2 ,
122
+ } ,
123
+ v => ReflectAccessId {
124
+ kind : ReflectAccessKind :: Allocation ,
125
+ id : ( v - 1 ) / 2 ,
126
+ } ,
127
+ }
124
128
}
125
129
}
126
130
@@ -521,4 +525,41 @@ mod test {
521
525
. join ( )
522
526
. unwrap ( ) ;
523
527
}
528
+
529
+ #[ test]
530
+ fn test_as_and_from_index_for_access_id_non_overlapping ( ) {
531
+ let global = ReflectAccessId :: for_global ( ) ;
532
+
533
+ let first_component = ReflectAccessId {
534
+ kind : ReflectAccessKind :: ComponentOrResource ,
535
+ id : 0 ,
536
+ } ;
537
+
538
+ let first_allocation = ReflectAccessId {
539
+ kind : ReflectAccessKind :: Allocation ,
540
+ id : 0 ,
541
+ } ;
542
+
543
+ let second_component = ReflectAccessId {
544
+ kind : ReflectAccessKind :: ComponentOrResource ,
545
+ id : 1 ,
546
+ } ;
547
+
548
+ let second_allocation = ReflectAccessId {
549
+ kind : ReflectAccessKind :: Allocation ,
550
+ id : 1 ,
551
+ } ;
552
+
553
+ assert_eq ! ( global. as_index( ) , 0 ) ;
554
+ assert_eq ! ( first_allocation. as_index( ) , 1 ) ;
555
+ assert_eq ! ( first_component. as_index( ) , 2 ) ;
556
+ assert_eq ! ( second_allocation. as_index( ) , 3 ) ;
557
+ assert_eq ! ( second_component. as_index( ) , 4 ) ;
558
+
559
+ assert_eq ! ( ReflectAccessId :: from_index( 0 ) , global) ;
560
+ assert_eq ! ( ReflectAccessId :: from_index( 1 ) , first_allocation) ;
561
+ assert_eq ! ( ReflectAccessId :: from_index( 2 ) , first_component) ;
562
+ assert_eq ! ( ReflectAccessId :: from_index( 3 ) , second_allocation) ;
563
+ assert_eq ! ( ReflectAccessId :: from_index( 4 ) , second_component) ;
564
+ }
524
565
}
0 commit comments