/// <summary> /// Writes an DBObject into log /// </summary> /// <param name="myObjectUUID">The UUID of the Object</param> /// <param name="myTypeManager">The corresponding type manager</param> /// <param name="myTypeAttribute">The type attribute</param> public static void ShowDBObject(ObjectUUID myObjectUUID, DBTypeManager myTypeManager, TypeAttribute myTypeAttribute, DBObjectCache myObjectCache) { var currentDBObject = myObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myTypeManager), myObjectUUID); if (currentDBObject.Failed()) throw new NotImplementedException(); }
private Exceptional<Boolean> GetComplexMatch(IEnumerable<Tuple<GraphDBType, AAttributeIndex>> myIDX, Dictionary<DBObjectStream, AOperationDefinition> operands, DBObjectCache dbObjectCache, IDChainDefinition primIDNode, IDChainDefinition operandIDNode, DBContext dbContext, TypesOfAssociativity associativity, ref IExpressionGraph resultGraph, SessionSettings mySessionToken) { LevelKey primLevelKey = CreateLevelKey(primIDNode, dbContext.DBTypeManager); LevelKey operandLevelKey = CreateLevelKey(operandIDNode, dbContext.DBTypeManager); foreach (var aIDX in myIDX) { if (aIDX.Item2.IsUUIDIndex) { #region UUID idx var currentIndexRelatedType = dbContext.DBTypeManager.GetTypeByUUID(aIDX.Item2.IndexRelatedTypeUUID); foreach (var aOperand in operands) { foreach (var _ObjectUUIDs in ((UUIDIndex)aIDX.Item2).GetAllUUIDs(currentIndexRelatedType, dbContext)) { var DBObjectStream = dbObjectCache.LoadDBObjectStream(aIDX.Item1, _ObjectUUIDs); if (DBObjectStream.Failed()) { return new Exceptional<bool>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } if (IsValidDBObjectStreamForBinExpr(DBObjectStream.Value, primIDNode.LastAttribute, dbContext.DBTypeManager)) { var aCtype = GraphDBTypeMapper.ConvertGraph2CSharp(primIDNode.LastAttribute.GetDBType(dbContext.DBTypeManager).Name); IObject dbos = GetDbos(primIDNode, DBObjectStream.Value, dbContext, mySessionToken, dbObjectCache); Exceptional<AOperationDefinition> tempResult; if (aCtype == BasicType.SetOfDBObjects) { tempResult = this.SimpleOperation(new TupleDefinition(aCtype, dbos, primIDNode.LastAttribute.GetDBType(dbContext.DBTypeManager)), aOperand.Value, TypesOfBinaryExpression.Complex); } else { tempResult = this.SimpleOperation(new ValueDefinition(aCtype, dbos), aOperand.Value, TypesOfBinaryExpression.Complex); } if (tempResult.Failed()) return new Exceptional<bool>(tempResult); var tempOperatorResult = ((ValueDefinition)tempResult.Value); if ((Boolean)tempOperatorResult.Value.Value) { switch (associativity) { case TypesOfAssociativity.Neutral: case TypesOfAssociativity.Left: IntegrateInGraph(aOperand.Key, resultGraph, operandLevelKey, dbContext, dbObjectCache); break; case TypesOfAssociativity.Right: IntegrateInGraph(DBObjectStream.Value, resultGraph, primLevelKey, dbContext, dbObjectCache); break; default: return new Exceptional<bool>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } } } } } #endregion } else { return new Exceptional<bool>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } } return new Exceptional<bool>(true); }
private Exceptional<Boolean> MatchComplexData(TypesOfAssociativity associativity, DataContainer data, DBContext dbContext, DBObjectCache dbObjectCache, TypesOfBinaryExpression typeOfBinExpr, IEnumerable<Tuple<GraphDBType, AAttributeIndex>> leftIndices, IEnumerable<Tuple<GraphDBType, AAttributeIndex>> rightIndices, ref List<GraphDBError> errors, ref IExpressionGraph result, SessionSettings mySessionToken) { #region data Dictionary<DBObjectStream, AOperationDefinition> operandsLeft = null; Dictionary<DBObjectStream, AOperationDefinition> operandsRight = null; #endregion #region handle extraordinaries if (data.Extraordinaries.Item1 != null) { #region left extraordinary //there is something like a function or so operandsLeft = new Dictionary<DBObjectStream, AOperationDefinition>(); //we have to calculate the real operand. //TODO: try to use attribute idx instead of uuid idx foreach (var aLeftIDX in leftIndices) { AAttributeIndex currentLeftIdx = null; #region get UUID idx if (!(aLeftIDX.Item2.IsUUIDIndex)) { currentLeftIdx = aLeftIDX.Item1.GetUUIDIndex(dbContext); } else { currentLeftIdx = aLeftIDX.Item2; } #endregion var currentIndexRelatedType = dbContext.DBTypeManager.GetTypeByUUID(currentLeftIdx.IndexRelatedTypeUUID); foreach (var aObjectUUIDs_Left in currentLeftIdx.GetAllValues(currentIndexRelatedType, dbContext)) { foreach (var aObjectUUID_Left in aObjectUUIDs_Left) { var leftDBObject = dbObjectCache.LoadDBObjectStream(aLeftIDX.Item1, aObjectUUID_Left); if (leftDBObject.Failed()) { throw new NotImplementedException(); } if (IsValidDBObjectStreamForBinExpr(leftDBObject.Value, data.IDChainDefinitions.Item1.LastAttribute, dbContext.DBTypeManager)) { var oper = GetOperand(data.IDChainDefinitions.Item1, data.Extraordinaries.Item1, dbContext, leftDBObject.Value, dbObjectCache, mySessionToken); if (oper.Failed()) return new Exceptional<bool>(oper); if (oper != null) { operandsLeft.Add(leftDBObject.Value, oper.Value); } } } } } //from now on the binary expression is right complex, because there are atom values on the left typeOfBinExpr = TypesOfBinaryExpression.RightComplex; #endregion } if (data.Extraordinaries.Item2 != null) { #region right extraordinary //there is something like a function or so operandsRight = new Dictionary<DBObjectStream, AOperationDefinition>(); foreach (var aRightIDX in rightIndices) { AAttributeIndex currentRightIdx = null; #region get UUID idx //we have to calculate the real operand. //TODO: try to use attribute idx instead of uuid idx if (!(aRightIDX.Item2.IsUUIDIndex)) { currentRightIdx = aRightIDX.Item1.GetUUIDIndex(dbContext); } else { currentRightIdx = aRightIDX.Item2; } #endregion var currentIndexRelatedType = dbContext.DBTypeManager.GetTypeByUUID(currentRightIdx.IndexRelatedTypeUUID); foreach (var aObjectUUIDs_Right in currentRightIdx.GetAllValues(currentIndexRelatedType, dbContext)) { foreach (var aObjectUUID_Right in aObjectUUIDs_Right) { var rightDBObject = dbObjectCache.LoadDBObjectStream(aRightIDX.Item1, aObjectUUID_Right); if (rightDBObject.Failed()) { throw new NotImplementedException(); } if (IsValidDBObjectStreamForBinExpr(rightDBObject.Value, data.IDChainDefinitions.Item2.LastAttribute, dbContext.DBTypeManager)) { var oper = GetOperand(data.IDChainDefinitions.Item2, data.Extraordinaries.Item2, dbContext, rightDBObject.Value, dbObjectCache, mySessionToken); if (oper.Failed()) return new Exceptional<bool>(oper); if (oper != null) { operandsRight.Add(rightDBObject.Value, oper.Value); } } } } } if (typeOfBinExpr == TypesOfBinaryExpression.RightComplex) { typeOfBinExpr = TypesOfBinaryExpression.Atom; } #endregion } #endregion switch (typeOfBinExpr) { case TypesOfBinaryExpression.Atom: #region atom switch (associativity) { case TypesOfAssociativity.Unknown: case TypesOfAssociativity.Neutral: GetComplexAtom(dbContext, operandsLeft, operandsRight, data.IDChainDefinitions.Item1, dbObjectCache, ref result); GetComplexAtom(dbContext, operandsRight, operandsLeft, data.IDChainDefinitions.Item2, dbObjectCache, ref result); break; case TypesOfAssociativity.Left: GetComplexAtom(dbContext, operandsLeft, operandsRight, data.IDChainDefinitions.Item1, dbObjectCache, ref result); break; case TypesOfAssociativity.Right: GetComplexAtom(dbContext, operandsRight, operandsLeft, data.IDChainDefinitions.Item2, dbObjectCache, ref result); break; default: return new Exceptional<bool>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } #endregion break; case TypesOfBinaryExpression.LeftComplex: #region Left complex GetComplexMatch(leftIndices, operandsRight, dbObjectCache, data.IDChainDefinitions.Item1, data.IDChainDefinitions.Item2, dbContext, associativity, ref result, mySessionToken); #endregion break; case TypesOfBinaryExpression.RightComplex: #region Right complex GetComplexMatch(rightIndices, operandsLeft, dbObjectCache, data.IDChainDefinitions.Item2, data.IDChainDefinitions.Item1, dbContext, associativity, ref result, mySessionToken); #endregion break; case TypesOfBinaryExpression.Complex: #region Complex LevelKey leftLevelKey = CreateLevelKey(data.IDChainDefinitions.Item1, dbContext.DBTypeManager); LevelKey rightLevelKey = CreateLevelKey(data.IDChainDefinitions.Item2, dbContext.DBTypeManager); GraphDBType leftGraphDBType = data.IDChainDefinitions.Item1.LastType; GraphDBType rightGraphDBType = data.IDChainDefinitions.Item2.LastType; #region exception if (leftIndices.CountIsGreater(1) || rightIndices.CountIsGreater(1)) { return new Exceptional<bool>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } #endregion var leftIndexRelatedType = dbContext.DBTypeManager.GetTypeByUUID(leftIndices.First().Item2.IndexRelatedTypeUUID); var rightIndexRelatedType = dbContext.DBTypeManager.GetTypeByUUID(rightIndices.First().Item2.IndexRelatedTypeUUID); foreach (var ObjectUUIDs_left in leftIndices.First().Item2.GetAllValues(leftIndexRelatedType, dbContext)) { foreach (var aLeftUUID in ObjectUUIDs_left) { var leftDBObject = dbObjectCache.LoadDBObjectStream(leftIndices.First().Item1, aLeftUUID); if (leftDBObject.Failed()) { return new Exceptional<bool>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } if (IsValidDBObjectStreamForBinExpr(leftDBObject.Value, data.IDChainDefinitions.Item1.LastAttribute, dbContext.DBTypeManager)) { foreach (var ObjectUUIDs_right in rightIndices.First().Item2.GetAllValues(rightIndexRelatedType, dbContext)) { foreach (var aRightUUID in ObjectUUIDs_right) { var rightDBObject = dbObjectCache.LoadDBObjectStream(rightIndices.First().Item1, aRightUUID); if (rightDBObject.Failed()) { return new Exceptional<bool>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } if (IsValidDBObjectStreamForBinExpr(rightDBObject.Value, data.IDChainDefinitions.Item2.LastAttribute, dbContext.DBTypeManager)) { //everything is valid var leftType = GraphDBTypeMapper.ConvertGraph2CSharp(data.IDChainDefinitions.Item1.LastAttribute.GetDBType(dbContext.DBTypeManager).Name); var rightType = GraphDBTypeMapper.ConvertGraph2CSharp(data.IDChainDefinitions.Item2.LastAttribute.GetDBType(dbContext.DBTypeManager).Name); AOperationDefinition leftValue; AOperationDefinition rightValue; if (data.IDChainDefinitions.Item1.LastAttribute.KindOfType == KindsOfType.SetOfReferences || data.IDChainDefinitions.Item1.LastAttribute.KindOfType == KindsOfType.ListOfNoneReferences || data.IDChainDefinitions.Item1.LastAttribute.KindOfType == KindsOfType.SetOfNoneReferences) leftValue = new TupleDefinition(leftType, leftDBObject.Value.GetAttribute(data.IDChainDefinitions.Item1.LastAttribute.UUID), data.IDChainDefinitions.Item1.LastAttribute.GetDBType(dbContext.DBTypeManager)); else leftValue = new ValueDefinition(leftType, leftDBObject.Value.GetAttribute(data.IDChainDefinitions.Item1.LastAttribute.UUID, data.IDChainDefinitions.Item1.LastAttribute.GetRelatedType(dbContext.DBTypeManager), dbContext)); if (data.IDChainDefinitions.Item2.LastAttribute.KindOfType == KindsOfType.SetOfReferences || data.IDChainDefinitions.Item2.LastAttribute.KindOfType == KindsOfType.ListOfNoneReferences || data.IDChainDefinitions.Item2.LastAttribute.KindOfType == KindsOfType.SetOfNoneReferences) rightValue = new TupleDefinition(rightType, rightDBObject.Value.GetAttribute(data.IDChainDefinitions.Item2.LastAttribute.UUID), data.IDChainDefinitions.Item2.LastAttribute.GetDBType(dbContext.DBTypeManager)); else rightValue = new ValueDefinition(rightType, rightDBObject.Value.GetAttribute(data.IDChainDefinitions.Item2.LastAttribute.UUID, data.IDChainDefinitions.Item2.LastAttribute.GetRelatedType(dbContext.DBTypeManager), dbContext)); var tempSimpleOperationResult = this.SimpleOperation(leftValue, rightValue, typeOfBinExpr); if (tempSimpleOperationResult.Failed()) return new Exceptional<bool>(tempSimpleOperationResult); var tempOperatorResult = tempSimpleOperationResult.Value; if ((Boolean)(tempOperatorResult as ValueDefinition).Value.Value) { //found sth that is really true #region insert into graph switch (associativity) { case TypesOfAssociativity.Neutral: case TypesOfAssociativity.Left: IntegrateInGraph(leftDBObject.Value, result, leftLevelKey, dbContext, dbObjectCache); break; case TypesOfAssociativity.Right: IntegrateInGraph(rightDBObject.Value, result, rightLevelKey, dbContext, dbObjectCache); break; case TypesOfAssociativity.Unknown: if (Type == TypesOfOperators.AffectsLowerLevels) { result.AddNodesWithComplexRelation(leftDBObject, leftLevelKey, rightDBObject, rightLevelKey, dbObjectCache, 1); } else { result.AddNodesWithComplexRelation(leftDBObject, leftLevelKey, rightDBObject, rightLevelKey, dbObjectCache, 0); } break; default: return new Exceptional<bool>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } #endregion } } } } #region clean lower levels if (Type == TypesOfOperators.AffectsLowerLevels) { switch (associativity) { case TypesOfAssociativity.Neutral: case TypesOfAssociativity.Left: CleanLowerLevel(leftLevelKey, dbContext, dbObjectCache, result); break; case TypesOfAssociativity.Right: CleanLowerLevel(rightLevelKey, dbContext, dbObjectCache, result); break; case TypesOfAssociativity.Unknown: CleanLowerLevel(leftLevelKey, dbContext, dbObjectCache, result); CleanLowerLevel(rightLevelKey, dbContext, dbObjectCache, result); break; default: return new Exceptional<bool>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } } #endregion } } } #endregion break; default: return new Exceptional<bool>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } return new Exceptional<bool>(true); }
/// <summary> /// This method returns the DBObjectStream that is referenced by this node. /// </summary> /// <param name="myDBObjectCache">The actual query cache.</param> /// <param name="myTypeUUID">The TypeUUID of the DBObject.</param> /// <returns>A DBObjectStream</returns> public DBObjectStream GetDBObjectStream(DBObjectCache myDBObjectCache, TypeUUID myTypeUUID) { lock (_ObjectUUID) { if (_Object != null) { return _Object; } else { var tempObject = myDBObjectCache.LoadDBObjectStream(myTypeUUID, GetObjectUUID()); if (tempObject.Failed()) { return null; } _Object = tempObject.Value; return _Object; } } }
/// <summary> /// Writes all paths included in the HashSet. Every object is represented via a given attribute. /// /// example path between fry and morbo (attribute is "Name") /// /// output: /// Fry -> Leela -> Lrrr -> Morbo /// </summary> /// <param name="myPaths">An HashSet which contains Lists of UUIDs</param> /// <param name="myTypeManager">The type manager to load the DBObjects</param> /// <param name="myTypeAttribute">The Type Attribute</param> /// <param name="myAttribute">The Attribute which shall be used for output.</param> public static void ShowDBObjects(HashSet<List<ObjectUUID>> myPaths, DBTypeManager myTypeManager, TypeAttribute myTypeAttribute, String myAttribute, DBObjectCache myObjectCache) { var attributeUUID = myTypeAttribute.GetRelatedType(myTypeManager).GetTypeSpecificAttributeByName(myAttribute).UUID; foreach (var path in myPaths) { var pathString = new StringBuilder(); Exceptional<DBObjectStream> currentDBObject; foreach (var _ObjectUUID in path) { //load from DB currentDBObject = myObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myTypeManager), _ObjectUUID); if (currentDBObject.Failed()) { throw new NotImplementedException(); } pathString.Append(currentDBObject.Value.GetAttribute(attributeUUID) + " -> "); } ////_Logger.Info(pathString.ToString()); pathString.Remove(0, pathString.Length); } }
/// <summary> /// Searches shortest, all shortest or all paths starting from "myStart" to "myEnd". /// </summary> /// <param name="myTypeAttribute">The Attribute representing the edge to follow (p.e. "Friends")</param> /// <param name="myTypeManager">The TypeManager for the Node type</param> /// <param name="myDBObjectCache">The Object Cache for faster object lookup</param> /// <param name="myStart">The start node</param> /// <param name="myEnd">The end node</param> /// <param name="shortestOnly">true, if only shortest path shall be found</param> /// <param name="findAll">if true and shortestOnly is true, all shortest paths will be found. if true, and shortest only is false, all paths will be searched</param> /// <param name="myMaxDepth">The maximum depth to search</param> /// <param name="myMaxPathLength">The maximum path length which shall be analyzed</param> /// <returns>A HashSet which contains all found paths. Every path is represented by a List of ObjectUUIDs</returns> public HashSet<List<ObjectUUID>> Find(TypeAttribute myTypeAttribute, DBTypeManager myTypeManager, DBObjectCache myDBObjectCache, DBObjectStream myStart, DBObjectStream myEnd, bool shortestOnly, bool findAll, byte myMaxDepth, byte myMaxPathLength) { #region data //queue for BFS Queue<Node> queue = new Queue<Node>(); //Dictionary to store visited TreeNodes BigDictionary<ObjectUUID, Node> visitedNodes = new BigDictionary<ObjectUUID, Node>(); //current depth byte depth = 0; //first node in path tree, the start of the select Node root = new Node(myStart.ObjectUUID); //root changed in Dictionary because of BidirectionalBFS HashSet<ObjectUUID> rootFriends = new HashSet<ObjectUUID>(); //target node, the target of the select Node target = new Node(myEnd.ObjectUUID); //holds the key of the backwardedge EdgeKey edgeKey = new EdgeKey(myTypeAttribute); //dummy node to check in which level the BFS is Node dummy = new Node(); //if the maxDepth is greater then maxPathLength, then set maxDepth to maxPathLength if (myMaxDepth > myMaxPathLength) { myMaxDepth = myMaxPathLength; } //enqueue first node to start the BFS queue.Enqueue(root); queue.Enqueue(dummy); //add root to visitedNodes visitedNodes.Add(root.Key, root); //holds the actual DBObject Exceptional<DBObjectStream> currentDBObject; #endregion #region BFS //Log start ////_Logger.Info("Starting BFS.."); //check if root node has edge and target has backwardedge var dbObject = myDBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myTypeManager), root.Key); if (dbObject.Failed()) { throw new NotImplementedException(); } if (!dbObject.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myTypeManager))) { ////_Logger.Info("Abort search! Start object has no edge!"); //Console.WriteLine("No paths found!"); return null; } var be = myDBObjectCache.LoadDBBackwardEdgeStream(myTypeAttribute.GetRelatedType(myTypeManager), target.Key); if (be.Failed()) { throw new NotImplementedException(); } if (!be.Value.ContainsBackwardEdge(edgeKey)) { ////_Logger.Info("Abort search! End object has no backwardedge!"); //Console.WriteLine("No paths found!"); return null; } //if there is more than one object in the queue and the actual depth is less than MaxDepth while ((queue.Count > 0) && (depth <= myMaxDepth)) { //get the first Object of the queue Node current = queue.Dequeue(); //dummy if (current.Key == null) { break; } //load DBObject currentDBObject = myDBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myTypeManager), current.Key); if (currentDBObject.Failed()) { throw new NotImplementedException(); } if (currentDBObject.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myTypeManager))) { if (myTypeAttribute.EdgeType is ASetOfReferencesEdgeType) { //get all referenced ObjectUUIDs using the given Edge var objectUUIDs = (currentDBObject.Value.GetAttribute(myTypeAttribute.UUID) as ASetOfReferencesEdgeType).GetAllReferenceIDs(); Node currentNode; foreach(ObjectUUID dbo in objectUUIDs) { //only for debug //var currentNodeObject = myTypeManager.LoadDBObject(myTypeAttribute.RelatedGraphType, dbo); //create a new node and set current = parent, currentNode = child currentNode = new Node(dbo, current); //if the child is the target if (currentNode.Key.Equals(myEnd.ObjectUUID)) { //node points on the target target.Parents.Add(current); //if shortestOnly == true we are finished here if(shortestOnly) { if (findAll) { //continue searching the current depth if there are any other shortest paths myMaxDepth = Convert.ToByte(depth); myMaxPathLength = Convert.ToByte(depth + 2); } else { ////_Logger.Info("found shortest path."); //got the shortest, finished return new TargetAnalyzer(root, rootFriends, target, myMaxPathLength, shortestOnly, findAll).getPaths(); } } } else { //been there before if (visitedNodes.ContainsKey(currentNode.Key)) { //if currentNode.Key isn't root set parent if (!rootFriends.Contains(currentNode.Key)) { //node has more then one parent visitedNodes[currentNode.Key].Parents.Add(current); } continue; } //never seen before //mark the node as visited visitedNodes.Add(currentNode.Key, currentNode); //and look what comes on the next level of depth queue.Enqueue(currentNode); //some logging if (queue.Count % 10000 == 0) { ////_Logger.Info(queue.Count + " elements enqueued.."); } } } } else if (myTypeAttribute.EdgeType is ASingleReferenceEdgeType) { throw new NotImplementedException(); } else { throw new NotImplementedException(); } } //if a new depth is reached if (queue.First() == dummy) { //enqueue the dummy at the end of to mark the next depth queue.Enqueue(queue.Dequeue()); //one step deeper in the dungen depth++; ////_Logger.Info("going deeper in the dungeon.. current level: " + depth); } } #endregion ////_Logger.Info("finished building path-graph.. starting analyzer"); //analyze paths return new TargetAnalyzer(root, rootFriends, target, myMaxPathLength, shortestOnly, findAll).getPaths(); }