diff --git a/docs/make.jl b/docs/make.jl index 72dd708c..14ec53c6 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -2,6 +2,8 @@ using Documenter using GraphMakie using DistributedFactorGraphs +DFG.@usingDFG true + makedocs(; modules = [DistributedFactorGraphs], format = Documenter.HTML(), diff --git a/src/DataBlobs/services/BlobEntry.jl b/src/DataBlobs/services/BlobEntry.jl index 70504480..96ca07c8 100644 --- a/src/DataBlobs/services/BlobEntry.jl +++ b/src/DataBlobs/services/BlobEntry.jl @@ -71,19 +71,21 @@ end """ $(SIGNATURES) Finds and returns the first blob entry that matches the filter. - +The result is sorted by `sortby[=getLabel]` and `sortlt[=natural_lt]` before returning the first entry. Also see: [`getBlobentry`](@ref) """ function getfirstBlobentry( v::AbstractGraphVariable; labelFilter::Union{Nothing, Function} = nothing, blobIdFilter::Union{Nothing, Function} = nothing, + sortby::Function = getLabel, + sortlt::Function = natural_lt, ) entries = getBlobentries(v; labelFilter, blobIdFilter) if isempty(entries) return nothing else - return entries[1] + return sort(entries; by = sortby, lt = sortlt)[1] end end @@ -184,6 +186,23 @@ function deleteBlobentry!(var::AbstractGraphVariable, entry::Blobentry) return deleteBlobentry!(var, entry.label) end +##============================================================================== +## Default bulk Agent and Graph Blobentry operations +##============================================================================== +function deleteAgentBlobentries!(dfg::AbstractDFG, labels::Vector{Symbol}) + cnts = map(labels) do label + return deleteAgentBlobentry!(dfg, label) + end + return sum(cnts) +end + +function deleteGraphBlobentries!(dfg::AbstractDFG, labels::Vector{Symbol}) + cnts = map(labels) do label + return deleteGraphBlobentry!(dfg, label) + end + return sum(cnts) +end + ##============================================================================== ## Blobentry - Helper functions, Lists, etc ##============================================================================== diff --git a/src/DistributedFactorGraphs.jl b/src/DistributedFactorGraphs.jl index 27d83503..b1612252 100644 --- a/src/DistributedFactorGraphs.jl +++ b/src/DistributedFactorGraphs.jl @@ -116,7 +116,7 @@ export getObservation ##------------------------------------------------------------------------------ export getVariable export hasVariable - +export mergeVariables! ##------------------------------------------------------------------------------ ## State ##------------------------------------------------------------------------------ @@ -126,6 +126,7 @@ export getStates # Factor ##------------------------------------------------------------------------------ export mergeFactor! +export mergeFactors! export hasFactor ##------------------------------------------------------------------------------ @@ -144,20 +145,22 @@ export getAgentBlobentries export mergeBlobentries! export mergeGraphBlobentry! +export mergeGraphBlobentries! export mergeAgentBlobentry! +export mergeAgentBlobentries! export deleteGraphBlobentry! export deleteAgentBlobentry! +export deleteGraphBlobentries! +export deleteAgentBlobentries! export listBlobentries export listGraphBlobentries export listAgentBlobentries export hasBlobentry - -# TODO not yet implemented in DFG -# addAgentBlobentry! -# addGraphBlobentry! +export hasGraphBlobentry +export hasAgentBlobentry ##------------------------------------------------------------------------------ ## Blobstores and Blobs @@ -199,14 +202,15 @@ export GraphsDFG # export addBlobentry!, getBlobentry, mergeBlobentry!, deleteBlobentry! # historic for VariableBlobentry # export addBlobentries!, getBlobentries, mergeBlobentries!, deleteBlobentries! -# TODO first pass progress # export addGraphBlobentry!, getGraphBlobentry, mergeGraphBlobentry!, deleteGraphBlobentry! # export addGraphBlobentries!, getGraphBlobentries, mergeGraphBlobentries!, deleteGraphBlobentries! # export addAgentBlobentry!, getAgentBlobentry, mergeAgentBlobentry!, deleteAgentBlobentry! # export addAgentBlobentries!, getAgentBlobentries, mergeAgentBlobentries!, deleteAgentBlobentries! +#TODO blob entries not implemented on factors yet # export addFactorBlobentry!, getFactorBlobentry, mergeFactorBlobentry!, deleteFactorBlobentry! # export addFactorBlobentries!, getFactorBlobentries, mergeFactorBlobentries!, deleteFactorBlobentries! +# TODO first pass progress # export addVariableMetadata!, getVariableMetadata, mergeVariableMetadata!, deleteVariableMetadata! # export addFactorMetadata!, getFactorMetadata, mergeFactorMetadata!, deleteFactorMetadata! # export addAgentMetadata!, getAgentMetadata, mergeAgentMetadata!, deleteAgentMetadata! @@ -546,31 +550,6 @@ include("services/DFGFactor.jl") include("Deprecated.jl") include("services/CompareUtils.jl") -#FIXME move -function mergeGraphBlobentry!(dfg::GraphsDFG, entry::Blobentry) - refBlobentries(dfg.graph)[getLabel(entry)] = entry - return 1 -end - -function mergeAgentBlobentry!(dfg::GraphsDFG, entry::Blobentry) - refBlobentries(dfg.agent)[getLabel(entry)] = entry - return 1 -end - -function mergeGraphBlobentries!(dfg::GraphsDFG, entries::Vector{Blobentry}) - cnts = map(entries) do entry - return mergeGraphBlobentry!(dfg, entry) - end - return sum(cnts) -end - -function mergeAgentBlobentries!(dfg::GraphsDFG, entries::Vector{Blobentry}) - cnts = map(entries) do entry - return mergeAgentBlobentry!(dfg, entry) - end - return sum(cnts) -end - # include("services/Sync.jl") # Include the FilesDFG API. diff --git a/src/GraphsDFG/services/GraphsDFG.jl b/src/GraphsDFG/services/GraphsDFG.jl index b34d53e4..d5a285ac 100644 --- a/src/GraphsDFG/services/GraphsDFG.jl +++ b/src/GraphsDFG/services/GraphsDFG.jl @@ -91,8 +91,8 @@ function mergeVariable!(dfg::GraphsDFG, variable::AbstractGraphVariable) return 1 end -function mergeVariables!(dfg::GraphsDFG, variables) - cnts = map(mergeVariable!, variables) +function DFG.mergeVariables!(dfg::GraphsDFG, variables) + cnts = map(v -> mergeVariable!(dfg, v), variables) return sum(cnts) end @@ -112,6 +112,11 @@ function mergeFactor!(dfg::GraphsDFG, factor::AbstractGraphFactor) return 1 end +function DFG.mergeFactors!(dfg::GraphsDFG, factors) + cnts = map(f -> mergeFactor!(dfg, f), factors) + return sum(cnts) +end + function deleteVariable!(dfg::GraphsDFG, label::Symbol)#::Tuple{AbstractGraphVariable, Vector{<:AbstractGraphFactor}} if !haskey(dfg.g.variables, label) throw(LabelNotFoundError("Variable", label)) @@ -592,3 +597,81 @@ function addGraphBlobentries!(fg::GraphsDFG, entries::Vector{Blobentry}) return addGraphBlobentry!(fg, entry) end end + +function DFG.addAgentBlobentry!(fg::GraphsDFG, entry::Blobentry) + if haskey(fg.agent.blobEntries, entry.label) + throw(LabelExistsError("Blobentry", entry.label)) + end + push!(fg.agent.blobEntries, entry.label => entry) + return entry +end + +function DFG.addAgentBlobentries!(fg::GraphsDFG, entries::Vector{Blobentry}) + return map(entries) do entry + return addAgentBlobentry!(fg, entry) + end +end + +function DFG.getAgentBlobentry(fg::GraphsDFG, label::Symbol) + if !haskey(fg.agent.blobEntries, label) + throw(LabelNotFoundError("Blobentry", label)) + end + return fg.agent.blobEntries[label] +end + +function DFG.getAgentBlobentries( + fg::GraphsDFG; + labelFilter::Union{Nothing, Function} = nothing, +) + entries = collect(values(fg.agent.blobEntries)) + filterDFG!(entries, labelFilter, getLabel) + return entries +end + +function DFG.mergeGraphBlobentry!(dfg::GraphsDFG, entry::Blobentry) + DFG.refBlobentries(dfg.graph)[getLabel(entry)] = entry + return 1 +end + +function DFG.mergeAgentBlobentry!(dfg::GraphsDFG, entry::Blobentry) + DFG.refBlobentries(dfg.agent)[getLabel(entry)] = entry + return 1 +end + +function DFG.mergeGraphBlobentries!(dfg::GraphsDFG, entries::Vector{Blobentry}) + cnts = map(entries) do entry + return mergeGraphBlobentry!(dfg, entry) + end + return sum(cnts) +end + +function DFG.mergeAgentBlobentries!(dfg::GraphsDFG, entries::Vector{Blobentry}) + cnts = map(entries) do entry + return mergeAgentBlobentry!(dfg, entry) + end + return sum(cnts) +end + +function DFG.deleteGraphBlobentry!(dfg::GraphsDFG, label::Symbol) + if !haskey(dfg.graph.blobEntries, label) + throw(LabelNotFoundError("Blobentry", label)) + end + delete!(dfg.graph.blobEntries, label) + return 1 +end + +function DFG.deleteAgentBlobentry!(dfg::GraphsDFG, label::Symbol) + if !haskey(dfg.agent.blobEntries, label) + throw(LabelNotFoundError("Blobentry", label)) + end + delete!(dfg.agent.blobEntries, label) + return 1 +end + +function DFG.hasGraphBlobentry(dfg::GraphsDFG, label::Symbol) + return haskey(dfg.graph.blobEntries, label) +end + +function DFG.hasAgentBlobentry(dfg::GraphsDFG, label::Symbol) + return haskey(dfg.agent.blobEntries, label) +end diff --git a/src/services/AbstractDFG.jl b/src/services/AbstractDFG.jl index 17886ee5..e1be6ba4 100644 --- a/src/services/AbstractDFG.jl +++ b/src/services/AbstractDFG.jl @@ -202,6 +202,7 @@ function getGraphBlobentries end function addGraphBlobentry! end function addGraphBlobentries! end function mergeGraphBlobentry! end +function mergeGraphBlobentries! end function deleteGraphBlobentry! end function getAgentBlobentry end @@ -209,6 +210,7 @@ function getAgentBlobentries end function addAgentBlobentry! end function addAgentBlobentries! end function mergeAgentBlobentry! end +function mergeAgentBlobentries! end function deleteAgentBlobentry! end function getModelBlobentry end @@ -222,6 +224,10 @@ function listGraphBlobentries end function listAgentBlobentries end function listModelBlobentries end +function hasGraphBlobentry end +function hasAgentBlobentry end +function hasModelBlobentry end + ##============================================================================== ## AbstractBlobstore CRUD ##============================================================================== @@ -369,6 +375,7 @@ otherwise, the variable will be added to the graph. Implement `mergeVariable!(dfg::AbstractDFG, variable::AbstractGraphVariable)` """ function mergeVariable! end +function mergeVariables! end """ $(SIGNATURES) @@ -377,6 +384,7 @@ otherwise, the factor will be added to the graph. Implement `mergeFactor!(dfg::AbstractDFG, factor::AbstractGraphFactor)` """ function mergeFactor! end +function mergeFactors! end """ $(SIGNATURES) diff --git a/test/testBlocks.jl b/test/testBlocks.jl index d9ee7b0b..7ff8d3d9 100644 --- a/test/testBlocks.jl +++ b/test/testBlocks.jl @@ -194,20 +194,63 @@ function GraphAgentBlobentries!(fg::AbstractDFG) metadata = "", ) - # User Blob Entries - #TODO - - # Robot Blob Entries - #TODO - - # Session Blob Entries + # Agent Blob Entries + ae = addAgentBlobentry!(fg, be) + @test ae == be + @test_throws DFG.LabelExistsError addAgentBlobentry!(fg, be) + ge = getAgentBlobentry(fg, :key1) + @test ge == be + @test hasAgentBlobentry(fg, :key1) + me = mergeAgentBlobentry!(fg, be) + @test me == 1 + de = deleteAgentBlobentry!(fg, :key1) + @test de == 1 + @test hasAgentBlobentry(fg, :key1) == false + @test_throws DFG.LabelNotFoundError getAgentBlobentry(fg, :key1) + @test_throws DFG.LabelNotFoundError deleteAgentBlobentry!(fg, :key1) + + # Graph Blob Entries ae = addGraphBlobentry!(fg, be) @test ae == be + @test_throws DFG.LabelExistsError addGraphBlobentry!(fg, be) ge = getGraphBlobentry(fg, :key1) @test ge == be - - #TODO - + @test hasGraphBlobentry(fg, :key1) + me = mergeGraphBlobentry!(fg, be) + @test me == 1 + de = deleteGraphBlobentry!(fg, :key1) + @test de == 1 + @test hasGraphBlobentry(fg, :key1) == false + @test_throws DFG.LabelNotFoundError getGraphBlobentry(fg, :key1) + @test_throws DFG.LabelNotFoundError deleteGraphBlobentry!(fg, :key1) + + be2 = Blobentry(; blobId = uuid4(), label = :key2, blobstore = :b) + + bes = [be, be2] + + ae = addAgentBlobentries!(fg, bes) + @test length(ae) == 2 + @test_throws DFG.LabelExistsError addAgentBlobentries!(fg, bes) + besr = getAgentBlobentries(fg) + @test length(besr) == 2 + me = mergeAgentBlobentries!(fg, bes) + @test me == 2 + de = deleteAgentBlobentries!(fg, [:key1, :key2]) + @test de == 2 + @test_throws DFG.LabelNotFoundError getAgentBlobentry(fg, :key1) + @test_throws DFG.LabelNotFoundError getAgentBlobentry(fg, :key2) + + ae = addGraphBlobentries!(fg, bes) + @test length(ae) == 2 + @test_throws DFG.LabelExistsError addGraphBlobentries!(fg, bes) + besr = getGraphBlobentries(fg) + @test length(besr) == 2 + me = mergeGraphBlobentries!(fg, bes) + @test me == 2 + de = deleteGraphBlobentries!(fg, [:key1, :key2]) + @test de == 2 + @test_throws DFG.LabelNotFoundError getGraphBlobentry(fg, :key1) + @test_throws DFG.LabelNotFoundError getGraphBlobentry(fg, :key2) end function DFGVariableSCA() @@ -400,11 +443,11 @@ function VariablesandFactorsCRUD_SET!(fg, v1, v2, v3, f0, f1, f2) @test getLabel(fg[getLabel(f1)]) == getLabel(f1) @test mergeVariable!(fg, v3) == 1 - @test mergeVariable!(fg, v3) == 1 + @test mergeVariables!(fg, [v3]) == 1 @test_throws LabelExistsError addVariable!(fg, v3) @test mergeFactor!(fg, f2) == 1 - @test mergeFactor!(fg, f2) == 1 + @test mergeFactors!(fg, [f2]) == 1 @test_throws LabelExistsError addFactor!(fg, f2) #TODO Graphs.jl, but look at refactoring absract @test_throws LabelExistsError addFactor!(fg, f2)