@@ -9,7 +9,7 @@ use safe_math::*;
9
9
use sp_arithmetic:: helpers_128bit:: sqrt;
10
10
use substrate_fixed:: types:: U64F64 ;
11
11
12
- use self :: tick:: { Tick , TickIndex } ;
12
+ use self :: tick:: { Tick , TickIndex , TickIndexBitmap } ;
13
13
14
14
pub mod pallet;
15
15
mod tick;
@@ -1115,46 +1115,34 @@ where
1115
1115
/// Deletion: 2 reads, 1-3 writes
1116
1116
///
1117
1117
1118
- // Addresses an index as (word, bit)
1119
- fn index_to_address ( index : u32 ) -> ( u32 , u32 ) {
1120
- let word: u32 = index. safe_div ( 128 ) ;
1121
- let bit: u32 = index. checked_rem ( 128 ) . unwrap_or_default ( ) ;
1122
- ( word, bit)
1123
- }
1124
-
1125
- // Reconstructs an index from address in lower level
1126
- fn address_to_index ( word : u32 , bit : u32 ) -> u32 {
1127
- word. saturating_mul ( 128 ) . saturating_add ( bit)
1128
- }
1118
+ // Use TickIndexBitmap::layer_to_index instead
1129
1119
1130
1120
pub fn insert_active_tick ( & mut self , index : TickIndex ) {
1131
1121
// Check the range
1132
1122
if ( index < TickIndex :: MIN ) || ( index > TickIndex :: MAX ) {
1133
1123
return ;
1134
1124
}
1135
1125
1136
- // Convert the tick index value to an offset_index for the tree representation
1137
- // to avoid working with the sign bit.
1138
- let offset_index = ( index. get ( ) + TickIndex :: OFFSET . get ( ) ) as u32 ;
1139
-
1140
- // Calculate index in each layer
1141
- let ( layer2_word, layer2_bit) = Self :: index_to_address ( offset_index) ;
1142
- let ( layer1_word, layer1_bit) = Self :: index_to_address ( layer2_word) ;
1143
- let ( layer0_word, layer0_bit) = Self :: index_to_address ( layer1_word) ;
1126
+ // Convert to bitmap representation
1127
+ let bitmap = TickIndexBitmap :: from ( index) ;
1144
1128
1145
1129
// Update layer words
1146
- let mut word0_value = self . state_ops . get_layer0_word ( layer0_word) ;
1147
- let mut word1_value = self . state_ops . get_layer1_word ( layer1_word) ;
1148
- let mut word2_value = self . state_ops . get_layer2_word ( layer2_word) ;
1149
-
1150
- let bit: u128 = 1 ;
1151
- word0_value = word0_value | bit. wrapping_shl ( layer0_bit) ;
1152
- word1_value = word1_value | bit. wrapping_shl ( layer1_bit) ;
1153
- word2_value = word2_value | bit. wrapping_shl ( layer2_bit) ;
1154
-
1155
- self . state_ops . set_layer0_word ( layer0_word, word0_value) ;
1156
- self . state_ops . set_layer1_word ( layer1_word, word1_value) ;
1157
- self . state_ops . set_layer2_word ( layer2_word, word2_value) ;
1130
+ let mut word0_value = self . state_ops . get_layer0_word ( bitmap. word_at ( 0 ) ) ;
1131
+ let mut word1_value = self . state_ops . get_layer1_word ( bitmap. word_at ( 1 ) ) ;
1132
+ let mut word2_value = self . state_ops . get_layer2_word ( bitmap. word_at ( 2 ) ) ;
1133
+
1134
+ // Set bits in each layer
1135
+ word0_value |= bitmap. bit_mask ( 0 ) ;
1136
+ word1_value |= bitmap. bit_mask ( 1 ) ;
1137
+ word2_value |= bitmap. bit_mask ( 2 ) ;
1138
+
1139
+ // Update the storage
1140
+ self . state_ops
1141
+ . set_layer0_word ( bitmap. word_at ( 0 ) , word0_value) ;
1142
+ self . state_ops
1143
+ . set_layer1_word ( bitmap. word_at ( 1 ) , word1_value) ;
1144
+ self . state_ops
1145
+ . set_layer2_word ( bitmap. word_at ( 2 ) , word2_value) ;
1158
1146
}
1159
1147
1160
1148
pub fn remove_active_tick ( & mut self , index : TickIndex ) {
@@ -1163,58 +1151,30 @@ where
1163
1151
return ;
1164
1152
}
1165
1153
1166
- // Convert the tick index value to an offset_index for the tree representation
1167
- // to avoid working with the sign bit.
1168
- let offset_index = ( index. get ( ) + TickIndex :: OFFSET . get ( ) ) as u32 ;
1169
-
1170
- // Calculate index in each layer
1171
- let ( layer2_word, layer2_bit) = Self :: index_to_address ( offset_index) ;
1172
- let ( layer1_word, layer1_bit) = Self :: index_to_address ( layer2_word) ;
1173
- let ( layer0_word, layer0_bit) = Self :: index_to_address ( layer1_word) ;
1154
+ // Convert to bitmap representation
1155
+ let bitmap = TickIndexBitmap :: from ( index) ;
1174
1156
1175
1157
// Update layer words
1176
- let mut word0_value = self . state_ops . get_layer0_word ( layer0_word ) ;
1177
- let mut word1_value = self . state_ops . get_layer1_word ( layer1_word ) ;
1178
- let mut word2_value = self . state_ops . get_layer2_word ( layer2_word ) ;
1158
+ let mut word0_value = self . state_ops . get_layer0_word ( bitmap . word_at ( 0 ) ) ;
1159
+ let mut word1_value = self . state_ops . get_layer1_word ( bitmap . word_at ( 1 ) ) ;
1160
+ let mut word2_value = self . state_ops . get_layer2_word ( bitmap . word_at ( 2 ) ) ;
1179
1161
1180
1162
// Turn the bit off (& !bit) and save as needed
1181
- let bit: u128 = 1 ;
1182
- word2_value = word2_value & !bit. wrapping_shl ( layer2_bit) ;
1183
- self . state_ops . set_layer2_word ( layer2_word, word2_value) ;
1163
+ word2_value &= !bitmap. bit_mask ( 2 ) ;
1164
+ self . state_ops
1165
+ . set_layer2_word ( bitmap. word_at ( 2 ) , word2_value) ;
1166
+
1184
1167
if word2_value == 0 {
1185
- word1_value = word1_value & !bit. wrapping_shl ( layer1_bit) ;
1186
- self . state_ops . set_layer1_word ( layer1_word, word1_value) ;
1187
- }
1188
- if word1_value == 0 {
1189
- word0_value = word0_value & !bit. wrapping_shl ( layer0_bit) ;
1190
- self . state_ops . set_layer0_word ( layer0_word, word0_value) ;
1168
+ word1_value &= !bitmap. bit_mask ( 1 ) ;
1169
+ self . state_ops
1170
+ . set_layer1_word ( bitmap. word_at ( 1 ) , word1_value) ;
1191
1171
}
1192
- }
1193
1172
1194
- // Finds the closest active bit and, if active bit exactly matches bit, then the next one
1195
- // Exact match: return Some([next, bit])
1196
- // Non-exact match: return Some([next])
1197
- // No match: return None
1198
- fn find_closest_active_bit_candidates ( & self , word : u128 , bit : u32 , lower : bool ) -> Vec < u32 > {
1199
- let mut result = vec ! [ ] ;
1200
- let mut mask: u128 = 1_u128 . wrapping_shl ( bit) ;
1201
- let mut layer0_active_bit: u32 = bit;
1202
- while mask > 0 {
1203
- if mask & word != 0 {
1204
- result. push ( layer0_active_bit) ;
1205
- if layer0_active_bit != bit {
1206
- break ;
1207
- }
1208
- }
1209
- mask = if lower {
1210
- layer0_active_bit = layer0_active_bit. saturating_sub ( 1 ) ;
1211
- mask. wrapping_shr ( 1 )
1212
- } else {
1213
- layer0_active_bit = layer0_active_bit. saturating_add ( 1 ) ;
1214
- mask. wrapping_shl ( 1 )
1215
- } ;
1173
+ if word1_value == 0 {
1174
+ word0_value &= !bitmap. bit_mask ( 0 ) ;
1175
+ self . state_ops
1176
+ . set_layer0_word ( bitmap. word_at ( 0 ) , word0_value) ;
1216
1177
}
1217
- result
1218
1178
}
1219
1179
1220
1180
pub fn find_closest_active_tick_index (
@@ -1227,28 +1187,31 @@ where
1227
1187
return None ;
1228
1188
}
1229
1189
1230
- // Convert the tick index value to an offset_index for the tree representation
1231
- // to avoid working with the sign bit.
1232
- let offset_index = ( index. get ( ) + TickIndex :: OFFSET . get ( ) ) as u32 ;
1190
+ // Convert to bitmap representation
1191
+ let bitmap = TickIndexBitmap :: from ( index) ;
1233
1192
let mut found = false ;
1234
1193
let mut result: u32 = 0 ;
1235
1194
1236
- // Calculate index in each layer
1237
- let ( layer2_word, layer2_bit) = Self :: index_to_address ( offset_index) ;
1238
- let ( layer1_word, layer1_bit) = Self :: index_to_address ( layer2_word) ;
1239
- let ( layer0_word, layer0_bit) = Self :: index_to_address ( layer1_word) ;
1195
+ // Layer positions from bitmap
1196
+ let layer0_word = bitmap. word_at ( 0 ) ;
1197
+ let layer0_bit = bitmap. bit_at ( 0 ) ;
1198
+ let layer1_word = bitmap. word_at ( 1 ) ;
1199
+ let layer1_bit = bitmap. bit_at ( 1 ) ;
1200
+ let layer2_word = bitmap. word_at ( 2 ) ;
1201
+ let layer2_bit = bitmap. bit_at ( 2 ) ;
1240
1202
1241
1203
// Find the closest active bits in layer 0, then 1, then 2
1242
1204
1243
1205
///////////////
1244
1206
// Level 0
1245
1207
let word0 = self . state_ops . get_layer0_word ( layer0_word) ;
1246
- let closest_bits_l0 = self . find_closest_active_bit_candidates ( word0, layer0_bit, lower) ;
1208
+ let closest_bits_l0 =
1209
+ TickIndexBitmap :: find_closest_active_bit_candidates ( word0, layer0_bit, lower) ;
1247
1210
1248
1211
closest_bits_l0. iter ( ) . for_each ( |& closest_bit_l0| {
1249
1212
///////////////
1250
1213
// Level 1
1251
- let word1_index = Self :: address_to_index ( 0 , closest_bit_l0) ;
1214
+ let word1_index = TickIndexBitmap :: layer_to_index ( 0 , closest_bit_l0) ;
1252
1215
1253
1216
// Layer 1 words are different, shift the bit to the word edge
1254
1217
let start_from_l1_bit = if word1_index < layer1_word {
@@ -1260,12 +1223,15 @@ where
1260
1223
} ;
1261
1224
let word1_value = self . state_ops . get_layer1_word ( word1_index) ;
1262
1225
1263
- let closest_bits_l1 =
1264
- self . find_closest_active_bit_candidates ( word1_value, start_from_l1_bit, lower) ;
1226
+ let closest_bits_l1 = TickIndexBitmap :: find_closest_active_bit_candidates (
1227
+ word1_value,
1228
+ start_from_l1_bit,
1229
+ lower,
1230
+ ) ;
1265
1231
closest_bits_l1. iter ( ) . for_each ( |& closest_bit_l1| {
1266
1232
///////////////
1267
1233
// Level 2
1268
- let word2_index = Self :: address_to_index ( word1_index, closest_bit_l1) ;
1234
+ let word2_index = TickIndexBitmap :: layer_to_index ( word1_index, closest_bit_l1) ;
1269
1235
1270
1236
// Layer 2 words are different, shift the bit to the word edge
1271
1237
let start_from_l2_bit = if word2_index < layer2_word {
@@ -1277,13 +1243,16 @@ where
1277
1243
} ;
1278
1244
1279
1245
let word2_value = self . state_ops . get_layer2_word ( word2_index) ;
1280
- let closest_bits_l2 =
1281
- self . find_closest_active_bit_candidates ( word2_value, start_from_l2_bit, lower) ;
1246
+ let closest_bits_l2 = TickIndexBitmap :: find_closest_active_bit_candidates (
1247
+ word2_value,
1248
+ start_from_l2_bit,
1249
+ lower,
1250
+ ) ;
1282
1251
1283
1252
if closest_bits_l2. len ( ) > 0 {
1284
1253
// The active tick is found, restore its full index and return
1285
1254
let offset_found_index =
1286
- Self :: address_to_index ( word2_index, closest_bits_l2[ 0 ] ) ;
1255
+ TickIndexBitmap :: layer_to_index ( word2_index, closest_bits_l2[ 0 ] ) ;
1287
1256
1288
1257
if lower {
1289
1258
if ( offset_found_index > result) || ( !found) {
@@ -1300,13 +1269,12 @@ where
1300
1269
} ) ;
1301
1270
} ) ;
1302
1271
1303
- if found {
1304
- // Convert the tree offset_index back to a tick index value
1305
- let tick_value = ( result as i32 ) . saturating_sub ( TickIndex :: OFFSET . get ( ) ) ;
1306
- Some ( TickIndex :: new_unchecked ( tick_value) )
1307
- } else {
1308
- None
1272
+ if !found {
1273
+ return None ;
1309
1274
}
1275
+
1276
+ // Convert the result offset_index back to a tick index
1277
+ TickIndex :: from_offset_index ( result) . ok ( )
1310
1278
}
1311
1279
1312
1280
pub fn find_closest_lower_active_tick_index ( & self , index : TickIndex ) -> Option < TickIndex > {
0 commit comments