Skip to content

Commit 2af6855

Browse files
committed
Refactor GraphsDFG serialization (loadDFG, saveDFG)
1 parent 51c8980 commit 2af6855

File tree

9 files changed

+112
-234
lines changed

9 files changed

+112
-234
lines changed

src/DataBlobs/entities/BlobStores.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,8 @@ Design goal: all `Blobstore`s with the same `label` can contain the same `blobid
3030
"""
3131
abstract type AbstractBlobstore{T} end
3232
const Blobstore = AbstractBlobstore
33+
34+
function StructUtils.lower(::StructUtils.StructStyle, store::AbstractBlobstore)
35+
return StructUtils.lower(Packed(store))
36+
end
37+
@choosetype AbstractBlobstore resolvePackedType

src/DataBlobs/services/BlobStores.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ struct FolderStore{T} <: AbstractBlobstore{T}
129129
folder::String
130130
end
131131

132+
FolderStore(label::Symbol, folder::String) = FolderStore{Vector{UInt8}}(label, folder)
133+
132134
function FolderStore(foldername::String; label::Symbol = :default, createfolder = true)
133135
storepath = joinpath(foldername, string(label))
134136
if createfolder && !isdir(storepath)

src/DistributedFactorGraphs.jl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,13 +249,14 @@ export GraphsDFG
249249
# export listVariableMetadata, listFactorMetadata, listAgentMetadata, listGraphMetadata
250250
# export listVariableBlobentryMetadata, listFactorBlobentryMetadata, listAgentBlobentryMetadata, listGraphBlobentryMetadata
251251

252+
export deleteVariables!
253+
export deleteFactors!
252254
##==============================================================================
253255
## Common Accessors
254256
##==============================================================================
255257
export getLabel
256258

257-
# might only be public
258-
export getId
259+
public getId
259260

260261
##==============================================================================
261262
## Internal or not yet ready
@@ -285,7 +286,7 @@ export mergeAgentTags!
285286
public listTags
286287
public mergeTags!
287288
public emptyTags!
288-
public deleteTags! #TODO do we want this one
289+
public deleteTags!
289290

290291
##------------------------------------------------------------------------------
291292
## Bloblets
@@ -574,9 +575,11 @@ include("DataBlobs/services/BlobStores.jl")
574575
include("DataBlobs/services/BlobPacking.jl")
575576
include("DataBlobs/services/BlobWrappers.jl")
576577

578+
#FIXME
577579
function getSolvable end
578580
function getVariableType end
579581
function isInitialized end
582+
function listTags end
580583
# In Memory Types
581584
include("GraphsDFG/GraphsDFG.jl")
582585
using .GraphsDFGs

src/FileDFG/services/FileDFG.jl

Lines changed: 62 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ v1 = addVariable!(dfg, :a, ContinuousScalar, tags = [:POSE], solvable=0)
1616
saveDFG(dfg, "/tmp/saveDFG.tar.gz")
1717
```
1818
"""
19-
function saveDFG(folder::AbstractString, dfg::AbstractDFG; saveMetadata::Bool = true)
19+
function saveDFG(folder::AbstractString, dfg::AbstractDFG)
2020

2121
# TODO: Deprecate the folder functionality
2222

@@ -47,13 +47,18 @@ function saveDFG(folder::AbstractString, dfg::AbstractDFG; saveMetadata::Bool =
4747
@showprogress "saving factors" for f in factors
4848
JSON.json("$factorFolder/$(f.label).json", f; style = DFGJSONStyle())
4949
end
50-
#GraphsDFG metadata
51-
if saveMetadata
52-
@assert isa(dfg, GraphsDFG) "only metadata for GraphsDFG are supported"
53-
@info "saving dfg metadata"
54-
fgPacked = GraphsDFGs.packDFGMetadata(dfg)
55-
JSON.json("$savepath/dfg.json", fgPacked; style = DFGJSONStyle())
56-
end
50+
51+
#GraphsDFG nodes
52+
@assert isa(dfg, GraphsDFG) "only metadata for GraphsDFG are supported"
53+
p = Progress(4, "Saving DFG Nodes")
54+
JSON.json("$savepath/graphroot.json", dfg.graph; style = DFGJSONStyle())
55+
next!(p)
56+
JSON.json("$savepath/agent.json", dfg.agent; style = DFGJSONStyle())
57+
next!(p)
58+
JSON.json("$savepath/solverparams.json", dfg.solverParams; style = DFGJSONStyle())
59+
next!(p)
60+
JSON.json("$savepath/blobstores.json", dfg.blobStores; style = DFGJSONStyle())
61+
next!(p)
5762

5863
savedir = dirname(savepath) # is this a path of just local name? #344 -- workaround with unique names
5964
savename = basename(string(savepath))
@@ -93,94 +98,43 @@ ls(dfg)
9398
See also: [`loadDFG`](@ref), [`saveDFG`](@ref)
9499
"""
95100
function loadDFG!(
96-
dfgLoadInto::AbstractDFG,
97-
dst::AbstractString;
98-
overwriteDFGMetadata::Bool = true,
99-
)
100-
#
101-
# loaddir gets deleted so needs to be unique
102-
loaddir = split(joinpath("/", "tmp", "caesar", "random", string(uuid1())), '-')[1]
103-
# Check if zipped destination (dst) by first doing fuzzy search from user supplied dst
104-
folder = dst # working directory for fileDFG variable and factor operations
105-
dstname = dst # path name could either be legacy FileDFG dir or .tar.gz file of FileDFG files.
106-
unzip = false
101+
dfgLoadInto::AbstractDFG{V, F},
102+
file::AbstractString;
103+
# overwriteDFGMetadata::Bool = true,
104+
) where {V <: AbstractGraphVariable, F <: AbstractGraphFactor}
107105
# add if doesn't have .tar.gz extension
108-
lastdirname = splitpath(dstname)[end]
109-
if !isdir(dst)
110-
unzip = true
111-
sdst = split(lastdirname, '.')
112-
if sdst[end] != "gz" # length(sdst) == 1 &&
113-
dstname *= ".tar.gz"
114-
lastdirname *= ".tar.gz"
115-
end
106+
if !contains(basename(file), ".tar.gz")
107+
file *= ".tar.gz"
116108
end
117109
# check the file actually exists
118-
@assert isfile(dstname) "cannot find file $dstname"
119-
# TODO -- what if it is not a tar.gz but classic folder instead?
120-
# do actual unzipping
121-
filename = lastdirname[1:(end - length(".tar.gz"))] |> string
122-
if unzip
123-
Base.mkpath(loaddir)
124-
folder = joinpath(loaddir, filename)
125-
@debug "loadDFG! detected a gzip $dstname -- unpacking via $loaddir now..."
126-
Base.rm(folder; recursive = true, force = true)
127-
# unzip the tar file
128-
tar_gz = open(dstname)
129-
tar = CodecZlib.GzipDecompressorStream(tar_gz)
130-
Tar.extract(tar, folder)
131-
close(tar)
132-
#or for non-compressed
133-
# Tar.extract(dstname, folder)
134-
end
110+
@assert isfile(file) "cannot find file $file"
135111

