@@ -25,7 +25,7 @@ public override string ToString()
2525 }
2626 }
2727
28- private const int SegmentSize = 16384 ;
28+ private const int SegmentSize = 1024 ;
2929
3030 private static TValue _fictive ;
3131
@@ -145,9 +145,13 @@ internal ref TValue TryGetInternalForWrite(uint index, out bool got)
145145
146146 if ( itemIndex >= values . Length )
147147 {
148- if ( itemIndex <= values . Length + 4 )
148+ if ( itemIndex <= values . Length + 4 || values . Length * 4 >= SegmentSize )
149149 {
150- Array . Resize ( ref values , Math . Min ( SegmentSize , Math . Max ( values . Length * 2 , 8 ) ) ) ;
150+ var newSize = Math . Min ( SegmentSize , Math . Max ( values . Length * 2 , 8 ) ) ;
151+ if ( newSize <= itemIndex )
152+ newSize *= 2 ;
153+
154+ Array . Resize ( ref values , newSize ) ;
151155
152156 _values [ realSegmentIndex ] = values ;
153157 }
@@ -220,10 +224,8 @@ private void resizeL0(int newRealSegmentsCount)
220224 Array . Resize ( ref _used , _navyData . Length ) ;
221225
222226 for ( var i = _navyData . Length - 1 ; i >= 0 && _navyData [ i ] is null ; i -- )
223- _navyData [ i ] = [ ] ;
224-
225- for ( var i = _values . Length - 1 ; i >= 0 && _values [ i ] is null ; i -- )
226227 {
228+ _navyData [ i ] = [ ] ;
227229 _values [ i ] = [ ] ;
228230 }
229231 }
@@ -302,7 +304,7 @@ private enum FindNearestMode { NotLess, NotMore }
302304 }
303305 }
304306 }
305-
307+
306308 if ( firstTry )
307309 {
308310 firstTry = false ;
@@ -395,7 +397,7 @@ private enum FindNearestMode { NotLess, NotMore }
395397 }
396398 }
397399 }
398-
400+
399401 if ( firstTry )
400402 {
401403 firstTry = false ;
@@ -592,19 +594,42 @@ private ref TValue getFromTree(uint index, bool forRead, out bool got, int realS
592594 else
593595 navyItem . zeroNext = ni ;
594596
597+ got = true ;
598+
595599 if ( ni >= navy . Length )
596600 {
597601 var newSize = ni * 2 ;
598602
599- Array . Resize ( ref _navyData [ realSegmentIndex ] , newSize ) ;
600- Array . Resize ( ref _values [ realSegmentIndex ] , newSize ) ;
603+ if ( newSize * 2 >= SegmentSize )
604+ {
605+ values = new TValue [ SegmentSize ] ;
606+
607+ navy = _navyData [ realSegmentIndex ] ;
608+ for ( var n = 0 ; n < navy . Length ; n ++ )
609+ {
610+ var relativeIndex = navy [ n ] . index & ( SegmentSize - 1 ) ;
611+ if ( relativeIndex == 0 && n != 0 )
612+ break ;
613+
614+ values [ relativeIndex ] = _values [ realSegmentIndex ] [ n ] ;
615+ }
616+
617+ _values [ realSegmentIndex ] = values ;
618+ _navyData [ realSegmentIndex ] = [ ] ;
619+
620+ return ref values [ index & ( SegmentSize - 1 ) ] ;
621+ }
622+ else
623+ {
624+ Array . Resize ( ref navy , newSize ) ;
625+ Array . Resize ( ref values , newSize ) ;
601626
602- navy = _navyData [ realSegmentIndex ] ;
603- values = _values [ realSegmentIndex ] ;
627+ _navyData [ realSegmentIndex ] = navy ;
628+ _values [ realSegmentIndex ] = values ;
629+ }
604630 }
605631
606632 navy [ ni ] . index = index ;
607- got = true ;
608633 return ref values [ ni ] ;
609634 }
610635
@@ -624,14 +649,17 @@ private ref TValue getFromTree(uint index, bool forRead, out bool got, int realS
624649 var oldValue = values [ i ] ;
625650
626651 navyItem . index = index ;
652+ values [ i ] = default ! ;
627653
628654 if ( oldIndex < _pseudoLength )
629655 this [ ( int ) oldIndex ] = oldValue ! ;
630656
631- values = _values [ realSegmentIndex ] ;
632- values [ i ] = default ! ;
633-
634657 got = true ;
658+
659+ if ( _navyData [ realSegmentIndex ] . Length == 0 )
660+ i = ( int ) ( index & ( SegmentSize - 1 ) ) ;
661+
662+ values = _values [ realSegmentIndex ] ;
635663 return ref values [ i ] ;
636664 }
637665 else
0 commit comments