@@ -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:: { Layer , Tick , TickIndex , TickIndexBitmap } ;
13
13
14
14
pub mod pallet;
15
15
mod tick;
@@ -1040,7 +1040,7 @@ where
1040
1040
/// Get fees above a tick
1041
1041
///
1042
1042
fn get_fees_above ( & mut self , tick_index : TickIndex , quote : bool ) -> U64F64 {
1043
- let maybe_tick_index = tick_index . find_closest_lower_active ( & self . state_ops ) ;
1043
+ let maybe_tick_index = self . find_closest_lower_active_tick_index ( tick_index ) ;
1044
1044
let current_tick = self . get_current_tick_index ( ) ;
1045
1045
1046
1046
if let Some ( tick_index) = maybe_tick_index {
@@ -1072,7 +1072,7 @@ where
1072
1072
1073
1073
/// Get fees below a tick
1074
1074
fn get_fees_below ( & mut self , tick_index : TickIndex , quote : bool ) -> U64F64 {
1075
- let maybe_tick_index = tick_index . find_closest_lower_active ( & self . state_ops ) ;
1075
+ let maybe_tick_index = self . find_closest_lower_active_tick_index ( tick_index ) ;
1076
1076
let current_tick = self . get_current_tick_index ( ) ;
1077
1077
1078
1078
if let Some ( tick_index) = maybe_tick_index {
@@ -1115,46 +1115,38 @@ 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 ( Layer :: Top ) ) ;
1131
+ let mut word1_value = self
1132
+ . state_ops
1133
+ . get_layer1_word ( bitmap. word_at ( Layer :: Middle ) ) ;
1134
+ let mut word2_value = self
1135
+ . state_ops
1136
+ . get_layer2_word ( bitmap. word_at ( Layer :: Bottom ) ) ;
1137
+
1138
+ // Set bits in each layer
1139
+ word0_value |= bitmap. bit_mask ( Layer :: Top ) ;
1140
+ word1_value |= bitmap. bit_mask ( Layer :: Middle ) ;
1141
+ word2_value |= bitmap. bit_mask ( Layer :: Bottom ) ;
1142
+
1143
+ // Update the storage
1144
+ self . state_ops
1145
+ . set_layer0_word ( bitmap. word_at ( Layer :: Top ) , word0_value) ;
1146
+ self . state_ops
1147
+ . set_layer1_word ( bitmap. word_at ( Layer :: Middle ) , word1_value) ;
1148
+ self . state_ops
1149
+ . set_layer2_word ( bitmap. word_at ( Layer :: Bottom ) , word2_value) ;
1158
1150
}
1159
1151
1160
1152
pub fn remove_active_tick ( & mut self , index : TickIndex ) {
@@ -1163,58 +1155,34 @@ where
1163
1155
return ;
1164
1156
}
1165
1157
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) ;
1158
+ // Convert to bitmap representation
1159
+ let bitmap = TickIndexBitmap :: from ( index) ;
1174
1160
1175
1161
// 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) ;
1162
+ let mut word0_value = self . state_ops . get_layer0_word ( bitmap. word_at ( Layer :: Top ) ) ;
1163
+ let mut word1_value = self
1164
+ . state_ops
1165
+ . get_layer1_word ( bitmap. word_at ( Layer :: Middle ) ) ;
1166
+ let mut word2_value = self
1167
+ . state_ops
1168
+ . get_layer2_word ( bitmap. word_at ( Layer :: Bottom ) ) ;
1179
1169
1180
1170
// 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) ;
1171
+ word2_value &= !bitmap. bit_mask ( Layer :: Bottom ) ;
1172
+ self . state_ops
1173
+ . set_layer2_word ( bitmap. word_at ( Layer :: Bottom ) , word2_value) ;
1174
+
1184
1175
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) ;
1176
+ word1_value &= !bitmap. bit_mask ( Layer :: Middle ) ;
1177
+ self . state_ops
1178
+ . set_layer1_word ( bitmap. word_at ( Layer :: Middle ) , word1_value) ;
1191
1179
}
1192
- }
1193
1180
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
- } ;
1181
+ if word1_value == 0 {
1182
+ word0_value &= !bitmap. bit_mask ( Layer :: Top ) ;
1183
+ self . state_ops
1184
+ . set_layer0_word ( bitmap. word_at ( Layer :: Top ) , word0_value) ;
1216
1185
}
1217
- result
1218
1186
}
1219
1187
1220
1188
pub fn find_closest_active_tick_index (
@@ -1227,28 +1195,31 @@ where
1227
1195
return None ;
1228
1196
}
1229
1197
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 ;
1198
+ // Convert to bitmap representation
1199
+ let bitmap = TickIndexBitmap :: from ( index) ;
1233
1200
let mut found = false ;
1234
1201
let mut result: u32 = 0 ;
1235
1202
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) ;
1203
+ // Layer positions from bitmap
1204
+ let layer0_word = bitmap. word_at ( Layer :: Top ) ;
1205
+ let layer0_bit = bitmap. bit_at ( Layer :: Top ) ;
1206
+ let layer1_word = bitmap. word_at ( Layer :: Middle ) ;
1207
+ let layer1_bit = bitmap. bit_at ( Layer :: Middle ) ;
1208
+ let layer2_word = bitmap. word_at ( Layer :: Bottom ) ;
1209
+ let layer2_bit = bitmap. bit_at ( Layer :: Bottom ) ;
1240
1210
1241
1211
// Find the closest active bits in layer 0, then 1, then 2
1242
1212
1243
1213
///////////////
1244
1214
// Level 0
1245
1215
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) ;
1216
+ let closest_bits_l0 =
1217
+ TickIndexBitmap :: find_closest_active_bit_candidates ( word0, layer0_bit, lower) ;
1247
1218
1248
1219
closest_bits_l0. iter ( ) . for_each ( |& closest_bit_l0| {
1249
1220
///////////////
1250
1221
// Level 1
1251
- let word1_index = Self :: address_to_index ( 0 , closest_bit_l0) ;
1222
+ let word1_index = TickIndexBitmap :: layer_to_index ( 0 , closest_bit_l0) ;
1252
1223
1253
1224
// Layer 1 words are different, shift the bit to the word edge
1254
1225
let start_from_l1_bit = if word1_index < layer1_word {
@@ -1260,12 +1231,15 @@ where
1260
1231
} ;
1261
1232
let word1_value = self . state_ops . get_layer1_word ( word1_index) ;
1262
1233
1263
- let closest_bits_l1 =
1264
- self . find_closest_active_bit_candidates ( word1_value, start_from_l1_bit, lower) ;
1234
+ let closest_bits_l1 = TickIndexBitmap :: find_closest_active_bit_candidates (
1235
+ word1_value,
1236
+ start_from_l1_bit,
1237
+ lower,
1238
+ ) ;
1265
1239
closest_bits_l1. iter ( ) . for_each ( |& closest_bit_l1| {
1266
1240
///////////////
1267
1241
// Level 2
1268
- let word2_index = Self :: address_to_index ( word1_index, closest_bit_l1) ;
1242
+ let word2_index = TickIndexBitmap :: layer_to_index ( word1_index, closest_bit_l1) ;
1269
1243
1270
1244
// Layer 2 words are different, shift the bit to the word edge
1271
1245
let start_from_l2_bit = if word2_index < layer2_word {
@@ -1277,13 +1251,16 @@ where
1277
1251
} ;
1278
1252
1279
1253
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) ;
1254
+ let closest_bits_l2 = TickIndexBitmap :: find_closest_active_bit_candidates (
1255
+ word2_value,
1256
+ start_from_l2_bit,
1257
+ lower,
1258
+ ) ;
1282
1259
1283
1260
if closest_bits_l2. len ( ) > 0 {
1284
1261
// The active tick is found, restore its full index and return
1285
1262
let offset_found_index =
1286
- Self :: address_to_index ( word2_index, closest_bits_l2[ 0 ] ) ;
1263
+ TickIndexBitmap :: layer_to_index ( word2_index, closest_bits_l2[ 0 ] ) ;
1287
1264
1288
1265
if lower {
1289
1266
if ( offset_found_index > result) || ( !found) {
@@ -1300,13 +1277,12 @@ where
1300
1277
} ) ;
1301
1278
} ) ;
1302
1279
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
1280
+ if !found {
1281
+ return None ;
1309
1282
}
1283
+
1284
+ // Convert the result offset_index back to a tick index
1285
+ TickIndex :: from_offset_index ( result) . ok ( )
1310
1286
}
1311
1287
1312
1288
pub fn find_closest_lower_active_tick_index ( & self , index : TickIndex ) -> Option < TickIndex > {
0 commit comments