136-
#GraphsDFG metadata
137-
if overwriteDFGMetadata
138-
@assert isa(dfgLoadInto, GraphsDFG) "Only GraphsDFG metadata are supported"
139-
@info "loading dfg metadata"
140-
jstr = read("$folder/dfg.json", String)
141-
fgPacked = JSON.parse(jstr, GraphsDFGs.PackedGraphsDFG; style = DFGJSONStyle())
142-
GraphsDFGs.unpackDFGMetadata!(dfgLoadInto, fgPacked)
143-
end
112+
# only extract the json files needed for the variables and factors
113+
tar_gz = open(file)
114+
tar = CodecZlib.GzipDecompressorStream(tar_gz)
115+
dfgnodenames = r"^(factors|variables)"
116+
loaddir = Tar.extract(hdr -> contains(hdr.path, dfgnodenames), tar)
117+
close(tar)
144118

145119
# extract the factor graph from fileDFG folder
146-
factors = FactorDFG[]
147-
varFolder = "$folder/variables"
148-
factorFolder = "$folder/factors"
149-
# Folder preparations
150-
!isdir(folder) && error("Can't load DFG graph - folder '$folder' doesn't exist")
151-
!isdir(varFolder) && error("Can't load DFG graph - folder '$varFolder' doesn't exist")
152-
!isdir(factorFolder) &&
153-
error("Can't load DFG graph - folder '$factorFolder' doesn't exist")
154-
155-
# varFiles = sort(readdir(varFolder; sort = false); lt = natural_lt)
156-
# factorFiles = sort(readdir(factorFolder; sort = false); lt = natural_lt)
157-
varFiles = readdir(varFolder; sort = false)
158-
factorFiles = readdir(factorFolder; sort = false)
159-
160-
# FIXME, why is this treated different from VariableSkeleton, VariableSummary?
120+
variablefiles = readdir(joinpath(loaddir, "variables"); sort = false, join = true)
161121

