Пример #1
0
 /// <summary>
 /// This will be invoked by the BulkInsert class.
 /// </summary>
 /// <param name="myTypeManager"></param>
 /// <param name="myDBTypeStream"></param>
 /// <param name="myDBObjectStream"></param>
 /// <param name="myBulkInsert"></param>
 internal BulkInsertDBO(DBContext myDBContext, GraphDBType myDBTypeStream, DBObjectStream myDBObjectStream, BulkInsert myBulkInsert)
 {
     _DBContext = myDBContext;
     _DBTypeStream = myDBTypeStream;
     _DBObjectStream = myDBObjectStream;
     _BulkInsert = myBulkInsert;
 }
Пример #2
0
        //public override IObject GetReturnType(IObject myWorkingBase, DBTypeManager myTypeManager)
        //{
        //    return base.GetReturnType(myWorkingBase, myTypeManager);
        //}
        /// <summary>
        /// Calls a webservice to get the current currency conversion ratio of the two given currencies and returns the calling value times the ratio.
        /// This method contains the entire logic of the function.
        /// </summary>
        /// <param name="dbContext">The current DBContext.</param>
        /// <param name="myParams">The parameters for the function. Must be two strings, that contains the currency codes. <see cref="CurrencyConverterFunction"/></param>
        /// <returns>The currency converted value</returns>
        public override Exceptional<FuncParameter> ExecFunc(DBContext dbContext, params FuncParameter[] myParams)
        {
            var resolvingEdge = (myParams[0].Value as DBTypeAttribute).GetValue();
            var source = (CallingObject as IReferenceEdge);

            var returningEdge = new EdgeTypeSetOfReferences();

            foreach(var dbStream in source.GetAllEdgeDestinations(dbContext.DBObjectCache))
            {

                if (dbStream.Failed())
                {
                    return new Exceptional<FuncParameter>(dbStream);
                }

                var hyperEdge = dbStream.Value.GetAttribute(resolvingEdge, resolvingEdge.GetDBType(dbContext.DBTypeManager), dbContext);
                if (hyperEdge.Value == null)
                {
                    return new Exceptional<FuncParameter>(new FuncParameter(null));
                }
                if (hyperEdge.Failed())
                {
                    return new Exceptional<FuncParameter>(hyperEdge);
                }

                returningEdge.AddRange((hyperEdge.Value as IReferenceEdge).GetAllReferenceIDs(), resolvingEdge.DBTypeUUID);

            }

            return new Exceptional<FuncParameter>(new FuncParameter(returningEdge, resolvingEdge));
        }
Пример #3
0
        /// <summary>
        /// This will create a new dbContext, based on <paramref name="dbContext"/> reusing all shared data
        /// </summary>
        /// <param name="dbContext"></param>
        public DBContext(DBContext dbContext)
        {
            #region Immutable objects

            _DBPluginManager = dbContext.DBPluginManager;
            _DBSettingsManager = dbContext.DBSettingsManager;
            _IGraphFSSession = dbContext._IGraphFSSession;

            #endregion

            _SessionSettings = new DBSessionSettings(dbContext.SessionSettings);
            _DBObjectManager = new ObjectManagement.DBObjectManager(this, _IGraphFSSession);

            //
            _DBIndexManager = new Indices.DBIndexManager(_IGraphFSSession, this);

            _DBTypeManager = new DBTypeManager(dbContext.DBTypeManager);

            _DBObjectCache = _DBObjectManager.GetSimpleDBObjectCache(this);
        }
