diff --git a/docs/src/sorted_containers.md b/docs/src/sorted_containers.md index 6c3e788a8..2007638a7 100644 --- a/docs/src/sorted_containers.md +++ b/docs/src/sorted_containers.md @@ -140,6 +140,7 @@ regress(token::Token) Base.searchsortedfirst(m::SortedContainer, k) Base.searchsortedlast(m::SortedContainer, k) searchsortedafter(m::SortedContainer, k) +searchsortedbefore(m::SortedContainer, k) searchequalrange(smd::SortedMultiDict, k) findkey(m::SortedSet, k) findkey(sd::SortedDict, k) diff --git a/src/DataStructures.jl b/src/DataStructures.jl index 5e5d767ec..f6ae97446 100644 --- a/src/DataStructures.jl +++ b/src/DataStructures.jl @@ -37,7 +37,7 @@ module DataStructures export SetSemiToken export pastendsemitoken, beforestartsemitoken export pastendtoken, beforestarttoken - export searchsortedafter, searchequalrange + export searchsortedafter, searchsortedbefore, searchequalrange export packcopy, packdeepcopy export exclusive, inclusive, semitokens, inclusive_key, exclusive_key export orderobject, ordtype, Lt, compare, onlysemitokens diff --git a/src/sorted_container_iteration.jl b/src/sorted_container_iteration.jl index 192152a3a..dbe99943c 100644 --- a/src/sorted_container_iteration.jl +++ b/src/sorted_container_iteration.jl @@ -455,6 +455,19 @@ function Base.searchsortedlast(m::SortedContainer, k_) end +""" + searchsortedbefore(m::SortedContainer, k) + +Return the semitoken of the last item in the container that is less than +`k` in the sort order. If there is no +such item, then the before-start semitoken is returned. Time: O(*c* log *n*) +""" +function searchsortedbefore(m::SortedContainer, k_) + i = findkeyless(m.bt, convert(keytype(m), k_)) + IntSemiToken(i) +end + + ## The next four are correctness-checking routines. They are ## not exported. diff --git a/test/test_sorted_containers.jl b/test/test_sorted_containers.jl index 4e7e5e966..7bcb7144d 100644 --- a/test/test_sorted_containers.jl +++ b/test/test_sorted_containers.jl @@ -485,6 +485,10 @@ function testSortedDictMethods() i17 = searchsortedlast(m1, 48) my_assert(deref_key((m1,i16)) == 47) my_assert(deref_key((m1,i17)) == 47) + i16 = searchsortedbefore(m1, 47) + i17 = searchsortedbefore(m1, 48) + my_assert(deref_key((m1,i16)) == 43) + my_assert(deref_key((m1,i17)) == 47) ww = my_primes(N) cc = last(m1) my_assert(cc[1] == last(ww)) @@ -1337,6 +1341,8 @@ function testSortedMultiDict() my_assert(deref((factors,i)) == Pair(77,77)) i = searchsortedafter(factors,77) my_assert(deref((factors,i)) == Pair(78,1)) + i = searchsortedbefore(factors,77) + my_assert(deref((factors,i)) == Pair(76,76)) expected = [1,2,4,5,8,10,16,20,40,80] i1,i2 = searchequalrange(factors, 80) i = i1 @@ -1613,16 +1619,21 @@ function testSortedSet() j1 = searchsortedfirst(m,0.5) j2 = searchsortedlast(m,0.5) j3 = searchsortedafter(m,0.5) + j4 = searchsortedbefore(m,0.5) my_assert(deref((m,j1)) > 0.5) my_assert(deref((m,j2)) < 0.5) my_assert(advance((m,j2)) == j1) my_assert(j1 == j3) + my_assert(j2 == j4) k1 = searchsortedfirst(m,smallest) k2 = searchsortedlast(m,smallest) k3 = searchsortedafter(m,smallest) + k4 = searchsortedbefore(m,smallest) my_assert(deref((m,k1)) == smallest) my_assert(deref((m,k2)) == smallest) my_assert(deref((m,regress((m,k3)))) == smallest) + my_assert(deref((m,advance((m,k4)))) == smallest) + my_assert(k4 == beforestartsemitoken(m)) secondsmallest = deref((m,k3)) sk = searchsortedfirst(m,0.4) ek = searchsortedfirst(m,0.6)