@@ -587,8 +587,7 @@ public class RelationAdvancedEnumerator<T> : IEnumerator<T>, ICollection<T>
587
587
protected readonly RelationInfo . ItemLoaderInfo ItemLoader ;
588
588
readonly IInternalObjectDBTransaction _tr ;
589
589
readonly IKeyValueDBTransaction _keyValueTr ;
590
- IKeyValueDBCursor ? _startCursor ;
591
- IKeyValueDBCursor ? _endCursor ;
590
+ IKeyValueDBCursor ? _untilCursor ;
592
591
IKeyValueDBCursor ? _cursor ;
593
592
bool _seekNeeded ;
594
593
readonly bool _ascending ;
@@ -628,85 +627,106 @@ public RelationAdvancedEnumerator(
628
627
629
628
void CreateCursors ( )
630
629
{
631
- _startCursor = _keyValueTr . CreateCursor ( ) ;
632
- if ( _startKeyProposition == KeyProposition . Ignored )
630
+ IKeyValueDBCursor ? startCursor = null ;
631
+ IKeyValueDBCursor ? endCursor = null ;
632
+ try
633
633
{
634
- if ( ! _startCursor . FindFirstKey ( _keyBytes ) )
634
+ startCursor = _keyValueTr . CreateCursor ( ) ;
635
+ if ( _startKeyProposition == KeyProposition . Ignored )
635
636
{
636
- return ;
637
+ if ( ! startCursor . FindFirstKey ( _keyBytes ) )
638
+ {
639
+ return ;
640
+ }
637
641
}
638
- }
639
- else
640
- {
641
- switch ( _startCursor . Find ( _startKeyBytes , ( uint ) _keyBytes . Length ) )
642
+ else
642
643
{
643
- case FindResult . Exact :
644
- if ( _startKeyProposition == KeyProposition . Excluded )
645
- {
646
- if ( ! _startCursor . FindNextKey ( _keyBytes ) ) return ;
647
- }
644
+ switch ( startCursor . Find ( _startKeyBytes , ( uint ) _keyBytes . Length ) )
645
+ {
646
+ case FindResult . Exact :
647
+ if ( _startKeyProposition == KeyProposition . Excluded )
648
+ {
649
+ if ( ! startCursor . FindNextKey ( _keyBytes ) ) return ;
650
+ }
648
651
649
- break ;
650
- case FindResult . Previous :
651
- if ( ! _startCursor . FindNextKey ( _keyBytes ) ) return ;
652
- if ( _startKeyProposition == KeyProposition . Excluded )
653
- {
654
- if ( ! _startCursor . FindNextKey ( _keyBytes ) ) return ;
655
- }
652
+ break ;
653
+ case FindResult . Previous :
654
+ if ( ! startCursor . FindNextKey ( _keyBytes ) ) return ;
655
+ if ( _startKeyProposition == KeyProposition . Excluded )
656
+ {
657
+ if ( ! startCursor . FindNextKey ( _keyBytes ) ) return ;
658
+ }
656
659
657
- break ;
658
- case FindResult . Next :
659
- if ( _startKeyProposition == KeyProposition . Excluded && _startCursor . KeyHasPrefix ( _startKeyBytes ) )
660
- {
661
- if ( ! _startCursor . FindNextKey ( _keyBytes ) ) return ;
662
- }
660
+ break ;
661
+ case FindResult . Next :
662
+ if ( _startKeyProposition == KeyProposition . Excluded && startCursor . KeyHasPrefix ( _startKeyBytes ) )
663
+ {
664
+ if ( ! startCursor . FindNextKey ( _keyBytes ) ) return ;
665
+ }
663
666
664
- break ;
665
- case FindResult . NotFound :
666
- return ;
667
- default :
668
- throw new ArgumentOutOfRangeException ( ) ;
667
+ break ;
668
+ case FindResult . NotFound :
669
+ return ;
670
+ default :
671
+ throw new ArgumentOutOfRangeException ( ) ;
672
+ }
669
673
}
670
- }
671
674
672
- _endCursor = _keyValueTr . CreateCursor ( ) ;
673
- var realEndKeyBytes = new ReadOnlySpan < byte > ( _endKeyBytes ) ;
674
- if ( _endKeyProposition == KeyProposition . Included )
675
- realEndKeyBytes = FindLastKeyWithPrefix ( _endKeyBytes . AsSpan ( ) , _endCursor ) ;
675
+ endCursor = _keyValueTr . CreateCursor ( ) ;
676
+ var realEndKeyBytes = new ReadOnlySpan < byte > ( _endKeyBytes ) ;
677
+ if ( _endKeyProposition == KeyProposition . Included )
678
+ realEndKeyBytes = FindLastKeyWithPrefix ( _endKeyBytes . AsSpan ( ) , endCursor ) ;
676
679
677
- if ( _endKeyProposition == KeyProposition . Ignored )
678
- {
679
- if ( ! _endCursor . FindLastKey ( _keyBytes ) ) return ;
680
- }
681
- else
682
- {
683
- switch ( _endCursor . Find ( realEndKeyBytes , ( uint ) _keyBytes . Length ) )
680
+ if ( _endKeyProposition == KeyProposition . Ignored )
684
681
{
685
- case FindResult . Exact :
686
- if ( _endKeyProposition == KeyProposition . Excluded )
687
- {
688
- if ( ! _endCursor . FindPreviousKey ( _keyBytes ) ) return ;
689
- }
682
+ if ( ! endCursor . FindLastKey ( _keyBytes ) ) return ;
683
+ }
684
+ else
685
+ {
686
+ switch ( endCursor . Find ( realEndKeyBytes , ( uint ) _keyBytes . Length ) )
687
+ {
688
+ case FindResult . Exact :
689
+ if ( _endKeyProposition == KeyProposition . Excluded )
690
+ {
691
+ if ( ! endCursor . FindPreviousKey ( _keyBytes ) ) return ;
692
+ }
690
693
691
- break ;
692
- case FindResult . Previous :
693
- break ;
694
- case FindResult . Next :
695
- if ( ! _endCursor . FindPreviousKey ( _keyBytes ) ) return ;
696
- break ;
697
- case FindResult . NotFound :
698
- return ;
699
- default :
700
- throw new ArgumentOutOfRangeException ( ) ;
694
+ break ;
695
+ case FindResult . Previous :
696
+ break ;
697
+ case FindResult . Next :
698
+ if ( ! endCursor . FindPreviousKey ( _keyBytes ) ) return ;
699
+ break ;
700
+ case FindResult . NotFound :
701
+ return ;
702
+ default :
703
+ throw new ArgumentOutOfRangeException ( ) ;
704
+ }
701
705
}
702
- }
703
706
704
- var startIndex = _startCursor . GetKeyIndex ( ) ;
705
- var endIndex = _endCursor . GetKeyIndex ( ) ;
706
- if ( startIndex > endIndex ) return ;
707
- _cursor = _keyValueTr . CreateCursor ( ) ;
708
- _cursor . FindKeyIndex ( _ascending ? startIndex : endIndex ) ;
709
- _seekNeeded = true ;
707
+ var startIndex = startCursor . GetKeyIndex ( ) ;
708
+ var endIndex = endCursor . GetKeyIndex ( ) ;
709
+ if ( startIndex > endIndex ) return ;
710
+ if ( _ascending )
711
+ {
712
+ _cursor = startCursor ;
713
+ _untilCursor = endCursor ;
714
+ }
715
+ else
716
+ {
717
+ _cursor = endCursor ;
718
+ _untilCursor = startCursor ;
719
+ }
720
+
721
+ startCursor = null ;
722
+ endCursor = null ;
723
+ _seekNeeded = true ;
724
+ }
725
+ finally
726
+ {
727
+ startCursor ? . Dispose ( ) ;
728
+ endCursor ? . Dispose ( ) ;
729
+ }
710
730
}
711
731
712
732
public RelationAdvancedEnumerator (
@@ -754,7 +774,7 @@ public bool MoveNext()
754
774
return false ;
755
775
}
756
776
757
- if ( _cursor . GetKeyIndex ( ) > _endCursor ! . GetKeyIndex ( ) )
777
+ if ( _cursor . GetKeyIndex ( ) > _untilCursor ! . GetKeyIndex ( ) )
758
778
{
759
779
return false ;
760
780
}
@@ -766,7 +786,7 @@ public bool MoveNext()
766
786
return false ;
767
787
}
768
788
769
- if ( _cursor . GetKeyIndex ( ) < _startCursor ! . GetKeyIndex ( ) )
789
+ if ( _cursor . GetKeyIndex ( ) < _untilCursor ! . GetKeyIndex ( ) )
770
790
{
771
791
return false ;
772
792
}
@@ -809,10 +829,8 @@ public byte[] GetKeyBytes()
809
829
810
830
public void Dispose ( )
811
831
{
812
- _startCursor ? . Dispose ( ) ;
813
- _startCursor = null ;
814
- _endCursor ? . Dispose ( ) ;
815
- _endCursor = null ;
832
+ _untilCursor ? . Dispose ( ) ;
833
+ _untilCursor = null ;
816
834
_cursor ? . Dispose ( ) ;
817
835
_cursor = null ;
818
836
}
@@ -848,7 +866,7 @@ public void CopyTo(T[] array, int arrayIndex)
848
866
CreateCursors ( ) ;
849
867
try
850
868
{
851
- var count = _endCursor == null ? 0 : ( int ) ( _endCursor . GetKeyIndex ( ) - _startCursor ! . GetKeyIndex ( ) + 1 ) ;
869
+ var count = _cursor == null ? 0 : ( int ) ( Math . Abs ( _cursor . GetKeyIndex ( ) - _untilCursor ! . GetKeyIndex ( ) ) + 1 ) ;
852
870
if ( count == 0 ) return ;
853
871
if ( array . Length - arrayIndex < count ) throw new ArgumentException ( "Array too small" ) ;
854
872
while ( MoveNext ( ) )
@@ -874,7 +892,7 @@ public int Count
874
892
try
875
893
{
876
894
CreateCursors ( ) ;
877
- return _endCursor == null ? 0 : ( int ) ( _endCursor . GetKeyIndex ( ) - _startCursor ! . GetKeyIndex ( ) + 1 ) ;
895
+ return _cursor == null ? 0 : ( int ) ( Math . Abs ( _cursor . GetKeyIndex ( ) - _untilCursor ! . GetKeyIndex ( ) ) + 1 ) ;
878
896
}
879
897
finally
880
898
{
0 commit comments