Example #1
1
        public TargetAnalyzer(Node myStart, HashSet<ObjectUUID> myStartFriends, Node myEnd, byte myMaxPathLength)
        {
            _Paths = new HashSet<List<ObjectUUID>>();

            _TempList = new List<ObjectUUID>();

            _Start = myStart;

            _StartFriends = myStartFriends;

            _End = myEnd;

            if (myMaxPathLength != 0)
            {
                _MaxPathLength = Convert.ToByte(myMaxPathLength - 1);
            }
            else
            {
                _MaxPathLength = Convert.ToByte(myMaxPathLength);
            }
        }
Example #2
0
 public Node(ObjectUUID myObjectUUID, Node myParent)
     : this(myObjectUUID)
 {
     _Parents.Add(myParent);
 }
Example #3
0
        /// <summary>
        /// Fügt dem Knoten ein Parent hinzu, existiert dieser schon, werden die Parents und Children des existierenden aktualisiert.
        /// </summary>
        /// <param name="myParent">Parent welcher hinzugefügt werden soll.</param>
        /// <returns></returns>
        public bool addParent(Node myParent)
        {
            bool equal = false;

            foreach (var thisParent in _Parents)
            {
                //check if the node wich should be added IS already existing
                if (thisParent._Key.Equals(myParent.Key))
                {
                    //exists
                    equal = true;

                    break;
                }
            }

            //node is NOT already existing, add
            if (!equal)
            {
                return _Parents.Add(myParent);
            }

            return false;
        }
Example #4
0
        /// <summary>
        /// Fügt dem Knoten ein Child hinzu, existiert dieser schon, werden die Parents und Children des existierenden aktualisiert.
        /// </summary>
        /// <param name="myChild">Child welches hinzugefügt werden soll.</param>
        /// <returns></returns>
        public bool addChild(Node myChild)
        {
            bool equal = false;

            foreach (var thisChild in _Children)
            {
                //check if the node wich should be added IS already existing
                if (thisChild._Key.Equals(myChild.Key))
                {
                    equal = true;

                    break;
                }
            }

            if (!equal)
            {
                return _Children.Add(myChild);
            }

            return false;
        }
Example #5
0
        /// <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();
        }
        public BidirectionalTargetAnalyzer(Node myStart, Node myEnd)
        {
            _TempListLeft = new LinkedList<ObjectUUID>();
            _TempListRight = new LinkedList<ObjectUUID>();

            _LeftPaths = new HashSet<LinkedList<ObjectUUID>>();
            _RightPaths = new HashSet<LinkedList<ObjectUUID>>();

            _Paths = new HashSet<List<ObjectUUID>>();
            _PathsQueue = new Queue<List<ObjectUUID>>();

            _Start = myStart;
            _End = myEnd;
        }
        private void getPath(Node myCurrent)
        {
            //add myCurrent to actual path
            _TempListLeft.AddLast(myCurrent.Key);
            //set flag to mark that myCurrent is in actual path
            myCurrent.AlreadyInPath = true;

            //abort recursion when myCurrent is the root node
            if (myCurrent.Key.Equals(_Start.Key))
            {
                //duplicate list
                var temp = new List<ObjectUUID>(_TempListLeft);

                if (!QueueContainsList(_PathsQueue, temp))
                {
                    //turn around the path (we're currently at the root)
                    temp.Reverse();

                    //add completed path to result list
                    _PathsQueue.Enqueue(temp);

                    //do some logging
                    PathViewer.LogPath(temp);

                    if (_ShortestOnly && !_FindAll)
                    {
                        //first path is analyzed
                        _Done = true; //we can stop evaluating next parents
                        return;
                    }
                }
            }

            foreach (Node parent in myCurrent.Parents)
            {
                //if parent node not already in actual path
                if (!parent.AlreadyInPath)
                {
                    //and MaxPathLength is not reached
                    if (_TempListLeft.Count < _MaxPathLength)
                    {
                        if (!_Done)
                        {
                            getPath(parent);
                        }
                    }
                }
            }

            //remove last node from actual path
            _TempListLeft.RemoveLast();
            //myCurrent isn't in actual path
            myCurrent.AlreadyInPath = false;

            return;
        }
        public BidirectionalTargetAnalyzer(Node myStart, Node myEnd, byte myMaxPathLength, bool myShortestOnly, bool myFindAll)
            : this(myStart, myEnd)
        {
            _ShortestOnly = myShortestOnly;
            _FindAll = myFindAll;

            _MaxPathLength = myMaxPathLength;
        }
