Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions src/InfrastructureSystems.jl
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,10 @@ Required interface functions for subtypes:

Optional interface functions:

- get_uuid()
- [`get_id`](@ref)
- [`supports_time_series`](@ref)

Subtypes may contain time series. Which requires

- `supports_time_series(::SupplementalAttribute)`

All subtypes must include an instance of ComponentUUIDs in order to track
All subtypes must include an instance of [`ComponentIDs`](@ref) in order to track
components attached to each attribute.
Comment on lines +111 to 112
"""
abstract type SupplementalAttribute <: InfrastructureSystemsType end
Expand Down Expand Up @@ -182,7 +179,7 @@ include("static_time_series.jl")
include("time_series_parameters.jl")
include("containers.jl")
include("component_container.jl")
include("component_uuids.jl")
include("component_ids.jl")
include("geographic_supplemental_attribute.jl")
include("generated/includes.jl")
include("time_series_parser.jl")
Expand Down
37 changes: 23 additions & 14 deletions src/component.jl
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
"""
Assign a new UUID to the component.
Assign a new integer ID to the component, drawn from the system counter, and update any
references to its old ID in the time series metadata store, supplemental attribute
associations, and subsystem membership sets.
"""
function assign_new_uuid_internal!(component::InfrastructureSystemsComponent)
old_uuid = get_uuid(component)
new_uuid = make_uuid()
function assign_new_id_internal!(data, component::InfrastructureSystemsComponent)
old_id = get_id(component)
new_id = get_next_component_id!(data)
mgr = get_time_series_manager(component)
if !isnothing(mgr)
replace_component_uuid!(mgr.metadata_store, old_uuid, new_uuid)
replace_component_id!(mgr.metadata_store, old_id, new_id)
end

associations = _get_supplemental_attribute_associations(component)
if !isnothing(associations)
replace_component_uuid!(associations, old_uuid, new_uuid)
replace_component_id!(associations, old_id, new_id)
end

set_uuid!(get_internal(component), new_uuid)
for ids in values(data.subsystems)
if old_id in ids
pop!(ids, old_id)
push!(ids, new_id)
end
end

set_id!(get_internal(component), new_id)
return
end

Expand Down Expand Up @@ -47,8 +56,8 @@ end
function clear_supplemental_attributes!(component::InfrastructureSystemsComponent)
mgr = _get_supplemental_attributes_manager(component)
isnothing(mgr) && return
for uuid in list_associated_supplemental_attribute_uuids(mgr.associations, component)
attribute = get_supplemental_attribute(mgr, uuid)
for id in list_associated_supplemental_attribute_ids(mgr.associations, component)
attribute = get_supplemental_attribute(mgr, id)
remove_supplemental_attribute!(mgr, component, attribute)
end
@debug "Cleared attributes in $(summary(component))."
Expand Down Expand Up @@ -85,7 +94,7 @@ function _get_supplemental_attributes(
isnothing(mgr) && return supplemental_attribute_type[]
return supplemental_attribute_type[
get_supplemental_attribute(mgr, x) for
x in list_associated_supplemental_attribute_uuids(
x in list_associated_supplemental_attribute_ids(
mgr.associations,
component,
supplemental_attribute_type,
Expand Down Expand Up @@ -116,12 +125,12 @@ function _get_supplemental_attributes(
mgr = _get_supplemental_attributes_manager(component)
isnothing(mgr) && return [supplemental_attribute_type]
attrs = Vector{supplemental_attribute_type}()
for uuid in list_associated_supplemental_attribute_uuids(
for id in list_associated_supplemental_attribute_ids(
mgr.associations,
component,
supplemental_attribute_type,
)
attribute = get_supplemental_attribute(mgr, uuid)
attribute = get_supplemental_attribute(mgr, id)
if filter_func(attribute)
push!(attrs, attribute)
end
Expand All @@ -132,12 +141,12 @@ end

function get_supplemental_attribute(
component::InfrastructureSystemsComponent,
uuid::Base.UUID,
id::Int,
)
mgr = _get_supplemental_attributes_manager(component)
isnothing(mgr) &&
error("$(summary(component)) does not have supplemental attributes")
return get_supplemental_attribute(mgr, uuid)
return get_supplemental_attribute(mgr, id)
end

function _get_supplemental_attributes_manager(component::InfrastructureSystemsComponent)
Expand Down
39 changes: 39 additions & 0 deletions src/component_ids.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# This is an abstraction of a Set in order to enable de-serialization of supplemental
# attributes.

"""
Set-like storage of component integer ids attached to a [`SupplementalAttribute`](@ref).

