@@ -20,12 +20,14 @@ struct Map <: AbstractDict{MOI.ConstraintIndex,AbstractBridge}
2020 # of creation so we need `OrderedDict` and not `Dict`.
2121 # For `VariableIndex` constraints: (variable, set type) -> bridge
2222 single_variable_constraints:: OrderedDict{Tuple{Int64,Type},AbstractBridge}
23+ needs_final_touch:: OrderedDict{Type,OrderedSet}
2324
2425 function Map ()
2526 return new (
2627 Union{Nothing,AbstractBridge}[],
2728 Tuple{Type,Type}[],
2829 OrderedDict {Tuple{Int64,Type},AbstractBridge} (),
30+ OrderedDict {Type,OrderedSet} (),
2931 )
3032 end
3133end
@@ -48,6 +50,7 @@ function Base.empty!(map::Map)
4850 empty! (map. bridges)
4951 empty! (map. constraint_types)
5052 empty! (map. single_variable_constraints)
53+ empty! (map. needs_final_touch)
5154 return map
5255end
5356
@@ -83,6 +86,7 @@ function Base.getindex(
8386end
8487
8588function Base. delete! (map:: Map , ci:: MOI.ConstraintIndex )
89+ _unregister_for_final_touch (map, map. bridges[_index (ci)])
8690 map. bridges[_index (ci)] = nothing
8791 return map
8892end
@@ -91,6 +95,8 @@ function Base.delete!(
9195 map:: Map ,
9296 ci:: MOI.ConstraintIndex{MOI.VariableIndex,S} ,
9397) where {S}
98+ bridge = map. single_variable_constraints[(ci. value, S)]
99+ _unregister_for_final_touch (map, bridge)
94100 delete! (map. single_variable_constraints, (ci. value, S))
95101 return map
96102end
@@ -278,6 +284,7 @@ function add_key_for_bridge(
278284 :: F ,
279285 :: S ,
280286) where {F<: MOI.AbstractFunction ,S<: MOI.AbstractSet }
287+ _register_for_final_touch (map, bridge)
281288 push! (map. bridges, bridge)
282289 push! (map. constraint_types, (F, S))
283290 return _index (length (map. bridges), F, S)
@@ -289,10 +296,40 @@ function add_key_for_bridge(
289296 func:: MOI.VariableIndex ,
290297 :: S ,
291298) where {S<: MOI.AbstractScalarSet }
299+ _register_for_final_touch (map, bridge)
292300 map. single_variable_constraints[(func. value, S)] = bridge
293301 return MOI. ConstraintIndex {MOI.VariableIndex,S} (func. value)
294302end
295303
304+ function _register_for_final_touch (map:: Map , bridge)
305+ if MOI. Bridges. needs_final_touch (bridge)
306+ if ! haskey (map. needs_final_touch, typeof (bridge))
307+ map. needs_final_touch[typeof (bridge)] = OrderedSet {typeof(bridge)} ()
308+ end
309+ push! (map. needs_final_touch[typeof (bridge)], bridge)
310+ end
311+ return
312+ end
313+ function _unregister_for_final_touch (b:: Map , bridge)
314+ if MOI. Bridges. needs_final_touch (bridge)
315+ delete! (b. needs_final_touch[typeof (bridge)], bridge)
316+ end
317+ return
318+ end
319+
320+ # function barrier to iterate over bridges of the same type in an efficient way
321+ function _final_touch (bridges)
322+ for bridge in bridges
323+ MOI. Utilities. final_touch (bridge)
324+ end
325+ end
326+
327+ function MOI. Utilities. final_touch (map:: Map )
328+ for bridges in values (map. needs_final_touch)
329+ _final_touch (bridges)
330+ end
331+ end
332+
296333"""
297334 EmptyMap <: AbstractDict{MOI.ConstraintIndex, AbstractBridge}
298335
@@ -315,3 +352,5 @@ Base.values(::EmptyMap) = MOI.Utilities.EmptyVector{AbstractBridge}()
315352has_bridges (:: EmptyMap ) = false
316353
317354number_of_type (:: EmptyMap , :: Type{<:MOI.ConstraintIndex} ) = 0
355+
356+ MOI. Utilities. final_touch (:: EmptyMap ) = nothing
0 commit comments