@@ -737,6 +737,23 @@ function twoended_merge!(v::AbstractVector{T}, lo::Integer, m::Integer, hi::Inte
737737 end
738738end
739739
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+
740757# merge v[lo:m] and v[m+1:hi] using buffer t[1:1+m-lo]
741758# based on Base.Sort MergeSort
742759function 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
749766 end
750767 a, b = 1 , m + 1
751768 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)
762771 while k < b
763772 v[k] = t[a]
764773 k += 1
@@ -816,17 +825,7 @@ function pagedMerge!(v::AbstractVector{T}, lo::Integer, m::Integer, hi::Integer,
816825 # merge
817826 # #################
818827 # 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 )
830829
831830 nextBlockA = 1
832831 nextBlockB = (m + blocksize- lo) ÷ blocksize + 1
@@ -837,38 +836,20 @@ function pagedMerge!(v::AbstractVector{T}, lo::Integer, m::Integer, hi::Integer,
837836 currentBlock = 0
838837 currentBlockIdx = 4
839838 # more efficient loop while more than blocksize elements of A and B are remaining
839+ while_condition1 (offset) = (_,_,k) -> k <= offset + blocksize
840840 while a < m- blocksize && b < hi- blocksize
841841 @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 )
854844 end
855845 # 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
857847 while a <= m && b <= hi
858848 @getNextBlock!
859- k_block = 1
860849 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 )
871851 end
852+ k_block = k - getBlockOffset (currentBlock)
872853 # copy remaining elements
873854 # either A or B is empty
874855 # copy rest of A
0 commit comments