private void UpdateLowerLevels(IExpressionNode myNode, LevelKey myCurrentLevelKey, IEnumerable<LevelKey> myLowerLevelKeys, IExpressionGraph myGraph) { if (myCurrentLevelKey.Level > 0) { lock (myGraph) { //iterate the next lower LevelKeys foreach (var aLowerLevelKey in myLowerLevelKeys) { #region data //get next lower attribute (might be more than one step away) int levelDistance = myCurrentLevelKey.Level - aLowerLevelKey.Level; //GraphDBType currentType = null; EdgeKey myCurrentBackwardEdgekey = null; TypeAttribute currentAttribute = null; SettingInvalidReferenceHandling invalidReferenceSetting = null; #endregion if (levelDistance >= 1) { if (myCurrentLevelKey.Level > 1) { myCurrentBackwardEdgekey = myCurrentLevelKey.Edges[myCurrentLevelKey.Level - 1]; } else { myCurrentBackwardEdgekey = myCurrentLevelKey.Edges[0]; } } else { throw new GraphDBException(new Error_ExpressionGraphInternal(new System.Diagnostics.StackTrace(true), "Distances below 1 are not valid.")); } IEnumerable<ObjectUUID> referencedUUIDs = null; GraphDBType referencedType = null; currentAttribute = _DBContext.DBTypeManager.GetTypeByUUID(myCurrentBackwardEdgekey.TypeUUID).GetTypeAttributeByUUID(myCurrentBackwardEdgekey.AttrUUID); if (currentAttribute.IsBackwardEdge) { var backwardEdgeTypeInfo = currentAttribute.BackwardEdgeDefinition.GetTypeAndAttributeInformation(_DBContext.DBTypeManager); var dbObjectStream = myNode.GetDBObjectStream(_DBObjectCache, backwardEdgeTypeInfo.Item1.UUID); referencedType = backwardEdgeTypeInfo.Item2.GetDBType(_DBContext.DBTypeManager); if (dbObjectStream.HasAttribute(backwardEdgeTypeInfo.Item2.UUID, backwardEdgeTypeInfo.Item1)) { referencedUUIDs = GetUUIDsForAttribute(dbObjectStream, backwardEdgeTypeInfo.Item2, backwardEdgeTypeInfo.Item1); } } else { referencedType = currentAttribute.GetRelatedType(_DBContext.DBTypeManager); if (myNode.BackwardEdges.ContainsKey(aLowerLevelKey.LastEdge)) { //take the edges that are already available referencedUUIDs = myNode.BackwardEdges[aLowerLevelKey.LastEdge].Select(item => item.Destination); } else { //load the backward edge stream var currentBackwardEdgeStream = _DBObjectCache.LoadDBBackwardEdgeStream(currentAttribute.GetDBType(_DBContext.DBTypeManager), myNode.GetObjectUUID()); if (currentBackwardEdgeStream.Failed()) { throw new GraphDBException(new Error_CouldNotLoadBackwardEdge(myNode.GetDBObjectStream(_DBObjectCache, currentAttribute.GetRelatedType(_DBContext.DBTypeManager).UUID), currentAttribute, currentBackwardEdgeStream.IErrors)); } if (currentBackwardEdgeStream.Value.ContainsBackwardEdge(myCurrentBackwardEdgekey)) { referencedUUIDs = currentBackwardEdgeStream.Value.GetBackwardEdgeUUIDs(myCurrentBackwardEdgekey); } } } if (referencedUUIDs != null) { var lowerLevelKeys = ExtractLowerLevelKeys(GetPreviousLevel(aLowerLevelKey.Level, myGraph.Levels), aLowerLevelKey, myGraph); EdgeKey edgeKeyForBackwardEdge = null; //get edgeKey for backwardEdge if (myCurrentLevelKey.Level == 1) { edgeKeyForBackwardEdge = aLowerLevelKey.LastEdge; } else { edgeKeyForBackwardEdge = aLowerLevelKey.Edges[aLowerLevelKey.Level - 1]; } Exceptional<DBObjectStream> referencedDBObject = null; foreach (var aReferenceObjectUUID in referencedUUIDs) { referencedDBObject = _DBObjectCache.LoadDBObjectStream(referencedType, aReferenceObjectUUID); if (!referencedDBObject.Success()) { #region error if (invalidReferenceSetting == null) { invalidReferenceSetting = (SettingInvalidReferenceHandling)_DBContext.DBSettingsManager.GetSetting(SettingInvalidReferenceHandling.UUID, _DBContext, Enums.TypesSettingScope.ATTRIBUTE, referencedType, currentAttribute).Value; } switch (invalidReferenceSetting.Behaviour) { case BehaviourOnInvalidReference.ignore: #region ignore //set lower levelKeys to null because it is not possible to go any lower AddNodeRecursiveBackward(aReferenceObjectUUID, myNode.GetObjectUUID(), myCurrentLevelKey, aLowerLevelKey, null, myGraph); myNode.AddBackwardEdge(edgeKeyForBackwardEdge, aReferenceObjectUUID, null); #endregion break; case BehaviourOnInvalidReference.log: AddWarning(new Warning_EdgeToNonExistingNode(myNode.GetDBObjectStream(_DBObjectCache, referencedType.UUID), currentAttribute.GetDBType(_DBContext.DBTypeManager), currentAttribute, referencedDBObject.IErrors)); break; default: throw new GraphDBException(new Error_NotImplemented(new System.Diagnostics.StackTrace())); } #endregion } else { AddNodeRecursiveBackward(aReferenceObjectUUID, myNode.GetObjectUUID(), myCurrentLevelKey, aLowerLevelKey, lowerLevelKeys, myGraph); myNode.AddBackwardEdge(edgeKeyForBackwardEdge, aReferenceObjectUUID, null); } } } } } } }
private void RemoveReferenceFromUpperLevel(IExpressionNode myExpressionNode, LevelKey mylevelKey, IExpressionGraph myGraph) { #region remove reference from upper level if (myGraph.Levels.ContainsKey(mylevelKey.Level + 1)) { foreach (var aForwardEdgeSet in myExpressionNode.ForwardEdges) { var forwardLevelKey = GetForwardLevelKey(mylevelKey, aForwardEdgeSet.Key, _DBContext.DBTypeManager); if (myGraph.ContainsLevelKey(forwardLevelKey)) { //go to every object the forwardEdge points to and remove the backward reference foreach (var aForwardEdge in aForwardEdgeSet.Value) { if (myGraph.Levels[forwardLevelKey.Level].ExpressionLevels[forwardLevelKey].Nodes.ContainsKey(aForwardEdge.Destination)) { myGraph.Levels[forwardLevelKey.Level].ExpressionLevels[forwardLevelKey].Nodes[aForwardEdge.Destination].RemoveBackwardEdge(mylevelKey.LastEdge, myExpressionNode.GetObjectUUID()); if (!myGraph.Levels[forwardLevelKey.Level].ExpressionLevels[forwardLevelKey].Nodes[aForwardEdge.Destination].BackwardEdges.Exists(item => item.Value.Count > 0)) { //the current object has no backward Edges... delete it //remove upper references RemoveReferenceFromUpperLevel(myGraph.Levels[forwardLevelKey.Level].ExpressionLevels[forwardLevelKey].Nodes[aForwardEdge.Destination], forwardLevelKey, myGraph); //remove the node itself myGraph.Levels[forwardLevelKey.Level].ExpressionLevels[forwardLevelKey].Nodes.Remove(aForwardEdge.Destination); } } } } } } #endregion }
private void MergeNodeIntoGraph(IExpressionGraph destinationGraph, LevelKey levelKey, IExpressionNode aNode, IExpressionGraph sourceGraph) { if (destinationGraph.Levels[levelKey.Level].ExpressionLevels[levelKey].Nodes.ContainsKey(aNode.GetObjectUUID())) { if (levelKey.Level != 0) { //check if the node has backward edes if ((aNode.BackwardEdges.Count != 0) || (destinationGraph.Levels[levelKey.Level].ExpressionLevels[levelKey].Nodes[aNode.GetObjectUUID()].BackwardEdges.Count != 0)) { //check if the node has backward edes destinationGraph.Levels[levelKey.Level].AddNode(levelKey, aNode); } } else { //nothing has to be checked destinationGraph.Levels[levelKey.Level].AddNode(levelKey, aNode); } } else { //the node does not exist if (levelKey.Level != 0) { if (aNode.BackwardEdges.Exists(item => item.Value.Count != 0)) { //check if the node has backward edes destinationGraph.Levels[levelKey.Level].AddNode(levelKey, aNode); } else { //remove the backward edge from the upper level RemoveReferenceFromUpperLevel(aNode, levelKey, sourceGraph); } } else { //nothing has to be checked destinationGraph.Levels[levelKey.Level].AddNode(levelKey, aNode); } } }
private void RemoveNodeReferncesFromGraph(IExpressionNode myExpressionNode, LevelKey mylevelKey, IExpressionGraph myGraph, HashSet<LevelKey> integratedByAnOtherGraph) { #region remove complex connection foreach (var aComplexConnection in myExpressionNode.ComplexConnection) { var expressionLevelEntry = myGraph.Levels[aComplexConnection.Key.Level].ExpressionLevels[aComplexConnection.Key]; foreach (var aReference in aComplexConnection.Value) { if (expressionLevelEntry.Nodes.ContainsKey(aReference)) { expressionLevelEntry.Nodes[aReference].RemoveComplexConnection(mylevelKey, myExpressionNode.GetObjectUUID()); RemoveNodeReferncesFromGraph(expressionLevelEntry.Nodes[aReference], aComplexConnection.Key, myGraph, integratedByAnOtherGraph); } if (myGraph.Levels.ContainsKey(aComplexConnection.Key.Level - 1)) { foreach (var aBackwardEdgeSet in expressionLevelEntry.Nodes[aReference].BackwardEdges) { //go to every object the backwardEdge points to and remove the forward reference var backwardLevelKey = GetBackwardLevelKey(aComplexConnection.Key, aBackwardEdgeSet.Key, _DBContext.DBTypeManager); if (myGraph.ContainsLevelKey(backwardLevelKey)) { foreach (var aBackwardEdge in aBackwardEdgeSet.Value) { if (myGraph.Levels[backwardLevelKey.Level].ExpressionLevels[backwardLevelKey].Nodes.ContainsKey(aBackwardEdge.Destination)) { myGraph.Levels[backwardLevelKey.Level].RemoveNode(backwardLevelKey, aBackwardEdge.Destination); } } } } } myGraph.Levels[aComplexConnection.Key.Level].RemoveNode(aComplexConnection.Key, aReference); } } #endregion #region remove reference from lower level if (mylevelKey.Level != 0) { if (myGraph.Levels.ContainsKey(mylevelKey.Level - 1)) { foreach (var aBackwardEdgeSet in myExpressionNode.BackwardEdges) { //go to every object the backwardEdge points to and remove the forward reference var backwardLevelKey = GetBackwardLevelKey(mylevelKey, aBackwardEdgeSet.Key, _DBContext.DBTypeManager); if (myGraph.ContainsLevelKey(backwardLevelKey)) { foreach (var aBackwardEdge in aBackwardEdgeSet.Value) { if (myGraph.Levels[backwardLevelKey.Level].ExpressionLevels[backwardLevelKey].Nodes.ContainsKey(aBackwardEdge.Destination)) { myGraph.Levels[backwardLevelKey.Level].ExpressionLevels[backwardLevelKey].Nodes[aBackwardEdge.Destination].RemoveForwardEdge(mylevelKey.LastEdge, myExpressionNode.GetObjectUUID()); } } } } } } #endregion RemoveReferenceFromUpperLevel(myExpressionNode, mylevelKey, myGraph); }
public void AddNode(LevelKey levelKey, IExpressionNode expressionNode) { lock (_Content) { if (_Content.ContainsKey(levelKey)) { var tempObjectUUID = expressionNode.GetObjectUUID(); if (_Content[levelKey].Nodes.ContainsKey(tempObjectUUID)) { //the node already exist, so update its edges foreach (var aBackwardEdge in expressionNode.BackwardEdges) { _Content[levelKey].Nodes[tempObjectUUID].AddBackwardEdges(aBackwardEdge.Value); } foreach (var aForwardsEdge in expressionNode.ForwardEdges) { _Content[levelKey].Nodes[tempObjectUUID].AddForwardEdges(aForwardsEdge.Value); } } else { _Content[levelKey].Nodes.Add(tempObjectUUID, expressionNode); } } else { _Content.Add(levelKey, new ExpressionLevelEntry(levelKey)); _Content[levelKey].Nodes.Add(expressionNode.GetObjectUUID(), expressionNode); } } }