Skip to content

Commit af1b1eb

Browse files
committed
Merge branch 'master' into 2Q20/378_cloudsolving
2 parents 404d192 + 0d5c545 commit af1b1eb

16 files changed

+337
-104
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ LightGraphs = "1.2, 1.3"
3131
Neo4j = "2"
3232
Reexport = "0.2, 0.3, 0.4, 0.5, 1"
3333
Requires = "0.5, 0.6, 0.7, 0.8, 0.9, 0.10, 1"
34-
Unmarshal = "0.3"
34+
Unmarshal = "0.3, 0.4"
3535
julia = "1.2"
3636

3737
[extras]

src/CloudGraphsDFG/entities/CloudGraphsDFG.jl

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ mutable struct CloudGraphsDFG{T <: AbstractParams} <: AbstractDFG
1010
userId::String
1111
robotId::String
1212
sessionId::String
13+
description::String
1314
encodePackedTypeFunc
1415
getPackedTypeFunc
1516
decodePackedTypeFunc
@@ -26,38 +27,41 @@ function CloudGraphsDFG{T}(neo4jConnection::Neo4j.Connection,
2627
userId::String,
2728
robotId::String,
2829
sessionId::String,
30+
description::String,
2931
encodePackedTypeFunc,
3032
getPackedTypeFunc,
3133
decodePackedTypeFunc,
3234
rebuildFactorMetadata!;
3335
solverParams::T=NoSolverParams()) where T <: AbstractParams
3436
graph = Neo4j.getgraph(neo4jConnection)
3537
neo4jInstance = Neo4jInstance(neo4jConnection, graph)
36-
return CloudGraphsDFG{T}(neo4jInstance, userId, robotId, sessionId, encodePackedTypeFunc, getPackedTypeFunc, decodePackedTypeFunc, rebuildFactorMetadata!, Symbol[], solverParams)
38+
return CloudGraphsDFG{T}(neo4jInstance, userId, robotId, sessionId, description, encodePackedTypeFunc, getPackedTypeFunc, decodePackedTypeFunc, rebuildFactorMetadata!, Symbol[], solverParams)
3739
end
3840
"""
3941
$(SIGNATURES)
4042
Create a new CloudGraphs-based DFG factor graph by specifying the Neo4j connection information.
4143
"""
4244
function CloudGraphsDFG{T}(host::String,
43-
port::Int,
44-
dbUser::String,
45-
dbPassword::String,
46-
userId::String,
47-
robotId::String,
48-
sessionId::String,
49-
encodePackedTypeFunc,
50-
getPackedTypeFunc,
51-
decodePackedTypeFunc,
52-
rebuildFactorMetadata!;
53-
solverParams::T=NoSolverParams()) where T <: AbstractParams
45+
port::Int,
46+
dbUser::String,
47+
dbPassword::String,
48+
userId::String,
49+
robotId::String,
50+
sessionId::String,
51+
description::String,
52+
encodePackedTypeFunc,
53+
getPackedTypeFunc,
54+
decodePackedTypeFunc,
55+
rebuildFactorMetadata!;
56+
solverParams::T=NoSolverParams()) where T <: AbstractParams
5457
neo4jConnection = Neo4j.Connection(host, port=port, user=dbUser, password=dbPassword);
55-
return CloudGraphsDFG{T}(neo4jConnection, userId, robotId, sessionId, encodePackedTypeFunc, getPackedTypeFunc, decodePackedTypeFunc, rebuildFactorMetadata!, solverParams=solverParams)
58+
return CloudGraphsDFG{T}(neo4jConnection, userId, robotId, sessionId, description, encodePackedTypeFunc, getPackedTypeFunc, decodePackedTypeFunc, rebuildFactorMetadata!, solverParams=solverParams)
5659
end
5760

5861

5962
function show(io::IO, c::CloudGraphsDFG)
6063
println(io, "CloudGraphsDFG:")
6164
println(io, " - Neo4J instance: $(c.neo4jInstance.connection.host)")
6265
println(io, " - Session: $(c.userId):$(c.robotId):$(c.sessionId)")
66+
println(io, " - Description: ", c.description)
6367
end

src/CloudGraphsDFG/services/CloudGraphsDFG.jl

