public bool HasAttribute <T>(AttributeKey <T> key) where T : class { if (key is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key); } DefaultAttribute[] attrs = Volatile.Read(ref this.attributes); if (attrs is null) { // no attribute exists return(false); } int i = Index(key); DefaultAttribute head = Volatile.Read(ref attrs[i]); if (head is null) { // No attribute exists which point to the bucket in which the head should be located return(false); } // check on the head can be done without synchronization if (head.GetKey() == key && !head.Removed) { return(true); } lock (head) { // we need to synchronize on the head DefaultAttribute curr = head.Next; while (curr is object) { if (!curr.Removed && curr.GetKey() == key) { return(true); } curr = curr.Next; } return(false); } }
public bool HasAttribute <T>(AttributeKey <T> key) where T : class { Contract.Requires(key != null); DefaultAttribute[] attrs = this.attributes; if (attrs == null) { // no attribute exists return(false); } int i = Index(key); DefaultAttribute head = Volatile.Read(ref attrs[i]); if (head == null) { // No attribute exists which point to the bucket in which the head should be located return(false); } // check on the head can be done without synchronization if (head.GetKey() == key && !head.Removed) { return(true); } lock (head) { // we need to synchronize on the head DefaultAttribute curr = head.Next; while (curr != null) { if (!curr.Removed && curr.GetKey() == key) { return(true); } curr = curr.Next; } return(false); } }
static int Index <T>(AttributeKey <T> key) => key.Id & Mask;