@@ -8,7 +8,7 @@ mutable struct Index{T, V} <: AbstractIndex{T, V}
88
99 longestprobe:: V
1010 initiallongestprobe:: V
11- deletions:: UInt16
11+ deletions:: V
1212
1313 function Index {T} (nelements:: Integer ) where {T}
1414 size = ceil (nelements / 0.9 ) # 0.9 load factor
@@ -29,20 +29,20 @@ _length(idx::Index) = length(idx.indices)
2929
3030function _setindex! (idx:: Index{T, V} , elem:: T , position:: Unsigned ) where {T, V}
3131 idx. vals[position] = elem
32- probeposition = 0x0
32+ probeposition:: V = 0x0
3333 k = position
34- location = hash (elem) % _length (idx)
34+ location = hash (elem) % _length (idx) + 0x1
3535 prevlongestprobe = idx. longestprobe
3636 @inbounds while k != 0x0
3737 probeposition += 0x1
38- location = location == _length (idx) ? UInt64 (0x1 ) : location + 0x1
3938 recordpos = idx. probepositions[location]
4039 if probeposition > recordpos
4140 k, idx. indices[location] = idx. indices[location], k
4241 idx. probepositions[location] = probeposition
4342 idx. longestprobe = max (idx. longestprobe, probeposition)
4443 probeposition = recordpos
4544 end
45+ location = location == _length (idx) ? UInt (0x1 ) : location + 0x1
4646 end
4747
4848 # reset longestprobe after some deletions deletions, this should maintain stable performance for _getindex and _getindex_array
@@ -58,17 +58,14 @@ function _getindex(idx::Index{T}, elem::T) where {T}
5858 ilength = _length (idx)
5959 if ilength > 0x0
6060 location = hash (elem) % ilength + 0x1
61- for probeposition ∈ 0x1 : (idx. longestprobe)
61+ @inbounds for probeposition ∈ 0x1 : (idx. longestprobe)
6262 pos = idx. indices[location]
6363 if pos > 0x0 && isequal (idx. vals[pos], elem)
6464 return location
6565 elseif pos == 0x0
6666 return 0x0
6767 end
68- location += 0x1
69- if location > _length (idx)
70- location = location % ilength
71- end
68+ location = location == ilength ? UInt (0x1 ) : location + 0x1
7269 end
7370 end
7471 return 0x0
@@ -79,17 +76,14 @@ function _getindex_array(idx::Index{T, V}, elem::T) where {T, V}
7976 ilength = _length (idx)
8077 if ilength > 0x0
8178 location = hash (elem) % ilength + 0x1
82- for probeposition ∈ 0x1 : (idx. longestprobe)
79+ @inbounds for probeposition ∈ 0x1 : (idx. longestprobe)
8380 pos = idx. indices[location]
8481 if pos > 0x0 && isequal (idx. vals[pos], elem)
8582 push! (locations, location)
8683 elseif pos == 0x0
8784 return locations
8885 end
89- location += 0x1
90- if location > ilength
91- location = location % ilength
92- end
86+ location = location == ilength ? UInt (0x1 ) : location + 0x1
9387 end
9488 end
9589 return locations
@@ -100,45 +94,43 @@ function _getindex_byposition(idx::Index{T}, i::Integer) where {T}
10094 ilength = _length (idx)
10195 if ilength > 0x0
10296 location = hash (elem) % ilength + 0x1
103- for probeposition ∈ 0x1 : (idx. longestprobe)
97+ @inbounds for probeposition ∈ 0x1 : (idx. longestprobe)
10498 pos = idx. indices[location]
10599 if pos > 0x0 && pos == i
106100 return location
107101 elseif pos == 0x0
108102 break
109103 end
110- location += 0x1
111- if location > ilength
112- location = location % ilength
113- end
104+ location = location == ilength ? UInt64 (0x1 ) : location + 0x1
114105 end
115106 end
116107 error (" Element not found. This should never happen." )
117108end
118109
119110function _delete! (idx:: Index , oldkeyindex:: Integer )
120- lastidx = findnext (x -> x <= 0x1 , idx. probepositions, oldkeyindex + 0x1 )
111+ lastidx = findnext (≤ ( 0x1 ) , idx. probepositions, oldkeyindex + 0x1 )
121112 @inbounds if ! isnothing (lastidx)
122- idx . indices[oldkeyindex : ( lastidx - 0x2 )] . = @view idx . indices[(oldkeyindex + 0x1 ) : (lastidx - 0x1 )]
123- idx. probepositions [oldkeyindex: (lastidx - 0x2 )] .=
124- @view (idx. probepositions[(oldkeyindex + 0x1 ): ( lastidx - 0x1 ) ]) .- true
125- idx. indices[lastidx - 0x1 ] = idx. probepositions[lastidx - 0x1 ] = false
113+ lastidx -= 0x1
114+ idx. indices [oldkeyindex: (lastidx - 0x1 )] .= @view idx . indices[(oldkeyindex + 0x1 ) : lastidx]
115+ idx . probepositions[oldkeyindex : (lastidx - 0x1 )] . = @view (idx. probepositions[(oldkeyindex + 0x1 ): lastidx]) .- 0x1
116+ idx. indices[lastidx] = idx. probepositions[lastidx] = 0x0
126117 else
127118 if oldkeyindex < _length (idx)
128119 idx. indices[oldkeyindex: (end - 0x1 )] .= @view idx. indices[(oldkeyindex + 0x1 ): end ]
129- idx. probepositions[oldkeyindex: (end - 0x1 )] .= @view (idx. probepositions[(oldkeyindex + 0x1 ): end ]) .- true
120+ idx. probepositions[oldkeyindex: (end - 0x1 )] .= @view (idx. probepositions[(oldkeyindex + 0x1 ): end ]) .- 0x1
130121 end
131122 if idx. probepositions[1 ] > 0x1
132123 idx. indices[end ] = idx. indices[1 ]
133124 idx. probepositions[end ] = idx. probepositions[1 ] - 0x1
134125
135- lastidx = findnext (x -> x <= 0x1 , idx. probepositions, 2 )
126+ lastidx = findnext (≤ ( 0x1 ) , idx. probepositions, 2 )
136127 if isnothing (lastidx)
137128 lastidx = oldkeyindex
138129 end
139- idx. indices[0x1 : (lastidx - 0x2 )] .= @view idx. indices[0x2 : (lastidx - 0x1 )]
140- idx. probepositions[0x1 : (lastidx - 0x2 )] .= @view (idx. probepositions[0x2 : (lastidx - 0x1 )]) .- true
141- idx. indices[lastidx - 0x1 ] = idx. probepositions[lastidx - 0x1 ] = 0x0
130+ lastidx -= 0x1
131+ idx. indices[0x1 : (lastidx - 0x1 )] .= @view idx. indices[0x2 : lastidx]
132+ idx. probepositions[0x1 : (lastidx - 0x1 )] .= @view (idx. probepositions[0x2 : lastidx]) .- 0x1
133+ idx. indices[lastidx] = idx. probepositions[lastidx] = 0x0
142134 else
143135 idx. indices[end ] = idx. probepositions[end ] = 0x0
144136 end
@@ -187,11 +179,11 @@ function Base.getindex(idx::Index{T}, elem::T, ::Val{false}) where {T}
187179 return i
188180end
189181
190- function Base. getindex (idx:: Index , i:: Integer )
182+ Base . @propagate_inbounds function Base. getindex (idx:: Index , i:: Integer )
191183 return idx. vals[i]
192184end
193185
194- function Base. setindex! (idx:: Index{T} , newval:: T , i:: Integer ) where {T}
186+ @inline function Base. setindex! (idx:: Index{T} , newval:: T , i:: Integer ) where {T}
195187 @boundscheck checkbounds (idx. vals, i)
196188 oldkeyindex = _getindex_byposition (idx, i)
197189 validx = idx. indices[oldkeyindex]
@@ -224,23 +216,23 @@ struct SubIndex{T, V, I} <: AbstractIndex{T, V}
224216end
225217SubIndex (idx:: Index{T, V} , indices:: I ) where {T, V, I} = SubIndex {T, V, I} (idx, indices, nothing )
226218
227- function Base. view (idx:: Index , I:: Union{AbstractRange, Colon} )
219+ @inline function Base. view (idx:: Index , I:: Union{AbstractRange, Colon} )
228220 @boundscheck checkbounds (idx, I)
229221 return SubIndex (idx, I)
230222end
231- function Base. view (idx:: Index{T, V} , I:: AbstractArray{<:Integer} ) where {T, V}
223+ @inline function Base. view (idx:: Index{T, V} , I:: AbstractArray{<:Integer} ) where {T, V}
232224 @boundscheck checkbounds (idx, I)
233225 return SubIndex (idx, I, Index (V .(I)))
234226end
235- function Base. view (idx:: Index{T, V} , I:: AbstractArray{Bool} ) where {T, V}
227+ @inline function Base. view (idx:: Index{T, V} , I:: AbstractArray{Bool} ) where {T, V}
236228 @boundscheck checkbounds (idx, I)
237229 return SubIndex (idx, I, Index (V .(findall (I))))
238230end
239- function Base. view (idx:: Index , I:: Integer )
231+ @inline function Base. view (idx:: Index , I:: Integer )
240232 @boundscheck checkbounds (idx, I)
241233 return @inbounds view (idx, I: I)
242234end
243- function Base. view (idx:: SubIndex , I)
235+ @inline function Base. view (idx:: SubIndex , I)
244236 @boundscheck checkbounds (idx, I)
245237 return @inbounds view (parent (idx), Base. reindex ((parentindices (idx),), (I,))[1 ])
246238end
@@ -266,6 +258,8 @@ function Base.getindex(si::SubIndex{T}, elem::T, ::Val{true}, ::Val{false}) wher
266258 resize! (res, i)
267259 return res
268260end
261+ Base. getindex (si:: SubIndex{T, V, Colon} , elem:: T , :: Val{true} , :: Val{false} ) where {T, V} =
262+ getindex (parent (si), elem, Val (true ), Val (false ))
269263function Base. getindex (si:: SubIndex{T, V, I} , elem:: T , :: Val{true} , :: Val{false} ) where {T, V, I <: AbstractArray{Bool} }
270264 res = getindex (parent (si), elem, Val (true ), Val (false ))
271265 res = res[parentindices (si)[res]]
@@ -296,7 +290,7 @@ function Base.getindex(si::SubIndex{T, V, I}, elem::T, ::Val{true}, ::Val{false}
296290 res = getindex (parent (si), elem, Val (true ), Val (false ))
297291 j = 0
298292 for i ∈ 1 : length (res)
299- pos = findfirst (== (res[i]), parentindices (si))
293+ pos = findfirst (isequal (res[i]), parentindices (si))
300294 if ! isnothing (pos)
301295 j += 1
302296 res[j] = pos
@@ -317,6 +311,8 @@ function Base.getindex(si::SubIndex{T, V}, elem::T, ::Val{false}, ::Val{false})
317311 position = findfirst (isequal (res), parentindices (si))
318312 return isnothing (position) ? V (0x0 ) : V (position)
319313end
314+ Base. getindex (si:: SubIndex{T, V, Colon} , elem:: T , :: Val{false} , :: Val{false} ) where {T, V} =
315+ getindex (parent (si), elem, Val (false ), Val (false ))
320316function Base. getindex (
321317 si:: SubIndex{T, V, I} ,
322318 elem:: T ,
341337function Base. getindex (si:: SubIndex{T, V, I} , elem:: T , :: Val{false} , :: Val{false} ) where {T, V, I <: AbstractRange }
342338 res = getindex (parent (si), elem, Val (false ), Val (false ))
343339 if res > 0x0
344- i = findfirst (== (res), parentindices (si))
340+ i = findfirst (isequal (res), parentindices (si))
345341 return isnothing (i) ? 0x0 : i
346342 else
347343 return 0x0
@@ -354,48 +350,59 @@ function Base.getindex(si::SubIndex{T}, elem::T, ::Val{false}) where {T}
354350 end
355351 return res
356352end
357- function Base. getindex (si:: SubIndex , i:: Union{Integer, AbstractVector{<:Integer}} )
353+ Base . @propagate_inbounds function Base. getindex (si:: SubIndex , i:: Union{Integer, AbstractVector{<:Integer}} )
358354 @boundscheck checkbounds (si, i)
359- return @inbounds parent (si)[Base. reindex ((parentindices (si),), (i,))[1 ]]
355+ return parent (si)[Base. reindex ((parentindices (si),), (i,))[1 ]]
360356end
361- function Base. getindex (si:: SubIndex{T, V, Colon} , i:: Union{Integer, AbstractVector{<:Integer}} ) where {T, V}
357+ Base. @propagate_inbounds function Base. getindex (
358+ si:: SubIndex{T, V, Colon} ,
359+ i:: Union{Integer, AbstractVector{<:Integer}} ,
360+ ) where {T, V}
362361 @boundscheck checkbounds (si, i)
363- return @inbounds parent (si)[i]
362+ return parent (si)[i]
364363end
365364
366- function Base. setindex! (si:: SubIndex{T} , newval:: T , i:: Integer ) where {T}
365+ Base . @propagate_inbounds function Base. setindex! (si:: SubIndex{T} , newval:: T , i:: Integer ) where {T}
367366 @boundscheck checkbounds (si, i)
368- @inbounds setindex! (parent (si), newval, Base. reindex ((parentindices (si),), (i,))[1 ])
367+ setindex! (parent (si), newval, Base. reindex ((parentindices (si),), (i,))[1 ])
369368 return si
370369end
371- function Base. setindex! (si:: SubIndex{T, V, Colon} , newval:: T , i:: Integer ) where {T, V}
370+ Base . @propagate_inbounds function Base. setindex! (si:: SubIndex{T, V, Colon} , newval:: T , i:: Integer ) where {T, V}
372371 @boundscheck checkbounds (si, i)
373- @inbounds setindex! (parent (si), newval, i)
372+ setindex! (parent (si), newval, i)
374373end
375- function Base. setindex! (si:: SubIndex{T} , newval:: T , oldval:: T ) where {T}
374+ Base . @propagate_inbounds function Base. setindex! (si:: SubIndex{T} , newval:: T , oldval:: T ) where {T}
376375 oldidx = parent (si)[oldval, true ]
377376 foldidx = findfirst (in (parentindices (si)), oldidx)
378377 if isnothing (foldidx)
379378 throw (KeyError (oldval))
380379 end
381- @inbounds parent (si)[oldidx[foldidx]] = newval
380+ parent (si)[oldidx[foldidx]] = newval
382381 return si
383382end
384- function Base. setindex! (si:: SubIndex{T, V, I} , newval:: T , oldval:: T ) where {T, V, I <: AbstractArray{Bool} }
383+ Base. @propagate_inbounds function Base. setindex! (
384+ si:: SubIndex{T, V, I} ,
385+ newval:: T ,
386+ oldval:: T ,
387+ ) where {T, V, I <: AbstractArray{Bool} }
385388 oldidx = parent (si)[oldval, true ]
386- oldidx = @inbounds oldidx[parentindices (si)[oldix]]
389+ oldidx = oldidx[parentindices (si)[oldix]]
387390 if length (oldidx) == 0
388391 throw (KeyError (oldval))
389392 end
390- @inbounds parent (si)[oldidx[1 ]] = newval
393+ parent (si)[oldidx[1 ]] = newval
391394 return si
392395end
393- function Base. setindex! (si:: SubIndex{T, V, I} , newval:: T , oldval:: T ) where {T, V, I <: AbstractArray{<:Integer} }
396+ Base. @propagate_inbounds function Base. setindex! (
397+ si:: SubIndex{T, V, I} ,
398+ newval:: T ,
399+ oldval:: T ,
400+ ) where {T, V, I <: AbstractArray{<:Integer} }
394401 oldidx = parent (si)[oldval, true ]
395402 foldidx = findfirst (in (si. revmapping), oldidx)
396403 if isnothing (foldidx)
397404 throw (KeyError (oldval))
398405 end
399- @inbounds parent (si)[oldidx[foldidx]] = newval
406+ parent (si)[oldidx[foldidx]] = newval
400407 return si
401408end
0 commit comments