Skip to content

Commit 19b7044

Browse files
Attempt to add support for getindex(::DiskArray, Int[]) (#194)
* Fix 186 * Fix pr * fix tests * check size of read befor calling readblock * fix deprecation * getindex_count fixed --------- Co-authored-by: Fabian Gans <[email protected]>
1 parent 34d5b0d commit 19b7044

File tree

3 files changed

+45
-11
lines changed

3 files changed

+45
-11
lines changed

src/batchgetindex.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,17 @@ end
6060

6161
function has_chunk_gap(cs,ids::AbstractVector{<:Integer})
6262
#Find largest jump in indices
63+
isempty(ids) && return false
6364
minind,maxind = extrema(ids)
6465
maxind - minind > first(cs)
6566
end
6667
#Return true for all multidimensional indices for now, could be optimised in the future
6768
has_chunk_gap(cs,ids) = true
6869

6970
#Compute the number of possible indices in the hyperrectangle
70-
span(v::AbstractArray{<:Integer}) = 1 -(-(extrema(v)...))
71+
function span(v::AbstractArray{<:Integer})
72+
iszero(length(v)) ? 0 : 1 -(-(extrema(v)...))
73+
end
7174
function span(v::AbstractArray{CartesianIndex{N}}) where N
7275
minind,maxind = extrema(v)
7376
prod((maxind-minind+oneunit(minind)).I)

src/diskarray.jl

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ function process_index(i::AbstractUnitRange{<:Integer}, cs, ::NoBatch)
129129
DiskIndex((length(i),), (length(i),), (Colon(),), (Colon(),), (i,)), Base.tail(cs)
130130
end
131131
function process_index(i::AbstractArray{<:Integer}, cs, ::NoBatch)
132-
indmin, indmax = extrema(i)
132+
indmin, indmax = isempty(i) ? (1,0) : extrema(i)
133133
DiskIndex(size(i), ((indmax - indmin + 1),), map(_->Colon(),size(i)), ((i .- (indmin - 1)),), (indmin:indmax,)), Base.tail(cs)
134134
end
135135
function process_index(i::AbstractArray{Bool,N}, cs, ::NoBatch) where {N}
@@ -144,7 +144,12 @@ end
144144
function process_index(i::AbstractArray{<:CartesianIndex{N}}, cs, ::NoBatch) where {N}
145145
csnow, csrem = splitcs(i, cs)
146146
s = arraysize_from_chunksize.(csnow)
147-
cindmin, cindmax = extrema(view(CartesianIndices(s), i))
147+
v = view(CartesianIndices(s), i)
148+
cindmin, cindmax = if isempty(v)
149+
one(CartesianIndex{N}), zero(CartesianIndex{N})
150+
else
151+
extrema(v)
152+
end
148153
indmin, indmax = cindmin.I, cindmax.I
149154
tempsize = indmax .- indmin .+ 1
150155
tempoffset = cindmin - oneunit(cindmin)
@@ -157,7 +162,7 @@ function process_index(i::CartesianIndices{N}, cs, ::NoBatch) where {N}
157162
cols = map(_ -> Colon(), i.indices)
158163
DiskIndex(length.(i.indices), length.(i.indices), cols, cols, i.indices), csrem
159164
end
160-
splitcs(i::AbstractArray{<:CartesianIndex}, cs) = splitcs(first(i).I, (), cs)
165+
splitcs(i::AbstractArray{<:CartesianIndex}, cs) = splitcs(oneunit(eltype(i)).I, (), cs)
161166
splitcs(i::AbstractArray{Bool}, cs) = splitcs(size(i), (), cs)
162167
splitcs(i::CartesianIndices, cs) = splitcs(i.indices, (), cs)
163168
splitcs(i::CartesianIndex, cs) = splitcs(i.I,(),cs)
@@ -233,13 +238,13 @@ function getindex_disk_nobatch!(out,a,i)
233238
outputarray = create_outputarray(out, a, indices.output_size)
234239
outalias = output_aliasing(indices,ndims(outputarray),ndims(a))
235240
if outalias === :identical
236-
readblock!(a, outputarray, indices.data_indices...)
241+
readblock_sizecheck!(a, outputarray, indices.data_indices...)
237242
elseif outalias === :reshapeoutput
238243
temparray = reshape(outputarray,indices.temparray_size)
239-
readblock!(a, temparray, indices.data_indices...)
244+
readblock_sizecheck!(a, temparray, indices.data_indices...)
240245
else
241246
temparray = Array{eltype(a)}(undef, indices.temparray_size...)
242-
readblock!(a, temparray, indices.data_indices...)
247+
readblock_sizecheck!(a, temparray, indices.data_indices...)
243248
transfer_results!(outputarray, temparray, indices.output_indices, indices.temparray_indices)
244249
end
245250
outputarray
@@ -297,18 +302,18 @@ function setindex_disk_batch!(a,v,i)
297302
readblock!(a, vtemparray, data_indices...)
298303
transfer_results_write!(v, temparray, output_indices, temparray_indices)
299304
end
300-
writeblock!(a, vtemparray, data_indices...)
305+
writeblock_sizecheck!(a, vtemparray, data_indices...)
301306
end
302307
end
303308

304309
function setindex_disk_nobatch!(a,v,i)
305310
indices = resolve_indices(a, i, NoBatch(batchstrategy(a)))
306311
outalias = output_aliasing(indices,ndims(a),ndims(v))
307312
if outalias === :identical
308-
writeblock!(a, v, indices.data_indices...)
313+
writeblock_sizecheck!(a, v, indices.data_indices...)
309314
elseif outalias === :reshapeoutput
310315
temparray = reshape(v,indices.temparray_size)
311-
writeblock!(a, temparray, indices.data_indices...)
316+
writeblock_sizecheck!(a, temparray, indices.data_indices...)
312317
else
313318
temparray = Array{eltype(a)}(undef, indices.temparray_size...)
314319
if any(ind->is_sparse_index(ind,density_threshold=1.0),indices.temparray_indices)
@@ -319,7 +324,21 @@ function setindex_disk_nobatch!(a,v,i)
319324
readblock!(a, temparray, indices.data_indices...)
320325
end
321326
transfer_results_write!(v, temparray, indices.output_indices, indices.temparray_indices)
322-
writeblock!(a, temparray, indices.data_indices...)
327+
writeblock_sizecheck!(a, temparray, indices.data_indices...)
328+
end
329+
end
330+
331+
"Like `readblock!`, but only exectued when data size to read is not empty"
332+
function readblock_sizecheck!(x,y,i...)
333+
if length(y) > 0
334+
readblock!(x,y,i...)
335+
end
336+
end
337+
338+
"Like `writeblock!`, but only exectued when data size to read is not empty"
339+
function writeblock_sizecheck!(x,y,i...)
340+
if length(y) > 0
341+
writeblock!(x,y,i...)
323342
end
324343
end
325344

test/runtests.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ end
3636
@test a[CartesianIndex(1,2,3)] == 15
3737
end
3838

39+
@testset "getindex with empty array" begin
40+
a = AccessCountDiskArray(reshape(1:24,2,3,4),chunksize=(2,2,2))
41+
@test a[Int[]] == Float64[]
42+
end
43+
3944
function test_getindex(a)
4045
@test a[2, 3, 1] == 10
4146
@test a[2, 3] == 10
@@ -491,6 +496,13 @@ end
491496
a = AccessCountDiskArray(reshape(1:20, 4, 5, 1); chunksize=(4, 1, 1))
492497
@test a[:, [1, 4], 1] == trueparent(a)[:, [1, 4], 1]
493498
@test getindex_count(a) == 1
499+
500+
#Test with empty vectors
501+
@test a[Int[]] == Int[]
502+
@test a[:,Int[],:] == zeros(Int,4,0,1)
503+
@test a[Int[],:,:] == zeros(Int,0,5,1)
504+
@test getindex_count(a) == 1
505+
494506
coords = CartesianIndex.([(1, 1, 1), (3, 1, 1), (2, 4, 1), (4, 4, 1)])
495507
@test a[coords] == trueparent(a)[coords]
496508
@test_broken getindex_count(a) == 4

0 commit comments

Comments
 (0)