/// <summary> /// If the PointInTime of parameter <c>relation</c> is greater than <c>registeredRelation</c>, /// we adjust the them. We favor to adjust only relations with <c>PointInTimeIsAdjustable</c> set to true. /// But if <c>force</c> is true, we always adjust <c>relation</c> also if both <c>PointInTimeIsAdjustable</c> /// are false.</summary> /// <param name="relation">Relation to adjust</param> /// <param name="registeredRelation">Relation to compare to</param> private static void AdjustRelationPointInTime(RelationBase relation, RelationBase registeredRelation, bool force) { if (relation.PointInTime > registeredRelation.PointInTime) { if (relation.PointInTimeIsAdjustable) { relation.SetInternalPointInTime(registeredRelation.PointInTime.Subtract(defaultRelationTimeCorrection)); } else if (registeredRelation.PointInTimeIsAdjustable && relation.PointInTime != UnknownPointInTime) { registeredRelation.SetInternalPointInTime(relation.PointInTime.Add(defaultRelationTimeCorrection)); } else if (force) { relation.SetInternalPointInTime(registeredRelation.PointInTime.Subtract(defaultRelationTimeCorrection)); } } }
/// <summary> /// Add a new Relation to the RelationCosmos. /// The relation(s) should be registered in time order oldest first to /// prevent lost relationships. /// </summary> /// <param name="relation">Relation to add</param> /// <exception cref="ArgumentNullException">If relation or relation.HRef is null</exception> public void Add(RelationBase relation) { if (relation == null) { throw new ArgumentNullException("relation"); } if (relation.HRef == null) { return; // nothing we can refer back } lock (syncRoot) { string href = relation.HRef; try { if (registeredRelations.Contains(href)) { Remove(relation); } if (deepCosmos && !allRelations.ContainsKey(href)) { allRelations.Add(href, relation); } // add the real (known) outgoing relations if (relation.OutgoingRelations.Count > 0) { foreach (string hrefOut in relation.OutgoingRelations) { if (hrefOut != null && hrefOut.Length > 0) { if (deepCosmos && !allRelations.Contains(hrefOut)) { allRelations.Add(hrefOut, new RelationProxy(hrefOut, relation.PointInTime, relation.PointInTimeIsAdjustable)); } if (deepCosmos) { if (href != hrefOut && allRelations.Contains(hrefOut)) { RelationBase known = allRelations[hrefOut]; // A relation can only contain refs to OLDER relation entries. // So we correct the unknown PointInTime to be the same dateTime of // the known entry subtract by the defaultRelationTimeCorrection. if (known.PointInTime > relation.PointInTime) { AdjustRelationPointInTime(relation, known, adjustPointInTime); } AddToRelationList(relation.HRef, known, allIncomingRelations); } } if (href != hrefOut && registeredRelations.Contains(hrefOut)) { RelationBase known = registeredRelations[hrefOut]; // A relation can only contain refs to OLDER relation entries. // So we correct the unknown PointInTime to be the same dateTime of // the known entry subtract by the defaultRelationTimeCorrection. if (known.PointInTime > relation.PointInTime) { AdjustRelationPointInTime(relation, known, adjustPointInTime); } AddToRelationList(known.HRef, relation, registeredIncomingRelations); } } } //foreach //reduce mem. usage: relation.OutgoingRelations.TrimToSize(); } else { // no outgoing links } // ensure new relation have a valid point in time entry. if (relation.PointInTime == UnknownPointInTime) { relation.SetInternalPointInTime(DateTime.UtcNow); // keep the movable information } // If we get relation(s) to add in unordered manner, that relation can be older then some known. // So we have to loop over yet known relations and test, if the known outgoing contains // reference(s) to the new one. If so, we add an entry to registeredIncomingRelations. foreach (RelationBase known in registeredRelations.Values) { if (known.OutgoingRelations.Contains(href)) { if (known.CompareTo(relation) <= 0) // known is OLDER // A relation can only contain refs to OLDER relation entries. // so we correct the unknown PointInTime to be the same dateTime of // the known entry subtract by the defaultRelationTimeCorrection. { AdjustRelationPointInTime(relation, known, adjustPointInTime); } else // known is NEWER // { } AddToRelationList(relation.HRef, known, registeredIncomingRelations); } //contains(relation) } //foreach //add to registered collection registeredRelations.Add(href, relation); } catch (Exception ex) { System.Diagnostics.Trace.WriteLine("RelationCosmos.Add() exception: " + ex.Message); } } }