162-
usePackedVariable =
163-
isa(dfgLoadInto, GraphsDFG) && getTypeDFGVariables(dfgLoadInto) == VariableDFG
164122
# type instability on `variables` as either `::Vector{Variable}` or `::Vector{VariableCompute{<:}}` (vector of abstract)
165-
variables = @showprogress 1 "loading variables" asyncmap(varFiles) do varFile
166-
jstr = read("$varFolder/$varFile", String)
167-
packedvar = JSON.parse(jstr, VariableDFG; style = DFGJSONStyle())
168-
v = usePackedVariable ? packedvar : unpackVariable(packedvar)
123+
variables = @showprogress 1 "loading variables" asyncmap(variablefiles) do file
124+
v = JSON.parsefile(file, V; style = DFGJSONStyle())
169125
return addVariable!(dfgLoadInto, v)
170126
end
171127

172-
@info "Loaded $(length(variables)) variables"#- $(map(v->v.label, variables))"
128+
@info "Loaded $(length(variables)) variables"
173129

174-
usePackedFactor =
175-
isa(dfgLoadInto, GraphsDFG) && getTypeDFGFactors(dfgLoadInto) == FactorDFG
130+
factorfiles = readdir(joinpath(loaddir, "factors"); sort = false, join = true)
176131

177-
# `factors` is not type stable `::Vector{Factor}` or `::Vector{FactorCompute{<:}}` (vector of abstract)
178-
factors = @showprogress 1 "loading factors" asyncmap(factorFiles) do factorFile
179-
f = JSON.parsefile("$factorFolder/$factorFile", FactorDFG; style = DFGJSONStyle())
132+
factors = @showprogress 1 "loading factors" asyncmap(factorfiles) do file
133+
f = JSON.parsefile(file, F; style = DFGJSONStyle())
180134
return addFactor!(dfgLoadInto, f)
181135
end
182136

183-
@info "Loaded $(length(factors)) factors"# - $(map(f->f.label, factors))"
137+
@info "Loaded $(length(factors)) factors"
184138