Supplemental attribute subtypes include a `ComponentIDs` field so associations can be
tracked and serialized without storing full component references.
"""
struct ComponentIDs <: InfrastructureSystemsType
ids::Set{Int}

function ComponentIDs(ids = Set{Int}())
new(ids)
end
end

Base.copy(x::ComponentIDs) = copy(x.ids)
Base.delete!(x::ComponentIDs, id) = delete!(x.ids, id)
Base.empty!(x::ComponentIDs) = empty!(x.ids)
Base.filter!(f, x::ComponentIDs) = filter!(f, x.ids)
Base.in(x, y::ComponentIDs) = in(x, y.ids)
Base.isempty(x::ComponentIDs) = isempty(x.ids)
Base.iterate(x::ComponentIDs, args...) = iterate(x.ids, args...)
Base.length(x::ComponentIDs) = length(x.ids)
Base.pop!(x::ComponentIDs) = pop!(x.ids)
Base.pop!(x::ComponentIDs, y) = pop!(x.ids, y)
Base.pop!(x::ComponentIDs, y, default) = pop!(x.ids, y, default)
Base.push!(x::ComponentIDs, y) = push!(x.ids, y)
Base.setdiff!(x::ComponentIDs, y::ComponentIDs) = setdiff!(x.ids, y.ids)
Base.sizehint!(x::ComponentIDs, newsz) = sizehint!(x.ids, newsz)

function deserialize(::Type{ComponentIDs}, data::Dict)
ids = Set{Int}()
for id in data["ids"]
push!(ids, Int(id))
end
return ComponentIDs(ids)
end
33 changes: 0 additions & 33 deletions src/component_uuids.jl

This file was deleted.

8 changes: 4 additions & 4 deletions src/components.jl
Original file line number Diff line number Diff line change
Expand Up @@ -315,18 +315,18 @@ See also: [`iterate_components`](@ref)
function get_components(
::Type{T},
components::Components;
component_uuids::Union{Nothing, Set{Base.UUID}} = nothing,
component_ids::Union{Nothing, Set{Int}} = nothing,
) where {T <: InfrastructureSystemsComponent}
return iterate_instances(T, components.data, component_uuids)
return iterate_instances(T, components.data, component_ids)
end

function get_components(
filter_func::Function,
::Type{T},
components::Components;
component_uuids::Union{Nothing, Set{Base.UUID}} = nothing,
component_ids::Union{Nothing, Set{Int}} = nothing,
) where {T <: InfrastructureSystemsComponent}
return iterate_instances(filter_func, T, components.data, component_uuids)
return iterate_instances(filter_func, T, components.data, component_ids)
end

"""
Expand Down
44 changes: 39 additions & 5 deletions src/internal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,31 +28,46 @@ deserialize(T::Type{<:SystemUnitsSettings}, val::Dict) = deserialize_struct(T, v
end

"""
Internal storage common to InfrastructureSystems types.
Sentinel value for the integer `id` of a component or supplemental attribute that has not
yet been attached to a [`SystemData`](@ref). Assigned IDs start at 1.
"""
const UNASSIGNED_ID = 0

"""
Internal storage common to [`InfrastructureSystemsType`](@ref)s.

Components and supplemental attributes are identified by an integer `id` assigned by the
owning [`SystemData`](@ref) when they are attached (see [`get_id`](@ref)); it is
[`UNASSIGNED_ID`](@ref) until then. The `uuid` is retained for time series, whose content
and metadata are still identified by UUID. Each instance also holds optional
[`SharedSystemReferences`](@ref) when attached to a system, optional unit metadata, and an
optional user extension dictionary accessed through [`get_ext`](@ref).
"""
mutable struct InfrastructureSystemsInternal <: InfrastructureSystemsType
id::Int
uuid::Base.UUID
shared_system_references::Union{Nothing, SharedSystemReferences}
units_info::Union{Nothing, SystemUnitsSettings}
ext::Union{Nothing, Dict{String, Any}}
end

"""
Creates InfrastructureSystemsInternal with a new UUID.
Creates InfrastructureSystemsInternal with a new UUID and an unassigned integer ID.
"""
InfrastructureSystemsInternal(;
id = UNASSIGNED_ID,
uuid = make_uuid(),
shared_system_references = nothing,
units_info = nothing,
ext = nothing,
) =
InfrastructureSystemsInternal(uuid, shared_system_references, units_info, ext)
InfrastructureSystemsInternal(id, uuid, shared_system_references, units_info, ext)

"""
Creates InfrastructureSystemsInternal with an existing UUID.
"""
InfrastructureSystemsInternal(u::Base.UUID) =
InfrastructureSystemsInternal(u, nothing, nothing, nothing)
InfrastructureSystemsInternal(UNASSIGNED_ID, u, nothing, nothing, nothing)

"""
Return a user-modifiable dictionary to store extra information.
Expand All @@ -76,6 +91,9 @@ end
get_uuid(internal::InfrastructureSystemsInternal) = internal.uuid
set_uuid!(internal::InfrastructureSystemsInternal, uuid) = internal.uuid = uuid

get_id(internal::InfrastructureSystemsInternal) = internal.id
set_id!(internal::InfrastructureSystemsInternal, id::Int) = internal.id = id

function set_shared_system_references!(
internal::InfrastructureSystemsInternal,
refs::Union{Nothing, SharedSystemReferences},
Expand All @@ -94,6 +112,22 @@ function get_uuid(obj::InfrastructureSystemsType)
return get_internal(obj).uuid
end

"""
Get the integer id of a component or supplemental attribute. Returns [`UNASSIGNED_ID`](@ref)
if the object has not been attached to a [`SystemData`](@ref).
"""
function get_id(obj::InfrastructureSystemsType)
return get_internal(obj).id
end

"""
Set the integer ID of a component or supplemental attribute.
"""
function set_id!(obj::InfrastructureSystemsType, id::Int)
set_id!(get_internal(obj), id)
return
end

"""
Assign a new UUID.
"""
Expand Down Expand Up @@ -139,7 +173,7 @@ function compare_values(
)
match = true
for name in fieldnames(InfrastructureSystemsInternal)
if name in exclude || (name == :uuid && !compare_uuids) ||
if name in exclude || (name in (:uuid, :id) && !compare_uuids) ||
name == :shared_system_references
continue
end
Expand Down
10 changes: 5 additions & 5 deletions src/iterators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@ function iterate_instances(
filter_func::Function,
::Type{T},
data::_ContainerTypes,
uuids::Set{Base.UUID},
ids::Set{Int},
) where {T <: InfrastructureSystemsType}
func_uuids = x -> get_uuid(x) in uuids
_filter_func = x -> filter_func(x) && func_uuids(x)
func_ids = x -> get_id(x) in ids
_filter_func = x -> filter_func(x) && func_ids(x)
return iterate_instances(_filter_func, T, data, nothing)
end

function iterate_instances(
::Type{T},
data::_ContainerTypes,
uuids::Set{Base.UUID},
ids::Set{Int},
) where {T <: InfrastructureSystemsType}
filter_func = x -> get_uuid(x) in uuids
filter_func = x -> get_id(x) in ids
return iterate_instances(filter_func, T, data, nothing)
end

Expand Down
Loading
Loading