Example #9
0
        //Logger
        //private static Logger //_Logger = LogManager.GetCurrentClassLogger();
        /// <summary>
        /// Please look at the class documentation for detailed description how this algorithm works.
        /// </summary>
        /// <param name="myTypeAttribute">The Attribute representing the edge to follow (p.e. "Friends")</param>
        /// <param name="myDBContext">The DBContext holds the TypeManager and the ObjectCache</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>m>
        public HashSet<List<ObjectUUID>> Find(TypeAttribute myTypeAttribute, DBContext myDBContext, DBObjectStream myStart, IReferenceEdge myEdge, DBObjectStream myEnd, bool shortestOnly, bool findAll, byte myMaxDepth, byte myMaxPathLength)
        {
            #region declarations
            //queue for BFS
            var queueLeft  = new Queue<Node>();
            var queueRight = new Queue<Node>();

            //Dictionary to store visited TreeNodes
            var visitedNodesLeft  = new BigDictionary<ObjectUUID, Node>();
            var visitedNodesRight = new BigDictionary<ObjectUUID, Node>();

            //set current depth left
            byte depthLeft = 2;
            //set current depth right
            byte depthRight = 1;

            //maximum depth
            byte maxDepthLeft = 0;
            byte maxDepthRight = 0;

            #region initialize maxDepths
            //if the maxDepth is greater then maxPathLength, then set maxDepth to maxPathLength
            if (myMaxDepth > myMaxPathLength)
            {
                myMaxDepth = myMaxPathLength;
            }

            //set depth for left side
            maxDepthLeft = Convert.ToByte(myMaxDepth / 2 + 1);

            //if myMaxDepth is 1 maxDepthRight keeps 0, just one side is searching
            if (myMaxDepth > 1)
            {
                //both sides have the same depth
                maxDepthRight = maxDepthLeft;
            }

            //if myMaxDepth is even, one side has to search in a greater depth
            if ((myMaxDepth % 2) == 0)
            {
                maxDepthRight = Convert.ToByte(maxDepthLeft - 1);
            }
            #endregion

            //shortest path length
            byte shortestPathLength = 0;

            //target node, the target of the select
            var target = new Node(myEnd.ObjectUUID);
            var root = new Node(myStart.ObjectUUID);
            HashSet<ObjectUUID> rootFriends = new HashSet<ObjectUUID>();

            //dummy node to check in which level the BFS is
            var dummyLeft = new Node();
            var dummyRight = new Node();

            #region get friends of startElement and check if they are the target and valid
            //instead of inserting only the startObject, we are using the startObject and the friends of the startObject (which could be restricted)
            var firstUUIDs = myEdge.GetAllReferenceIDs();

            foreach (var element in firstUUIDs)
            {
                if (element != null)
                {
                    //create a new node and set root = parent
                    var currentNodeLeft = new Node(element);

                    #region check if the child is the target
                    //start and target are conntected directly
                    if (currentNodeLeft.Key == myEnd.ObjectUUID)
                    {
                        //set depthRight to zero
                        depthRight = 0;

                        //add node (which coud be the target) to startFriends (if start and target are directly connected, the target in the rootFriends list is needed)
                        rootFriends.Add(currentNodeLeft.Key);

                        shortestPathLength = Convert.ToByte(depthLeft);

                        return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                    }
                    #endregion check if the child is the target

                    //check if element has edge
                    var dbo = myDBContext.DBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), currentNodeLeft.Key);
                    if (dbo.Failed())
                    {
                        continue;
                    }

                    if (!dbo.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager)))
                    {
                        continue;
                    }

                    //enqueue node to start from left side
                    queueLeft.Enqueue(currentNodeLeft);

                    //add node to visitedNodes
                    visitedNodesLeft.Add(currentNodeLeft.Key, currentNodeLeft);

                    //add node to startFriends
                    rootFriends.Add(currentNodeLeft.Key);
                }
            }

            #endregion get friends of startElement and check if they are the target and valid

            //elements of myEdge doesn't have edge
            if (visitedNodesLeft.Count == 0)
            {
                return null;
            }

            //check if target already found
            if (shortestPathLength != 0)
            {
                return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
            }

            //enqueue dummyLeft to analyze the depth of the left side
            queueLeft.Enqueue(dummyLeft);

            //holds the key of the backwardedge
            var edgeKey = new EdgeKey(myTypeAttribute);

            //holds the actual DBObject
            Exceptional<DBObjectStream> currentDBObjectLeft;
            Exceptional<BackwardEdgeStream> currentDBObjectRight;
            #endregion declarations

            #region BidirectionalBFS
            //check if the EdgeType is ASetReferenceEdgeType
            #region EdgeType is ASetReferenceEdgeType
            if (myEdge is ASetOfReferencesEdgeType)
            {
                #region initialize variables
                //enqueue target node to start from right side
                queueRight.Enqueue(target);

                //enqueue dummyRight to analyze the depth of the right side
                queueRight.Enqueue(dummyRight);

                //add root and target to visitedNodes
                visitedNodesRight.Add(target.Key, target);
                #endregion initialize variables

                #region check if target has backwardedge
                var be = myDBContext.DBObjectCache.LoadDBBackwardEdgeStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), target.Key);
                if (be.Failed())
                {
                    throw new NotImplementedException();
                }

                if (!be.Value.ContainsBackwardEdge(edgeKey))
                {
                    return null;
                }
                #endregion check if target has backwardedge

                //if there is more than one object in the queue and the actual depth is less than MaxDepth
                while (((queueLeft.Count > 0) && (queueRight.Count > 0)) && ((depthLeft <= maxDepthLeft) || (depthRight <= maxDepthRight)))
                {
                    #region both queues contain objects and both depths are not reached
                    if (((queueLeft.Count > 0) && (queueRight.Count > 0)) && ((depthLeft <= maxDepthLeft) && (depthRight <= maxDepthRight)))
                    {
                        //hold the actual element of the queues
                        Node currentLeft;
                        Node currentRight;

                        #region check if there is a dummyNode at the beginning of a queue
                        //first of both queues are dummies
                        if ((queueLeft.First<Node>() == dummyLeft) && (queueRight.First<Node>() == dummyRight))
                        {
                            //if maxDepth of a side is reached and there is a dummy, one level is totaly searched
                            if (depthLeft == maxDepthLeft && depthRight == maxDepthRight)
                            {
                                ////_Logger.Info("going deeper in the dungeon on the left side.. current level: " + depthLeft);
                                depthLeft++;
                                ////_Logger.Info("going deeper in the dungeon on the right side.. current level: " + depthRight);
                                depthRight++;

                                continue;
                            }
                            else if (depthLeft == maxDepthLeft)
                            {
                                ////_Logger.Info("going deeper in the dungeon on the left side.. current level: " + depthLeft);
                                depthLeft++;

                                continue;
                            }
                            else if (depthRight == maxDepthRight)
                            {
                                ////_Logger.Info("going deeper in the dungeon on the right side.. current level: " + depthRight);
                                depthRight++;

                                continue;
                            }

                            //dequeue dummies
                            queueLeft.Dequeue();
                            queueRight.Dequeue();

                            //increase depth's
                            ////_Logger.Info("going deeper in the dungeon on the left side.. current level: " + depthLeft);
                            depthLeft++;
                            ////_Logger.Info("going deeper in the dungeon on the right side.. current level: " + depthRight);
                            depthRight++;

                            //if both queues are empty -> break loop
                            if (queueLeft.Count == 0 && queueRight.Count == 0)
                            {
                                break;
                            }
                            //if left queue is empty enqueue right dummy and continue
                            else if (queueLeft.Count == 0)
                            {
                                queueRight.Enqueue(dummyRight);
                                continue;
                            }
                            //if right queue is empty enqueue left dummy and continue
                            else if (queueRight.Count == 0)
                            {
                                queueLeft.Enqueue(dummyLeft);
                                continue;
                            }
                            //enqueue both dummies
                            else
                            {
                                queueLeft.Enqueue(dummyLeft);
                                queueRight.Enqueue(dummyRight);
                            }
                        }
                        //first of left queue is a dummy
                        else if (queueLeft.First<Node>() == dummyLeft)
                        {
                            //if maxDepth of a side is reached and there is a dummy, one level is totaly searched
                            if (depthLeft == maxDepthLeft)
                            {
                                //_Logger.Info("going deeper in the dungeon on the left side.. current level: " + depthLeft);
                                depthLeft++;

                                continue;
                            }

                            //dequeue dummy
                            queueLeft.Dequeue();

                            //increase depth
                            //_Logger.Info("going deeper in the dungeon on the left side.. current level: " + depthLeft);
                            depthLeft++;

                            //if left queue is empty continue
                            if (queueLeft.Count == 0)
                            {
                                continue;
                            }
                            //enqueue dummy
                            else
                            {
                                queueLeft.Enqueue(dummyLeft);
                            }
                        }
                        //first of right queue is a dummy
                        else if (queueRight.First<Node>() == dummyRight)
                        {
                            //if maxDepth of a side is reached and there is a dummy, one level is totaly searched
                            if (depthRight == maxDepthRight)
                            {
                                //_Logger.Info("going deeper in the dungeon on the right side.. current level: " + depthRight);
                                depthRight++;

                                continue;
                            }

                            //dequeue dummy
                            queueRight.Dequeue();

                            //increase depth
                            //_Logger.Info("going deeper in the dungeon on the right side.. current level: " + depthRight);
                            depthRight++;

                            //if right queue is empty continue
                            if (queueRight.Count == 0)
                            {
                                continue;
                            }
                            //enqueue dummy
                            else
                            {
                                queueRight.Enqueue(dummyRight);
                            }
                        }
                        #endregion check if there is a dummyNode at the beginning of a queue

                        #region get first nodes of the queues
                        //get the first Object of the queue
                        currentLeft = queueLeft.Dequeue();
                        //get the first Object of the queue
                        currentRight = queueRight.Dequeue();
                        #endregion get first nodes of the queues

                        #region load DBObjects
                        //load DBObject
                        currentDBObjectLeft = myDBContext.DBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), currentLeft.Key);
                        if (currentDBObjectLeft.Failed())
                        {
                            throw new NotImplementedException();
                        }

                        //load DBObject
                        currentDBObjectRight = myDBContext.DBObjectCache.LoadDBBackwardEdgeStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), new ObjectUUID(currentRight.Key.ToString().TrimStart()));
                        if (currentDBObjectRight.Failed())
                        {
                            throw new NotImplementedException();
                        }
                        #endregion load DBObjects

                        #region the edge and the backwardedge are existing
                        if (currentDBObjectLeft.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager))
                            && currentDBObjectRight.Value.ContainsBackwardEdge(edgeKey))
                        {
                            //get all referenced ObjectUUIDs using the given Edge
                            var objectUUIDsLeft = (currentDBObjectLeft.Value.GetAttribute(myTypeAttribute.UUID) as ASetOfReferencesEdgeType).GetAllReferenceIDs();
                            Node currentNodeLeft;

                            #region check left friends
                            foreach (var dboLeft in objectUUIDsLeft)
                            {
                                #region if the child is the target
                                if (dboLeft == myEnd.ObjectUUID)
                                {
                                    //set currentLeft as parent of target
                                    target.addParent(currentLeft);

                                    #region check if already visited
                                    if (visitedNodesLeft.ContainsKey(dboLeft))
                                    {
                                        //set currentLeft as parent
                                        visitedNodesLeft[dboLeft].addParent(currentLeft);

                                        //set currentNodeLeft as child
                                        currentLeft.addChild(visitedNodesLeft[dboLeft]);
                                    }
                                    else
                                    {
                                        //create a new node and set currentLeft = parent
                                        currentNodeLeft = new Node(dboLeft, currentLeft);

                                        //set currentNodeLeft as child of currentLeft
                                        currentLeft.addChild(currentNodeLeft);

                                        //never seen before
                                        //mark the node as visited
                                        visitedNodesLeft.Add(currentNodeLeft.Key, currentNodeLeft);

                                        //and put node into the queue
                                        queueLeft.Enqueue(currentNodeLeft);
                                    }
                                    #endregion check if already visited

                                    #region check how much parents are searched
                                    if (shortestOnly && !findAll)
                                    {
                                        //_Logger.Info("found shortest path..starting analyzer");

                                        if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                        {
                                            shortestPathLength = myMaxPathLength;
                                        }
                                        else
                                        {
                                            shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                        }

                                        return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                    }
                                    //if find all shortest paths
                                    else if (shortestOnly && findAll)
                                    {
                                        //set maxDepth to actual depth
                                        maxDepthLeft = depthLeft;
                                        maxDepthRight = depthRight;

                                        if ((depthLeft + depthRight) > myMaxPathLength)
                                        {
                                            shortestPathLength = myMaxPathLength;
                                        }
                                        else
                                        {
                                            shortestPathLength = Convert.ToByte(depthLeft + depthRight);
                                        }
                                    }
                                    #endregion check how much parents are searched
                                }
                                #endregion if the child is the target
                                #region already visited
                                else if (visitedNodesLeft.ContainsKey(dboLeft))
                                {
                                    //set currentLeft as parent
                                    visitedNodesLeft[dboLeft].addParent(currentLeft);

                                    //set currentNodeLeft as child
                                    currentLeft.addChild(visitedNodesLeft[dboLeft]);
                                }
                                #endregion already visited
                                #region set as visited
                                else
                                {
                                    //create a new node and set currentLeft = parent
                                    currentNodeLeft = new Node(dboLeft, currentLeft);

                                    //set currentNodeLeft as child of currentLeft
                                    currentLeft.addChild(currentNodeLeft);

                                    //never seen before
                                    //mark the node as visited
                                    visitedNodesLeft.Add(currentNodeLeft.Key, currentNodeLeft);

                                    //and put node into the queue
                                    queueLeft.Enqueue(currentNodeLeft);
                                }
                                #endregion set as visited
                            }
                            #endregion check left friends

                            //get all referenced ObjectUUIDs using the given Edge
                            var objectUUIDsRight = currentDBObjectRight.Value.GetBackwardEdgeUUIDs(edgeKey);
                            Node currentNodeRight;

                            #region check right friends
                            foreach (ObjectUUID dboRight in objectUUIDsRight)
                            {
                                #region if the child is the target
                                if (rootFriends.Contains(dboRight))
                                {
                                    #region check if already visited
                                    //mark node as visited
                                    if (visitedNodesRight.ContainsKey(dboRight))
                                    {
                                        //set found children
                                        visitedNodesRight[dboRight].addChild(currentRight);

                                        currentRight.addParent(visitedNodesRight[dboRight]);
                                    }
                                    else
                                    {
                                        //create a new node and set currentRight = child
                                        currentNodeRight = new Node(dboRight);
                                        currentNodeRight.addChild(currentRight);

                                        //set currentNodeRight as parent of current Right
                                        currentRight.addParent(currentNodeRight);

                                        //never seen before
                                        //mark the node as visited
                                        visitedNodesRight.Add(currentNodeRight.Key, currentNodeRight);

                                        //and look what comes on the next level of depth
                                        queueRight.Enqueue(currentNodeRight);
                                    }
                                    #endregion check if already visited

                                    #region check how much paths are searched
                                    if (shortestOnly && !findAll)
                                    {
                                        if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                        {
                                            shortestPathLength = myMaxPathLength;
                                        }
                                        else
                                        {
                                            shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                        }

                                        return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                    }
                                    //if find all shortest paths
                                    else if (shortestOnly && findAll)
                                    {
                                        //set maxDepth to actual depth
                                        maxDepthLeft = depthLeft;
                                        maxDepthRight = depthRight;

                                        if ((depthLeft + depthRight) > myMaxPathLength)
                                        {
                                            shortestPathLength = myMaxPathLength;
                                        }
                                        else
                                        {
                                            shortestPathLength = Convert.ToByte(depthLeft + depthRight);
                                        }
                                    }
                                    #endregion check how much paths are searched
                                }
                                #endregion if the child is the target
                                #region already visited
                                else if (visitedNodesRight.ContainsKey(dboRight))
                                {
                                    //set found children
                                    visitedNodesRight[dboRight].addChild(currentRight);

                                    currentRight.addParent(visitedNodesRight[dboRight]);
                                }
                                #endregion already visited
                                #region set as visited
                                else
                                {
                                    //create a new node and set currentRight = child
                                    currentNodeRight = new Node(dboRight);
                                    currentNodeRight.addChild(currentRight);

                                    //set currentNodeRight as parent of current Right
                                    currentRight.addParent(currentNodeRight);

                                    //never seen before
                                    //mark the node as visited
                                    visitedNodesRight.Add(currentNodeRight.Key, currentNodeRight);

                                    //and look what comes on the next level of depth
                                    queueRight.Enqueue(currentNodeRight);
                                }
                                #endregion set as visited
                            }
                            #endregion check right friends

                            #region build intersection of visitedNodesLeft and visitedNodesRight

                            //marks if intersection nodes are existing
                            bool foundIntersect = false;

                            foreach (var node in visitedNodesLeft)
                            {
                                if (visitedNodesRight[node.Key] != null)
                                {
                                    //set nodes children and parents
                                    node.Value.addChildren(visitedNodesRight[node.Key].Children);
                                    node.Value.addParents(visitedNodesRight[node.Key].Parents);

                                    //set nodes children and parents
                                    visitedNodesRight[node.Key].addChildren(node.Value.Children);
                                    visitedNodesRight[node.Key].addParents(node.Value.Parents);

                                    foundIntersect = true;
                                }
                            }
                            #endregion build intersection of visitedNodesLeft and visitedNodesRight

                            #region analyze intersection
                            //if intersection nodes existing
                            if (foundIntersect)
                            {
                                //only shortest path
                                if (shortestOnly && !findAll)
                                {
                                    //_Logger.Info("found shortest path..starting analyzer");

                                    if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                    {
                                        shortestPathLength = myMaxPathLength;
                                    }
                                    else
                                    {
                                        shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                    }

                                    return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                }
                                //if find all shortest paths
                                else if (shortestOnly && findAll)
                                {
                                    //set maxDepth to actual depth
                                    maxDepthLeft = depthLeft;
                                    maxDepthRight = depthRight;

                                    if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                    {
                                        shortestPathLength = myMaxPathLength;
                                    }
                                    else if (shortestPathLength == 0)
                                    {
                                        shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                    }

                                }
                            }
                            #endregion analyze intersection
                        }
                        #endregion the edge and the backwardedge are existing
                        #region only the edge exists
                        else if (currentDBObjectLeft.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager)))
                        {
                            //get all referenced ObjectUUIDs using the given Edge
                            var objectUUIDsLeft = (currentDBObjectLeft.Value.GetAttribute(myTypeAttribute.UUID) as ASetOfReferencesEdgeType).GetAllReferenceIDs();
                            Node currentNodeLeft;

                            #region check left friends
                            foreach (ObjectUUID dboLeft in objectUUIDsLeft)
                            {
                                #region if the child is the target
                                if (dboLeft == myEnd.ObjectUUID)
                                {
                                    target.addParent(currentLeft);

                                    #region check if already visited
                                    if (visitedNodesLeft.ContainsKey(dboLeft))
                                    {
                                        //set currentLeft as parent
                                        visitedNodesLeft[dboLeft].addParent(currentLeft);

                                        //set currentNodeLeft as child
                                        currentLeft.addChild(visitedNodesLeft[dboLeft]);
                                    }
                                    else
                                    {
                                        //create a new node and set currentLeft = parent
                                        currentNodeLeft = new Node(dboLeft, currentLeft);

                                        //set currentNodeLeft as child of currentLeft
                                        currentLeft.addChild(currentNodeLeft);

                                        //never seen before
                                        //mark the node as visited
                                        visitedNodesLeft.Add(currentNodeLeft.Key, currentNodeLeft);

                                        //and put node into the queue
                                        queueLeft.Enqueue(currentNodeLeft);
                                    }
                                    #endregion check if already visited

                                    #region check how much paths are searched
                                    if (shortestOnly && !findAll)
                                    {
                                        //_Logger.Info("found shortest path..starting analyzer");

                                        if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                        {
                                            shortestPathLength = myMaxPathLength;
                                        }
                                        else
                                        {
                                            shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                        }

                                        return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                    }
                                    else if (shortestOnly && findAll)
                                    {
                                        maxDepthLeft = depthLeft;

                                        shortestPathLength = Convert.ToByte(maxDepthLeft + maxDepthRight);
                                    }
                                    #endregion check if already visited
                                }
                                #endregion if the child is the target
                                #region already visited from right side
                                else if (visitedNodesRight.ContainsKey(dboLeft))
                                {
                                    //get node
                                    Node temp = visitedNodesRight[dboLeft];
                                    //add parent new
                                    temp.addParent(currentLeft);
                                    //add as child
                                    currentLeft.addChild(temp);

                                    visitedNodesRight.Remove(temp.Key);
                                    visitedNodesRight.Add(temp.Key, temp);

                                    if (visitedNodesLeft.Remove(temp.Key))
                                    {
                                        visitedNodesLeft.Add(temp.Key, temp);
                                    }

                                    if (shortestOnly && !findAll)
                                    {
                                        //_Logger.Info("found shortest path..starting analyzer");

                                        if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                        {
                                            shortestPathLength = myMaxPathLength;
                                        }
                                        else
                                        {
                                            shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                        }

                                        return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                    }
                                    else if (shortestOnly && findAll)
                                    {
                                        maxDepthLeft = depthLeft;

                                        shortestPathLength = Convert.ToByte(maxDepthLeft + maxDepthRight);
                                    }
                                }
                                #endregion already visited from right side
                                #region already visited
                                else if (visitedNodesLeft.ContainsKey(dboLeft))
                                {
                                    //set found parents from left side as parents of matchNode
                                    //matchNode has now parents and children
                                    visitedNodesLeft[dboLeft].addParent(currentLeft);

                                    currentLeft.addChild(visitedNodesLeft[dboLeft]);
                                }
                                #endregion already visited
                                #region set as visited
                                else
                                {
                                    //create a new node and set currentLeft = parent
                                    currentNodeLeft = new Node(dboLeft, currentLeft);

                                    //set currentNodeLeft as child of currentLeft
                                    currentLeft.addChild(currentNodeLeft);

                                    //never seen before
                                    //mark the node as visited
                                    visitedNodesLeft.Add(currentNodeLeft.Key, currentNodeLeft);

                                    //and look what comes on the next level of depth
                                    queueLeft.Enqueue(currentNodeLeft);
                                }
                                #endregion set as visited
                            }
                            #endregion check left friends
                        }
                        #endregion only the edge exists
                        #region only the backwardedge exists
                        else if (currentDBObjectRight.Value.ContainsBackwardEdge(edgeKey))
                        {
                            //get all referenced ObjectUUIDs using the given Edge
                            var objectUUIDsRight = currentDBObjectRight.Value.GetBackwardEdgeUUIDs(edgeKey);
                            Node currentNodeRight;

                            #region check right friends
                            foreach (ObjectUUID dboRight in objectUUIDsRight)
                            {
                                #region if the child is the target
                                if (rootFriends.Contains(dboRight))
                                {
                                    #region check if already visited
                                    //mark node as visited
                                    if (visitedNodesRight.ContainsKey(dboRight))
                                    {
                                        //set found children
                                        visitedNodesRight[dboRight].addChild(currentRight);

                                        currentRight.addParent(visitedNodesRight[dboRight]);
                                    }
                                    else
                                    {
                                        //create a new node and set currentRight = child
                                        currentNodeRight = new Node(dboRight);
                                        currentNodeRight.addChild(currentRight);

                                        //set currentNodeRight as parent of current Right
                                        currentRight.addParent(currentNodeRight);

                                        //never seen before
                                        //mark the node as visited
                                        visitedNodesRight.Add(currentNodeRight.Key, currentNodeRight);

                                        //and look what comes on the next level of depth
                                        queueRight.Enqueue(currentNodeRight);
                                    }
                                    #endregion check if already visited

                                    #region check how much paths are searched
                                    if (shortestOnly && !findAll)
                                    {
                                        if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                        {
                                            shortestPathLength = myMaxPathLength;
                                        }
                                        else
                                        {
                                            shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                        }

                                        return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                    }
                                    else if (shortestOnly && findAll)
                                    {
                                        maxDepthRight = depthRight;

                                        shortestPathLength = Convert.ToByte(maxDepthLeft + maxDepthRight);
                                    }
                                    #endregion check how much paths are searched
                                }
                                #endregion if the child is the target
                                #region already visited from left side
                                else if (visitedNodesLeft.ContainsKey(dboRight))
                                {
                                    //get node
                                    Node temp = visitedNodesLeft[dboRight];
                                    temp.addChild(currentRight);
                                    currentRight.addParent(temp);

                                    visitedNodesLeft.Remove(temp.Key);
                                    visitedNodesLeft.Add(temp.Key, temp);

                                    if (visitedNodesRight.Remove(temp.Key))
                                    {
                                        visitedNodesRight.Add(temp.Key, temp);
                                    }

                                    if (shortestOnly && !findAll)
                                    {
                                        //_Logger.Info("found shortest path..starting analyzer");

                                        if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                        {
                                            shortestPathLength = myMaxPathLength;
                                        }
                                        else
                                        {
                                            shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                        }

                                        return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                    }
                                    else if (shortestOnly && findAll)
                                    {
                                        maxDepthRight = depthRight;

                                        shortestPathLength = Convert.ToByte(maxDepthLeft + maxDepthRight);
                                    }
                                }
                                #endregion already visited from left side
                                #region already visited
                                else if (visitedNodesRight.ContainsKey(dboRight))
                                {
                                    //set found children
                                    visitedNodesRight[dboRight].addChild(currentRight);

                                    currentRight.addParent(visitedNodesRight[dboRight]);
                                }
                                #endregion already visited
                                #region set as visited
                                else
                                {
                                    //create a new node and set currentRight = child
                                    currentNodeRight = new Node(dboRight);
                                    currentNodeRight.addChild(currentRight);

                                    //set currentNodeRight as parent of currentRight
                                    currentRight.addParent(currentNodeRight);

                                    //never seen before
                                    //mark the node as visited
                                    visitedNodesRight.Add(currentNodeRight.Key, currentNodeRight);

                                    //and look what comes on the next level of depth
                                    queueRight.Enqueue(currentNodeRight);
                                }
                                #endregion set as visited
                            }
                            #endregion check right friends
                        }
                        #endregion only the backwardedge exists
                    }
                    #endregion  both queues contain objects and both depths are not reached

                    #region only left queue contain objects
                    else if ((queueLeft.Count > 0) && (depthLeft <= maxDepthLeft))
                    {
                        #region check if first element of queue is a dummy
                        //dummy
                        if (queueLeft.First<Node>().Key == null)
                        {
                            queueLeft.Dequeue();

                            //_Logger.Info("going deeper in the dungeon on the left side.. current level: " + depthLeft);
                            depthLeft++;

                            if (queueLeft.Count == 0)
                            {
                                continue;
                            }
                            else if (depthLeft > maxDepthLeft)
                            {
                                continue;
                            }
                        }
                        #endregion check if first element of queue is a dummy

                        //get the first Object of the queue
                        Node currentLeft = queueLeft.Dequeue();

                        //load DBObject
                        currentDBObjectLeft = myDBContext.DBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), currentLeft.Key);
                        if (currentDBObjectLeft.Failed())
                        {
                            throw new NotImplementedException();
                        }

                        if (currentDBObjectLeft.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager)))
                        {
                            //get all referenced ObjectUUIDs using the given Edge
                            var objectUUIDsLeft = (currentDBObjectLeft.Value.GetAttribute(myTypeAttribute.UUID) as ASetOfReferencesEdgeType).GetAllReferenceIDs();
                            Node currentNodeLeft;

                            #region check left friends
                            foreach (ObjectUUID dboLeft in objectUUIDsLeft)
                            {
                                #region if the child is the target
                                if (dboLeft == myEnd.ObjectUUID)
                                {
                                    target.addParent(currentLeft);

                                    #region check if already visited
                                    if (visitedNodesLeft.ContainsKey(dboLeft))
                                    {
                                        //set currentLeft as parent
                                        visitedNodesLeft[dboLeft].addParent(currentLeft);

                                        //set currentNodeLeft as child
                                        currentLeft.addChild(visitedNodesLeft[dboLeft]);
                                    }
                                    else
                                    {
                                        //create a new node and set currentLeft = parent
                                        currentNodeLeft = new Node(dboLeft, currentLeft);

                                        //set currentNodeLeft as child of currentLeft
                                        currentLeft.addChild(currentNodeLeft);

                                        //never seen before
                                        //mark the node as visited
                                        visitedNodesLeft.Add(currentNodeLeft.Key, currentNodeLeft);

                                        //and put node into the queue
                                        queueLeft.Enqueue(currentNodeLeft);
                                    }
                                    #endregion check if already visited

                                    #region check how much paths are searched
                                    if (shortestOnly && !findAll)
                                    {
                                        //_Logger.Info("found shortest path..starting analyzer");

                                        if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                        {
                                            shortestPathLength = myMaxPathLength;
                                        }
                                        else
                                        {
                                            shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                        }

                                        return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                    }
                                    else if (shortestOnly && findAll)
                                    {
                                        maxDepthLeft = depthLeft;

                                        shortestPathLength = Convert.ToByte(maxDepthLeft + maxDepthRight);
                                    }
                                    #endregion check how much paths are searched
                                }
                                #endregion if the child is the target
                                #region already visited from right side
                                else if (visitedNodesRight.ContainsKey(dboLeft))
                                {
                                    //get node
                                    Node temp = visitedNodesRight[dboLeft];
                                    //add parent new
                                    temp.addParent(currentLeft);
                                    //add as child
                                    currentLeft.addChild(temp);

                                    visitedNodesRight.Remove(temp.Key);
                                    visitedNodesRight.Add(temp.Key, temp);

                                    if (visitedNodesLeft.Remove(temp.Key))
                                    {
                                        visitedNodesLeft.Add(temp.Key, temp);
                                    }

                                    if (shortestOnly && !findAll)
                                    {
                                        //_Logger.Info("found shortest path..starting analyzer");

                                        if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                        {
                                            shortestPathLength = myMaxPathLength;
                                        }
                                        else
                                        {
                                            shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                        }

                                        return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                    }
                                    else if (shortestOnly && findAll)
                                    {
                                        maxDepthLeft = depthLeft;

                                        if (shortestPathLength < (maxDepthLeft + maxDepthRight))
                                        {
                                            shortestPathLength = Convert.ToByte(maxDepthLeft + maxDepthRight);
                                        }
                                    }
                                }
                                #endregion already visited from right side
                                #region already visited
                                else if (visitedNodesLeft.ContainsKey(dboLeft))
                                {
                                    //set found parents from left side as parents of matchNode
                                    //matchNode has now parents and children
                                    visitedNodesLeft[dboLeft].addParent(currentLeft);

                                    currentLeft.addChild(visitedNodesLeft[dboLeft]);
                                }
                                #endregion already visited
                                #region set as visited
                                else
                                {
                                    //create a new node and set currentLeft = parent
                                    currentNodeLeft = new Node(dboLeft, currentLeft);

                                    currentLeft.addChild(currentNodeLeft);

                                    //never seen before
                                    //mark the node as visited
                                    visitedNodesLeft.Add(currentNodeLeft.Key, currentNodeLeft);
                                    //and look what comes on the next level of depth
                                    queueLeft.Enqueue(currentNodeLeft);
                                }
                                #endregion set as visited
                            }
                            #endregion check left friends
                        }
                    }
                    #endregion only left queue contain objects

                    #region only right queue contain objects
                    else if ((queueRight.Count > 0) && (depthRight <= maxDepthRight))
                    {
                        //get the first Object of the queue
                        Node currentRight;

                        #region check if first element of the queue is a dummy
                        //dummy
                        if (queueRight.First<Node>().Key == null)
                        {
                            queueRight.Dequeue();

                            //_Logger.Info("going deeper in the dungeon on the right side.. current level: " + depthRight);
                            depthRight++;

                            if (queueRight.Count == 0)
                            {
                                continue;
                            }
                        }
                        #endregion check if first element of the queue is a dummy

                        currentRight = queueRight.Dequeue();

                        //load DBObject
                        currentDBObjectRight = myDBContext.DBObjectCache.LoadDBBackwardEdgeStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), currentRight.Key);
                        if (currentDBObjectRight.Failed())
                        {
                            throw new NotImplementedException();
                        }

                        if (currentDBObjectRight.Value.ContainsBackwardEdge(edgeKey))
                        {
                            //get all referenced ObjectUUIDs using the given Edge
                            var objectUUIDsRight = currentDBObjectRight.Value.GetBackwardEdgeUUIDs(edgeKey);
                            Node currentNodeRight;

                            #region check right friends
                            foreach (ObjectUUID dboRight in objectUUIDsRight)
                            {
                                #region if the child is the target
                                if (rootFriends.Contains(dboRight))
                                {
                                    #region check if already visited
                                    //mark node as visited
                                    if (visitedNodesRight.ContainsKey(dboRight))
                                    {
                                        //set found children
                                        visitedNodesRight[dboRight].addChild(currentRight);

                                        currentRight.addParent(visitedNodesRight[dboRight]);
                                    }
                                    else
                                    {
                                        //create a new node and set currentRight = child
                                        currentNodeRight = new Node(dboRight);
                                        currentNodeRight.addChild(currentRight);

                                        //set currentNodeRight as parent of current Right
                                        currentRight.addParent(currentNodeRight);

                                        //never seen before
                                        //mark the node as visited
                                        visitedNodesRight.Add(currentNodeRight.Key, currentNodeRight);

                                        //and look what comes on the next level of depth
                                        queueRight.Enqueue(currentNodeRight);
                                    }
                                    #endregion check if already visited

                                    #region check how much paths are searched
                                    if (shortestOnly && !findAll)
                                    {
                                        //_Logger.Info("found shortest path..starting analyzer");
                                        shortestPathLength = Convert.ToByte(depthLeft + depthRight);

                                        return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                    }
                                    else if (shortestOnly && findAll)
                                    {
                                        maxDepthRight = depthRight;

                                        shortestPathLength = Convert.ToByte(maxDepthLeft + maxDepthRight);
                                    }
                                    #endregion check how much paths are searched
                                }
                                #endregion if the child is the target
                                #region already visited from left side
                                else if (visitedNodesLeft.ContainsKey(dboRight))
                                {
                                    //get node
                                    Node temp = visitedNodesLeft[dboRight];
                                    temp.addChild(currentRight);
                                    currentRight.addParent(temp);

                                    visitedNodesLeft.Remove(temp.Key);
                                    visitedNodesLeft.Add(temp.Key, temp);

                                    if (visitedNodesRight.Remove(temp.Key))
                                    {
                                        visitedNodesRight.Add(temp.Key, temp);
                                    }

                                    if (shortestOnly && !findAll)
                                    {
                                        //_Logger.Info("found shortest path..starting analyzer");

                                        if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                        {
                                            shortestPathLength = myMaxPathLength;
                                        }
                                        else
                                        {
                                            shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                        }

                                        return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                    }
                                    else if (shortestOnly && findAll)
                                    {
                                        maxDepthRight = depthRight;

                                        shortestPathLength = Convert.ToByte(maxDepthLeft + maxDepthRight);
                                    }
                                }
                                #endregion already visited from left side
                                #region already visited
                                else if (visitedNodesRight.ContainsKey(dboRight))
                                {
                                    //set found children
                                    visitedNodesRight[dboRight].addChild(currentRight);

                                    currentRight.addParent(visitedNodesRight[dboRight]);
                                }
                                #endregion already visited
                                #region set as visited
                                else
                                {
                                    //create a new node and set currentRight = child
                                    currentNodeRight = new Node(dboRight);
                                    currentNodeRight.addChild(currentRight);

                                    currentRight.addParent(currentNodeRight);

                                    //never seen before
                                    //mark the node as visited
                                    visitedNodesRight.Add(currentNodeRight.Key, currentNodeRight);
                                    //and look what comes on the next level of depth
                                    queueRight.Enqueue(currentNodeRight);
                                }
                                #endregion set as visited
                            }
                            #endregion check right friends
                        }
                    }
                    #endregion only right queue contain objects

                    #region abort loop
                    else
                    {
                        break;
                    }
                    #endregion abort loop
                }
            }
            #endregion EdgeType is ASetReferenceEdgeType
            //check if the EdgeType is ASingleReferenceEdgeType
            #region EdgeType is ASingleReferenceEdgeType
            else if (myEdge is ASingleReferenceEdgeType)
            {
                #region initialize variables
                //if the maxDepth is greater then maxPathLength, then set maxDepth to maxPathLength
                if (myMaxDepth > myMaxPathLength)
                {
                    myMaxDepth = myMaxPathLength;
                }

                //set depth for left side
                maxDepthLeft = myMaxDepth;
                #endregion initialize variables

                #region check if friends of root node have edge
                foreach (var node in visitedNodesLeft)
                {
                    var dbo = myDBContext.DBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), node.Key);
                    if (dbo.Failed())
                    {
                        if (visitedNodesLeft.Count != 0)
                        {
                            visitedNodesLeft.Remove(node.Key);
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                    }

                    if (!dbo.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager)))
                    {
                        if (visitedNodesLeft.Count != 0)
                        {
                            visitedNodesLeft.Remove(node.Key);
                        }
                        else
                        {
                            return null;
                        }
                    }
                }
                #endregion check if friends of root node have edge

                //if there is more than one object in the queue and the actual depth is less than MaxDepth
                while ((queueLeft.Count > 0) && (depthLeft <= maxDepthLeft))
                {
                    #region check if first element of queue is a dummy
                    //dummy
                    if (queueLeft.First<Node>().Key == null)
                    {
                        queueLeft.Dequeue();

                        //_Logger.Info("going deeper in the dungeon on the left side.. current level: " + depthLeft);
                        depthLeft++;

                        if ((queueLeft.Count == 0) || (depthLeft > maxDepthLeft))
                        {
                            break;
                        }
                        else
                        {
                            queueLeft.Enqueue(dummyLeft);
                            continue;
                        }
                    }
                    #endregion check if first element of queue is a dummy

                    #region load DBObject
                    //get the first Object of the queue
                    var currentLeft = queueLeft.Dequeue();

                    //load DBObject
                    currentDBObjectLeft = myDBContext.DBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), currentLeft.Key);
                    if (currentDBObjectLeft.Failed())
                    {
                        throw new NotImplementedException();
                    }
                    #endregion load DBObject

                    #region check if currentDBObjectLeft has attribute
                    if (currentDBObjectLeft.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager)))
                    {
                        //get referenced ObjectUUID using the given Edge
                        var objectUUIDsLeft = (currentDBObjectLeft.Value.GetAttribute(myTypeAttribute.UUID) as ASingleReferenceEdgeType).GetAllReferenceIDs();
                        Node currentNodeLeft;

                        #region check left friend
                        var dboLeft = objectUUIDsLeft.First();

                        //create a new node and set currentLeft = parent
                        currentNodeLeft = new Node(dboLeft, currentLeft);

                        #region if the child is the target
                        if (currentNodeLeft.Key == myEnd.ObjectUUID)
                        {
                            //set currentLeft as parent of target
                            target.addParent(currentLeft);

                            //shortestPathLength is actual depth of left side plus 1 (because the depth starts with zero, but the pathLength with 1)
                            shortestPathLength = Convert.ToByte(depthLeft + 1);

                            return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
                        }
                        #endregion if the child is the target
                        #region already visited
                        else if (visitedNodesLeft.ContainsKey(currentNodeLeft.Key))
                        {
                            //set currentLeft as parent
                            visitedNodesLeft[currentNodeLeft.Key].addParent(currentLeft);

                            //set currentNodeLeft as child
                            currentLeft.addChild(visitedNodesLeft[currentNodeLeft.Key]);
                        }
                        #endregion already visited
                        #region set as visited
                        else
                        {
                            //set currentNodeLeft as child of currentLeft
                            currentLeft.addChild(currentNodeLeft);

                            //never seen before
                            //mark the node as visited
                            visitedNodesLeft.Add(currentNodeLeft.Key, currentNodeLeft);

                            //and put node into the queue
                            queueLeft.Enqueue(currentNodeLeft);
                        }
                        #endregion set as visited

                        #endregion check left friend
                    }
                    #endregion check if currentDBObjectLeft has attribute
                    #region abort loop
                    else
                    {
                        break;
                    }
                    #endregion abort loop
                }
            }
            #endregion EdgeType is ASingleReferenceEdgeType
            else
            {
                throw new NotImplementedException();
            }

            #region start TargetAnalyzer
            if (shortestOnly && findAll)
            {
                if (shortestPathLength > myMaxPathLength)
                {
                    shortestPathLength = myMaxPathLength;
                }

                return new TargetAnalyzer(root, rootFriends, target, shortestPathLength, shortestOnly, findAll).getPaths();
            }
            else
            {
                return new TargetAnalyzer(root, rootFriends, target, myMaxPathLength, shortestOnly, findAll).getPaths();
            }
            #endregion start TargetAnalyzer

            #endregion BidirectionalBFS
        }