Пример #4
0
        //Logger
        //private static Logger //_Logger = LogManager.GetCurrentClassLogger();
        /// <summary>
        /// Sucht im Graphen nach Knoten "myEnd" ausgehend vom Knoten "myStart", bis zur max. Tiefe "myMaxDepth".
        /// </summary>
        /// <param name="myTypeAttribute">Kante über die gesucht werden soll</param>
        /// <param name="myDBContext"></param>
        /// <param name="myStart">Startknoten</param>
        /// <param name="myEnd">gesuchter Knoten</param>
        /// <param name="myMaxDepth">max. Tiefe</param>
        /// <returns>true wenn gesuchter Knoten min. 1 mal gefunden, false sonst</returns>
        public bool Find(TypeAttribute myTypeAttribute, DBContext myDBContext, DBObjectStream myStart, DBObjectStream myEnd, byte myMaxDepth)
        {
            #region data
            //queue for BFS
            Queue<ObjectUUID> queue = new Queue<ObjectUUID>();

            //Dictionary to store visited TreeNodes
            BigHashSet<ObjectUUID> visitedNodes = new BigHashSet<ObjectUUID>();

            //current depth
            byte depth = 1;

            //first node in path tree, the start of the select
            ObjectUUID root = myStart.ObjectUUID;

            //target node, the target of the select
            ObjectUUID target = myEnd.ObjectUUID;

            //dummy node to check in which level the BFS is
            ObjectUUID dummy = null;

            //enqueue first node to start the BFS
            queue.Enqueue(root);
            queue.Enqueue(dummy);

            //add root to visitedNodes
            visitedNodes.Add(root);

            //holds the actual DBObject
            Exceptional<DBObjectStream> currentDBObject;
            #endregion data

            #region BFS

            #region validate root
            //check if root has edge
            var dbo = myDBContext.DBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), root);
            if (dbo.Failed())
            {
                throw new NotImplementedException();
            }

            if (!dbo.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager)))
            {
                return false;
            }
            #endregion validate root

            //if there is more than one object in the queue and the actual depth is less than MaxDepth
            while ((queue.Count > 1) && (depth <= myMaxDepth))
            {
                //get the first Object of the queue
                ObjectUUID nodeOfQueue = queue.Dequeue();

                #region check if nodeOfQueue is a dummy
                //if nodeOfQueue is a dummy, this level is completely worked off
                if (nodeOfQueue == null)
                {
                    depth++;

                    queue.Enqueue(nodeOfQueue);

                    continue;
                }
                #endregion check if current is a dummy

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

                if (currentDBObject.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager)))
                {
                    #region EdgeType is ASetOfReferencesEdgeType
                    if (myTypeAttribute.EdgeType is ASetOfReferencesEdgeType)
                    {
                        //get all referenced ObjectUUIDs using the given Edge
                        var objectUUIDs = (currentDBObject.Value.GetAttribute(myTypeAttribute.UUID) as ASetOfReferencesEdgeType).GetAllReferenceIDs();
                        ObjectUUID currentNode;

                        foreach (ObjectUUID obj in objectUUIDs)
                        {
                            #region obj is target
                            //if the child is the target
                            if (target.Equals(obj))
                            {
                                return true;
                            }
                            #endregion obj is target
                            #region never seen before
                            else if (!visitedNodes.Contains(obj))
                            {
                                //create new node and set nodeOfQueue as parent
                                currentNode = new ObjectUUID(obj.ToString());

                                //mark the node as visited
                                visitedNodes.Add(currentNode);

                                //put created node in queue
                                queue.Enqueue(currentNode);
                            }
                            #endregion never seen before
                        }
                    }
                    #endregion EdgeType is ASetOfReferencesEdgeType
                    #region EdgeType is ASingleReferenceEdgeType
                    else if (myTypeAttribute.EdgeType is ASingleReferenceEdgeType)
                    {
                        //get all referenced ObjectUUIDs using the given Edge
                        var objectUUIDs = (currentDBObject.Value.GetAttribute(myTypeAttribute.UUID) as ASingleReferenceEdgeType).GetAllReferenceIDs();
                        ObjectUUID objectUUID = objectUUIDs.First<ObjectUUID>();
                        ObjectUUID currentNode;

                        #region obj is target
                        //if the child is the target
                        if (target.Equals(objectUUID))
                        {
                            return true;
                        }
                        #endregion obj is target
                        #region never seen before
                        else if (!visitedNodes.Contains(objectUUID))
                        {
                            //create new node and set nodeOfQueue as parent
                            currentNode = new ObjectUUID(objectUUID.ToString());

                            //mark the node as visited
                            visitedNodes.Add(currentNode);

                            //put created node in queue
                            queue.Enqueue(currentNode);
                        }
                        #endregion never seen before
                    }
                    #endregion EdgeType is ASingleReferenceEdgeType
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
            }

            #endregion BFS

            return false;
        }