Lines changed: 78 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ function _getDuplicatedEmptyDFG(dfg::CloudGraphsDFG)::CloudGraphsDFG
1717
dfg.userId,
1818
dfg.robotId,
1919
sessionId,
20+
dfg.description,
2021
dfg.encodePackedTypeFunc,
2122
dfg.getPackedTypeFunc,
2223
dfg.decodePackedTypeFunc,
@@ -32,11 +33,13 @@ function getDescription(dfg::CloudGraphsDFG)
3233
"description")
3334
end
3435
function setDescription!(dfg::CloudGraphsDFG, description::String)
35-
_setNodeProperty(
36-
dfg.neo4jInstance,
37-
[dfg.sessionId, dfg.robotId, dfg.userId, "SESSION"],
38-
"description",
39-
description)
36+
count = _setNodeProperty(dfg.neo4jInstance,
37+
[dfg.sessionId, dfg.robotId, dfg.userId, "SESSION"],
38+
"description",
39+
description)
40+
@assert(count == 1)
41+
dfg.description = description
42+
return getDescription(dfg)
4043
end
4144

4245
function getSerializationModule(dfg::CloudGraphsDFG)::Module where G <: AbstractDFG
@@ -53,43 +56,89 @@ function getUserData(dfg::CloudGraphsDFG)::Dict{Symbol, String}
5356
propVal = _getNodeProperty(dfg.neo4jInstance, _getLabelsForType(dfg, User), "data")
5457
return JSON2.read(String(base64decode(propVal)), Dict{Symbol, String})
5558
end
56-
function setUserData!(dfg::CloudGraphsDFG, data::Dict{Symbol, String})::Bool
59+
function setUserData!(dfg::CloudGraphsDFG, data::Dict{Symbol, String})::Dict{Symbol, String}
5760
count = _setNodeProperty(dfg.neo4jInstance, [dfg.userId, "USER"], "data", base64encode(JSON2.write(data)))
58-
return count == 1
61+
@assert(count == 1)
62+
return getUserData(dfg)
5963
end
64+
6065
function getRobotData(dfg::CloudGraphsDFG)::Dict{Symbol, String}
6166
propVal = _getNodeProperty(dfg.neo4jInstance, [dfg.userId, dfg.robotId, "ROBOT"], "data")
6267
return JSON2.read(String(base64decode(propVal)), Dict{Symbol, String})
6368
end
64-
function setRobotData!(dfg::CloudGraphsDFG, data::Dict{Symbol, String})::Bool
69+
function setRobotData!(dfg::CloudGraphsDFG, data::Dict{Symbol, String})::Dict{Symbol, String}
6570
count = _setNodeProperty(dfg.neo4jInstance, [dfg.userId, dfg.robotId, "ROBOT"], "data", base64encode(JSON2.write(data)))
66-
return count == 1
71+
@assert(count == 1)
72+
return getRobotData(dfg)
6773
end
74+
6875
function getSessionData(dfg::CloudGraphsDFG)::Dict{Symbol, String}
6976
propVal = _getNodeProperty(dfg.neo4jInstance, [dfg.userId, dfg.robotId, dfg.sessionId, "SESSION"], "data")
7077
return JSON2.read(String(base64decode(propVal)), Dict{Symbol, String})
7178
end
72-
function setSessionData!(dfg::CloudGraphsDFG, data::Dict{Symbol, String})::Bool
79+
function setSessionData!(dfg::CloudGraphsDFG, data::Dict{Symbol, String})::Dict{Symbol, String}
7380
count = _setNodeProperty(dfg.neo4jInstance, [dfg.userId, dfg.robotId, dfg.sessionId, "SESSION"], "data", base64encode(JSON2.write(data)))
74-
return count == 1
81+
@assert(count == 1)
82+
return getSessionData(dfg)
7583
end
7684

