Skip to content

Commit c0f1719

Browse files
authored
More metadata for FileDFG and restore as saved (#1038)
* More metadata support for file dfg * getBlobEntryFirst for Variable
1 parent 6dce1d8 commit c0f1719

File tree

10 files changed

+126
-46
lines changed

10 files changed

+126
-46
lines changed

src/DataBlobs/services/BlobEntry.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,14 @@ function getBlobEntryFirst(var::AbstractDFGVariable, key::Regex)
114114
)
115115
end
116116

117+
function getBlobEntryFirst(var::Variable, key::Regex)
118+
firstIdx = findfirst(x->contains(string(x.label), key), var.blobEntries)
119+
if isnothing(firstIdx)
120+
throw(KeyError("$key"))
121+
end
122+
return var.blobEntries[firstIdx]
123+
end
124+
117125
getBlobEntry(var::AbstractDFGVariable, key::AbstractString) = getBlobEntry(var,Regex(key))
118126

119127
#TODO split betweeen getfirstBlobEntry and getBlobEntry

src/DistributedFactorGraphs.jl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,12 @@ include("entities/AbstractDFGSummary.jl")
347347

348348
include("services/AbstractDFG.jl")
349349

350+
#Blobs
351+
include("DataBlobs/services/BlobEntry.jl")
352+
include("DataBlobs/services/BlobStores.jl")
353+
include("DataBlobs/services/BlobPacking.jl")
354+
include("DataBlobs/services/HelpersDataWrapEntryBlob.jl")
355+
350356
# In Memory Types
351357
include("GraphsDFG/GraphsDFG.jl")
352358
@reexport using .GraphsDFGs
@@ -362,11 +368,6 @@ include("services/DFGVariable.jl")
362368
include("services/DFGFactor.jl")
363369
include("Deprecated.jl")
364370
include("services/CompareUtils.jl")
365-
#Blobs
366-
include("DataBlobs/services/BlobEntry.jl")
367-
include("DataBlobs/services/BlobStores.jl")
368-
include("DataBlobs/services/BlobPacking.jl")
369-
include("DataBlobs/services/HelpersDataWrapEntryBlob.jl")
370371

371372
# Include the FilesDFG API.
372373
include("FileDFG/FileDFG.jl")

