@@ -737,6 +737,23 @@ function twoended_merge!(v::AbstractVector{T}, lo::Integer, m::Integer, hi::Inte
737
737
end
738
738
end
739
739
740
+ # core merging loop used throughout PagedMergeSort
741
+ Base. @propagate_inbounds function merge! (f:: Function ,
742
+ target:: AbstractVector{T} , source_a:: AbstractVector{T} , source_b:: AbstractVector{T} ,
743
+ o:: Ordering , a:: Integer , b:: Integer , k:: Integer ) where T
744
+ while f (a,b,k)
745
+ if lt (o, source_b[b], source_a[a])
746
+ target[k] = source_b[b]
747
+ b += 1
748
+ else
749
+ target[k] = source_a[a]
750
+ a += 1
751
+ end
752
+ k += 1
753
+ end
754
+ a,b,k
755
+ end
756
+
740
757
# merge v[lo:m] and v[m+1:hi] using buffer t[1:1+m-lo]
741
758
# based on Base.Sort MergeSort
742
759
function merge! (v:: AbstractVector{T} , lo:: Integer , m:: Integer , hi:: Integer , o:: Ordering , t:: AbstractVector{T} ) where T
@@ -749,16 +766,8 @@ function merge!(v::AbstractVector{T}, lo::Integer, m::Integer, hi::Integer, o::O
749
766
end
750
767
a, b = 1 , m + 1
751
768
k = lo
752
- while k < b <= hi
753
- if lt (o, v[b], t[a])
754
- v[k] = v[b]
755
- b += 1
756
- else
757
- v[k] = t[a]
758
- a += 1
759
- end
760
- k += 1
761
- end
769
+ f (_,b,k) = k < b <= hi
770
+ a,b,k = merge! (f,v,t,v,o,a,b,k)
762
771
while k < b
763
772
v[k] = t[a]
764
773
k += 1
@@ -816,17 +825,7 @@ function pagedMerge!(v::AbstractVector{T}, lo::Integer, m::Integer, hi::Integer,
816
825
# merge
817
826
# #################
818
827
# merge into buf until full
819
- j = 1
820
- while j <= 3 blocksize # cannot run out of input elements here
821
- if lt (o, v[b], v[a]) # -> merge! would have been used
822
- buf[j] = v[b]
823
- b += 1
824
- else
825
- buf[j] = v[a]
826
- a += 1
827
- end
828
- j += 1
829
- end
828
+ a,b,k = merge! ((_,_,k) -> k<= 3 blocksize,buf,v,v,o,a,b,1 )
830
829
831
830
nextBlockA = 1
832
831
nextBlockB = (m + blocksize- lo) ÷ blocksize + 1
@@ -837,38 +836,20 @@ function pagedMerge!(v::AbstractVector{T}, lo::Integer, m::Integer, hi::Integer,
837
836
currentBlock = 0
838
837
currentBlockIdx = 4
839
838
# more efficient loop while more than blocksize elements of A and B are remaining
839
+ while_condition1 (offset) = (_,_,k) -> k <= offset + blocksize
840
840
while a < m- blocksize && b < hi- blocksize
841
841
@getNextBlock!
842
- offset = (currentBlock- 1 )* blocksize
843
- k = lo + offset
844
- while k <= blocksize+ offset + lo - 1
845
- if lt (o, v[b], v[a])
846
- v[k] = v[b]
847
- b += 1
848
- else
849
- v[k] = v[a]
850
- a += 1
851
- end
852
- k += 1
853
- end
842
+ offset = getBlockOffset (currentBlock)
843
+ a,b,k = merge! (while_condition1 (offset),v,v,v,o,a,b,offset+ 1 )
854
844
end
855
845
# merge until either A or B is empty
856
- k_block = 1
846
+ while_condition2 (offset) = (a,b,k) -> k <= offset + blocksize && a <= m && b <= hi
857
847
while a <= m && b <= hi
858
848
@getNextBlock!
859
- k_block = 1
860
849
offset = getBlockOffset (currentBlock)
861
- while k_block <= blocksize && a <= m && b <= hi
862
- if lt (o, v[b], v[a])
863
- v[offset+ k_block] = v[b]
864
- b += 1
865
- else
866
- v[offset+ k_block] = v[a]
867
- a += 1
868
- end
869
- k_block += 1
870
- end
850
+ a,b,k = merge! (while_condition2 (offset),v,v,v,o,a,b,offset+ 1 )
871
851
end
852
+ k_block = k - getBlockOffset (currentBlock)
872
853
# copy remaining elements
873
854
# either A or B is empty
874
855
# copy rest of A
0 commit comments