@@ -2585,4 +2585,86 @@ internal static void GatherUsedFiles(IntPtr nodePtr, CancellationToken cancellat
2585
2585
}
2586
2586
}
2587
2587
}
2588
+
2589
+ internal static void FastIterate ( int deepness , IntPtr top , ref StructList < CursorItem > stack , ref Span < byte > buffer ,
2590
+ ref long keyIndex , CursorIterateCallback callback )
2591
+ {
2592
+ if ( top == IntPtr . Zero )
2593
+ return ;
2594
+ if ( deepness == stack . Count )
2595
+ {
2596
+ stack . AddRef ( ) . Set ( top , 0 ) ;
2597
+ }
2598
+
2599
+ ref var header = ref NodeUtils12 . Ptr2NodeHeader ( top ) ;
2600
+ if ( header . IsNodeLeaf )
2601
+ {
2602
+ var prefixSpan = NodeUtils12 . GetPrefixSpan ( top ) ;
2603
+ if ( prefixSpan . Length > buffer . Length )
2604
+ {
2605
+ buffer = GC . AllocateUninitializedArray < byte > ( NewSize ( prefixSpan . Length , buffer . Length ) ) ;
2606
+ }
2607
+
2608
+ prefixSpan . CopyTo ( buffer ) ;
2609
+ if ( header . HasLongKeys )
2610
+ {
2611
+ var longKeys = NodeUtils12 . GetLongKeyPtrs ( top ) ;
2612
+ for ( var i = ( int ) stack . Last . _posInNode ; i < longKeys . Length ; i ++ , stack . Last . _posInNode ++ )
2613
+ {
2614
+ var key = NodeUtils12 . LongKeyPtrToSpan ( longKeys [ i ] ) ;
2615
+ if ( key . Length + prefixSpan . Length > buffer . Length )
2616
+ {
2617
+ buffer = GC . AllocateUninitializedArray < byte > ( NewSize ( key . Length + prefixSpan . Length ,
2618
+ buffer . Length ) ) ;
2619
+ prefixSpan . CopyTo ( buffer ) ;
2620
+ }
2621
+
2622
+ key . CopyTo ( buffer [ prefixSpan . Length ..] ) ;
2623
+ callback . Invoke ( keyIndex , buffer [ ..( prefixSpan . Length + key . Length ) ] ) ;
2624
+ keyIndex ++ ;
2625
+ }
2626
+ }
2627
+ else
2628
+ {
2629
+ var keyOfs = NodeUtils12 . GetKeySpans ( top , out var keyData ) ;
2630
+ for ( var i = ( int ) stack . Last . _posInNode ; i < keyOfs . Length - 1 ; i ++ , stack . Last . _posInNode ++ )
2631
+ {
2632
+ var key = keyData . Slice ( keyOfs [ i ] , keyOfs [ i + 1 ] - keyOfs [ i ] ) ;
2633
+ if ( key . Length + prefixSpan . Length > buffer . Length )
2634
+ {
2635
+ buffer = GC . AllocateUninitializedArray < byte > ( NewSize ( key . Length + prefixSpan . Length ,
2636
+ buffer . Length ) ) ;
2637
+ prefixSpan . CopyTo ( buffer ) ;
2638
+ }
2639
+
2640
+ key . CopyTo ( buffer [ prefixSpan . Length ..] ) ;
2641
+ callback . Invoke ( keyIndex , buffer [ ..( prefixSpan . Length + key . Length ) ] ) ;
2642
+ keyIndex ++ ;
2643
+ }
2644
+ }
2645
+ }
2646
+ else
2647
+ {
2648
+ var children = NodeUtils12 . GetBranchValuePtrs ( top ) ;
2649
+ for ( var i = ( int ) stack [ deepness ] . _posInNode ; i < children . Length ; i ++ , stack [ deepness ] . _posInNode ++ )
2650
+ {
2651
+ FastIterate ( deepness + 1 , children [ i ] , ref stack , ref buffer , ref keyIndex , callback ) ;
2652
+ }
2653
+ }
2654
+
2655
+ stack . Pop ( ) ;
2656
+ }
2657
+
2658
+ static int NewSize ( int size , int existingSize )
2659
+ {
2660
+ if ( existingSize * 2L > Array . MaxLength )
2661
+ {
2662
+ if ( size > Array . MaxLength )
2663
+ throw new ArgumentOutOfRangeException ( ) ;
2664
+ return Array . MaxLength ;
2665
+ }
2666
+
2667
+ size = Math . Max ( size , existingSize * 2 ) ;
2668
+ return size ;
2669
+ }
2588
2670
}
0 commit comments