Skip to content

Commit 26adf96

Browse files
authored
Remove union in IndexMap (jump-dev#1276)
* Remove union in IndexMap * Add convert from Dict to CleverDict * Fix MethodError principle for convert
1 parent d23a1f5 commit 26adf96

File tree

4 files changed

+46
-15
lines changed

4 files changed

+46
-15
lines changed

src/Utilities/CleverDicts.jl

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ mutable struct CleverDict{K,V,F<:Function,I<:Function} <: AbstractDict{K,V}
8686
end
8787
end
8888
function CleverDict{K,V}(n::Integer = 0) where {K,V}
89-
return CleverDict{K,V}(key_to_index, Base.Fix1(index_to_key, K), n)
89+
return CleverDict{K,V}(key_to_index, index_to_key, n)
9090
end
9191

9292
"""
@@ -106,6 +106,13 @@ function key_to_index end
106106

107107
_is_dense(c::CleverDict) = c.is_dense
108108

109+
function _inverse_hash(c::CleverDict{K}, index::Integer) where {K}
110+
return c.inverse_hash(Int64(index))::K
111+
end
112+
function _inverse_hash(c::CleverDict{K,V,F,typeof(index_to_key)}, index::Integer) where {K,V,F<:Function}
113+
return index_to_key(K, Int64(index))::K
114+
end
115+
109116
"""
110117
add_item(c::CleverDict{K, V}, val::Val)::K where {K, V}
111118
@@ -116,7 +123,7 @@ function add_item(c::CleverDict{K,V}, val::V)::K where {K,V}
116123
error("Keys were added out of order. `add_item` requires that keys are always added in order.")
117124
end
118125
# adding a key in order
119-
key = c.inverse_hash(Int64(c.last_index + 1))::K
126+
key = _inverse_hash(c, c.last_index + 1)
120127
c[key] = val
121128
return key
122129
end
@@ -142,9 +149,9 @@ function Base.haskey(c::CleverDict{K}, key::K) where {K}
142149
return _is_dense(c) ? c.hash(key)::Int64 in c.set : haskey(c.dict, key)
143150
end
144151

145-
function Base.keys(c::CleverDict{K}) where {K}
152+
function Base.keys(c::CleverDict)
146153
return if _is_dense(c)
147-
[c.inverse_hash(Int64(index))::K for index in c.set]
154+
[_inverse_hash(c, index) for index in c.set]
148155
else
149156
collect(keys(c.dict))
150157
end
@@ -284,7 +291,7 @@ function Base.iterate(
284291
return nothing
285292
else
286293
el, i = itr
287-
new_el = c.inverse_hash(Int64(el))::K => c.vector[el]::V
294+
new_el = _inverse_hash(c, el) => c.vector[el]::V
288295
@static if VERSION >= v"1.4.0"
289296
return new_el, State(i[2], i[1])
290297
else
@@ -318,7 +325,7 @@ function Base.iterate(
318325
return nothing
319326
else
320327
el, i = itr
321-
new_el = c.inverse_hash(Int64(el))::K => c.vector[el]::V
328+
new_el = _inverse_hash(c, el) => c.vector[el]::V
322329
@static if VERSION >= v"1.4.0"
323330
return new_el, State(i[2], i[1])
324331
else
@@ -377,4 +384,21 @@ function map_values!(f::Function, d::CleverDict)
377384
return
378385
end
379386

387+
function Base.convert(
388+
::Type{CleverDict{K,V,typeof(key_to_index),typeof(index_to_key)}},
389+
d::CleverDict{K,V,typeof(key_to_index),typeof(index_to_key)},
390+
) where {K,V}
391+
return d
392+
end
393+
function Base.convert(
394+
::Type{CleverDict{K,V,typeof(key_to_index),typeof(index_to_key)}},
395+
src::AbstractDict{K,V},
396+
) where {K,V}
397+
dest = CleverDict{K,V}()
398+
for key in sort(collect(keys(src)), by=dest.hash)
399+
dest[key] = src[key]
400+
end
401+
return dest
402+
end
403+
380404
end

src/Utilities/copy.jl

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ _index_to_variable(i) = MOI.VariableIndex(i)
8787
const DenseVariableDict{V} = CleverDicts.CleverDict{
8888
MOI.VariableIndex,
8989
V,
90-
typeof(MOI.index_value),
91-
typeof(_index_to_variable),
90+
typeof(CleverDicts.key_to_index),
91+
typeof(CleverDicts.index_to_key),
9292
}
9393
function dense_variable_dict(::Type{V}, n) where {V}
9494
return CleverDicts.CleverDict{MOI.VariableIndex,V}(
@@ -99,12 +99,7 @@ function dense_variable_dict(::Type{V}, n) where {V}
9999
end
100100

101101
struct IndexMap <: AbstractDict{MOI.Index,MOI.Index}
102-
# just keeping the union to make it more backward compatible
103-
# we should remove as soon as possible.
104-
varmap::Union{
105-
DenseVariableDict{MOI.VariableIndex},
106-
Dict{MOI.VariableIndex,MOI.VariableIndex},
107-
}
102+
varmap::DenseVariableDict{MOI.VariableIndex}
108103
conmap::DoubleDicts.MainIndexDoubleDict
109104
end
110105

src/Utilities/vector_of_constraints.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ struct VectorOfConstraints{
2626
MOI.ConstraintIndex{F,S},
2727
Tuple{F,S},
2828
typeof(CleverDicts.key_to_index),
29-
Base.Fix1{typeof(CleverDicts.index_to_key),DataType}
29+
typeof(CleverDicts.index_to_key),
3030
}
3131

3232
function VectorOfConstraints{F,S}() where {F,S}

test/Utilities/CleverDicts.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,4 +249,16 @@ CleverDicts.index_to_key(::Type{MyKey}, index::Int64) = MyKey(index)
249249
@test d[MathOptInterface.VariableIndex(0)] == "b"
250250
@test_throws ErrorException CleverDicts.add_item(d, "c")
251251
end
252+
253+
@testset "convert" begin
254+
vals = [MathOptInterface.VariableIndex(-i) for i in 1:10]
255+
d = Dict(MathOptInterface.VariableIndex(i) => vals[i] for i in 1:10)
256+
T = MathOptInterface.Utilities.DenseVariableDict{MathOptInterface.VariableIndex}
257+
c = convert(T, d)
258+
@test c isa T
259+
@test c.is_dense
260+
@test c.last_index == 10
261+
@test c.vector == vals
262+
@test c === convert(T, c)
263+
end
252264
end

0 commit comments

Comments
 (0)