Пример #5
0
        /// <summary>
        /// Sucht im Graphen nach Knoten "myEnd" ausgehend von der Knotenmenge "myEdge", bis zur max. Tiefe "myMaxDepth".
        /// </summary>
        /// <param name="myTypeAttribute">Kante über die gesucht werden soll</param>
        /// <param name="myDBContext"></param>
        /// <param name="myStart">Startknoten</param>
        /// <param name="myEnd">gesuchter Knoten</param>
        /// <param name="myEdge">Menge an Knoten, ausgehend vom Startknoten welche mittels einer Funktion eingeschränkt wurde</param>
        /// <param name="myMaxDepth">max. Tiefe</param>
        /// <returns>true wenn gesuchter Knoten min. 1 mal gefunden, false sonst</returns>
        public bool Find(TypeAttribute myTypeAttribute, DBContext myDBContext, DBObjectStream myStart, DBObjectStream myEnd, IReferenceEdge myEdge, byte myMaxDepth)
        {
            #region data
            //queue for BFS
            Queue<ObjectUUID> queue = new Queue<ObjectUUID>();

            //Dictionary to store visited TreeNodes
            BigHashSet<ObjectUUID> visitedNodes = new BigHashSet<ObjectUUID>();

            //current depth
            byte depth = 2;

            //first node in path tree, the start of the select
            ObjectUUID root = myStart.ObjectUUID;

            //constrainted set of nodes, of start node
            HashSet<ObjectUUID> rootFriends = new HashSet<ObjectUUID>();

            //target node, the target of the select
            ObjectUUID target = myEnd.ObjectUUID;

            //dummy node to check in which level the BFS is
            ObjectUUID dummy = null;

            //add root to visitedNodes
            visitedNodes.Add(root);

            //holds the actual DBObject
            Exceptional<DBObjectStream> currentDBObject;
            #endregion data

            #region validate root
            //check if root has edge
            var dbo = myDBContext.DBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), root);
            if (dbo.Failed())
            {
                throw new NotImplementedException();
            }

            if (!dbo.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager)))
            {
                return false;
            }
            #endregion validate root

            #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();

            for (int i = 0; i < firstUUIDs.Count(); i++)
            {
                var element = firstUUIDs.ElementAt(i);

                if (element != null)
                {
                    //create a new node and set root = parent
                    var currentNode = element;

                    #region check if the child is the target
                    //start and target are conntected directly
                    if (currentNode.Equals(myEnd.ObjectUUID))
                    {
                        //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(currentNode);

                        return true;
                    }
                    #endregion check if the child is the target

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

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

                    //enqueue node to start from left side
                    queue.Enqueue(currentNode);

                    //add node to visitedNodes
                    visitedNodes.Add(currentNode);

                    //add node to startFriends
                    rootFriends.Add(currentNode);
                }
            }
            #endregion get friends of startElement and check if they are the target and valid

            //enqueue dummy
            queue.Enqueue(dummy);

            #region BFS

            //if there is more than one object in the queue and the actual depth is less than MaxDepth
            while ((queue.Count > 1) && (depth <= myMaxDepth))
            {
                //get the first Object of the queue
                ObjectUUID nodeOfQueue = queue.Dequeue();

                #region check if nodeOfQueue is a dummy
                //if nodeOfQueue is a dummy, this level is completely worked off
                if (nodeOfQueue == null)
                {
                    depth++;

                    queue.Enqueue(nodeOfQueue);

                    continue;
                }
                #endregion check if current is a dummy

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

                if (currentDBObject.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager)))
                {
                    #region EdgeType is ASetOfReferencesEdgeType
                    if (myTypeAttribute.EdgeType is ASetOfReferencesEdgeType)
                    {
                        //get all referenced ObjectUUIDs using the given Edge
                        var objectUUIDs = (currentDBObject.Value.GetAttribute(myTypeAttribute.UUID) as ASetOfReferencesEdgeType).GetAllReferenceIDs();
                        ObjectUUID currentNode;

                        foreach (ObjectUUID obj in objectUUIDs)
                        {
                            #region obj is target
                            //if the child is the target
                            if (target.Equals(obj))
                            {
                                return true;
                            }
                            #endregion obj is target
                            #region never seen before
                            else if (!visitedNodes.Contains(obj))
                            {
                                //create new node and set nodeOfQueue as parent
                                currentNode = new ObjectUUID(obj.ToString());

                                //mark the node as visited
                                visitedNodes.Add(currentNode);

                                //put created node in queue
                                queue.Enqueue(currentNode);
                            }
                            #endregion never seen before
                        }
                    }
                    #endregion EdgeType is ASetOfReferencesEdgeType
                    #region EdgeType is ASingleReferenceEdgeType
                    else if (myTypeAttribute.EdgeType is ASingleReferenceEdgeType)
                    {
                        //get all referenced ObjectUUIDs using the given Edge
                        var objectUUIDs = (currentDBObject.Value.GetAttribute(myTypeAttribute.UUID) as ASingleReferenceEdgeType).GetAllReferenceIDs();
                        ObjectUUID objectUUID = objectUUIDs.First<ObjectUUID>();
                        ObjectUUID currentNode;

                        #region obj is target
                        //if the child is the target
                        if (target.Equals(objectUUID))
                        {
                            return true;
                        }
                        #endregion obj is target
                        #region never seen before
                        else if (!visitedNodes.Contains(objectUUID))
                        {
                            //create new node and set nodeOfQueue as parent
                            currentNode = new ObjectUUID(objectUUID.ToString());

                            //mark the node as visited
                            visitedNodes.Add(currentNode);

                            //put created node in queue
                            queue.Enqueue(currentNode);
                        }
                        #endregion never seen before
                    }
                    #endregion EdgeType is ASingleReferenceEdgeType
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
            }

            #endregion BFS

            return false;
        }
