-
Notifications
You must be signed in to change notification settings - Fork 98
/
CachedArrays.jl
139 lines (112 loc) · 2.83 KB
/
CachedArrays.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
"""
$(TYPEDEF)
Type providing a re-sizable array.
The size of a `CachedArray` is changed via the [`setsize!`](@ref) function.
A `CachedArray` can be build with the constructors
- [`CachedArray(a::AbstractArray)`](@ref)
- [`CachedArray(T,N)`](@ref)
```jldoctests
using Gridap.Arrays
# Create an empty CachedArray
a = CachedArray(Float64,2)
# Resize to new shape (2,3)
setsize!(a,(2,3))
size(a)
# output
(2, 3)
```
"""
mutable struct CachedArray{T,N,A<:AbstractArray{T,N}} <: AbstractArray{T,N}
array::A
buffer::Dict{NTuple{N,Int},A}
@doc """
CachedArray(a::AbstractArray)
Constructs a `CachedArray` from a given array.
"""
function CachedArray(array::A) where {T,N,A<:AbstractArray{T,N}}
buffer = Dict{NTuple{N,Int},A}()
buffer[size(array)] = array
new{T,N,A}(array,buffer)
end
end
"""
const CachedMatrix{T,A} = CachedArray{T,2,A}
"""
const CachedMatrix{T,A} = CachedArray{T,2,A}
"""
const CachedVector{T,A} = CachedArray{T,1,A}
"""
const CachedVector{T,A} = CachedArray{T,1,A}
"""
$(SIGNATURES)
"""
CachedVector(a::AbstractVector) = CachedArray(a)
"""
$(SIGNATURES)
"""
CachedMatrix(a::AbstractMatrix) = CachedArray(a)
"""
CachedArray(T,N)
Constructs an empty `CachedArray` of element type `T` and `N` dimensions.
"""
function CachedArray(T,N)
s = tuple([0 for i in 1:N]...)
a = Array{T,N}(undef,s)
CachedArray(a)
end
"""
$(SIGNATURES)
"""
function CachedVector(T)
CachedArray(T,1)
end
"""
$(SIGNATURES)
"""
function CachedMatrix(T)
CachedArray(T,2)
end
size(self::CachedArray) = size(self.array)
"""
$(SIGNATURES)
Changes the size of the `CachedArray` `a` to the size described the the tuple
`s`.
After calling `setsize!`, the array can store uninitialized values.
"""
function setsize!(a::CachedArray{T,N},s::NTuple{N,Int}) where {T,N}
if s != size(a.array)
if haskey(a.buffer,s)
a.array = a.buffer[s]
else
a.array = similar(a.array,T,s...)
a.buffer[s] = a.array
end
end
end
function setsize!(a::CachedArray{T,N},s::NTuple{N,<:Integer}) where {T,N}
_s::NTuple{N,Int} = s
setsize!(a,_s)
end
@propagate_inbounds function getindex(self::CachedArray, kj::Integer)
self.array[kj]
end
@propagate_inbounds function getindex(self::CachedArray{T,N}, kj::Vararg{Integer,N}) where {T,N}
self.array[kj...]
end
@propagate_inbounds function setindex!(B::CachedArray, v, kj::Integer)
B.array[kj] = v
v
end
@propagate_inbounds function setindex!(B::CachedArray{T,N}, v, kj::Vararg{Integer,N}) where {T,N}
B.array[kj...] = v
v
end
function similar(::Type{CachedArray{T,N,A}},s::Tuple{Vararg{Int}}) where {T,N,A}
a = similar(A,s)
CachedArray(a)
end
Base.convert(::Type{CachedArray{T,N,A}},a::CachedArray{T,N,A}) where {T,N,A} = a
function Base.convert(::Type{CachedArray{T,N,A}},a::CachedArray) where {T,N,A}
array = convert(A,a.array)
CachedArray(array)
end