7785
# New API
78-
getUserData(dfg::CloudGraphsDFG, key::Symbol)::String = error("Not supported yet")
79-
getRobotData(dfg::CloudGraphsDFG, key::Symbol)::String = error("Not supported yet")
80-
getSessionData(dfg::CloudGraphsDFG, key::Symbol)::String = error("Not supported yet")
86+
getUserData(dfg::CloudGraphsDFG, key::Symbol) = getUserData(dfg::CloudGraphsDFG)[key]
87+
getRobotData(dfg::CloudGraphsDFG, key::Symbol)::String = getRobotData(dfg::CloudGraphsDFG)[key]
88+
getSessionData(dfg::CloudGraphsDFG, key::Symbol)::String = getSessionData(dfg::CloudGraphsDFG)[key]
89+
90+
function updateUserData!(dfg::CloudGraphsDFG, pair::Pair{Symbol,String})
91+
data = getUserData(dfg::CloudGraphsDFG)
92+
push!(data, pair)
93+
setUserData!(dfg, data)
94+
end
95+
96+
function updateRobotData!(dfg::CloudGraphsDFG, pair::Pair{Symbol,String})
97+
data = getRobotData(dfg::CloudGraphsDFG)
98+
push!(data, pair)
99+
setRobotData!(dfg, data)
100+
end
101+
102+
function updateSessionData!(dfg::CloudGraphsDFG, pair::Pair{Symbol,String})
103+
data = getSessionData(dfg::CloudGraphsDFG)
104+
push!(data, pair)
105+
setSessionData!(dfg, data)
106+
end
107+
108+
function deleteUserData!(dfg::CloudGraphsDFG, key::Symbol)
109+
data = getUserData(dfg::CloudGraphsDFG)
110+
delval = pop!(data, key)
111+
setUserData!(dfg, data)
112+
return delval
113+
end
114+
115+
function deleteRobotData!(dfg::CloudGraphsDFG, key::Symbol)
116+
data = getRobotData(dfg::CloudGraphsDFG)
117+
delval = pop!(data, key)
118+
setRobotData!(dfg, data)
119+
return delval
120+
end
81121

82-
updateUserData!(dfg::CloudGraphsDFG, pair::Pair{Symbol,String}) = error("Not supported yet")
83-
updateRobotData!(dfg::CloudGraphsDFG, pair::Pair{Symbol,String}) = error("Not supported yet")
84-
updateSessionData!(dfg::CloudGraphsDFG, pair::Pair{Symbol,String}) = error("Not supported yet")
122+
function deleteSessionData!(dfg::CloudGraphsDFG, key::Symbol)
123+
data = getSessionData(dfg::CloudGraphsDFG)
124+
delval = pop!(data, key)
125+
setSessionData!(dfg, data)
126+
return delval
127+
end
128+
129+
130+
function emptyUserData!(dfg::CloudGraphsDFG)
131+
return setUserData!(dfg, Dict{Symbol, String}())
132+
end
85133

86-
deleteUserData!(dfg::CloudGraphsDFG, key::Symbol) = error("Not supported yet")
87-
deleteRobotData!(dfg::CloudGraphsDFG, key::Symbol) = error("Not supported yet")
88-
deleteSessionData!(dfg::CloudGraphsDFG, key::Symbol) = error("Not supported yet")
134+
function emptyRobotData!(dfg::CloudGraphsDFG)
135+
return setRobotData!(dfg, Dict{Symbol, String}())
136+
end
137+
138+
function emptySessionData!(dfg::CloudGraphsDFG)
139+
return setSessionData!(dfg, Dict{Symbol, String}())
140+
end
89141

90-
emptyUserData!(dfg::CloudGraphsDFG) = error("Not supported yet")
91-
emptyRobotData!(dfg::CloudGraphsDFG) = error("Not supported yet")
92-
emptySessionData!(dfg::CloudGraphsDFG) = error("Not supported yet")
93142

94143
##==============================================================================
95144
## CRUD Interfaces
@@ -132,17 +181,15 @@ function addVariable!(dfg::CloudGraphsDFG, variable::DFGVariable)::DFGVariable
132181
return variable
133182
end
134183

135-
function addFactor!(dfg::CloudGraphsDFG, factor::DFGFactor)
136-
addFactor!(dfg, factor._variableOrderSymbols, factor)
137-
end
138184

139-
function addFactor!(dfg::CloudGraphsDFG, variables::Vector{<:DFGVariable}, factor::DFGFactor)::DFGFactor
185+
function addFactor!(dfg::CloudGraphsDFG, factor::DFGFactor)::DFGFactor
140186
if exists(dfg, factor)
141187
error("Factor '$(factor.label)' already exists in the factor graph")
142188
end
143189

144-
# Update the variable ordering
145-
factor._variableOrderSymbols = map(v->v.label, variables)
190+
variableIds = factor._variableOrderSymbols
191+
variables = map(vId -> getVariable(dfg, vId), variableIds)
192+
146193

