From 61a3a621cf6d85a6375e93f9998325fa951817f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Tue, 9 Mar 2021 10:40:08 +0100 Subject: [PATCH 1/3] Remove union in IndexMap --- src/Utilities/copy.jl | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Utilities/copy.jl b/src/Utilities/copy.jl index 03543113d9..13a801e52a 100644 --- a/src/Utilities/copy.jl +++ b/src/Utilities/copy.jl @@ -99,12 +99,7 @@ function dense_variable_dict(::Type{V}, n) where {V} end struct IndexMap <: AbstractDict{MOI.Index,MOI.Index} - # just keeping the union to make it more backward compatible - # we should remove as soon as possible. - varmap::Union{ - DenseVariableDict{MOI.VariableIndex}, - Dict{MOI.VariableIndex,MOI.VariableIndex}, - } + varmap::DenseVariableDict{MOI.VariableIndex} conmap::DoubleDicts.MainIndexDoubleDict end From ca557bebf7d29bcde54259cfe04e1d5bef5f6c9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Thu, 11 Mar 2021 23:07:46 +0100 Subject: [PATCH 2/3] Add convert from Dict to CleverDict --- src/Utilities/CleverDicts.jl | 30 ++++++++++++++++++++------ src/Utilities/copy.jl | 4 ++-- src/Utilities/vector_of_constraints.jl | 2 +- test/Utilities/CleverDicts.jl | 12 +++++++++++ 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/Utilities/CleverDicts.jl b/src/Utilities/CleverDicts.jl index ba3260a81c..953d12d7e2 100644 --- a/src/Utilities/CleverDicts.jl +++ b/src/Utilities/CleverDicts.jl @@ -86,7 +86,7 @@ mutable struct CleverDict{K,V,F<:Function,I<:Function} <: AbstractDict{K,V} end end function CleverDict{K,V}(n::Integer = 0) where {K,V} - return CleverDict{K,V}(key_to_index, Base.Fix1(index_to_key, K), n) + return CleverDict{K,V}(key_to_index, index_to_key, n) end """ @@ -106,6 +106,13 @@ function key_to_index end _is_dense(c::CleverDict) = c.is_dense +function _inverse_hash(c::CleverDict{K}, index::Integer) where {K} + return c.inverse_hash(Int64(index))::K +end +function _inverse_hash(c::CleverDict{K,V,F,typeof(index_to_key)}, index::Integer) where {K,V,F<:Function} + return index_to_key(K, Int64(index))::K +end + """ add_item(c::CleverDict{K, V}, val::Val)::K where {K, V} @@ -116,7 +123,7 @@ function add_item(c::CleverDict{K,V}, val::V)::K where {K,V} error("Keys were added out of order. `add_item` requires that keys are always added in order.") end # adding a key in order - key = c.inverse_hash(Int64(c.last_index + 1))::K + key = _inverse_hash(c, c.last_index + 1) c[key] = val return key end @@ -142,9 +149,9 @@ function Base.haskey(c::CleverDict{K}, key::K) where {K} return _is_dense(c) ? c.hash(key)::Int64 in c.set : haskey(c.dict, key) end -function Base.keys(c::CleverDict{K}) where {K} +function Base.keys(c::CleverDict) return if _is_dense(c) - [c.inverse_hash(Int64(index))::K for index in c.set] + [_inverse_hash(c, index) for index in c.set] else collect(keys(c.dict)) end @@ -284,7 +291,7 @@ function Base.iterate( return nothing else el, i = itr - new_el = c.inverse_hash(Int64(el))::K => c.vector[el]::V + new_el = _inverse_hash(c, el) => c.vector[el]::V @static if VERSION >= v"1.4.0" return new_el, State(i[2], i[1]) else @@ -318,7 +325,7 @@ function Base.iterate( return nothing else el, i = itr - new_el = c.inverse_hash(Int64(el))::K => c.vector[el]::V + new_el = _inverse_hash(c, el) => c.vector[el]::V @static if VERSION >= v"1.4.0" return new_el, State(i[2], i[1]) else @@ -377,4 +384,15 @@ function map_values!(f::Function, d::CleverDict) return end +function Base.convert(::Type{CleverDict{K,V,F,I}}, d::CleverDict{K,V,F,I}) where {K,V,F,I} + return d +end +function Base.convert(::Type{CleverDict{K,V,F,I}}, src::AbstractDict{K,V}) where {K,V,F,I} + dest = CleverDict{K,V}()::CleverDict{K,V,F,I} + for key in sort(collect(keys(src)), by=dest.hash) + dest[key] = src[key] + end + return dest +end + end diff --git a/src/Utilities/copy.jl b/src/Utilities/copy.jl index 13a801e52a..11177724b8 100644 --- a/src/Utilities/copy.jl +++ b/src/Utilities/copy.jl @@ -87,8 +87,8 @@ _index_to_variable(i) = MOI.VariableIndex(i) const DenseVariableDict{V} = CleverDicts.CleverDict{ MOI.VariableIndex, V, - typeof(MOI.index_value), - typeof(_index_to_variable), + typeof(CleverDicts.key_to_index), + typeof(CleverDicts.index_to_key), } function dense_variable_dict(::Type{V}, n) where {V} return CleverDicts.CleverDict{MOI.VariableIndex,V}( diff --git a/src/Utilities/vector_of_constraints.jl b/src/Utilities/vector_of_constraints.jl index 9b8af523a0..25742e13ac 100644 --- a/src/Utilities/vector_of_constraints.jl +++ b/src/Utilities/vector_of_constraints.jl @@ -26,7 +26,7 @@ struct VectorOfConstraints{ MOI.ConstraintIndex{F,S}, Tuple{F,S}, typeof(CleverDicts.key_to_index), - Base.Fix1{typeof(CleverDicts.index_to_key),DataType} + typeof(CleverDicts.index_to_key), } function VectorOfConstraints{F,S}() where {F,S} diff --git a/test/Utilities/CleverDicts.jl b/test/Utilities/CleverDicts.jl index 0fa0d55193..56f9eb6eb5 100644 --- a/test/Utilities/CleverDicts.jl +++ b/test/Utilities/CleverDicts.jl @@ -249,4 +249,16 @@ CleverDicts.index_to_key(::Type{MyKey}, index::Int64) = MyKey(index) @test d[MathOptInterface.VariableIndex(0)] == "b" @test_throws ErrorException CleverDicts.add_item(d, "c") end + + @testset "convert" begin + vals = [MathOptInterface.VariableIndex(-i) for i in 1:10] + d = Dict(MathOptInterface.VariableIndex(i) => vals[i] for i in 1:10) + T = MathOptInterface.Utilities.DenseVariableDict{MathOptInterface.VariableIndex} + c = convert(T, d) + @test c isa T + @test c.is_dense + @test c.last_index == 10 + @test c.vector == vals + @test c === convert(T, c) + end end From 83da6ae0524de251377544c9a5646cbafbf4af7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Fri, 12 Mar 2021 22:09:57 +0100 Subject: [PATCH 3/3] Fix MethodError principle for convert --- src/Utilities/CleverDicts.jl | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Utilities/CleverDicts.jl b/src/Utilities/CleverDicts.jl index 953d12d7e2..bf08efd14d 100644 --- a/src/Utilities/CleverDicts.jl +++ b/src/Utilities/CleverDicts.jl @@ -384,11 +384,17 @@ function map_values!(f::Function, d::CleverDict) return end -function Base.convert(::Type{CleverDict{K,V,F,I}}, d::CleverDict{K,V,F,I}) where {K,V,F,I} +function Base.convert( + ::Type{CleverDict{K,V,typeof(key_to_index),typeof(index_to_key)}}, + d::CleverDict{K,V,typeof(key_to_index),typeof(index_to_key)}, +) where {K,V} return d end -function Base.convert(::Type{CleverDict{K,V,F,I}}, src::AbstractDict{K,V}) where {K,V,F,I} - dest = CleverDict{K,V}()::CleverDict{K,V,F,I} +function Base.convert( + ::Type{CleverDict{K,V,typeof(key_to_index),typeof(index_to_key)}}, + src::AbstractDict{K,V}, +) where {K,V} + dest = CleverDict{K,V}() for key in sort(collect(keys(src)), by=dest.hash) dest[key] = src[key] end