@@ -148,7 +148,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
148
148
// SAFETY: Matched table IDs are guaranteed to still exist.
149
149
let table = unsafe { self . tables . get ( table_id) . debug_checked_unwrap ( ) } ;
150
150
151
- let range = range. unwrap_or ( 0 .. table. entity_count ( ) ) ;
151
+ let range = range. unwrap_or ( table. table_rows ( ) ) ;
152
152
accum =
153
153
// SAFETY:
154
154
// - The fetched table matches both D and F
@@ -163,11 +163,11 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
163
163
// SAFETY: Matched table IDs are guaranteed to still exist.
164
164
let table = unsafe { self . tables . get ( archetype. table_id ( ) ) . debug_checked_unwrap ( ) } ;
165
165
166
- let range = range. unwrap_or ( 0 .. archetype. len ( ) ) ;
166
+ let range = range. unwrap_or ( archetype. archetype_rows ( ) ) ;
167
167
168
168
// When an archetype and its table have equal entity counts, dense iteration can be safely used.
169
169
// this leverages cache locality to optimize performance.
170
- if table. entity_count ( ) == archetype. len ( ) {
170
+ if table. entity_count ( ) == archetype. entity_count ( ) {
171
171
accum =
172
172
// SAFETY:
173
173
// - The fetched archetype matches both D and F
@@ -345,7 +345,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
345
345
}
346
346
let table = self . tables . get ( archetype. table_id ( ) ) . debug_checked_unwrap ( ) ;
347
347
debug_assert ! (
348
- archetype. len ( ) == table. entity_count( ) ,
348
+ archetype. entity_count ( ) == table. entity_count( ) ,
349
349
"archetype and its table must have the same length. "
350
350
) ;
351
351
@@ -930,14 +930,14 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Iterator for QueryIter<'w, 's, D, F>
930
930
{
931
931
let mut accum = init;
932
932
// Empty any remaining uniterated values from the current table/archetype
933
- while self . cursor . current_row != self . cursor . current_len {
933
+ while ! self . cursor . current_range . is_empty ( ) {
934
934
let Some ( item) = self . next ( ) else { break } ;
935
935
accum = func ( accum, item) ;
936
936
}
937
937
938
938
for id in self . cursor . storage_id_iter . clone ( ) . copied ( ) {
939
939
// SAFETY:
940
- // - The range(None) is equivalent to [0, storage.entity_count)
940
+ // - The range(None) is equivalent to storage.rows
941
941
accum = unsafe { self . fold_over_storage_range ( accum, & mut func, id, None ) } ;
942
942
}
943
943
accum
@@ -2365,10 +2365,8 @@ struct QueryIterationCursor<'w, 's, D: QueryData, F: QueryFilter> {
2365
2365
archetype_entities : & ' w [ ArchetypeEntity ] ,
2366
2366
fetch : D :: Fetch < ' w > ,
2367
2367
filter : F :: Fetch < ' w > ,
2368
- // length of the table or length of the archetype, depending on whether both `D`'s and `F`'s fetches are dense
2369
- current_len : u32 ,
2370
- // either table row or archetype index, depending on whether both `D`'s and `F`'s fetches are dense
2371
- current_row : u32 ,
2368
+ // remaining range of the table or archetype being iterated over, depending on whether both `D`'s and `F`'s fetches are dense
2369
+ current_range : Range < u32 > ,
2372
2370
}
2373
2371
2374
2372
impl < D : QueryData , F : QueryFilter > Clone for QueryIterationCursor < ' _ , ' _ , D , F > {
@@ -2380,8 +2378,7 @@ impl<D: QueryData, F: QueryFilter> Clone for QueryIterationCursor<'_, '_, D, F>
2380
2378
archetype_entities : self . archetype_entities ,
2381
2379
fetch : self . fetch . clone ( ) ,
2382
2380
filter : self . filter . clone ( ) ,
2383
- current_len : self . current_len ,
2384
- current_row : self . current_row ,
2381
+ current_range : self . current_range . clone ( ) ,
2385
2382
}
2386
2383
}
2387
2384
}
@@ -2420,8 +2417,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {
2420
2417
archetype_entities : & [ ] ,
2421
2418
storage_id_iter : query_state. matched_storage_ids . iter ( ) ,
2422
2419
is_dense : query_state. is_dense ,
2423
- current_len : 0 ,
2424
- current_row : 0 ,
2420
+ current_range : 0 ..0 ,
2425
2421
}
2426
2422
}
2427
2423
@@ -2433,8 +2429,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {
2433
2429
table_entities : self . table_entities ,
2434
2430
archetype_entities : self . archetype_entities ,
2435
2431
storage_id_iter : self . storage_id_iter . clone ( ) ,
2436
- current_len : self . current_len ,
2437
- current_row : self . current_row ,
2432
+ current_range : 0 ..0 ,
2438
2433
}
2439
2434
}
2440
2435
@@ -2445,8 +2440,8 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {
2445
2440
/// dropped to prevent aliasing mutable references.
2446
2441
#[ inline]
2447
2442
unsafe fn peek_last ( & mut self , query_state : & ' s QueryState < D , F > ) -> Option < D :: Item < ' w , ' s > > {
2448
- if self . current_row > 0 {
2449
- let index = self . current_row - 1 ;
2443
+ if self . current_range . start > 0 {
2444
+ let index = self . current_range . start - 1 ;
2450
2445
if self . is_dense {
2451
2446
// SAFETY: This must have been called previously in `next` as `current_row > 0`
2452
2447
let entity = unsafe { self . table_entities . get_unchecked ( index as usize ) } ;
@@ -2494,9 +2489,12 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {
2494
2489
unsafe { ids. map ( |id| tables[ id. table_id ] . entity_count ( ) ) . sum ( ) }
2495
2490
} else {
2496
2491
// SAFETY: The if check ensures that storage_id_iter stores ArchetypeIds
2497
- unsafe { ids. map ( |id| archetypes[ id. archetype_id ] . len ( ) ) . sum ( ) }
2492
+ unsafe {
2493
+ ids. map ( |id| archetypes[ id. archetype_id ] . entity_count ( ) )
2494
+ . sum ( )
2495
+ }
2498
2496
} ;
2499
- remaining_matched + self . current_len - self . current_row
2497
+ remaining_matched + self . current_range . len ( ) as u32
2500
2498
}
2501
2499
2502
2500
// NOTE: If you are changing query iteration code, remember to update the following places, where relevant:
@@ -2517,7 +2515,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {
2517
2515
if self . is_dense {
2518
2516
loop {
2519
2517
// we are on the beginning of the query, or finished processing a table, so skip to the next
2520
- if self . current_row == self . current_len {
2518
+ let Some ( next ) = self . current_range . next ( ) else {
2521
2519
let table_id = self . storage_id_iter . next ( ) ?. table_id ;
2522
2520
let table = tables. get ( table_id) . debug_checked_unwrap ( ) ;
2523
2521
if table. is_empty ( ) {
@@ -2530,18 +2528,17 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {
2530
2528
F :: set_table ( & mut self . filter , & query_state. filter_state , table) ;
2531
2529
}
2532
2530
self . table_entities = table. entities ( ) ;
2533
- self . current_len = table. entity_count ( ) ;
2534
- self . current_row = 0 ;
2535
- }
2531
+ self . current_range = table. table_rows ( ) ;
2532
+
2533
+ continue ;
2534
+ } ;
2536
2535
2537
2536
// SAFETY: set_table was called prior.
2538
2537
// `current_row` is a table row in range of the current table, because if it was not, then the above would have been executed.
2539
- let entity =
2540
- unsafe { self . table_entities . get_unchecked ( self . current_row as usize ) } ;
2538
+ let entity = unsafe { self . table_entities . get_unchecked ( next as usize ) } ;
2541
2539
// SAFETY: The row is less than the u32 len, so it must not be max.
2542
- let row = unsafe { TableRow :: new ( NonMaxU32 :: new_unchecked ( self . current_row ) ) } ;
2540
+ let row = unsafe { TableRow :: new ( NonMaxU32 :: new_unchecked ( next ) ) } ;
2543
2541
if !F :: filter_fetch ( & query_state. filter_state , & mut self . filter , * entity, row) {
2544
- self . current_row += 1 ;
2545
2542
continue ;
2546
2543
}
2547
2544
@@ -2553,12 +2550,11 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {
2553
2550
let item =
2554
2551
unsafe { D :: fetch ( & query_state. fetch_state , & mut self . fetch , * entity, row) } ;
2555
2552
2556
- self . current_row += 1 ;
2557
2553
return Some ( item) ;
2558
2554
}
2559
2555
} else {
2560
2556
loop {
2561
- if self . current_row == self . current_len {
2557
+ let Some ( next ) = self . current_range . next ( ) else {
2562
2558
let archetype_id = self . storage_id_iter . next ( ) ?. archetype_id ;
2563
2559
let archetype = archetypes. get ( archetype_id) . debug_checked_unwrap ( ) ;
2564
2560
if archetype. is_empty ( ) {
@@ -2582,23 +2578,21 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {
2582
2578
) ;
2583
2579
}
2584
2580
self . archetype_entities = archetype. entities ( ) ;
2585
- self . current_len = archetype. len ( ) ;
2586
- self . current_row = 0 ;
2587
- }
2581
+ self . current_range = archetype. archetype_rows ( ) ;
2582
+
2583
+ continue ;
2584
+ } ;
2588
2585
2589
2586
// SAFETY: set_archetype was called prior.
2590
2587
// `current_row` is an archetype index row in range of the current archetype, because if it was not, then the if above would have been executed.
2591
- let archetype_entity = unsafe {
2592
- self . archetype_entities
2593
- . get_unchecked ( self . current_row as usize )
2594
- } ;
2588
+ let archetype_entity =
2589
+ unsafe { self . archetype_entities . get_unchecked ( next as usize ) } ;
2595
2590
if !F :: filter_fetch (
2596
2591
& query_state. filter_state ,
2597
2592
& mut self . filter ,
2598
2593
archetype_entity. id ( ) ,
2599
2594
archetype_entity. table_row ( ) ,
2600
2595
) {
2601
- self . current_row += 1 ;
2602
2596
continue ;
2603
2597
}
2604
2598
@@ -2615,7 +2609,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {
2615
2609
archetype_entity. table_row ( ) ,
2616
2610
)
2617
2611
} ;
2618
- self . current_row += 1 ;
2612
+
2619
2613
return Some ( item) ;
2620
2614
}
2621
2615
}
0 commit comments