185139
if isa(dfgLoadInto, GraphsDFG) && getTypeDFGFactors(dfgLoadInto) != FactorDFG
186140
# Finally, rebuild the CCW's for the factors to completely reinflate them
@@ -189,12 +143,7 @@ function loadDFG!(
189143
end
190144
end
191145

192-
# remove the temporary unzipped file
193-
if unzip
194-
@info "DFG.loadDFG! is deleting a temp folder created during unzip, $loaddir"
195-
# need this because the number of files created in /tmp/caesar/random is becoming redonkulous.
196-
Base.rm(loaddir; recursive = true, force = true)
197-
end
146+
Base.rm(loaddir; recursive = true, force = true)
198147

199148
return dfgLoadInto
200149
end
@@ -215,35 +164,40 @@ function loadDFG(file::AbstractString)
215164
# check the file actually exists
216165
@assert isfile(file) "cannot find file $file"
217166

218-
# only extract dfg.json to rebuild DFG object
167+
# only extract the json files needed to rebuild DFG object
219168
tar_gz = open(file)
220169
tar = CodecZlib.GzipDecompressorStream(tar_gz)
221-
loaddir = Tar.extract(hdr -> contains(hdr.path, "dfg.json"), tar)
170+
dfgnodenames = r"^(agent\.json|blobstores\.json|graphroot\.json|solverparams\.json)$"
171+
loaddir = Tar.extract(hdr -> contains(hdr.path, dfgnodenames), tar)
222172
close(tar)
223173

224-
#Only GraphsDFG metadata supported
225-
jstr = read("$loaddir/dfg.json", String)
226-
# ---------------------------------
227-
#TODO deprecate old format, v0.28
228-
local fgPacked
229-
try
230-
fgPacked = JSON.parse(jstr, GraphsDFGs.PackedGraphsDFG; style = DFGJSONStyle())
231-
catch e
232-
if e isa MethodError
233-
@warn "Deprecated serialization: Failed to read DFG metadata. Attempting to load using the old format. Error:" e
234-
fgPacked = GraphsDFGs.PackedGraphsDFG(
235-
JSON.parse(jstr, GraphsDFGs._OldPackedGraphsDFG; style = DFGJSONStyle()),
236-
)
237-
else
238-
rethrow(e)
239-
end
240-
end
241-
# ----------------------------------
242-
dfg = GraphsDFGs.unpackDFGMetadata(fgPacked)
174+
progess = Progress(4, "Loading DFG Nodes")
175+
agent = JSON.parsefile(joinpath(loaddir, "agent.json"), Agent; style = DFGJSONStyle())
176+
next!(progess)
177+
graph = JSON.parsefile(
178+
joinpath(loaddir, "graphroot.json"),
179+
Graphroot;
180+
style = DFGJSONStyle(),
181+
)
182+
next!(progess)
183+
solverParams = JSON.parsefile(
184+
joinpath(loaddir, "solverparams.json"),
185+
AbstractDFGParams;
186+
style = DFGJSONStyle(),
187+
)
188+
next!(progess)
189+
blobStores = JSON.parsefile(
190+
joinpath(loaddir, "blobstores.json"),
191+
Dict{Symbol, AbstractBlobstore};
192+
style = DFGJSONStyle(),
193+
)
194+
next!(progess)
195+
196+
dfg = GraphsDFG(; agent, graph, solverParams, blobStores)
243197

244198
@debug "DFG.loadDFG is deleting a temp folder created during unzip, $loaddir"
245199
# cleanup temporary folder
246200
Base.rm(loaddir; recursive = true, force = true)
247201

248-
return loadDFG!(dfg, file; overwriteDFGMetadata = false)
202+
return loadDFG!(dfg, file)
249203
end

src/GraphsDFG/GraphsDFG.jl

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,7 @@ import ...DistributedFactorGraphs:
6363
addGraphBlobentry!,
6464
addGraphBlobentries!,
6565
listGraphBlobentries,
66-
listAgentBlobentries,
67-
getTypeDFGVariables,
68-
getTypeDFGFactors
66+
listAgentBlobentries
6967

7068
include("FactorGraphs/FactorGraphs.jl")
7169
using .FactorGraphs
@@ -74,7 +72,6 @@ using .FactorGraphs
7472
# Imports
7573
include("entities/GraphsDFG.jl")
7674
include("services/GraphsDFG.jl")
77-
include("services/GraphsDFGSerialization.jl")
7875

7976
# Exports
8077
export GraphsDFG

0 commit comments

Comments
 (0)