From 65e3316b7d6db5f4420fec3f412d0a1a84eb77f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogumi=C5=82=20Kami=C5=84ski?= Date: Sat, 30 Apr 2022 08:20:31 +0200 Subject: [PATCH] Fix error in constructor (#82) --- Project.toml | 5 +++-- src/PooledArrays.jl | 29 +++++++++++++++++------------ test/runtests.jl | 24 +++++++++++++++++++++++- 3 files changed, 43 insertions(+), 15 deletions(-) diff --git a/Project.toml b/Project.toml index d4108dd..0b90562 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "PooledArrays" uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" -version = "1.4.1" +version = "1.4.2" [deps] DataAPI = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" @@ -12,6 +12,7 @@ julia = "1" [extras] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" [targets] -test = ["Test"] +test = ["OffsetArrays", "Test"] diff --git a/src/PooledArrays.jl b/src/PooledArrays.jl index a840034..7daf2b9 100644 --- a/src/PooledArrays.jl +++ b/src/PooledArrays.jl @@ -114,20 +114,25 @@ function _label(xs::AbstractArray, ) where {T, I<:Integer} @inbounds for i in start:length(xs) - x = xs[i] - lbl = get(invpool, x, zero(I)) - if lbl !== zero(I) - labels[i] = lbl + idx = i + firstindex(xs) - 1 + if !isassigned(xs, idx) + labels[i] = zero(I) else - if nlabels == typemax(I) - I2 = _widen(I) - return _label(xs, T, I2, i, convert(Vector{I2}, labels), - convert(Dict{T, I2}, invpool), pool, nlabels) + x = xs[idx] + lbl = get(invpool, x, zero(I)) + if lbl !== zero(I) + labels[i] = lbl + else + if nlabels == typemax(I) + I2 = _widen(I) + return _label(xs, T, I2, i, convert(Vector{I2}, labels), + convert(Dict{T, I2}, invpool), pool, nlabels) + end + nlabels += 1 + labels[i] = nlabels + invpool[x] = nlabels + push!(pool, x) end - nlabels += 1 - labels[i] = nlabels - invpool[x] = nlabels - push!(pool, x) end end labels, invpool, pool diff --git a/test/runtests.jl b/test/runtests.jl index 04973b6..105a708 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,4 +1,4 @@ -using Test +using Test, OffsetArrays using PooledArrays using DataAPI: refarray, refvalue, refpool, invrefpool using PooledArrays: refcount @@ -601,3 +601,25 @@ end @test popfirst!(x) == "1" @test x == ["2"] end + +@testset "constructor corner cases" begin + x = Vector{Any}(undef, 3) + y = PooledArray(x) + @test y isa PooledArray{Any} + @test !any(i -> isassigned(y, i), eachindex(y)) + @test all(iszero, y.refs) + @test isempty(y.pool) + @test isempty(y.invpool) + + x[2] = "a" + for v in (x, OffsetVector(x, -5)) + y = PooledArray(v) + @test y isa PooledArray{Any} + @test !isassigned(x, 1) + @test x[2] == "a" + @test !isassigned(x, 3) + @test y.refs == [0, 1, 0] + @test y.pool == ["a"] + @test y.invpool == Dict("a" => 1) + end +end