@@ -20,14 +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 }
23+ needs_final_touch:: Vector{Any }
2424
2525 function Map ()
2626 return new (
2727 Union{Nothing,AbstractBridge}[],
2828 Tuple{Type,Type}[],
2929 OrderedDict {Tuple{Int64,Type},AbstractBridge} (),
30- OrderedDict {Type,OrderedSet} () ,
30+ Any[] ,
3131 )
3232 end
3333end
@@ -78,6 +78,14 @@ function Base.getindex(
7878 return map. single_variable_constraints[(ci. value, S)]
7979end
8080
81+ function _unregister_for_final_touch (b:: Map , bridge)
82+ if MOI. Bridges. needs_final_touch (bridge)
83+ i = findfirst (== (bridge), b. needs_final_touch)
84+ deleteat! (b. needs_final_touch, i)
85+ end
86+ return
87+ end
88+
8189function Base. delete! (map:: Map , ci:: MOI.ConstraintIndex )
8290 _unregister_for_final_touch (map, map. bridges[_index (ci)]:: AbstractBridge )
8391 map. bridges[_index (ci)] = nothing
@@ -298,7 +306,6 @@ function add_key_for_bridge(
298306 :: S ,
299307 is_available:: Function ,
300308) where {F<: MOI.AbstractFunction ,S<: MOI.AbstractSet }
301- _register_for_final_touch (map, bridge)
302309 _ensure_available (map, F, S, is_available)
303310 push! (map. bridges, bridge)
304311 push! (map. constraint_types, (F, S))
@@ -312,39 +319,17 @@ function add_key_for_bridge(
312319 :: S ,
313320 :: Function ,
314321) where {S<: MOI.AbstractScalarSet }
315- _register_for_final_touch (map, bridge)
316322 map. single_variable_constraints[(func. value, S)] = bridge
317323 return MOI. ConstraintIndex {MOI.VariableIndex,S} (func. value)
318324end
319325
320- function _register_for_final_touch (map:: Map , bridge:: BT ) where {BT}
321- if MOI. Bridges. needs_final_touch (bridge)
322- if ! haskey (map. needs_final_touch, BT)
323- map. needs_final_touch[BT] = OrderedSet {BT} ()
324- end
325- push! (map. needs_final_touch[BT], bridge)
326- end
327- return
328- end
329-
330- function _unregister_for_final_touch (b:: Map , bridge:: BT ) where {BT}
331- if MOI. Bridges. needs_final_touch (bridge)
332- delete! (b. needs_final_touch[BT], bridge)
333- end
334- return
335- end
336-
337- # Function barrier to iterate over bridges of the same type in an efficient way.
338- function _final_touch (bridges, model)
339- for bridge in bridges
340- MOI. Bridges. final_touch (bridge, model)
341- end
342- return
343- end
344-
345326function MOI. Bridges. final_touch (map:: Map , model:: MOI.ModelLike )
346- for bridges in values (map. needs_final_touch)
347- _final_touch (bridges, model)
327+ # A bridge's `final_touch` may add a new bridge that needs `final_touch`,
328+ # but that's okay because it will push a new element to the end of
329+ # `map.needs_final_touch` and this iterator will keep going until it reaches
330+ # the end (because it's a `Base.Vector{Any}`).
331+ for bridge in map. needs_final_touch
332+ MOI. Bridges. final_touch (bridge, model)
348333 end
349334 return
350335end
0 commit comments