147194
# Construct the properties to save
148195
props = packFactor(dfg, factor)
@@ -163,16 +210,11 @@ function addFactor!(dfg::CloudGraphsDFG, variables::Vector{<:DFGVariable}, facto
163210
return factor
164211
end
165212

166-
function addFactor!(dfg::CloudGraphsDFG, variableIds::Vector{Symbol}, factor::DFGFactor)::DFGFactor
167-
variables = map(vId -> getVariable(dfg, vId), variableIds)
168-
return addFactor!(dfg, variables, factor)
169-
end
170-
171213
function getVariable(dfg::CloudGraphsDFG, label::Union{Symbol, String})::DFGVariable
172214
if typeof(label) == String
173215
label = Symbol(label)
174216
end
175-
nodeId = _tryGetNeoNodeIdFromNodeLabel(dfg.neo4jInstance, dfg.userId, dfg.robotId, dfg.sessionId, label)
217+
nodeId = _tryGetNeoNodeIdFromNodeLabel(dfg.neo4jInstance, dfg.userId, dfg.robotId, dfg.sessionId, label, nodeType="VARIABLE")
176218
if nodeId == nothing
177219
error("Unable to retrieve the ID for variable '$label'. Please check your connection to the database and that the variable exists.")
178220
end
@@ -191,7 +233,7 @@ function getFactor(dfg::CloudGraphsDFG, label::Union{Symbol, String})::DFGFactor
191233
if typeof(label) == String
192234
label = Symbol(label)
193235
end
194-
nodeId = _tryGetNeoNodeIdFromNodeLabel(dfg.neo4jInstance, dfg.userId, dfg.robotId, dfg.sessionId, label)
236+
nodeId = _tryGetNeoNodeIdFromNodeLabel(dfg.neo4jInstance, dfg.userId, dfg.robotId, dfg.sessionId, label, nodeType="FACTOR")
195237
if nodeId == nothing
196238
error("Unable to retrieve the ID for factor '$label'. Please check your connection to the database and that the factor exists.")
197239
end

src/CloudGraphsDFG/services/CommonFunctions.jl

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,15 @@ end
160160
$(SIGNATURES)
161161
Try get a Neo4j node ID from a node label.
162162
"""
163-
function _tryGetNeoNodeIdFromNodeLabel(neo4jInstance::Neo4jInstance, userId::String, robotId::String, sessionId::String, nodeLabel::Symbol)::Union{Nothing, Int}
163+
function _tryGetNeoNodeIdFromNodeLabel(neo4jInstance::Neo4jInstance, userId::String, robotId::String, sessionId::String, nodeLabel::Symbol; nodeType::Union{Nothing, String}=nothing)::Union{Nothing, Int}
164164
@debug "Looking up symbolic node ID where n.label = '$nodeLabel'..."
165-
nodes = _getNeoNodesFromCyphonQuery(neo4jInstance, "(node:$userId:$robotId:$sessionId) where exists(node.label) and node.label = \"$(string(nodeLabel))\"")
166-
if(length(nodes) != 1)
165+
if nodeType == nothing
166+
nodes = _getNeoNodesFromCyphonQuery(neo4jInstance, "(node:$userId:$robotId:$sessionId) where exists(node.label) and node.label = \"$(string(nodeLabel))\"")
167+
else
168+
nodes = _getNeoNodesFromCyphonQuery(neo4jInstance, "(node:$nodeType:$userId:$robotId:$sessionId) where exists(node.label) and node.label = \"$(string(nodeLabel))\"")
169+
end
170+
171+
if length(nodes) != 1
167172
return nothing
168173
end
169174
nodeId = nodes[1].id

src/Deprecated.jl

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,7 @@ Base.getproperty(x::DFGFactor,f::Symbol) = begin
3838
elseif f == :_internalId
3939
getfield(x,:_dfgNodeParams)._internalId
4040
elseif f == :data
41-
42-
if !(@isdefined getFactorDataWarnOnce)
43-
@warn "get: data field is deprecated, use getSolverData. Further warnings are suppressed"
44-
global getFactorDataWarnOnce = true
45-
end
46-
41+
Base.depwarn("DFGFactor get: data field is deprecated, use getSolverData", :getproperty)
4742
getfield(x, :solverData)
4843
else
4944
getfield(x,f)
@@ -57,12 +52,7 @@ Base.setproperty!(x::DFGFactor,f::Symbol, val) = begin
5752
elseif f == :_internalId
5853
getfield(x,:_dfgNodeParams)._internalId = val
5954
elseif f == :data
60-
61-
if !(@isdefined setFactorDataWarnOnce)
62-
@warn "set: data field is deprecated, use ...TODO? Further warnings are suppressed"
63-
global setFactorDataWarnOnce = true
64-
end
65-
55+
Base.depwarn("DFGFactor set: data field is deprecated, use getSolverData", :getproperty)
6656
setfield!(x,:solverData, val)
6757
else
6858
setfield!(x,f,val)

src/DistributedFactorGraphs.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ include("services/AbstractDFG.jl")
249249

250250
# In Memory Types
251251
include("GraphsDFG/GraphsDFG.jl")
252+
@reexport using .GraphsDFGs
252253
include("LightDFG/LightDFG.jl")
253254
@reexport using .LightDFGs
254255
#supported in Memory fg types

src/GraphsDFG/GraphsDFG.jl

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,49 @@
1+
module GraphsDFGs
2+
13
using Graphs
4+
using DocStringExtensions
5+
6+
using ...DistributedFactorGraphs
7+
8+
# import DFG functions to extend
9+
import ...DistributedFactorGraphs: setSolverParams!,
10+
getFactor,
11+
setDescription!,
12+
# getLabelDict,
13+
getUserData,
14+
setUserData!,
15+
getRobotData,
16+
setRobotData!,
17+
getSessionData,
18+
setSessionData!,
19+
addVariable!,
20+
getVariable,
21+
getAddHistory,
22+
addFactor!,
23+
getSolverParams,
24+
exists,
25+
isVariable,
26+
isFactor,
27+
getDescription,
28+
updateVariable!,
29+
updateFactor!,
30+
deleteVariable!,
31+
deleteFactor!,
32+
getVariables,
33+
listVariables,
34+
ls,
35+
getFactors,
36+
listFactors,
37+
lsf,
38+
isFullyConnected,
39+
hasOrphans,
40+
getNeighbors,
41+
buildSubgraph,
42+
copyGraph!,
43+
getBiadjacencyMatrix,
44+
_getDuplicatedEmptyDFG,
45+
toDot,
46+
toDotFile
247

348
# Imports
449
include("entities/GraphsDFG.jl")
@@ -7,4 +52,4 @@ include("services/GraphsDFG.jl")
752
# Exports
853
export GraphsDFG
954

10-
export toDot, toDotFile
55+
end

src/GraphsDFG/services/GraphsDFG.jl

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,9 @@ function getVariable(dfg::GraphsDFG, label::Union{Symbol, String})::DFGVariable
121121
if !haskey(dfg.labelDict, label)
122122
error("Variable label '$(label)' does not exist in the factor graph")
123123
end
124-
return dfg.g.vertices[dfg.labelDict[label]].dfgNode
124+
node = dfg.g.vertices[dfg.labelDict[label]].dfgNode
125+
!isa(node, AbstractDFGVariable) && error("Node with label '$(label)' is not a variable")
126+
return node
125127
end
126128

127129
function getFactor(dfg::GraphsDFG, factorId::Int64)::DFGFactor
@@ -140,7 +142,9 @@ function getFactor(dfg::GraphsDFG, label::Union{Symbol, String})::DFGFactor
140142
if !haskey(dfg.labelDict, label)
141143
error("Factor label '$(label)' does not exist in the factor graph")
142144
end
143-
return dfg.g.vertices[dfg.labelDict[label]].dfgNode
145+
node = dfg.g.vertices[dfg.labelDict[label]].dfgNode
146+
!isa(node, AbstractDFGFactor) && error("Node with label '$(label)' is not a factor")
147+
return node
144148
end
145149

146150
function updateVariable!(dfg::GraphsDFG, variable::DFGVariable)::DFGVariable
@@ -262,3 +266,10 @@ Produces a dot-format of the graph for visualization.
262266
function toDot(dfg::GraphsDFG)::String
263267
return Graphs.to_dot(dfg.g)
264268
end
269+
270+
function toDotFile(dfg::GraphsDFG, fileName::String="/tmp/dfg.dot")::Nothing
271+
open(fileName, "w") do fid
272+
write(fid, Graphs.to_dot(dfg.g))
273+
end
274+
return nothing
275+
end

0 commit comments

Comments
 (0)