src/FileDFG/services/FileDFG.jl

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,6 @@ function loadDFG!(dfgLoadInto::AbstractDFG, dst::AbstractString; overwriteDFGMet
149149
end
150150

151151
# extract the factor graph from fileDFG folder
152-
variables = DFGVariable[]
153152
factors = DFGFactor[]
154153
varFolder = "$folder/variables"
155154
factorFolder = "$folder/factors"
@@ -160,43 +159,62 @@ function loadDFG!(dfgLoadInto::AbstractDFG, dst::AbstractString; overwriteDFGMet
160159

161160
varFiles = sort(readdir(varFolder; sort=false); lt=natural_lt)
162161
factorFiles = sort(readdir(factorFolder; sort=false); lt=natural_lt)
163-
@showprogress 1 "loading variables" for varFile in varFiles
164-
jstr = read("$varFolder/$varFile", String)
165-
try
166-
packedData = JSON3.read(jstr, PackedVariable)
167-
push!(variables, unpackVariable(packedData))
168-
catch ex
169-
@error("JSON3 is having trouble reading $varFolder/$varFile into a PackedVariable")
170-
@show jstr
171-
throw(ex)
162+
163+
if isa(dfgLoadInto, GraphsDFG) && GraphsDFGs._variablestype(dfgLoadInto) == Variable
164+
variables = @showprogress 1 "loading variables" map(varFiles) do varFile
165+
jstr = read("$varFolder/$varFile", String)
166+
return JSON3.read(jstr, PackedVariable)
167+
end
168+
else
169+
variables = DFGVariable[]
170+
@showprogress 1 "loading variables" for varFile in varFiles
171+
jstr = read("$varFolder/$varFile", String)
172+
try
173+
packedData = JSON3.read(jstr, PackedVariable)
174+
push!(variables, unpackVariable(packedData))
175+
catch ex
176+
@error("JSON3 is having trouble reading $varFolder/$varFile into a PackedVariable")
177+
@show jstr
178+
throw(ex)
179+
end
172180
end
173181
end
174-
@info "Loaded $(length(variables)) variables - $(map(v->v.label, variables))"
182+
183+
@info "Loaded $(length(variables)) variables"#- $(map(v->v.label, variables))"
175184
@info "Inserting variables into graph..."
176185
# Adding variables
177186
map(v->addVariable!(dfgLoadInto, v), variables)
178187

179-
@showprogress 1 "loading factors" for factorFile in factorFiles
180-
jstr = read("$factorFolder/$factorFile", String)
181-
try
182-
packedData = JSON3.read(jstr, PackedFactor)
183-
push!(factors, unpackFactor(dfgLoadInto, packedData))
184-
catch ex
185-
@error("JSON3 is having trouble reading $factorFolder/$factorFile into a PackedFactor")
186-
@show jstr
187-
throw(ex)
188+
if isa(dfgLoadInto, GraphsDFG) && GraphsDFGs._factorstype(dfgLoadInto) == PackedFactor
189+
factors = @showprogress 1 "loading factors" map(factorFiles) do factorFile
190+
jstr = read("$factorFolder/$factorFile", String)
191+
return JSON3.read(jstr, PackedFactor)
192+
end
193+
else
194+
@showprogress 1 "loading factors" for factorFile in factorFiles
195+
jstr = read("$factorFolder/$factorFile", String)
196+
try
197+
packedData = JSON3.read(jstr, PackedFactor)
198+
push!(factors, unpackFactor(dfgLoadInto, packedData))
199+
catch ex
200+
@error("JSON3 is having trouble reading $factorFolder/$factorFile into a PackedFactor")
201+
@show jstr
202+
throw(ex)
203+
end
188204
end
189205
end
190-
@info "Loaded $(length(variables)) factors - $(map(f->f.label, factors))"
206+
@info "Loaded $(length(factors)) factors"# - $(map(f->f.label, factors))"
191207
@info "Inserting factors into graph..."
192208
# # Adding factors
193209
map(f->addFactor!(dfgLoadInto, f), factors)
194210

195-
# Finally, rebuild the CCW's for the factors to completely reinflate them
196-
# NOTE CREATES A NEW DFGFactor IF CCW TYPE CHANGES
197-
@info "Rebuilding CCW's for the factors..."
198-
@showprogress 1 "build factor operational memory" for factor in factors
199-
rebuildFactorMetadata!(dfgLoadInto, factor)
211+
if isa(dfgLoadInto, GraphsDFG) && GraphsDFGs._factorstype(dfgLoadInto) != PackedFactor
212+
# Finally, rebuild the CCW's for the factors to completely reinflate them
213+
# NOTE CREATES A NEW DFGFactor IF CCW TYPE CHANGES
214+
@info "Rebuilding CCW's for the factors..."
215+
@showprogress 1 "build factor operational memory" for factor in factors
216+
rebuildFactorMetadata!(dfgLoadInto, factor)
217+
end
200218
end
201219

202220
# remove the temporary unzipped file

src/GraphsDFG/entities/GraphsDFG.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ mutable struct GraphsDFG{T <: AbstractParams, V <: AbstractDFGVariable, F <:Abst
2121
sessionBlobEntries::OrderedDict{Symbol, BlobEntry}
2222
addHistory::Vector{Symbol} #TODO: Discuss more - is this an audit trail?
2323
solverParams::T # Solver parameters
24-
blobStores::Dict{Symbol, <:AbstractBlobStore}
24+
blobStores::Dict{Symbol, AbstractBlobStore}
2525
end
2626

2727
"""
@@ -46,7 +46,7 @@ function GraphsDFG{T,V,F}(
4646
sessionBlobEntries::OrderedDict{Symbol, BlobEntry} = OrderedDict{Symbol, BlobEntry}(),
4747
addHistory::Vector{Symbol} = Symbol[],
4848
solverParams::T=T(),
49-
blobstores=Dict{Symbol, AbstractBlobStore}(),
49+
blobStores=Dict{Symbol, AbstractBlobStore}(),
5050
) where {T <: AbstractParams, V <:AbstractDFGVariable, F<:AbstractDFGFactor}
5151
# Validate the userLabel, robotLabel, and sessionLabel
5252
!isValidLabel(userLabel) && error("'$userLabel' is not a valid User label")
@@ -67,7 +67,7 @@ function GraphsDFG{T,V,F}(
6767
sessionBlobEntries,
6868
addHistory,
6969
solverParams,
70-
blobstores
70+
blobStores
7171
)
7272
end
7373

@@ -92,7 +92,7 @@ GraphsDFG(
9292
robotData::Dict{Symbol, SmallDataTypes},
9393
sessionData::Dict{Symbol, SmallDataTypes},
9494
solverParams::AbstractParams,
95-
blobstores=Dict{Symbol, AbstractBlobStore}()
95+
blobStores=Dict{Symbol, AbstractBlobStore}()
9696
) = GraphsDFG{typeof(solverParams),DFGVariable,DFGFactor}(
9797
FactorGraph{Int,DFGVariable,DFGFactor}();
9898
description,
@@ -103,7 +103,7 @@ GraphsDFG(
103103
robotData,
104104
sessionData,
105105
solverParams,
106-
blobstores
106+
blobStores
107107
)
108108

109109

@@ -116,7 +116,7 @@ function GraphsDFG{T,V,F}(
116116
robotData::Dict{Symbol, SmallDataTypes},
117117
sessionData::Dict{Symbol, SmallDataTypes},
118118
solverParams::T,
119-
blobstores=Dict{Symbol, AbstractBlobStore}()
119+
blobStores=Dict{Symbol, AbstractBlobStore}()
120120
) where {T <: AbstractParams, V <:AbstractDFGVariable, F<:AbstractDFGFactor}
121121
return GraphsDFG{T,V,F}(
122122
FactorGraph{Int,V,F}();
@@ -128,6 +128,6 @@ function GraphsDFG{T,V,F}(
128128
robotData,
129129
sessionData,
130130
solverParams,
131-
blobstores
131+
blobStores
132132
)
133133
end

src/GraphsDFG/services/GraphsDFG.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11

2+
function getDFGMetadata(fg::GraphsDFG)
3+
metafields = Set(fieldnames(GraphsDFG))
4+
setdiff!(metafields, [:g, :solverParams])
5+
metaprops = NamedTuple(k => getproperty(fg, k) for k in metafields)
6+
return metaprops
7+
end
28

39
function exists(dfg::GraphsDFG{P,V,F}, node::V) where {P <: AbstractParams, V <: AbstractDFGVariable, F <: AbstractDFGFactor}
410
return haskey(dfg.g.variables, node.label)

src/GraphsDFG/services/GraphsDFGSerialization.jl

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ using InteractiveUtils
1414
addHistory::Vector{Symbol}
1515
solverParams::T
1616
solverParams_type::String = string(typeof(solverParams))
17-
#TODO
18-
# blobStores::Dict{Symbol, AbstractBlobStore}
17+
# TODO remove Union.Nothing in DFG v0.24
18+
typePackedVariable::Union{Nothing,Bool} = false # Are variables packed or full
19+
typePackedFactor::Union{Nothing,Bool} = false # Are factors packed or full
20+
blobStores::Union{Nothing, Dict{Symbol, FolderStore{Vector{UInt8}}}}
1921
end
2022

2123
StructTypes.StructType(::Type{PackedGraphsDFG}) = StructTypes.AbstractType()
@@ -27,25 +29,60 @@ function StructTypes.subtypes(::Type{PackedGraphsDFG})
2729
NamedTuple(map(s->Symbol(s)=>PackedGraphsDFG{s}, subs))
2830
end
2931

32+
_variablestype(fg::GraphsDFG{<:AbstractParams,T,<:AbstractDFGFactor}) where T = T
33+
_factorstype(fg::GraphsDFG{<:AbstractParams,<:AbstractDFGVariable, T}) where T = T
34+
3035
##
3136
"""
3237
$(SIGNATURES)
3338
Packing function to serialize DFG metadata from.
3439
"""
3540
function packDFGMetadata(fg::GraphsDFG)
3641
commonfields = intersect(fieldnames(PackedGraphsDFG), fieldnames(GraphsDFG))
42+
43+
setdiff!(commonfields, [:blobStores])
44+
blobStores = Dict{Symbol, FolderStore{Vector{UInt8}}}()
45+
foreach(values(fg.blobStores)) do store
46+
if store isa FolderStore{Vector{UInt8}}
47+
blobStores[store.key] = store
48+
else
49+
@warn "BlobStore $(store.key) of type $(typeof(store)) is not supported yet and will not be saved"
50+
end
51+
end
52+
3753
props = (k => getproperty(fg, k) for k in commonfields)
38-
return PackedGraphsDFG(;props...)
54+
return PackedGraphsDFG(;
55+
typePackedVariable = _variablestype(fg) == Variable,
56+
typePackedFactor = _factorstype(fg) == PackedFactor,
57+
blobStores,
58+
props...
59+
)
3960
end
4061

4162
function unpackDFGMetadata(packed::PackedGraphsDFG)
4263
commonfields = intersect(fieldnames(GraphsDFG), fieldnames(PackedGraphsDFG))
64+
65+
#FIXME Deprecate remove in DFG v0.24
66+
setdiff!(commonfields, [:blobStores])
67+
blobStores = Dict{Symbol, AbstractBlobStore}()
68+
!isnothing(packed.blobStores) && merge!(blobStores, packed.blobStores)
69+
4370
props = (k => getproperty(packed, k) for k in commonfields)
44-
GraphsDFG(;props...)
71+
72+
VT = isnothing(packed.typePackedVariable) || !packed.typePackedVariable ? DFGVariable : Variable
73+
FT = isnothing(packed.typePackedFactor) || !packed.typePackedFactor ? DFGFactor : PackedFactor
74+
# VT = isnothing(packed.typePackedVariable) || packed.typePackedVariable ? Variable : DFGVariable
75+
# FT = isnothing(packed.typePackedFactor) || packed.typePackedFactor ? PackedFactor : DFGFactor
76+
GraphsDFG{typeof(packed.solverParams), VT, FT}(;blobStores, props...)
4577
end
4678

4779
function unpackDFGMetadata!(dfg::GraphsDFG, packed::PackedGraphsDFG)
4880
commonfields = intersect(fieldnames(GraphsDFG), fieldnames(PackedGraphsDFG))
81+
82+
#FIXME Deprecate remove Nothing union in DFG v0.24
83+
setdiff!(commonfields, [:blobStores])
84+
!isnothing(packed.blobStores) && merge!(dfg.blobStores, packed.blobStores)
85+
4986
props = (k => getproperty(packed, k) for k in commonfields)
5087
foreach(props) do (k,v)
5188
setproperty!(dfg, k, v)

src/services/AbstractDFG.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1266,7 +1266,7 @@ function mergeVariableData!(dfg::AbstractDFG, sourceVariable::AbstractDFGVariabl
12661266
:solverDataDict in fieldnames(typeof(var)) && mergeVariableSolverData!(var, sourceVariable)
12671267

12681268
#update if its not a InMemoryDFGTypes, otherwise it was a reference
1269-
# if satelite nodes are used it can be updated seprarately
1269+
# if satelite nodes are used it can be updated separately
12701270
# !(isa(dfg, InMemoryDFGTypes)) && updateVariable!(dfg, var)
12711271

12721272
return var

src/services/DFGFactor.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ Get the variable ordering for this factor.
118118
Should be equivalent to listNeighbors unless something was deleted in the graph.
119119
"""
120120
getVariableOrder(fct::DFGFactor) = fct._variableOrderSymbols::Vector{Symbol}
121+
getVariableOrder(fct::PackedFactor) = fct._variableOrderSymbols::Vector{Symbol}
121122
getVariableOrder(dfg::AbstractDFG, fct::Symbol) = getVariableOrder(getFactor(dfg, fct))
122123

123124
##------------------------------------------------------------------------------

src/services/DFGVariable.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,8 @@ Note: Rather use SmallData CRUD
450450
"""
451451
getSmallData(v::DFGVariable) = v.smallData
452452

453+
getSmallData(v::Variable) = JSON3.read(base64decode(v.metadata))
454+
453455
"""
454456
$(SIGNATURES)
455457
Set the small data for a variable.

src/services/Serialization.jl

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ end
162162
## Variable Packing and unpacking
163163
##==============================================================================
164164

165-
function packVariable(v::AbstractDFGVariable; includePPEs::Bool=true, includeSolveData::Bool=true, includeDataEntries::Bool=true)
165+
function packVariable(v::DFGVariable; includePPEs::Bool=true, includeSolveData::Bool=true, includeDataEntries::Bool=true)
166166
return PackedVariable(;
167167
id=v.id,
168168
label = v.label,
@@ -177,7 +177,11 @@ function packVariable(v::AbstractDFGVariable; includePPEs::Bool=true, includeSol
177177
blobEntries = collect(values(v.dataDict)),
178178
_version = string(DFG._getDFGVersion()))
179179
end
180-
180+
181+
function packVariable(v::Variable; includePPEs::Bool=true, includeSolveData::Bool=true, includeDataEntries::Bool=true)
182+
return v
183+
end
184+
181185
function unpackVariable(variable::PackedVariable; skipVersionCheck::Bool=false)
182186
!skipVersionCheck && _versionCheck(variable)
183187

@@ -205,8 +209,9 @@ function unpackVariable(variable::PackedVariable; skipVersionCheck::Bool=false)
205209
smallData=metadata,
206210
dataDict=dataDict,
207211
solvable=variable.solvable )
208-
end
212+
end
209213

214+
DFGVariable(v::Variable) = unpackVariable(v)
210215

211216
##==============================================================================
212217
## Factor Packing and unpacking
@@ -250,6 +255,8 @@ function packFactor(f::DFGFactor)
250255
return props
251256
end
252257

258+
packFactor(f::PackedFactor) = f
259+
253260
function reconstFactorData end
254261

255262
function decodePackedType(dfg::AbstractDFG, varOrder::AbstractVector{Symbol}, ::Type{T}, packeddata::GenericFunctionNodeData{PT}) where {T<:FactorOperationalMemory, PT}

0 commit comments

Comments
 (0)