@@ -42,11 +42,13 @@ mutable struct PooledArray{T, R<:Integer, N, RA} <: AbstractArray{T, N}
42
42
if length (pool) != length (invpool)
43
43
throw (ArgumentError (" inconsistent pool and invpool" ))
44
44
end
45
- # refs mustn't overflow pool
46
- minref, maxref = extrema (rs. a)
47
- # 0 indicates #undef
48
- if length (rs. a) > 0 && (minref < 0 || maxref > length (invpool))
49
- throw (ArgumentError (" Reference array points beyond the end of the pool" ))
45
+ if length (rs. a) > 0
46
+ # 0 indicates #undef
47
+ # refs mustn't overflow pool
48
+ minref, maxref = extrema (rs. a)
49
+ if (minref < 0 || maxref > length (invpool))
50
+ throw (ArgumentError (" Reference array points beyond the end of the pool" ))
51
+ end
50
52
end
51
53
pa = new {T,R,N,RA} (rs. a, pool, invpool, refcount)
52
54
finalizer (x -> Threads. atomic_sub! (x. refcount, 1 ), pa)
@@ -444,40 +446,25 @@ Base.convert(::Type{Array}, pa::PooledArray{T, R, N}) where {T, R, N} = convert(
444
446
445
447
# We need separate functions due to dispatch ambiguities
446
448
447
- for T in (PooledArray, SubArray{<: Any , <: Any , <: PooledArray })
448
- @eval Base. @propagate_inbounds function Base. getindex (A:: $T , I:: Integer... )
449
- idx = DataAPI. refarray (A)[I... ]
450
- iszero (idx) && throw (UndefRefError ())
451
- return @inbounds DataAPI. refpool (A)[idx]
452
- end
453
-
454
- @eval Base. @propagate_inbounds function Base. getindex (A:: $T , I:: Union{Real, AbstractVector} ...)
455
- # make sure we do not increase A.refcount in case creation of newrefs fails
456
- newrefs = DataAPI. refarray (A)[I... ]
457
- @assert newrefs isa AbstractArray
458
- Threads. atomic_add! (refcount (A), 1 )
459
- return PooledArray (RefArray (newrefs), DataAPI. invrefpool (A), DataAPI. refpool (A), refcount (A))
460
- end
461
- end
462
-
463
- if VERSION < v " 1.1"
464
- Base. @propagate_inbounds function Base. getindex (A:: SubArray{T,D,P,I,true} ,
465
- i:: Int ) where {I<: Tuple {Union{Base. Slice,
466
- AbstractUnitRange},
467
- Vararg{Any}}, P<: PooledArray , T, D}
468
- idx = DataAPI. refarray (A)[i]
469
- iszero (idx) && throw (UndefRefError ())
470
- return @inbounds DataAPI. refpool (A)[idx]
471
- end
472
- end
473
-
474
- # Defined to avoid ambiguities with Base
475
- Base. @propagate_inbounds function Base. getindex (A:: SubArray{<:Any, N, <:PooledArray} , I:: Vararg{Int,N} ) where {T,N}
476
- idx = DataAPI. refarray (A)[I... ]
449
+ Base. @propagate_inbounds function Base. getindex (A:: PooledArray , I:: Int )
450
+ idx = DataAPI. refarray (A)[I]
477
451
iszero (idx) && throw (UndefRefError ())
478
452
return @inbounds DataAPI. refpool (A)[idx]
479
453
end
480
454
455
+ # we handle fast only the case when the first index is an abstract vector
456
+ # this is to make sure other indexing synraxes use standard dispatch from Base
457
+ # the reason is that creation of DataAPI.refarray(A) is unfortunately slow
458
+ Base. @propagate_inbounds function Base. getindex (A:: PooledArrOrSub ,
459
+ I1:: AbstractVector ,
460
+ I2:: Union{Real, AbstractVector} ...)
461
+ # make sure we do not increase A.refcount in case creation of newrefs fails
462
+ newrefs = DataAPI. refarray (A)[I1, I2... ]
463
+ @assert newrefs isa AbstractArray
464
+ Threads. atomic_add! (refcount (A), 1 )
465
+ return PooledArray (RefArray (newrefs), DataAPI. invrefpool (A), DataAPI. refpool (A), refcount (A))
466
+ end
467
+
481
468
Base. @propagate_inbounds function Base. isassigned (pa:: PooledArrOrSub , I:: Int... )
482
469
! iszero (DataAPI. refarray (pa)[I... ])
483
470
end
0 commit comments