Пример #6
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
        }
Пример #7
0
        public override Exceptional<FuncParameter> ExecFunc(DBContext dbContext, params FuncParameter[] myParams)
        {
            // The edge we starting of (e.g. Friends)
            var typeAttribute = CallingAttribute;

            // The destination DBObjects, they are of the type "typeAttribute.RelatedDBType"
            var destDBOs = (myParams[0].Value as DBEdge).GetDBObjects();

            byte maxDepth = Convert.ToByte((myParams[1].Value as DBInt64).GetValue());

            byte maxPathLength = Convert.ToByte((myParams[2].Value as DBInt64).GetValue());

            //check if values incorrect
            if (maxDepth < 1 && maxPathLength < 2)
            {
                Exceptional<FuncParameter> errorResult = new Exceptional<FuncParameter>();
                IError error = new Error_InvalidFunctionParameter("maxDepth", ">= 1", maxDepth);
                errorResult.PushIError(error);
                error = new Error_InvalidFunctionParameter("maxPathLength", ">= 2", maxPathLength);
                errorResult.PushIError(error);

                return errorResult;
            }
            else if (maxDepth < 1)
            {
                return new Exceptional<FuncParameter>(new Error_InvalidFunctionParameter("maxDepth", ">= 1", maxDepth));
            }
            else if (maxPathLength < 2)
            {
                return new Exceptional<FuncParameter>(new Error_InvalidFunctionParameter("maxPathLength", ">= 2", maxPathLength));
            }

            bool onlyShortestPath = (myParams[3].Value as DBBoolean).GetValue();

            bool allPaths = (myParams[4].Value as DBBoolean).GetValue();

            if (!onlyShortestPath && !allPaths)
            {
                allPaths = true;
            }

            #region Call graph function

            if (destDBOs.Count() != 1)
                throw new GraphDBException(new Error_NotImplemented(new StackTrace(true)));

            var dbObject = destDBOs.First();
            if (dbObject.Failed())
            {
                throw new GraphDBException(dbObject.IErrors);
            }

            HashSet<List<ObjectUUID>> paths;

            if (onlyShortestPath && allPaths) //use bi-directional search for "all shortest paths"
            {
                //normal BFS
                //paths = new BreadthFirstSearch().Find(typeAttribute, typeManager, cache, mySourceDBObject, dbObject, onlyShortestPath, allPaths, maxDepth, maxPathLength);

                //bidirectional BFS
                paths = new BidirectionalBFS().Find(typeAttribute, dbContext, CallingDBObjectStream as DBObjectStream, CallingObject as IReferenceEdge, dbObject.Value, onlyShortestPath, allPaths, maxDepth, maxPathLength);
            }
            else //use uni-directional search for "shortest path and all paths up to given depth"
            {
                //normal BFS
                //paths = new BreadthFirstSearch().Find(typeAttribute, dbContext.DBTypeManager, dbContext.DBObjectCache, CallingDBObjectStream as DBObjectStream, dbObject.Value, onlyShortestPath, allPaths, maxDepth, maxPathLength);

                //bidirectional BFS
                paths = new BidirectionalBFS().Find(typeAttribute, dbContext, CallingDBObjectStream as DBObjectStream, CallingObject as IReferenceEdge, dbObject.Value, onlyShortestPath, allPaths, maxDepth, maxPathLength);
            }

            //This variable will be returned
            Exceptional<FuncParameter> pResult = new Exceptional<FuncParameter>();

            if (paths != null)
            {
                pResult.Value = new FuncParameter(new EdgeTypePath(paths, typeAttribute, typeAttribute.GetDBType(dbContext.DBTypeManager)), typeAttribute);
            }
            else
            {
                return new Exceptional<FuncParameter>(new FuncParameter(new EdgeTypePath(new HashSet<List<ObjectUUID>>(), typeAttribute, typeAttribute.GetDBType(dbContext.DBTypeManager)), typeAttribute));
            }

            #endregion

            return pResult;
        }