Exemplo n.º 1
0
        private IObject GetDbos(IDChainDefinition myIDChainDefinition, DBObjectStream myDBObjectStream, DBContext dbContext, SessionSettings mySessionToken, DBObjectCache dbObjectCache)
        {
            if (myIDChainDefinition.LastAttribute.IsBackwardEdge)
            {
                var contBackwardExcept = myDBObjectStream.ContainsBackwardEdge(myIDChainDefinition.LastAttribute.BackwardEdgeDefinition, dbContext, dbObjectCache, myIDChainDefinition.LastAttribute.GetRelatedType(dbContext.DBTypeManager));

                if (contBackwardExcept.Failed())
                    throw new GraphDBException(contBackwardExcept.IErrors);

                if (contBackwardExcept.Value)
                {
                    var beStream = dbObjectCache.LoadDBBackwardEdgeStream(myIDChainDefinition.LastType, myDBObjectStream.ObjectUUID).Value;
                    if (beStream.ContainsBackwardEdge(myIDChainDefinition.LastAttribute.BackwardEdgeDefinition))
                        return beStream.GetBackwardEdges(myIDChainDefinition.LastAttribute.BackwardEdgeDefinition);
                    else
                        return null;
                }
                else
                {
                    return null;
                }
            }
            else
            {
                if (myIDChainDefinition.LastAttribute.KindOfType == KindsOfType.SpecialAttribute)
                {
                    return myDBObjectStream.GetAttribute(myIDChainDefinition.LastAttribute.UUID, myIDChainDefinition.LastAttribute.GetRelatedType(dbContext.DBTypeManager), dbContext);
                }
                else
                {
                    return myDBObjectStream.GetAttribute(myIDChainDefinition.LastAttribute.UUID);
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Searches shortest, all shortest or all paths starting from "myStart" to "myEnd".
        /// </summary>
        /// <param name="myTypeAttribute">The Attribute representing the edge to follow (p.e. "Friends")</param>
        /// <param name="myTypeManager">The TypeManager for the Node type</param>
        /// <param name="myDBObjectCache">The Object Cache for faster object lookup</param>
        /// <param name="myStart">The start node</param>
        /// <param name="myEnd">The end node</param>
        /// <param name="shortestOnly">true, if only shortest path shall be found</param>
        /// <param name="findAll">if true and shortestOnly is true, all shortest paths will be found. if true, and shortest only is false, all paths will be searched</param>
        /// <param name="myMaxDepth">The maximum depth to search</param>
        /// <param name="myMaxPathLength">The maximum path length which shall be analyzed</param>
        /// <returns>A HashSet which contains all found paths. Every path is represented by a List of ObjectUUIDs</returns>
        public HashSet<List<ObjectUUID>> Find(TypeAttribute myTypeAttribute, DBTypeManager myTypeManager, DBObjectCache myDBObjectCache, DBObjectStream myStart, DBObjectStream myEnd, bool shortestOnly, bool findAll, byte myMaxDepth, byte myMaxPathLength)
        {
            #region data

            //queue for BFS
            Queue<Node> queue = new Queue<Node>();

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

            //current depth
            byte depth = 0;

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

            //root changed in Dictionary because of BidirectionalBFS
            HashSet<ObjectUUID> rootFriends = new HashSet<ObjectUUID>();

            //target node, the target of the select
            Node target = new Node(myEnd.ObjectUUID);

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

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

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

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

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

            //holds the actual DBObject
            Exceptional<DBObjectStream> currentDBObject;

            #endregion

            #region BFS

            //Log start
            ////_Logger.Info("Starting BFS..");

            //check if root node has edge and target has backwardedge
            var dbObject = myDBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myTypeManager), root.Key);
            if (dbObject.Failed())
            {
                throw new NotImplementedException();
            }

            if (!dbObject.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myTypeManager)))
            {
                ////_Logger.Info("Abort search! Start object has no edge!");
                //Console.WriteLine("No paths found!");
                return null;
            }

            var be = myDBObjectCache.LoadDBBackwardEdgeStream(myTypeAttribute.GetRelatedType(myTypeManager), target.Key);
            if (be.Failed())
            {
                throw new NotImplementedException();
            }

            if (!be.Value.ContainsBackwardEdge(edgeKey))
            {
                ////_Logger.Info("Abort search! End object has no backwardedge!");
                //Console.WriteLine("No paths found!");
                return null;
            }

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

                //dummy
                if (current.Key == null)
                {
                    break;
                }

                //load DBObject
                currentDBObject = myDBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myTypeManager), current.Key);
                if (currentDBObject.Failed())
                {
                    throw new NotImplementedException();
                }

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

                        foreach(ObjectUUID dbo in objectUUIDs)
                        {
                            //only for debug
                            //var currentNodeObject = myTypeManager.LoadDBObject(myTypeAttribute.RelatedGraphType, dbo);

                            //create a new node and set current = parent, currentNode = child
                            currentNode = new Node(dbo, current);

                            //if the child is the target
                            if (currentNode.Key.Equals(myEnd.ObjectUUID))
                            {
                                //node points on the target
                                target.Parents.Add(current);

                                //if shortestOnly == true we are finished here
                                if(shortestOnly)
                                {
                                    if (findAll)
                                    {
                                        //continue searching the current depth if there are any other shortest paths
                                        myMaxDepth = Convert.ToByte(depth);
                                        myMaxPathLength = Convert.ToByte(depth + 2);
                                    }
                                    else
                                    {
                                        ////_Logger.Info("found shortest path.");
                                        //got the shortest, finished
                                        return new TargetAnalyzer(root, rootFriends, target, myMaxPathLength, shortestOnly, findAll).getPaths();
                                    }
                                }
                            }
                            else
                            {
                                //been there before
                                if (visitedNodes.ContainsKey(currentNode.Key))
                                {
                                    //if currentNode.Key isn't root set parent
                                    if (!rootFriends.Contains(currentNode.Key))
                                    {
                                        //node has more then one parent
                                        visitedNodes[currentNode.Key].Parents.Add(current);
                                    }
                                    continue;
                                }

                                //never seen before
                                //mark the node as visited
                                visitedNodes.Add(currentNode.Key, currentNode);
                                //and look what comes on the next level of depth
                                queue.Enqueue(currentNode);

                                //some logging
                                if (queue.Count % 10000 == 0)
                                {
                                    ////_Logger.Info(queue.Count + " elements enqueued..");
                                }
                            }
                        }
                    }
                    else if (myTypeAttribute.EdgeType is ASingleReferenceEdgeType)
                    {
                        throw new NotImplementedException();
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }

                //if a new depth is reached
                if (queue.First() == dummy)
                {
                    //enqueue the dummy at the end of to mark the next depth
                    queue.Enqueue(queue.Dequeue());
                    //one step deeper in the dungen
                    depth++;
                    ////_Logger.Info("going deeper in the dungeon.. current level: " + depth);
                }
            }

            #endregion

            ////_Logger.Info("finished building path-graph.. starting analyzer");
            //analyze paths
            return new TargetAnalyzer(root, rootFriends, target, myMaxPathLength, shortestOnly, findAll).getPaths();
        }