Example #10
0
        private void getPath(Node myCurrent)
        {
            if (!_TempList.Contains(myCurrent.Key))
            {
                //add myCurrent to actual path
                _TempList.Add(myCurrent.Key);

                //set flag to mark that myCurrent is in actual path
                myCurrent.AlreadyInPath = true;

                //abort recursion when myCurrent is the root node
                if (_StartFriends.Contains(myCurrent.Key))
                {
                    //duplicate list
                    var temp = new List<ObjectUUID>(_TempList);

                    //reverse because the path is calculated beginning at the target
                    temp.Reverse();

                    //add completed path to result list
                    _Paths.Add(temp);

                    //log the path
                    PathViewer.LogPath(temp);
                }

                foreach (Node parent in myCurrent.Parents)
                {
                    //if parent node not already in actual path
                    if (!parent.AlreadyInPath && !parent.Key.Equals(_Start.Key))
                    {
                        //and MaxPathLength is not reached
                        if (_TempList.Count < _MaxPathLength)
                        {
                            if (!_Done)
                            {
                                getPath(parent);
                            }
                        }
                    }
                }

                if (_TempList.Count != 0)
                {
                    //remove last node from actual path
                    _TempList.Remove(_TempList.Last<ObjectUUID>());
                    //myCurrent isn't in actual path
                    myCurrent.AlreadyInPath = false;
                }
            }
            return;
        }
Example #11
0
 public TargetAnalyzer(Node myStart, HashSet<ObjectUUID> myStartFriends, Node myEnd, byte myMaxPathLength, bool myShortestOnly, bool myFindAll)
     : this(myStart, myStartFriends, myEnd, myMaxPathLength)
 {
     _ShortestOnly = myShortestOnly;
     _FindAll = myFindAll;
 }