public EdmDirectValueAnnotationsManager() { this.annotationsDictionaryLock = new object(); this.unsortedElements = VersioningList<IEdmElement>.Create(); this.unsortedElementsLock = new object(); this.annotationsDictionary = VersioningDictionary<IEdmElement, object>.Create(new Func<IEdmElement, IEdmElement, int>(this.CompareElements)); }
/// <summary> /// Sets an annotation value for an EDM element. If the value is null, no annotation is added and an existing annotation with the same name is removed. /// </summary> /// <param name="element">The annotated element.</param> /// <param name="namespaceName">Namespace that the annotation belongs to.</param> /// <param name="localName">Name of the annotation within the namespace.</param> /// <param name="value">New annotation to set.</param> public void SetAnnotationValue(IEdmElement element, string namespaceName, string localName, object value) { lock (this.annotationsDictionaryLock) { // Use a local variable to store any interim changes to the annotations dictionary, and perform one atomic update // to the field. Otherwise, other threads could see a dictionary in an interim state. VersioningDictionary<IEdmElement, object> annotationsDictionary = this.annotationsDictionary; this.SetAnnotationValue(element, namespaceName, localName, value, ref annotationsDictionary); this.annotationsDictionary = annotationsDictionary; } }
public void SetAnnotationValues(IEnumerable<IEdmDirectValueAnnotationBinding> annotations) { lock (this.annotationsDictionaryLock) { VersioningDictionary<IEdmElement, object> versioningDictionary = this.annotationsDictionary; foreach (IEdmDirectValueAnnotationBinding annotation in annotations) { this.SetAnnotationValue(annotation.Element, annotation.NamespaceUri, annotation.Name, annotation.Value, ref versioningDictionary); } this.annotationsDictionary = versioningDictionary; } }
private object GetAnnotationValue(IEdmElement element, string namespaceName, string localName, VersioningDictionary <IEdmElement, object> annotationsDictionary) { object value; IEdmDirectValueAnnotation edmDirectValueAnnotation = EdmDirectValueAnnotationsManager.FindTransientAnnotation(EdmDirectValueAnnotationsManager.GetTransientAnnotations(element, annotationsDictionary), namespaceName, localName); if (edmDirectValueAnnotation == null) { IEnumerable <IEdmDirectValueAnnotation> attachedAnnotations = this.GetAttachedAnnotations(element); if (attachedAnnotations != null) { IEnumerator <IEdmDirectValueAnnotation> enumerator = attachedAnnotations.GetEnumerator(); using (enumerator) { while (enumerator.MoveNext()) { IEdmDirectValueAnnotation current = enumerator.Current; if (!(current.NamespaceUri == namespaceName) || !(current.Name == localName)) { continue; } value = current.Value; return(value); } return(null); } return(value); } return(null); } else { return(edmDirectValueAnnotation.Value); } }
/// <summary> /// Initializes a new instance of the <see cref="EdmDirectValueAnnotationsManager"/> class. /// </summary> public EdmDirectValueAnnotationsManager() { this.annotationsDictionary = VersioningDictionary <IEdmElement, object> .Create(this.CompareElements); }
private void SetAnnotationValue(IEdmElement element, string namespaceName, string localName, object value, ref VersioningDictionary <IEdmElement, object> annotationsDictionary) { object transientAnnotations = GetTransientAnnotations(element, annotationsDictionary); object transientAnnotationsBeforeSet = transientAnnotations; SetAnnotation(this.GetAttachedAnnotations(element), ref transientAnnotations, namespaceName, localName, value); // There is at least one case (removing an annotation that was not present to begin with) where the transient annotations are not changed, // so test to see if updating the dictionary is necessary. if (transientAnnotations != transientAnnotationsBeforeSet) { annotationsDictionary = annotationsDictionary.Set(element, transientAnnotations); } }
/// <summary> /// Initializes a new instance of the <see cref="EdmDirectValueAnnotationsManager"/> class. /// </summary> public EdmDirectValueAnnotationsManager() { this.annotationsDictionary = VersioningDictionary<IEdmElement, object>.Create(this.CompareElements); }
private void SetAnnotationValue(IEdmElement element, string namespaceName, string localName, object value, ref VersioningDictionary<IEdmElement, object> annotationsDictionary) { object transientAnnotations = GetTransientAnnotations(element, annotationsDictionary); object transientAnnotationsBeforeSet = transientAnnotations; SetAnnotation(this.GetAttachedAnnotations(element), ref transientAnnotations, namespaceName, localName, value); // There is at least one case (removing an annotation that was not present to begin with) where the transient annotations are not changed, // so test to see if updating the dictionary is necessary. if (transientAnnotations != transientAnnotationsBeforeSet) { annotationsDictionary = annotationsDictionary.Set(element, transientAnnotations); } }
/// <summary> /// Sets an annotation value for an EDM element. If the value is null, no annotation is added and an existing annotation with the same name is removed. /// </summary> /// <param name="element">The annotated element.</param> /// <param name="namespaceName">Namespace that the annotation belongs to.</param> /// <param name="localName">Name of the annotation within the namespace.</param> /// <param name="value">New annotation to set.</param> public void SetAnnotationValue(IEdmElement element, string namespaceName, string localName, object value) { lock (this.annotationsDictionaryLock) { // Use a local variable to store any interim changes to the annotations dictionary, and perform one atomic update // to the field. Otherwise, other threads could see a dictionary in an interim state. VersioningDictionary <IEdmElement, VersioningList <IEdmDirectValueAnnotation> > annotationsDictionary = this.annotationsDictionary; this.SetAnnotationValue(element, namespaceName, localName, value, ref annotationsDictionary); this.annotationsDictionary = annotationsDictionary; } }
/// <summary> /// Gets annotations associated with an element. /// </summary> /// <param name="element">The annotated element.</param> /// <returns>The immediate annotations for the element.</returns> public IEnumerable <IEdmDirectValueAnnotation> GetDirectValueAnnotations(IEdmElement element) { // Fetch the annotations dictionary once and only once, because this.annotationsDictionary might get updated by another thread. VersioningDictionary <IEdmElement, VersioningList <IEdmDirectValueAnnotation> > annotationsDictionary = this.annotationsDictionary; IEnumerable <IEdmDirectValueAnnotation> immutableAnnotations = this.GetAttachedAnnotations(element); VersioningList <IEdmDirectValueAnnotation> transientAnnotations = GetTransientAnnotations(element, annotationsDictionary); if (immutableAnnotations != null) { foreach (IEdmDirectValueAnnotation existingAnnotation in immutableAnnotations) { if (!IsDead(existingAnnotation.NamespaceUri, existingAnnotation.Name, transientAnnotations)) { yield return(existingAnnotation); } } } foreach (IEdmDirectValueAnnotation existingAnnotation in TransientAnnotations(transientAnnotations)) { yield return(existingAnnotation); } }
/// <summary> /// Retrieves the transient annotations for an EDM element. /// </summary> /// <param name="element">The annotated element.</param> /// <param name="annotationsDictionary">The dictionary for looking up the element's annotations.</param> /// <returns>The transient annotations for the element, in a form managed by the annotations manager.</returns> /// <remarks>This method is static to guarantee that the annotations dictionary is not fetched more than once per lookup operation.</remarks> private static VersioningList <IEdmDirectValueAnnotation> GetTransientAnnotations(IEdmElement element, VersioningDictionary <IEdmElement, VersioningList <IEdmDirectValueAnnotation> > annotationsDictionary) { VersioningList <IEdmDirectValueAnnotation> transientAnnotations; annotationsDictionary.TryGetValue(element, out transientAnnotations); return(transientAnnotations); }
/// <summary> /// Retrieves a set of annotation values. For each requested value, returns null if no annotation with the given name exists for the given element. /// </summary> /// <param name="annotations">The set of requested annotations</param> /// <returns>Returns values that correspond to the provided annotations. A value is null if no annotation with the given name exists for the given element.</returns> public object[] GetAnnotationValues(IEnumerable <IEdmDirectValueAnnotationBinding> annotations) { // Fetch the annotations dictionary once and only once, because this.annotationsDictionary might get updated by another thread. VersioningDictionary <IEdmElement, VersioningList <IEdmDirectValueAnnotation> > annotationsDictionary = this.annotationsDictionary; object[] values = new object[annotations.Count()]; int index = 0; foreach (IEdmDirectValueAnnotationBinding annotation in annotations) { values[index++] = this.GetAnnotationValue(annotation.Element, annotation.NamespaceUri, annotation.Name, annotationsDictionary); } return(values); }
/// <summary> /// Retrieves an annotation value for an EDM element. Returns null if no annotation with the given name exists for the given element. /// </summary> /// <param name="element">The annotated element.</param> /// <param name="namespaceName">Namespace that the annotation belongs to.</param> /// <param name="localName">Local name of the annotation.</param> /// <returns>Returns the annotation that corresponds to the provided name. Returns null if no annotation with the given name exists for the given element.</returns> public object GetAnnotationValue(IEdmElement element, string namespaceName, string localName) { // Fetch the annotations dictionary once and only once, because this.annotationsDictionary might get updated by another thread. VersioningDictionary <IEdmElement, VersioningList <IEdmDirectValueAnnotation> > annotationsDictionary = this.annotationsDictionary; return(this.GetAnnotationValue(element, namespaceName, localName, annotationsDictionary)); }
/// <summary> /// Sets a set of annotation values. If a supplied value is null, no annotation is added and an existing annotation with the same name is removed. /// </summary> /// <param name="annotations">The annotations to set</param> public void SetAnnotationValues(IEnumerable <IEdmDirectValueAnnotationBinding> annotations) { lock (this.annotationsDictionaryLock) { // Use a local variable to store any interim changes to the annotations dictionary, and perform one atomic update // to the field. Otherwise, other threads could see a dictionary in an interim state. VersioningDictionary <IEdmElement, VersioningList <IEdmDirectValueAnnotation> > annotationsDictionary = this.annotationsDictionary; foreach (IEdmDirectValueAnnotationBinding annotation in annotations) { this.SetAnnotationValue(annotation.Element, annotation.NamespaceUri, annotation.Name, annotation.Value, ref annotationsDictionary); } this.annotationsDictionary = annotationsDictionary; } }
private void SetAnnotationValue(IEdmElement element, string namespaceName, string localName, object value, ref VersioningDictionary <IEdmElement, object> annotationsDictionary) { object transientAnnotations = EdmDirectValueAnnotationsManager.GetTransientAnnotations(element, annotationsDictionary); object obj = transientAnnotations; EdmDirectValueAnnotationsManager.SetAnnotation(this.GetAttachedAnnotations(element), ref transientAnnotations, namespaceName, localName, value); if (transientAnnotations != obj) { annotationsDictionary = annotationsDictionary.Set(element, transientAnnotations); } }
/// <summary> /// Sets a set of annotation values. If a supplied value is null, no annotation is added and an existing annotation with the same name is removed. /// </summary> /// <param name="annotations">The annotations to set</param> public void SetAnnotationValues(IEnumerable<IEdmDirectValueAnnotationBinding> annotations) { lock (this.annotationsDictionaryLock) { // Use a local variable to store any interim changes to the annotations dictionary, and perform one atomic update // to the field. Otherwise, other threads could see a dictionary in an interim state. VersioningDictionary<IEdmElement, object> annotationsDictionary = this.annotationsDictionary; foreach (IEdmDirectValueAnnotationBinding annotation in annotations) { this.SetAnnotationValue(annotation.Element, annotation.NamespaceUri, annotation.Name, annotation.Value, ref annotationsDictionary); } this.annotationsDictionary = annotationsDictionary; } }
/// <summary> /// Retrieves the transient annotations for an EDM element. /// </summary> /// <param name="element">The annotated element.</param> /// <param name="annotationsDictionary">The dictionary for looking up the element's annotations.</param> /// <returns>The transient annotations for the element, in a form managed by the annotations manager.</returns> /// <remarks>This method is static to guarantee that the annotations dictionary is not fetched more than once per lookup operation.</remarks> private static object GetTransientAnnotations(IEdmElement element, VersioningDictionary<IEdmElement, object> annotationsDictionary) { object transientAnnotations; annotationsDictionary.TryGetValue(element, out transientAnnotations); return transientAnnotations; }
public void MapIntegerInsertionAndDeletion() { VersioningDictionary <int, int> map = VersioningDictionary <int, int> .Create(CompareIntegers); int value; Assert.IsTrue(map is VersioningDictionary <int, int> .EmptyVersioningDictionary, "Dictionary type"); Assert.IsFalse(map.TryGetValue(0, out value), "Zero key"); // Test conversions back and forth between EmptyDictionary, OneKeyDictionary, and TwoKeyDictionary. map = map.Set(1, 10); Assert.IsTrue(map is VersioningDictionary <int, int> .OneKeyDictionary, "Dictionary type"); Assert.AreEqual(map.Get(1), 10, "Key value"); Assert.IsFalse(map.TryGetValue(0, out value), "Zero key"); map = map.Set(1, 100); Assert.IsTrue(map is VersioningDictionary <int, int> .OneKeyDictionary, "Dictionary type"); Assert.AreEqual(map.Get(1), 100, "Key value"); Assert.IsFalse(map.TryGetValue(0, out value), "Zero key"); map = map.Remove(1); Assert.IsTrue(map is VersioningDictionary <int, int> .EmptyVersioningDictionary, "Dictionary type"); map = map.Set(1, 10); map = map.Set(2, 20); Assert.IsTrue(map is VersioningDictionary <int, int> .TwoKeyDictionary, "Dictionary type"); Assert.AreEqual(map.Get(1), 10, "Key value"); Assert.AreEqual(map.Get(2), 20, "Key value"); Assert.IsFalse(map.TryGetValue(0, out value), "Zero key"); map = map.Set(1, 100); Assert.IsTrue(map is VersioningDictionary <int, int> .TwoKeyDictionary, "Dictionary type"); Assert.AreEqual(map.Get(1), 100, "Key value"); Assert.AreEqual(map.Get(2), 20, "Key value"); map = map.Set(2, 200); Assert.IsTrue(map is VersioningDictionary <int, int> .TwoKeyDictionary, "Dictionary type"); Assert.AreEqual(map.Get(1), 100, "Key value"); Assert.AreEqual(map.Get(2), 200, "Key value"); VersioningDictionary <int, int> oneMap = map.Remove(1); Assert.IsTrue(oneMap is VersioningDictionary <int, int> .OneKeyDictionary, "Dictionary type"); Assert.AreEqual(oneMap.Get(2), 200, "Key value"); Assert.IsTrue(map is VersioningDictionary <int, int> .TwoKeyDictionary, "Dictionary type"); Assert.AreEqual(map.Get(1), 100, "Key value"); Assert.AreEqual(map.Get(2), 200, "Key value"); Assert.IsFalse(map.TryGetValue(0, out value), "Zero key"); oneMap = map.Remove(2); Assert.IsTrue(oneMap is VersioningDictionary <int, int> .OneKeyDictionary, "Dictionary type"); Assert.AreEqual(oneMap.Get(1), 100, "Key value"); Assert.IsTrue(map is VersioningDictionary <int, int> .TwoKeyDictionary, "Dictionary type"); Assert.AreEqual(map.Get(1), 100, "Key value"); Assert.AreEqual(map.Get(2), 200, "Key value"); // Test conversion to a TreeDictionary. map = map.Set(3, 30); Assert.IsTrue(map is VersioningDictionary <int, int> .TreeDictionary, "Dictionary type"); Assert.AreEqual(map.Get(1), 100, "Key value"); Assert.AreEqual(map.Get(2), 200, "Key value"); Assert.AreEqual(map.Get(3), 30, "Key value"); Assert.IsFalse(map.TryGetValue(0, out value), "Zero key"); map = map.Set(3, 300); Assert.IsTrue(map is VersioningDictionary <int, int> .TreeDictionary, "Dictionary type"); Assert.AreEqual(map.Get(1), 100, "Key value"); Assert.AreEqual(map.Get(2), 200, "Key value"); Assert.AreEqual(map.Get(3), 300, "Key value"); // Test that a significant number of keys does not force conversion to a HashKeyDictionary. for (int i = 1; i <= 100; i++) { map = map.Set(i, i * 10); } Assert.IsTrue(map is VersioningDictionary <int, int> .TreeDictionary, "Dictionary type"); for (int i = 1; i <= 100; i++) { Assert.AreEqual(i * 10, map.Get(i), "Key value"); } Assert.IsFalse(map.TryGetValue(0, out value), "Zero key"); // Test removing half the keys. for (int i = 1; i < 100; i += 2) { map = map.Remove(i); } Assert.IsTrue(map is VersioningDictionary <int, int> .TreeDictionary, "Dictionary type"); for (int i = 1; i < 100; i += 2) { Assert.IsFalse(map.TryGetValue(i, out value), "Odd key"); Assert.AreEqual((i + 1) * 10, map.Get(i + 1), "Even key value"); } // Test conversion to a HashTreeDictionary. for (int i = 1; i <= 10000; i++) { map = map.Set(i, i * 2); } Assert.IsTrue(map is VersioningDictionary <int, int> .HashTreeDictionary, "Dictionary type"); for (int i = 1; i <= 10000; i++) { Assert.AreEqual(i * 2, map.Get(i), "Key value"); } Assert.IsFalse(map.TryGetValue(0, out value), "Zero key"); // Test removing half the keys. for (int i = 1; i < 10000; i += 2) { map = map.Remove(i); } Assert.IsTrue(map is VersioningDictionary <int, int> .HashTreeDictionary, "Dictionary type"); for (int i = 1; i < 10000; i += 2) { Assert.IsFalse(map.TryGetValue(i, out value), "Odd key"); Assert.AreEqual((i + 1) * 2, map.Get(i + 1), "Even key value"); } }
private object GetAnnotationValue(IEdmElement element, string namespaceName, string localName, VersioningDictionary<IEdmElement, object> annotationsDictionary) { IEdmDirectValueAnnotation annotation = FindTransientAnnotation(GetTransientAnnotations(element, annotationsDictionary), namespaceName, localName); if (annotation != null) { return annotation.Value; } IEnumerable<IEdmDirectValueAnnotation> immutableAnnotations = this.GetAttachedAnnotations(element); if (immutableAnnotations != null) { foreach (IEdmDirectValueAnnotation existingAnnotation in immutableAnnotations) { if (existingAnnotation.NamespaceUri == namespaceName && existingAnnotation.Name == localName) { // No need to check that the immutable annotation isn't Dead, because if it were // the tombstone would have been found in the transient annotations. return existingAnnotation.Value; } } } return null; }
private object GetAnnotationValue(IEdmElement element, string namespaceName, string localName, VersioningDictionary<IEdmElement, object> annotationsDictionary) { object value; IEdmDirectValueAnnotation edmDirectValueAnnotation = EdmDirectValueAnnotationsManager.FindTransientAnnotation(EdmDirectValueAnnotationsManager.GetTransientAnnotations(element, annotationsDictionary), namespaceName, localName); if (edmDirectValueAnnotation == null) { IEnumerable<IEdmDirectValueAnnotation> attachedAnnotations = this.GetAttachedAnnotations(element); if (attachedAnnotations != null) { IEnumerator<IEdmDirectValueAnnotation> enumerator = attachedAnnotations.GetEnumerator(); using (enumerator) { while (enumerator.MoveNext()) { IEdmDirectValueAnnotation current = enumerator.Current; if (!(current.NamespaceUri == namespaceName) || !(current.Name == localName)) { continue; } value = current.Value; return value; } return null; } return value; } return null; } else { return edmDirectValueAnnotation.Value; } }
public static string GetNamespaceAlias(this IEdmModel model, string namespaceName) { VersioningDictionary <string, string> annotationValue = model.GetAnnotationValue <VersioningDictionary <string, string> >(model, "http://schemas.microsoft.com/ado/2011/04/edm/internal", "NamespaceAlias"); return(annotationValue.Get(namespaceName)); }
public void SetAnnotationValue(IEdmElement element, string namespaceName, string localName, object value) { lock (this.annotationsDictionaryLock) { VersioningDictionary<IEdmElement, object> versioningDictionary = this.annotationsDictionary; this.SetAnnotationValue(element, namespaceName, localName, value, ref versioningDictionary); this.annotationsDictionary = versioningDictionary; } }
private object GetAnnotationValue(IEdmElement element, string namespaceName, string localName, VersioningDictionary <IEdmElement, object> annotationsDictionary) { IEdmDirectValueAnnotation annotation = FindTransientAnnotation(GetTransientAnnotations(element, annotationsDictionary), namespaceName, localName); if (annotation != null) { return(annotation.Value); } IEnumerable <IEdmDirectValueAnnotation> immutableAnnotations = this.GetAttachedAnnotations(element); if (immutableAnnotations != null) { foreach (IEdmDirectValueAnnotation existingAnnotation in immutableAnnotations) { if (existingAnnotation.NamespaceUri == namespaceName && existingAnnotation.Name == localName) { // No need to check that the immutable annotation isn't Dead, because if it were // the tombstone would have been found in the transient annotations. return(existingAnnotation.Value); } } } return(null); }
private void SetAnnotationValue(IEdmElement element, string namespaceName, string localName, object value, ref VersioningDictionary<IEdmElement, object> annotationsDictionary) { object transientAnnotations = EdmDirectValueAnnotationsManager.GetTransientAnnotations(element, annotationsDictionary); object obj = transientAnnotations; EdmDirectValueAnnotationsManager.SetAnnotation(this.GetAttachedAnnotations(element), ref transientAnnotations, namespaceName, localName, value); if (transientAnnotations != obj) { annotationsDictionary = annotationsDictionary.Set(element, transientAnnotations); } }
/// <summary> /// Gets the serialization alias for a given namespace. /// </summary> /// <param name="model">Model that will be serialized.</param> /// <param name="namespaceName">Namespace the alias is needed for.</param> /// <returns>The alias of the given namespace, or null if one does not exist.</returns> public static string GetNamespaceAlias(this IEdmModel model, string namespaceName) { VersioningDictionary <string, string> mappings = model.GetAnnotationValue <VersioningDictionary <string, string> >(model, EdmConstants.InternalUri, CsdlConstants.NamespaceAliasAnnotation); return(mappings.Get(namespaceName)); }
public object GetAnnotationValue(IEdmElement element, string namespaceName, string localName) { VersioningDictionary <IEdmElement, object> versioningDictionary = this.annotationsDictionary; return(this.GetAnnotationValue(element, namespaceName, localName, versioningDictionary)); }