//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; }
/// <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; }