Skip to content
This repository has been archived by the owner on May 4, 2019. It is now read-only.

Commit

Permalink
Add type stable copy!(::DataArray, ::Integer, ...) methods
Browse files Browse the repository at this point in the history
  • Loading branch information
garborg committed Dec 3, 2014
1 parent 245526e commit d155a8f
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 16 deletions.
42 changes: 41 additions & 1 deletion src/dataarray.jl
Expand Up @@ -140,7 +140,7 @@ function Base.copy!(dest::DataArray, src::DataArray) # -> DataArray{T}
# only copy initialized elements
dest_data = dest.data
src_data = src.data
length(dest_data) >= length(src_data) || error(BoundsError())
length(dest_data) >= length(src_data) || throw(BoundsError())
src_chunks = src.na.chunks
for i = 1:length(src_data)
@inbounds if !Base.unsafe_bitgetindex(src_chunks, i)
Expand All @@ -152,6 +152,46 @@ function Base.copy!(dest::DataArray, src::DataArray) # -> DataArray{T}
dest
end

function Base.copy!(dest::DataArray, doffs::Integer, src::DataArray) # -> DataArray{T}
copy!(dest, doffs, src, 1, length(src))
end

# redundant on Julia 0.4
function Base.copy!(dest::DataArray, doffs::Integer, src::DataArray, soffs::Integer) # -> DataArray{T}
soffs <= length(src) || throw(BoundsError())
copy!(dest, doffs, src, soffs, length(src)-soffs+1)
end

function Base.copy!(dest::DataArray, doffs::Integer, src::DataArray, soffs::Integer, n::Integer) # -> DataArray{T}
if n == 0
return dest
elseif n < 0
throw(BoundsError())
end
if isbits(eltype(src))
copy!(dest.data, doffs, src.data, soffs, n)
else
# Elements of src_data are not necessarily initialized, so
# only copy initialized elements
dest_data = dest.data
src_data = src.data
if doffs < 1 || length(dest_data) - doffs + 1 < n ||
soffs < 1 || length(src_data) - soffs + 1 < n
throw(BoundsError())
end
src_chunks = src.na.chunks
for i = 0:(n-1)
di, si = doffs + i, soffs + i

@inbounds if !Base.unsafe_bitgetindex(src_chunks, si)
dest_data[di] = src_data[si]
end
end
end
copy!(dest.na, doffs, src.na, soffs, n)
dest
end

Base.fill!(A::DataArray, ::NAtype) = (fill!(A.na, true); A)
Base.fill!(A::DataArray, v) = (fill!(A.data, v); fill!(A.na, false); A)

Expand Down
56 changes: 41 additions & 15 deletions test/dataarray.jl
Expand Up @@ -52,19 +52,45 @@ module TestDataArray
# check case where only NA occurs in final position
@assert isequal(unique(@data [1, 2, 1, NA]), @data [1, 2, NA])

# Test vecbind
# a = [1:4]
# d = DataArray(a)
# @assert isequal(vecbind(a,a), [a,a])
# @assert isequal(vecbind(a,1.0 * a), 1.0 * [a,a])
# @assert isequal(vecbind(d,a), [d,d])
# @assert isequal(vecbind(a,d), [d,d])
# @assert isequal(vecbind(1.0 * a,d), 1.0 * [d,d])
# @assert isequal(vecbind(d,d), [d,d])
# @assert isequal(vecbind(a,IndexedVector(a)), [a,a])
# @assert isequal(vecbind(a,IndexedVector(d)), [d,d])
# @assert isequal(vecbind(PooledDataArray(a),IndexedVector(d)), [d,d])
# @assert isequal(vecbind(PooledDataArray(a),IndexedVector(a)), [a,a])
# @assert isequal(vecbind(a,RepeatedVector(a,2)), [a,a,a])
# @assert (vecbind(a,StackedVector({a,1.0*a})) == [a,a,a])
# Test copy!
function nonbits(dv)
ret = similar(dv, Integer)
for i = 1:length(dv)
if !isna(dv, i)
ret[i] = dv[i]
end
end
ret
end
set1 = Any[@data([1, NA, 3]), @data([NA, 5]), @data([1, 2, 3, 4, 5]),
@data([NA, 5, 3]), @data([1, 5, 3])]
set2 = map(nonbits, set1)

for (dest, src, bigsrc, res1, res2) in Any[set1, set2]
@test isequal(copy!(copy(dest), src), res1)
@test isequal(copy!(copy(dest), 1, src), res1)
@test isequal(copy!(copy(dest), 2, src, 2), res2)
@test isequal(copy!(copy(dest), 2, src, 2, 1), res2)

# likely forthcoming in 0.4
# @test isequal(copy!(copy(dest), 99, src, 99, 0), dest)

for idx in [0, 4]
@test_throws BoundsError copy!(dest, idx, src)
@test_throws BoundsError copy!(dest, idx, src, 1)
@test_throws BoundsError copy!(dest, idx, src, 1, 1)
@test_throws BoundsError copy!(dest, 1, src, idx)
@test_throws BoundsError copy!(dest, 1, src, idx, 1)
end

@test_throws BoundsError copy!(dest, 1, src, 1, -1)

@test_throws BoundsError copy!(dest, bigsrc)

@test_throws BoundsError copy!(dest, 3, src)
@test_throws BoundsError copy!(dest, 3, src, 1)
@test_throws BoundsError copy!(dest, 3, src, 1, 2)
@test_throws BoundsError copy!(dest, 1, src, 2, 2)
end

end

0 comments on commit d155a8f

Please sign in to comment.