You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Make variable names and function signatures more consistent
- always use lo, m, hi in function signatures
- rename array indices
- use two variables instead of one to clarify if index is absolute or in current block (oIdx -> k, k_block)
# merge v[lo:hiA] and v[hiA+1:hi] ([A;B]) using buffer t[1:1 + hi-lo]
687
+
# merge v[lo:m] and v[m+1:hi] ([A;B]) using buffer t[1:1+hi-lo]
688
688
# this is faster than merge! but requires twice as much auxiliary memory.
689
-
functiontwoended_merge!(v::AbstractVector{T}, lo::Integer, hiA::Integer, hi::Integer, o::Ordering, t::AbstractVector{T}) where T
690
-
@assert lo <= hiA <= hi
691
-
loA = lo
692
-
loB = hiA +1
693
-
hiB = hi
694
-
695
-
# output array indices
696
-
oL =1
697
-
oR =1+ hi - lo
689
+
functiontwoended_merge!(v::AbstractVector{T}, lo::Integer, m::Integer, hi::Integer, o::Ordering, t::AbstractVector{T}) where T
690
+
@assert lo <= m <= hi
698
691
699
692
# input array indices
700
-
iAL = loA
701
-
iBL = loB
702
-
iAR = hiA
703
-
iBR = hiB
693
+
a_lo = lo
694
+
a_hi = m
695
+
b_lo = m +1
696
+
b_hi = hi
697
+
# output array indices
698
+
k_lo =1
699
+
k_hi =1+ hi - lo
704
700
705
701
@inboundsbegin
706
702
# two ended merge
707
703
# while at least 2 elements remain in both A and B
708
-
whileiAL<iAR&&iBL<iBR
709
-
iflt(o,v[iBL], v[iAL])
710
-
t[oL] = v[iBL]
711
-
iBL+=1
704
+
whilea_lo<a_hi&&b_lo<b_hi
705
+
iflt(o, v[b_lo], v[a_lo])
706
+
t[k_lo] = v[b_lo]
707
+
b_lo+=1
712
708
else
713
-
t[oL] = v[iAL]
714
-
iAL+=1
709
+
t[k_lo] = v[a_lo]
710
+
a_lo+=1
715
711
end
716
-
oL+=1
717
-
if!lt(o,v[iBR], v[iAR])
718
-
t[oR] = v[iBR]
719
-
iBR-=1
712
+
k_lo+=1
713
+
if!lt(o, v[b_hi], v[a_hi])
714
+
t[k_hi] = v[b_hi]
715
+
b_hi-=1
720
716
else
721
-
t[oR] = v[iAR]
722
-
iAR-=1
717
+
t[k_hi] = v[a_hi]
718
+
a_hi-=1
723
719
end
724
-
oR-=1
720
+
k_hi-=1
725
721
end
726
722
# regular merge
727
723
# until either A or B runs out
728
-
whileiAL<=iAR&&iBL<=iBR
729
-
iflt(o,v[iBL], v[iAL])
730
-
t[oL] = v[iBL]
731
-
iBL+=1
724
+
whilea_lo<=a_hi&&b_lo<=b_hi
725
+
iflt(o, v[b_lo], v[a_lo])
726
+
t[k_lo] = v[b_lo]
727
+
b_lo+=1
732
728
else
733
-
t[oL] = v[iAL]
734
-
iAL+=1
729
+
t[k_lo] = v[a_lo]
730
+
a_lo+=1
735
731
end
736
-
oL+=1
732
+
k_lo+=1
737
733
end
738
734
# either A or B is empty -> copy remaining items
739
-
whileiAL<=iAR
740
-
t[oL] = v[iAL]
741
-
iAL+=1
742
-
oL+=1
735
+
whilea_lo<=a_hi
736
+
t[k_lo] = v[a_lo]
737
+
a_lo+=1
738
+
k_lo+=1
743
739
end
744
-
whileiBL<=iBR
745
-
t[oL] = v[iBL]
746
-
iBL+=1
747
-
oL+=1
740
+
whileb_lo<=b_hi
741
+
t[k_lo] = v[b_lo]
742
+
b_lo+=1
743
+
k_lo+=1
748
744
end
749
745
# copy back from t to v
750
746
offset = lo-1
@@ -755,34 +751,32 @@ function twoended_merge!(v::AbstractVector{T}, lo::Integer, hiA::Integer, hi::In
755
751
end
756
752
end
757
753
758
-
# merge v[lo:lo+lenA-1] and v[lo+lenA:hi] using buffer t[1:lenA]
754
+
# merge v[lo:m] and v[m+1:hi] using buffer t[1:1+m-lo]
759
755
# based on Base.Sort MergeSort
760
-
functionmerge!(v::AbstractVector{T}, lo::Integer, hi::Integer, lenA::Integer, o::Ordering, t::AbstractVector{T}) where T
756
+
functionmerge!(v::AbstractVector{T}, lo::Integer, m::Integer, hi::Integer, o::Ordering, t::AbstractVector{T}) where T
761
757
@inboundsbegin
762
-
i =1
763
-
j = lo
764
-
while i <= lenA
758
+
i, j =1, lo
759
+
while j <= m
765
760
t[i] = v[j]
766
761
i +=1
767
762
j +=1
768
763
end
769
-
iA =1
764
+
a, b =1, m +1
770
765
k = lo
771
-
iB = lo + lenA
772
-
while k < iB <= hi
773
-
iflt(o,v[iB], t[iA])
774
-
v[k] = v[iB]
775
-
iB +=1
766
+
while k < b <= hi
767
+
iflt(o, v[b], t[a])
768
+
v[k] = v[b]
769
+
b +=1
776
770
else
777
-
v[k] = t[iA]
778
-
iA+=1
771
+
v[k] = t[a]
772
+
a+=1
779
773
end
780
774
k +=1
781
775
end
782
-
whileiA <= lenA
783
-
v[k] = t[iA]
776
+
whilek < b
777
+
v[k] = t[a]
784
778
k +=1
785
-
iA+=1
779
+
a+=1
786
780
end
787
781
end
788
782
end
@@ -792,7 +786,7 @@ end
792
786
# otherwise use next block in B
793
787
macrogetNextBlock!()
794
788
quote
795
-
ifiA> nextBlockA * blocksize + lo
789
+
ifa> nextBlockA * blocksize + lo
796
790
currentBlock = nextBlockA
797
791
nextBlockA +=1
798
792
else
@@ -804,18 +798,17 @@ macro getNextBlock!()
804
798
end|> esc
805
799
end
806
800
807
-
# merge v[lo:hiA] and v[hiA+1:hi] using buffer buf in O(sqrt(n)) space
808
-
functionpagedMerge!(v::AbstractVector{T}, lo::Integer, hiA::Integer, hi::Integer, o::Ordering, buf::AbstractVector{T}, blockLocation::AbstractVector{<:Integer}) where T
809
-
@assert lo < hiA < hi
810
-
iA = lo
811
-
iB = hiA +1
812
-
hiB = hi
813
-
lenA = hiA +1- lo
814
-
lenB = hiB - hiA
801
+
# merge v[lo:m] and v[m+1:hi] using buffer buf in O(sqrt(n)) space
802
+
functionpagedMerge!(v::AbstractVector{T}, lo::Integer, m::Integer, hi::Integer, o::Ordering, buf::AbstractVector{T}, blockLocation::AbstractVector{<:Integer}) where T
803
+
@assert lo < m < hi
804
+
a = lo
805
+
b = m +1
806
+
lenA =1+ m - lo
807
+
lenB = hi - m
815
808
816
809
# regular merge if buffer is big enough
817
810
if lenA <=length(buf)
818
-
merge!(v, lo, hi, lenA, o, buf)
811
+
merge!(v, lo, m, hi, o, buf)
819
812
return
820
813
elseif lenB <=length(buf)
821
814
#TODO ?
@@ -824,11 +817,11 @@ function pagedMerge!(v::AbstractVector{T}, lo::Integer, hiA::Integer, hi::Intege
824
817
return
825
818
end
826
819
827
-
len =hi+1- lo
820
+
len =lenA+lenB
828
821
blocksize =isqrt(len)
829
822
nBlocks = len ÷ blocksize
830
823
@assertlength(buf) >=3blocksize
831
-
@assertlength(blockLocation) >= nBlocks+1
824
+
@assertlength(blockLocation) >= nBlocks+1
832
825
833
826
@inlinegetBlockOffset(block) = (block-1)*blocksize + lo -1
834
827
@@ -837,92 +830,93 @@ function pagedMerge!(v::AbstractVector{T}, lo::Integer, hiA::Integer, hi::Intege
837
830
# merge
838
831
##################
839
832
# merge into buf until full
840
-
oBuf=1
841
-
whileoBuf<=3blocksize # cannot run out of input elements here
842
-
iflt(o, v[iB], v[iA]) # -> merge! would have been used
843
-
buf[oBuf] = v[iB]
844
-
iB+=1
833
+
j=1
834
+
whilej<=3blocksize # cannot run out of input elements here
835
+
iflt(o, v[b], v[a]) # -> merge! would have been used
836
+
buf[j] = v[b]
837
+
b+=1
845
838
else
846
-
buf[oBuf] = v[iA]
847
-
iA+=1
839
+
buf[j] = v[a]
840
+
a+=1
848
841
end
849
-
oBuf+=1
842
+
j+=1
850
843
end
851
844
852
845
nextBlockA =1
853
-
nextBlockB = (hiA+blocksize-lo) ÷ blocksize +1
846
+
nextBlockB = (m +blocksize-lo) ÷ blocksize +1
854
847
blockLocation .=0
855
848
blockLocation[1:3] =-1:-1:-3
856
849
857
-
oIdx=1
850
+
k=1
858
851
currentBlock =0
859
852
currentBlockIdx =4
860
853
# more efficient loop while more than blocksize elements of A and B are remaining
861
-
whileiA<hiA-blocksize &&iB<hiB-blocksize
854
+
whilea<m-blocksize &&b<hi-blocksize
862
855
@getNextBlock!
863
856
offset = (currentBlock-1)*blocksize
864
-
oIdx= lo + offset
865
-
whileoIdx<= blocksize+offset + lo -1
866
-
iflt(o, v[iB], v[iA])
867
-
v[oIdx] = v[iB]
868
-
iB+=1
857
+
k= lo + offset
858
+
whilek<= blocksize+offset + lo -1
859
+
iflt(o, v[b], v[a])
860
+
v[k] = v[b]
861
+
b+=1
869
862
else
870
-
v[oIdx] = v[iA]
871
-
iA+=1
863
+
v[k] = v[a]
864
+
a+=1
872
865
end
873
-
oIdx+=1
866
+
k+=1
874
867
end
875
868
end
876
869
# merge until either A or B is empty
877
-
while iA <= hiA && iB <= hiB
870
+
k_block =1
871
+
while a <= m && b <= hi
878
872
@getNextBlock!
879
-
oIdx=1
873
+
k_block=1
880
874
offset =getBlockOffset(currentBlock)
881
-
whileoIdx<= blocksize &&iA<=hiA&&iB<=hiB
882
-
iflt(o, v[iB], v[iA])
883
-
v[offset+oIdx] = v[iB]
884
-
iB+=1
875
+
whilek_block<= blocksize &&a<=m&&b<=hi
876
+
iflt(o, v[b], v[a])
877
+
v[offset+k_block] = v[b]
878
+
b+=1
885
879
else
886
-
v[offset+oIdx] = v[iA]
887
-
iA+=1
880
+
v[offset+k_block] = v[a]
881
+
a+=1
888
882
end
889
-
oIdx+=1
883
+
k_block+=1
890
884
end
891
885
end
892
886
# copy remaining elements
893
887
# either A or B is empty
894
888
# copy rest of A
895
-
whileiA<=hiA
896
-
ifoIdx> blocksize
889
+
whilea<=m
890
+
ifk_block> blocksize
897
891
@getNextBlock!
898
-
oIdx=1
892
+
k_block=1
899
893
end
900
894
offset =getBlockOffset(currentBlock)
901
-
whileoIdx<= blocksize &&iA<=hiA
902
-
v[offset +oIdx] = v[iA]
903
-
iA+=1
904
-
oIdx+=1
895
+
whilek_block<= blocksize &&a<=m
896
+
v[offset +k_block] = v[a]
897
+
a+=1
898
+
k_block+=1
905
899
end
906
900
end
907
901
# copy rest of B
908
-
whileiB<=hiB
909
-
ifoIdx> blocksize
902
+
whileb<=hi
903
+
ifk_block> blocksize
910
904
@getNextBlock!
911
-
oIdx=1
905
+
k_block=1
912
906
end
913
907
offset =getBlockOffset(currentBlock)
914
-
whileoIdx<= blocksize &&iB<=hiB
915
-
v[offset +oIdx] = v[iB]
916
-
iB+=1
917
-
oIdx+=1
908
+
whilek_block<= blocksize &&b<=hi
909
+
v[offset +k_block] = v[b]
910
+
b+=1
911
+
k_block+=1
918
912
end
919
913
end
920
914
# copy last partial block to end
921
-
partialBlockPresent =oIdx<= blocksize
915
+
partialBlockPresent =k_block<= blocksize
922
916
if partialBlockPresent
923
917
offset =getBlockOffset(currentBlock)
924
918
offset2 = nBlocks*blocksize + lo -1
925
-
for j =1:oIdx-1
919
+
for j =1:k_block-1
926
920
v[offset2 + j] = v[offset + j]
927
921
end
928
922
blockLocation[currentBlockIdx-1] =0
@@ -1048,7 +1042,7 @@ function threaded_pagedmergesort!(v::AbstractVector, lo::Integer, hi::Integer, o
1048
1042
pagedmergesort!(v, m+1, hi, o, buf, blockLocation)
0 commit comments