From 766331349cc24d06150ce9d83c20da6e780d55e7 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Tue, 15 Dec 2020 10:54:28 -0600 Subject: [PATCH 01/24] Switch to GitHub Actions for CI (#714) --- .github/workflows/CI.yml | 46 ++++++++++++++++++++++++++++++++++++ .travis.yml | 50 ---------------------------------------- appveyor.yml | 36 ----------------------------- 3 files changed, 46 insertions(+), 86 deletions(-) create mode 100644 .github/workflows/CI.yml delete mode 100644 .travis.yml delete mode 100644 appveyor.yml diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml new file mode 100644 index 000000000..8d4311794 --- /dev/null +++ b/.github/workflows/CI.yml @@ -0,0 +1,46 @@ +name: CI +on: + pull_request: + push: + branches: + - master + tags: '*' +jobs: + test: + name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + version: + - '1.0' + - '1' +# - 'nightly' + os: + - ubuntu-latest + - macOS-latest + - windows-latest + arch: + - x64 + steps: + - uses: actions/checkout@v2 + - uses: julia-actions/setup-julia@v1 + with: + version: ${{ matrix.version }} + arch: ${{ matrix.arch }} + - uses: actions/cache@v1 + env: + cache-name: cache-artifacts + with: + path: ~/.julia/artifacts + key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }} + restore-keys: | + ${{ runner.os }}-test-${{ env.cache-name }}- + ${{ runner.os }}-test- + ${{ runner.os }}- + - uses: julia-actions/julia-buildpkg@v1 + - uses: julia-actions/julia-runtest@v1 + - uses: julia-actions/julia-processcoverage@v1 + - uses: codecov/codecov-action@v1 + with: + file: lcov.info diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 6b53b3bf9..000000000 --- a/.travis.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Documentation: http://docs.travis-ci.com/user/languages/julia/ -language: julia -os: - - linux - - osx -julia: - - 1.0 - - nightly -notifications: - email: false -# uncomment the following lines to override the default test script -#script: -# - if [[ -a .git/shallow ]]; then git fetch --unshallow; fi -# - julia -e 'Pkg.clone(pwd()); Pkg.build("DataStructures"); Pkg.test("DataStructures"; coverage=true)' -after_success: - # push coverage results to Coveralls - - julia -e 'import Pkg; cd(Pkg.dir("DataStructures")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())' - # push coverage results to Codecov - - julia -e 'import Pkg; cd(Pkg.dir("DataStructures")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())' -# Documenter auto-deploy -# https://juliadocs.github.io/Documenter.jl/stable/man/hosting/#.travis.yml-Configuration-1 -jobs: - allow_failures: - - julia: nightly - include: - - name: "Benchmark" - julia: 1.2 - os: linux - before_script: - - git fetch origin '+refs/heads/master:refs/remotes/origin/master' - - git branch baseline origin/master - # Run benchmark outside `script` so that it's hidden by default: - - julia --project=benchmark -e ' - using Pkg; Pkg.instantiate(); - include("benchmark/runjudge.jl");' - - script: - - julia --project=benchmark -e ' - using Pkg; Pkg.instantiate(); - include("benchmark/pprintjudge.jl");' - after_success: skip - if: type = pull_request - - stage: "Documentation" - julia: 1.2 - os: linux - script: - - julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); - Pkg.instantiate()' - - julia --project=docs/ docs/make.jl - after_success: skip diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 55ef8a7fb..000000000 --- a/appveyor.yml +++ /dev/null @@ -1,36 +0,0 @@ -environment: - matrix: - - julia_version: 1.0 - - julia_version: latest - -platform: - - x86 # 32-bit - - x64 # 64-bit - -## uncomment the following lines to allow failures on nightly julia -## (tests will run but not make your overall status red) -matrix: - allow_failures: - - julia_version: latest - -branches: - only: - - master - - /release-.*/ - -notifications: - - provider: Email - on_build_success: false - on_build_failure: false - on_build_status_changed: false - -install: - - ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/JuliaCI/Appveyor.jl/version-1/bin/install.ps1")) - -build_script: - - echo "%JL_BUILD_SCRIPT%" - - C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%" - -test_script: - - echo "%JL_TEST_SCRIPT%" - - C:\julia\bin\julia -e "%JL_TEST_SCRIPT%" From f3d15dcc6586a864ab76b48281808aab2ae5316b Mon Sep 17 00:00:00 2001 From: Vadim Platonov Date: Mon, 18 Jan 2021 20:16:10 +0100 Subject: [PATCH 02/24] Fix MutableBinaryHeap, same issue as #686 --- src/heaps/arrays_as_heaps.jl | 1 + src/heaps/binary_heap.jl | 2 -- src/heaps/mutable_binary_heap.jl | 6 +++++- test/test_mutable_binheap.jl | 6 ++++++ 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/heaps/arrays_as_heaps.jl b/src/heaps/arrays_as_heaps.jl index b2202bea0..47af9e4bc 100644 --- a/src/heaps/arrays_as_heaps.jl +++ b/src/heaps/arrays_as_heaps.jl @@ -2,6 +2,7 @@ using Base.Order: Forward, Ordering, lt +const DefaultReverseOrdering = Base.ReverseOrdering{Base.ForwardOrdering} # Heap operations on flat arrays # ------------------------------ diff --git a/src/heaps/binary_heap.jl b/src/heaps/binary_heap.jl index 503852e92..2b399f863 100644 --- a/src/heaps/binary_heap.jl +++ b/src/heaps/binary_heap.jl @@ -50,8 +50,6 @@ BinaryHeap(ordering::Base.Ordering, xs::AbstractVector{T}) where T = BinaryHeap{ BinaryHeap{T, O}() where {T, O<:Base.Ordering} = BinaryHeap{T}(O()) BinaryHeap{T, O}(xs::AbstractVector) where {T, O<:Base.Ordering} = BinaryHeap{T}(O(), xs) -const DefaultReverseOrdering = Base.ReverseOrdering{Base.ForwardOrdering} - # These constructors needed for BinaryMaxHeap, until we have https://github.com/JuliaLang/julia/pull/37822 BinaryHeap{T, DefaultReverseOrdering}() where {T} = BinaryHeap{T}(Base.Reverse) BinaryHeap{T, DefaultReverseOrdering}(xs::AbstractVector) where {T} = BinaryHeap{T}(Base.Reverse, xs) diff --git a/src/heaps/mutable_binary_heap.jl b/src/heaps/mutable_binary_heap.jl index cc6525de7..699aa538c 100644 --- a/src/heaps/mutable_binary_heap.jl +++ b/src/heaps/mutable_binary_heap.jl @@ -179,9 +179,13 @@ MutableBinaryHeap(ordering::Base.Ordering, xs::AbstractVector{T}) where T = Muta MutableBinaryHeap{T, O}() where {T, O<:Base.Ordering} = MutableBinaryHeap{T}(O()) MutableBinaryHeap{T, O}(xs::AbstractVector) where {T, O<:Base.Ordering} = MutableBinaryHeap{T}(O(), xs) +# These constructors needed for BinaryMaxHeap, until we have https://github.com/JuliaLang/julia/pull/37822 +MutableBinaryHeap{T, DefaultReverseOrdering}() where {T} = MutableBinaryHeap{T}(Base.Reverse) +MutableBinaryHeap{T, DefaultReverseOrdering}(xs::AbstractVector) where {T} = MutableBinaryHeap{T}(Base.Reverse, xs) + # Forward/reverse ordering type aliases const MutableBinaryMinHeap{T} = MutableBinaryHeap{T, Base.ForwardOrdering} -const MutableBinaryMaxHeap{T} = MutableBinaryHeap{T, Base.ReverseOrdering} +const MutableBinaryMaxHeap{T} = MutableBinaryHeap{T, DefaultReverseOrdering} MutableBinaryMinHeap(xs::AbstractVector{T}) where T = MutableBinaryMinHeap{T}(xs) MutableBinaryMaxHeap(xs::AbstractVector{T}) where T = MutableBinaryMaxHeap{T}(xs) diff --git a/test/test_mutable_binheap.jl b/test/test_mutable_binheap.jl index 9af1d963b..2a40501d6 100644 --- a/test/test_mutable_binheap.jl +++ b/test/test_mutable_binheap.jl @@ -78,6 +78,12 @@ end @test true end + @testset "Type Aliases" begin + # https://github.com/JuliaCollections/DataStructures.jl/issues/686 + @test MutableBinaryMaxHeap{Int}() isa MutableBinaryMaxHeap{Int} + @test MutableBinaryMinHeap{Int}() isa MutableBinaryMinHeap{Int} + end + @testset "basic tests" begin h = MutableBinaryMinHeap{Int}() From ebf144430775ff668bb272bbcfdcdac349dffa9f Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Tue, 19 Jan 2021 14:01:24 +0000 Subject: [PATCH 03/24] bump version --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 5e79352bb..bd3ee09d2 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "DataStructures" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.8" +version = "0.18.9" [deps] From 2c181852d1fbf941d6532ca3a9e71989972cf078 Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Tue, 19 Jan 2021 14:04:55 +0000 Subject: [PATCH 04/24] CI this branch --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 8d4311794..d6c332f64 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -3,7 +3,7 @@ on: pull_request: push: branches: - - master + - release-0.18 tags: '*' jobs: test: From 08ae3a788f447c0588f04dc1dbe17d5691a3b157 Mon Sep 17 00:00:00 2001 From: Chris Rackauckas Date: Mon, 9 Aug 2021 10:06:16 -0400 Subject: [PATCH 05/24] inline a bit to remove an inference trigger --- Project.toml | 2 +- src/heaps/arrays_as_heaps.jl | 4 ++-- src/heaps/binary_heap.jl | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Project.toml b/Project.toml index bd3ee09d2..726f25489 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "DataStructures" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.9" +version = "0.18.10" [deps] diff --git a/src/heaps/arrays_as_heaps.jl b/src/heaps/arrays_as_heaps.jl index 47af9e4bc..39a7e53f3 100644 --- a/src/heaps/arrays_as_heaps.jl +++ b/src/heaps/arrays_as_heaps.jl @@ -45,7 +45,7 @@ function percolate_up!(xs::AbstractArray, i::Integer, x=xs[i], o::Ordering=Forwa xs[i] = x end -percolate_up!(xs::AbstractArray, i::Integer, o::Ordering) = percolate_up!(xs, i, xs[i], o) +@inline percolate_up!(xs::AbstractArray, i::Integer, o::Ordering) = percolate_up!(xs, i, xs[i], o) """ heappop!(v, [ord]) @@ -68,7 +68,7 @@ end Given a binary heap-ordered array, push a new element `x`, preserving the heap property. For efficiency, this function does not check that the array is indeed heap-ordered. """ -function heappush!(xs::AbstractArray, x, o::Ordering=Forward) +@inline function heappush!(xs::AbstractArray, x, o::Ordering=Forward) push!(xs, x) percolate_up!(xs, length(xs), o) return xs diff --git a/src/heaps/binary_heap.jl b/src/heaps/binary_heap.jl index 2b399f863..9edf718ab 100644 --- a/src/heaps/binary_heap.jl +++ b/src/heaps/binary_heap.jl @@ -87,7 +87,7 @@ Base.isempty(h::BinaryHeap) = isempty(h.valtree) Adds the `value` element to the heap `h`. """ -function Base.push!(h::BinaryHeap, v) +@inline function Base.push!(h::BinaryHeap, v) heappush!(h.valtree, v, h.ordering) return h end From e53a05f16edd7053c5ebf6d416be1a14d6144f9d Mon Sep 17 00:00:00 2001 From: StephenVavasis Date: Tue, 7 Dec 2021 18:24:09 -0500 Subject: [PATCH 06/24] =?UTF-8?q?Fixed=20long-standing=20bug=20in=20balanc?= =?UTF-8?q?ed=5Ftree.jl=20that=20corrupted=20SortedMult=E2=80=A6=20(#775)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fixed long-standing bug in balanced_tree.jl that corrupted SortedMultiDict for certain insertions. * Added test case from issue #773 --- src/balanced_tree.jl | 203 ++++++++++++++++----------------- test/test_sorted_containers.jl | 26 +++++ 2 files changed, 123 insertions(+), 106 deletions(-) diff --git a/src/balanced_tree.jl b/src/balanced_tree.jl index 13d15e575..81cf7c83d 100644 --- a/src/balanced_tree.jl +++ b/src/balanced_tree.jl @@ -354,6 +354,7 @@ end ## done whether the iterm ## is already in the tree, so insertion of a new item always succeeds. + function Base.insert!(t::BalancedTree23{K,D,Ord}, k, d, allowdups::Bool) where {K,D,Ord <: Ordering} ## First we find the greatest data node that is <= k. @@ -395,134 +396,122 @@ function Base.insert!(t::BalancedTree23{K,D,Ord}, k, d, allowdups::Bool) where { ## go back and fix the parent. newind = push_or_reuse!(t.data, t.freedatainds, KDRec{K,D}(0,k,d)) + push!(t.useddatacells, newind) p1 = parent - oldchild = leafind newchild = newind minkeynewchild = k splitroot = false curdepth = depth + existingchild = leafind + ## This loop ascends the tree (i.e., follows the path from a leaf to the root) ## starting from the parent p1 of - ## where the new key k would go. For each 3-node we encounter + ## where the new key k will go. + ## Variables updated by the loop: + ## p1: parent of where the new node goes + ## newchild: index of the child to be inserted + ## minkeynewchild: the minimum key in the subtree rooted at newchild + ## existingchild: a child of p1; the newchild must + ## be inserted in the slot to the right of existingchild + ## curdepth: depth of newchild + ## For each 3-node we encounter ## during the ascent, we add a new child, which requires splitting ## the 3-node into two 2-nodes. Then we keep going until we hit the root. ## If we encounter a 2-node, then the ascent can stop; we can - ## change the 2-node to a 3-node with the new child. Invariants - ## during this loop are: - ## p1: the parent node (a tree node index) where the insertion must occur - ## oldchild,newchild: the two children of the parent node; oldchild - ## was already in the tree; newchild was just added to it. - ## minkeynewchild: This is the key that is the minimum value in - ## the subtree rooted at newchild. - - while t.tree[p1].child3 > 0 - isleaf = (curdepth == depth) - oldtreenode = t.tree[p1] - - ## Node p1 index a 3-node. There are three cases for how to - ## insert new child. All three cases involve splitting the - ## existing node (oldtreenode, numbered p1) into - ## two new nodes. One keeps the index p1; the other has - ## has a new index called newparentnum. - - - cmp = isleaf ? cmp3_leaf(ord, oldtreenode, minkeynewchild) : - cmp3_nonleaf(ord, oldtreenode, minkeynewchild) - - if cmp == 1 - lefttreenodenew = TreeNode{K}(oldtreenode.child1, newchild, 0, - oldtreenode.parent, - minkeynewchild, minkeynewchild) - righttreenodenew = TreeNode{K}(oldtreenode.child2, oldtreenode.child3, 0, - oldtreenode.parent, oldtreenode.splitkey2, - oldtreenode.splitkey2) - minkeynewchild = oldtreenode.splitkey1 - whichp = 1 - elseif cmp == 2 - lefttreenodenew = TreeNode{K}(oldtreenode.child1, oldtreenode.child2, 0, - oldtreenode.parent, - oldtreenode.splitkey1, oldtreenode.splitkey1) - righttreenodenew = TreeNode{K}(newchild, oldtreenode.child3, 0, - oldtreenode.parent, - oldtreenode.splitkey2, oldtreenode.splitkey2) - whichp = 2 + ## change the 2-node to a 3-node with the new child. + + while true + + + # Let newchild1,...newchild4 be the new children of + # the parent node + # Initially, take the three children of the existing parent + # node and set newchild4 to 0. + + newchild1 = t.tree[p1].child1 + newchild2 = t.tree[p1].child2 + minkeychild2 = t.tree[p1].splitkey1 + newchild3 = t.tree[p1].child3 + minkeychild3 = t.tree[p1].splitkey2 + p1parent = t.tree[p1].parent + newchild4 = 0 + + # Now figure out which of the 4 children is the new node + # and insert it into newchild1 ... newchild4 + + if newchild1 == existingchild + newchild4 = newchild3 + minkeychild4 = minkeychild3 + newchild3 = newchild2 + minkeychild3 = minkeychild2 + newchild2 = newchild + minkeychild2 = minkeynewchild + elseif newchild2 == existingchild + newchild4 = newchild3 + minkeychild4 = minkeychild3 + newchild3 = newchild + minkeychild3 = minkeynewchild + elseif newchild3 == existingchild + newchild4 = newchild + minkeychild4 = minkeynewchild else - lefttreenodenew = TreeNode{K}(oldtreenode.child1, oldtreenode.child2, 0, - oldtreenode.parent, - oldtreenode.splitkey1, oldtreenode.splitkey1) - righttreenodenew = TreeNode{K}(oldtreenode.child3, newchild, 0, - oldtreenode.parent, - minkeynewchild, minkeynewchild) - minkeynewchild = oldtreenode.splitkey2 - whichp = 2 + throw(AssertionError("Tree structure is corrupted 1")) + end + + # Two cases: either we need to split the tree node + # if newchild4>0 else we convert a 2-node to a 3-node + # if newchild4==0 + + if newchild4 == 0 + # Change the parent from a 2-node to a 3-node + t.tree[p1] = TreeNode{K}(newchild1, newchild2, newchild3, + p1parent, minkeychild2, minkeychild3) + if curdepth == depth + replaceparent!(t.data, newchild, p1) + else + replaceparent!(t.tree, newchild, p1) + end + break end - # Replace p1 with a new 2-node and insert another 2-node at - # index newparentnum. - t.tree[p1] = lefttreenodenew - newparentnum = push_or_reuse!(t.tree, t.freetreeinds, righttreenodenew) - if isleaf - par = (whichp == 1) ? p1 : newparentnum - # fix the parent of the new datanode. - replaceparent!(t.data, newind, par) - push!(t.useddatacells, newind) - replaceparent!(t.data, righttreenodenew.child1, newparentnum) - replaceparent!(t.data, righttreenodenew.child2, newparentnum) + # Split the parent + t.tree[p1] = TreeNode{K}(newchild1, newchild2, 0, + p1parent, minkeychild2, minkeychild2) + newtreenode = TreeNode{K}(newchild3, newchild4, 0, + p1parent, minkeychild4, minkeychild2) + newparentnum = push_or_reuse!(t.tree, t.freetreeinds, newtreenode) + if curdepth == depth + replaceparent!(t.data, newchild2, p1) + replaceparent!(t.data, newchild3, newparentnum) + replaceparent!(t.data, newchild4, newparentnum) else - # If this is not a leaf, we still have to fix the - # parent fields of the two nodes that are now children - ## of the newparent. - replaceparent!(t.tree, righttreenodenew.child1, newparentnum) - replaceparent!(t.tree, righttreenodenew.child2, newparentnum) + replaceparent!(t.tree, newchild2, p1) + replaceparent!(t.tree, newchild3, newparentnum) + replaceparent!(t.tree, newchild4, newparentnum) end - oldchild = p1 + # Update the loop variables for the next level of the + # ascension + existingchild = p1 newchild = newparentnum - ## If p1 is the root (i.e., we have encountered only 3-nodes during - ## our ascent of the tree), then the root must be split. - if p1 == t.rootloc - @invariant curdepth == 1 + p1 = p1parent + minkeynewchild = minkeychild3 + curdepth -= 1 + if curdepth == 0 splitroot = true break end - p1 = t.tree[oldchild].parent - curdepth -= 1 end - ## big loop terminated either because a 2-node was reached - ## (splitroot == false) or we went up the whole tree seeing - ## only 3-nodes (splitroot == true). - if !splitroot - - ## If our ascent reached a 2-node, then we convert it to - ## a 3-node by giving it a child3 field that is >0. - ## Encountering a 2-node halts the ascent up the tree. - - isleaf = curdepth == depth - oldtreenode = t.tree[p1] - cmpres = isleaf ? cmp2_leaf(ord, oldtreenode, minkeynewchild) : - cmp2_nonleaf(ord, oldtreenode, minkeynewchild) - - - t.tree[p1] = cmpres == 1 ? - TreeNode{K}(oldtreenode.child1, newchild, oldtreenode.child2, - oldtreenode.parent, - minkeynewchild, oldtreenode.splitkey1) : - TreeNode{K}(oldtreenode.child1, oldtreenode.child2, newchild, - oldtreenode.parent, - oldtreenode.splitkey1, minkeynewchild) - if isleaf - replaceparent!(t.data, newind, p1) - push!(t.useddatacells, newind) - end - else - ## Splitroot is set if the ascent of the tree encountered only 3-nodes. - ## In this case, the root itself was replaced by two nodes, so we need - ## a new root above those two. + # If the root has been split, then we need to add a level + # to the tree that is the parent of the old root and the new node. - newroot = TreeNode{K}(oldchild, newchild, 0, 0, - minkeynewchild, minkeynewchild) + if splitroot + @invariant existingchild == t.rootloc + newroot = TreeNode{K}(existingchild, newchild, 0, + 0, minkeynewchild, minkeynewchild) + newrootloc = push_or_reuse!(t.tree, t.freetreeinds, newroot) - replaceparent!(t.tree, oldchild, newrootloc) + replaceparent!(t.tree, existingchild, newrootloc) replaceparent!(t.tree, newchild, newrootloc) t.rootloc = newrootloc t.depth += 1 @@ -615,7 +604,7 @@ end ##, 1 if i2 precedes i1. function compareInd(t::BalancedTree23, i1::Int, i2::Int) - @assert(i1 in t.useddatacells && i2 in t.useddatacells) + @invariant(i1 in t.useddatacells && i2 in t.useddatacells) if i1 == i2 return 0 end @@ -624,6 +613,7 @@ function compareInd(t::BalancedTree23, i1::Int, i2::Int) p1 = t.data[i1].parent p2 = t.data[i2].parent @invariant_support_statement curdepth = t.depth + curdepth = t.depth while true @invariant curdepth > 0 if p1 == p2 @@ -647,6 +637,7 @@ function compareInd(t::BalancedTree23, i1::Int, i2::Int) p1 = t.tree[i1a].parent p2 = t.tree[i2a].parent @invariant_support_statement curdepth -= 1 + curdepth -= 1 end end diff --git a/test/test_sorted_containers.jl b/test/test_sorted_containers.jl index 846d1f915..3d4b7df5c 100644 --- a/test/test_sorted_containers.jl +++ b/test/test_sorted_containers.jl @@ -1403,6 +1403,32 @@ function testSortedMultiDict() end # issue #216 my_assert(DataStructures.isordered(SortedMultiDict{Int, String})) + # issue #773 + s = SortedMultiDict{Int, Int}() + insert!(s, 4, 41) + insert!(s, 3, 31) + insert!(s, 2, 21) + insert!(s, 2, 22) + insert!(s, 2, 23) + insert!(s, 2, 24) + insert!(s, 2, 25) + insert!(s, 2, 26) + insert!(s, 1, 11) + insert!(s, 1, 12) + st1 = insert!(s, 1, 13) + st2 = insert!(s, 1, 14) + st3 = insert!(s, 1, 15) + st4 = insert!(s, 1, 16) + st5 = insert!(s, 1, 17) + st6 = insert!(s, 1, 18) + delete!((s, st6)) + delete!((s, st5)) + delete!((s, st4)) + delete!((s, st3)) + delete!((s, st2)) + delete!((s, st1)) + insert!(s, 1, 19) + checkcorrectness(s.bt, true) true end From 2a7e84977683be3a377bc24a60932045874e30c4 Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Wed, 8 Dec 2021 15:38:46 -0600 Subject: [PATCH 07/24] bump version --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 726f25489..e554a0b9c 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "DataStructures" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.10" +version = "0.18.11" [deps] From 39766be6bf968f9d21b7fe66fdadcabad72ce9ea Mon Sep 17 00:00:00 2001 From: Kristoffer Date: Sat, 19 Feb 2022 20:03:52 +0100 Subject: [PATCH 08/24] fix syntax for `return_type`, fixes test on 1.8 --- src/mutable_list.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mutable_list.jl b/src/mutable_list.jl index 13b8827b7..27e8c2fa4 100644 --- a/src/mutable_list.jl +++ b/src/mutable_list.jl @@ -68,7 +68,7 @@ end function Base.map(f::Base.Callable, l::MutableLinkedList{T}) where T if isempty(l) && f isa Function - S = Core.Compiler.return_type(f, (T,)) + S = Core.Compiler.return_type(f, Tuple{T}) return MutableLinkedList{S}() elseif isempty(l) && f isa Type return MutableLinkedList{f}() From 612d0ef930a8de1c3fed337c65b27103e0d7b8c2 Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Fri, 6 May 2022 13:13:38 +0100 Subject: [PATCH 09/24] bump patch --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index e554a0b9c..5beffead9 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "DataStructures" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.11" +version = "0.18.12" [deps] From d0dd2a012ebd07ff31193b21130109baa50cfe2b Mon Sep 17 00:00:00 2001 From: Frames Catherine White Date: Tue, 24 May 2022 11:33:34 +0100 Subject: [PATCH 10/24] Compat compat --- Project.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index 5beffead9..631d208f3 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "DataStructures" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.12" +version = "0.18.13" [deps] @@ -9,7 +9,7 @@ InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240" OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" [compat] -Compat = "3.0.0" +Compat = "3,4" OrderedCollections = "1.1.0" julia = "1" From 468234cd19432225dfa8870fa73e15e7a97108f0 Mon Sep 17 00:00:00 2001 From: Micah Rufsvold <86363075+mrufsvold@users.noreply.github.com> Date: Wed, 28 Jun 2023 22:57:33 -0400 Subject: [PATCH 11/24] fix: check key values, not `get` return for haskey(k, orderedrobindict) (#858) * fix: check key values, not `get` return for haskey(k, orderedrobindict) * Fix: use isequal in setindex! * re-fix: use `get` for `in keys()` but descend to the actual id-dict * Remove accidental paste in docstring * consolidate tests for issue under testset --------- Co-authored-by: Micah Rufsvold --- src/ordered_robin_dict.jl | 6 +++--- test/runtests.jl | 3 ++- test/test_ordered_robin_dict.jl | 7 +++++++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/ordered_robin_dict.jl b/src/ordered_robin_dict.jl index fcbe29a36..863ad3442 100644 --- a/src/ordered_robin_dict.jl +++ b/src/ordered_robin_dict.jl @@ -131,7 +131,7 @@ function Base.setindex!(h::OrderedRobinDict{K, V}, v0, key0) where {K,V} else @assert haskey(h, key0) @inbounds orig_v = h.vals[index] - (orig_v != v0) && (@inbounds h.vals[index] = v0) + !isequal(orig_v, v0) && (@inbounds h.vals[index] = v0) end check_for_rehash(h) && rehash!(h) @@ -302,8 +302,8 @@ julia> haskey(D, 'c') false ``` """ -Base.haskey(h::OrderedRobinDict, key) = (get(h.dict, key, -2) > 0) -Base.in(key, v::Base.KeySet{K,T}) where {K,T<:OrderedRobinDict{K}} = (get(v.dict, key, -1) >= 0) +Base.haskey(h::OrderedRobinDict, key) = (get(h.dict, key, -1) > 0) +Base.in(key, v::Base.KeySet{K,T}) where {K,T<:OrderedRobinDict{K}} = (get(v.dict.dict, key, -1) >= 0) """ getkey(collection, key, default) diff --git a/test/runtests.jl b/test/runtests.jl index 7a5aa7686..9fa3f2e64 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -7,7 +7,8 @@ import DataStructures: IntSet @test [] == detect_ambiguities(Base, Core, DataStructures) -tests = ["deprecations", +tests = [ + "deprecations", "int_set", "sparse_int_set", "deque", diff --git a/test/test_ordered_robin_dict.jl b/test/test_ordered_robin_dict.jl index 2a78fc7aa..79efa6572 100644 --- a/test/test_ordered_robin_dict.jl +++ b/test/test_ordered_robin_dict.jl @@ -78,6 +78,13 @@ @test od60[14] == 15 end + @testset "Fixes issue 857" begin + h = OrderedRobinDict{Any,Any}([("a", missing), ("b", -2)]) + @test 5 == (h["a"] = 5) + @test "b" in keys(h) + @test haskey(h,"b") + end + # ############################# # Copied and modified from Base/test/dict.jl From 4bc0db227ba19595c28a56cd9163dfc55b8e099c Mon Sep 17 00:00:00 2001 From: Frames White Date: Thu, 29 Jun 2023 11:03:09 +0800 Subject: [PATCH 12/24] bump version --- Project.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index 631d208f3..2ec8b4296 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,6 @@ name = "DataStructures" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.13" - +version = "0.18.14" [deps] Compat = "34da2185-b29b-5c13-b0c7-acf172513d20" From eb136b92c75f83d69800a09e97d8c30899588797 Mon Sep 17 00:00:00 2001 From: Frames White Date: Thu, 3 Aug 2023 09:51:07 -0400 Subject: [PATCH 13/24] remove type piracy on eltype etc --- src/sorted_dict.jl | 4 +--- src/sorted_set.jl | 8 -------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/sorted_dict.jl b/src/sorted_dict.jl index db2afe34a..0598e8018 100644 --- a/src/sorted_dict.jl +++ b/src/sorted_dict.jl @@ -308,7 +308,7 @@ Returns the key type for SortedDict, SortedMultiDict and SortedSet. This function may also be applied to the type itself. Time: O(1) """ @inline Base.keytype(m::SortedDict{K,D,Ord}) where {K,D,Ord <: Ordering} = K -@inline Base.keytype(::Type{SortedDict{K,D,Ord}}) where {K,D,Ord <: Ordering} = K +@inline Base.valtype(m::SortedDict{K,D,Ord}) where {K,D,Ord <: Ordering} = D """ valtype(sc) @@ -316,8 +316,6 @@ This function may also be applied to the type itself. Time: O(1) Returns the value type for SortedDict and SortedMultiDict. This function may also be applied to the type itself. Time: O(1) """ -@inline Base.valtype(m::SortedDict{K,D,Ord}) where {K,D,Ord <: Ordering} = D -@inline Base.valtype(::Type{SortedDict{K,D,Ord}}) where {K,D,Ord <: Ordering} = D """ ordtype(sc) diff --git a/src/sorted_set.jl b/src/sorted_set.jl index 8547e91fc..a885137de 100644 --- a/src/sorted_set.jl +++ b/src/sorted_set.jl @@ -174,14 +174,6 @@ end return exactfound end -""" - eltype(sc) - -Returns the key type for SortedSet. -This function may also be applied to the type itself. Time: O(1) -""" -@inline Base.eltype(::Type{SortedSet{K,Ord}}) where {K,Ord <: Ordering} = K - """ keytype(sc) From 3776698802d7ee1581a60f006abd351ea69588cf Mon Sep 17 00:00:00 2001 From: Frames White Date: Thu, 3 Aug 2023 09:51:23 -0400 Subject: [PATCH 14/24] bump version --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 2ec8b4296..3f3dbe55d 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "DataStructures" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.14" +version = "0.18.15" [deps] Compat = "34da2185-b29b-5c13-b0c7-acf172513d20" From 430bec997fa2ae0408bbadc22a0ae40c7db8c2c0 Mon Sep 17 00:00:00 2001 From: Eric Hanson <5846501+ericphanson@users.noreply.github.com> Date: Sun, 3 Dec 2023 15:38:07 +0100 Subject: [PATCH 15/24] remove tests for `sort(::Dict)` --- test/test_sorting.jl | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/test/test_sorting.jl b/test/test_sorting.jl index 445420b0d..173bb1199 100644 --- a/test/test_sorting.jl +++ b/test/test_sorting.jl @@ -29,16 +29,9 @@ @test d == rev end - @testset "sort unordered" begin - unordered = Dict(zip('a':'z', 26:-1:1)) - @test sort(unordered) == forward - @test sort(unordered; rev=true) == rev - @test sort(unordered; byvalue=true) == rev - @test sort(unordered; byvalue=true, rev=true) == forward - end end @testset "Bug DataStructures.jl/#394" begin - @test sort(Dict(k=>string(k) for k in 1:3))[1] == "1" + @test sort(OrderedDict(k=>string(k) for k in 1:3))[1] == "1" end end From ccd675d8155112091efda3313455e9400e8402fc Mon Sep 17 00:00:00 2001 From: Dan Taras Date: Wed, 9 Feb 2022 13:42:50 +0100 Subject: [PATCH 16/24] Resize to new size. Fixes #788 --- src/robin_dict.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/robin_dict.jl b/src/robin_dict.jl index 8cec85205..cc96cfa52 100644 --- a/src/robin_dict.jl +++ b/src/robin_dict.jl @@ -197,8 +197,8 @@ function rehash!(h::RobinDict{K,V}, newsz = length(h.keys)) where {K, V} sz = length(oldk) newsz = _tablesz(newsz) if h.count == 0 - resize!(h.keys, sz) - resize!(h.vals, sz) + resize!(h.keys, newsz) + resize!(h.vals, newsz) resize!(h.hashes, newsz) fill!(h.hashes, 0) h.count = 0 From 72af1f6b65036c0cc1e11f2c8ef8d7475cc3b035 Mon Sep 17 00:00:00 2001 From: Koustav Chowdhury Date: Fri, 5 Jan 2024 10:56:58 +0530 Subject: [PATCH 17/24] bump version --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 3f3dbe55d..1e64c6812 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "DataStructures" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.15" +version = "0.18.16" [deps] Compat = "34da2185-b29b-5c13-b0c7-acf172513d20" From b5ba47d658235e6a67d9c05a539dfbc503c6246f Mon Sep 17 00:00:00 2001 From: Nick Robinson Date: Tue, 20 Feb 2024 18:47:28 +0000 Subject: [PATCH 18/24] Backport deque memory fix (#898) * Use `Base._unsetindex!` in `pop!` and `popfirst!` (#897) * Bump codecov/codecov-action from 3 to 4 Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3 to 4. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v3...v4) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Use `Base._unsetindex!` in `pop!` and `popfirst!` for Deque So that popped elements are not rooted by the deque and can be GCed when they drop out of caller scope. * Test Deque for leaks * Use `Base._unsetindex!` in `pop!` and `popfirst!` for CircularDeque So that popped elements are not rooted by the deque and can be GCed when they drop out of caller scope. * Test CircularDeque for leaks --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump version * Make compatible with ancient Julia versions * fixup! Make compatible with ancient Julia versions * fixup! fixup! Make compatible with ancient Julia versions --------- Signed-off-by: dependabot[bot] Co-authored-by: Kiran Pamnany Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Project.toml | 2 +- src/DataStructures.jl | 8 +++++++- src/circ_deque.jl | 2 ++ src/deque.jl | 2 ++ test/test_circ_deque.jl | 23 +++++++++++++++++++++++ test/test_deque.jl | 24 ++++++++++++++++++++++++ 6 files changed, 59 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index 1e64c6812..1ce044127 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "DataStructures" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.16" +version = "0.18.17" [deps] Compat = "34da2185-b29b-5c13-b0c7-acf172513d20" diff --git a/src/DataStructures.jl b/src/DataStructures.jl index c9d386f39..552aff4fc 100644 --- a/src/DataStructures.jl +++ b/src/DataStructures.jl @@ -112,4 +112,10 @@ module DataStructures include("splay_tree.jl") include("deprecations.jl") -end \ No newline at end of file + + @static if VERSION <= v"1.3" + _unsetindex!(a, i) = a + else + _unsetindex! = Base._unsetindex! + end +end diff --git a/src/circ_deque.jl b/src/circ_deque.jl index 3159d7d6a..6c03e8463 100644 --- a/src/circ_deque.jl +++ b/src/circ_deque.jl @@ -63,6 +63,7 @@ end @inline Base.@propagate_inbounds function Base.pop!(D::CircularDeque) v = last(D) + _unsetindex!(D.buffer, D.last) # see issue/884 D.n -= 1 tmp = D.last - 1 D.last = ifelse(tmp < 1, D.capacity, tmp) @@ -90,6 +91,7 @@ Remove the element at the front. """ @inline Base.@propagate_inbounds function Base.popfirst!(D::CircularDeque) v = first(D) + _unsetindex!(D.buffer, D.first) # see issue/884 D.n -= 1 tmp = D.first + 1 D.first = ifelse(tmp > D.capacity, 1, tmp) diff --git a/src/deque.jl b/src/deque.jl index dd6c0b503..5ae47459a 100644 --- a/src/deque.jl +++ b/src/deque.jl @@ -276,6 +276,7 @@ function Base.pop!(q::Deque{T}) where T @assert rear.back >= rear.front @inbounds x = rear.data[rear.back] + _unsetindex!(rear.data, rear.back) # see issue/884 rear.back -= 1 if rear.back < rear.front if q.nblocks > 1 @@ -301,6 +302,7 @@ function Base.popfirst!(q::Deque{T}) where T @assert head.back >= head.front @inbounds x = head.data[head.front] + _unsetindex!(head.data, head.front) # see issue/884 head.front += 1 if head.back < head.front if q.nblocks > 1 diff --git a/test/test_circ_deque.jl b/test/test_circ_deque.jl index adf3ddd6d..269d8a76c 100644 --- a/test/test_circ_deque.jl +++ b/test/test_circ_deque.jl @@ -81,6 +81,29 @@ for i in 1:5 push!(D, i) end @test collect([i for i in D]) == collect(1:5) end + + VERSION >= v"1.3" && @testset "pop! and popfirst! do not leak" begin + D = CircularDeque{String}(5) + + @testset "pop! doesn't leak" begin + push!(D,"foo") + push!(D,"bar") + ss2 = Base.summarysize(D) + pop!(D) + GC.gc(true) + ss1 = Base.summarysize(D) + @test ss1 < ss2 + end + @testset "popfirst! doesn't leak" begin + push!(D,"baz") + push!(D,"bug") + ss2 = Base.summarysize(D) + popfirst!(D) + GC.gc(true) + ss1 = Base.summarysize(D) + @test ss1 < ss2 + end + end end nothing diff --git a/test/test_deque.jl b/test/test_deque.jl index 8c35ba289..35f78ea5c 100644 --- a/test/test_deque.jl +++ b/test/test_deque.jl @@ -197,4 +197,28 @@ @test typeof(empty!(q)) === typeof(Deque{Int}()) @test isempty(q) end + + VERSION >= v"1.3" && @testset "pop! and popfirst! don't leak" begin + q = Deque{String}(5) + GC.gc(true) + + @testset "pop! doesn't leak" begin + push!(q,"foo") + push!(q,"bar") + ss2 = Base.summarysize(q.head) + pop!(q) + GC.gc(true) + ss1 = Base.summarysize(q.head) + @test ss1 < ss2 + end + @testset "popfirst! doesn't leak" begin + push!(q,"baz") + push!(q,"bug") + ss2 = Base.summarysize(q.head) + popfirst!(q) + GC.gc(true) + ss1 = Base.summarysize(q.head) + @test ss1 < ss2 + end + end end # @testset Deque From 37912cf05c5f6bdd969dd1325f346b68d0914c84 Mon Sep 17 00:00:00 2001 From: KronosTheLate <61620837+KronosTheLate@users.noreply.github.com> Date: Tue, 6 Feb 2024 15:37:10 +0100 Subject: [PATCH 19/24] Conditional import of Base.isfull --- src/circular_buffer.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/circular_buffer.jl b/src/circular_buffer.jl index 3d991cd61..45fd88bce 100644 --- a/src/circular_buffer.jl +++ b/src/circular_buffer.jl @@ -179,6 +179,11 @@ Return capacity of CircularBuffer. """ capacity(cb::CircularBuffer) = cb.capacity +# Base might define `isfull` from julia 1.11 onwards, see julia PR #53159 +if isdefined(Base, :isfull) + import Base: isfull +end + """ isfull(cb::CircularBuffer) From 5156e74a7347426283f1c5688e0c683bc4937ad8 Mon Sep 17 00:00:00 2001 From: Frames White Date: Tue, 5 Mar 2024 16:16:42 +0800 Subject: [PATCH 20/24] bump version --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 1ce044127..ed958efa3 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "DataStructures" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.17" +version = "0.18.18" [deps] Compat = "34da2185-b29b-5c13-b0c7-acf172513d20" From 2dbfb80e37fc5bb7cbb8fd34d0b10086fd3ed9b8 Mon Sep 17 00:00:00 2001 From: JamesWrigley Date: Fri, 12 Apr 2024 12:55:05 +0200 Subject: [PATCH 21/24] Delete unnecessary methods to fix invalidations - Base.keys() already works on AbstractDict's so we don't need one for Accumulator. - Base.eltype() is already defined for AbstractArray's and CircularBuffer is an AbstractVector so it doesn't need to define it again. - A Base.convert() from AbstractArray to Array is already defined: https://github.com/JuliaLang/julia/blob/1ae41a2c0a3ba49d4b39dc4933dddf952b5f7f3c/base/array.jl#L612 --- src/accumulator.jl | 2 -- src/circular_buffer.jl | 4 ---- 2 files changed, 6 deletions(-) diff --git a/src/accumulator.jl b/src/accumulator.jl index c9fab92e4..015b0ebfd 100644 --- a/src/accumulator.jl +++ b/src/accumulator.jl @@ -55,8 +55,6 @@ Base.setindex!(ct::Accumulator, x, v) = setindex!(ct.map, x, v) Base.haskey(ct::Accumulator, x) = haskey(ct.map, x) -Base.keys(ct::Accumulator) = keys(ct.map) - Base.values(ct::Accumulator) = values(ct.map) Base.sum(ct::Accumulator) = sum(values(ct.map)) diff --git a/src/circular_buffer.jl b/src/circular_buffer.jl index 45fd88bce..bab84e39e 100644 --- a/src/circular_buffer.jl +++ b/src/circular_buffer.jl @@ -154,8 +154,6 @@ Return the number of elements currently in the buffer. """ Base.length(cb::CircularBuffer) = cb.length -Base.eltype(::Type{CircularBuffer{T}}) where T = T - """ size(cb::CircularBuffer) @@ -163,8 +161,6 @@ Return a tuple with the size of the buffer. """ Base.size(cb::CircularBuffer) = (length(cb),) -Base.convert(::Type{Array}, cb::CircularBuffer{T}) where {T} = T[x for x in cb] - """ isempty(cb::CircularBuffer) From 91a76c963e7ad3864729b6ce63aebc581cc53031 Mon Sep 17 00:00:00 2001 From: JamesWrigley Date: Fri, 12 Apr 2024 13:49:31 +0200 Subject: [PATCH 22/24] Bump version to 0.18.19 --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index ed958efa3..a0aea6a93 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "DataStructures" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.18" +version = "0.18.19" [deps] Compat = "34da2185-b29b-5c13-b0c7-acf172513d20" From 266216a3a03b7e980bb7191dafe62331d36ea2dc Mon Sep 17 00:00:00 2001 From: Frames White Date: Thu, 18 Apr 2024 14:18:27 +0800 Subject: [PATCH 23/24] mark heapify to inline --- src/heaps/arrays_as_heaps.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/heaps/arrays_as_heaps.jl b/src/heaps/arrays_as_heaps.jl index 39a7e53f3..3f6241b68 100644 --- a/src/heaps/arrays_as_heaps.jl +++ b/src/heaps/arrays_as_heaps.jl @@ -81,7 +81,7 @@ end In-place [`heapify`](@ref). """ -function heapify!(xs::AbstractArray, o::Ordering=Forward) +@inline function heapify!(xs::AbstractArray, o::Ordering=Forward) for i in heapparent(length(xs)):-1:1 percolate_down!(xs, i, o) end From 45f9985c5d2129e3a1c50f83449544b66ecd7594 Mon Sep 17 00:00:00 2001 From: Frames White Date: Thu, 18 Apr 2024 14:18:52 +0800 Subject: [PATCH 24/24] bump version --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index a0aea6a93..7e27f0d2e 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "DataStructures" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.19" +version = "0.18.20" [deps] Compat = "34da2185-b29b-5c13-b0c7-acf172513d20"