Exemple #1
0
        /// <summary>
        /// Either retrieve an existing part instance with the specified sharing id, or
        /// create and share a new part instance using <paramref name="creator"/> within
        /// <paramref name="operation"/>.
        /// </summary>
        /// <param name="sharingId">Sharing id for the part in question.</param>
        /// <param name="operation">Operation in which to activate a new part instance if necessary.</param>
        /// <param name="creator">Activator that can activate a new part instance if necessary.</param>
        /// <returns>The part instance corresponding to <paramref name="sharingId"/> within this lifetime context.</returns>
        /// <remarks>This method is lock-free if the part instance already exists. If the part instance must be created,
        /// a lock will be taken that will serialize other writes via this method (concurrent reads will continue to
        /// be safe and lock-free). It is important that the composition, and thus lock acquisition, is strictly
        /// leaf-to-root in the lifetime tree.</remarks>
        public object GetOrCreate(int sharingId, CompositionOperation operation, CompositeActivator creator)
        {
            object result;

            if (_sharedPartInstances != null && _sharedPartInstances.TryGetValue(sharingId, out result))
            {
                return(result);
            }

            // Remains locked for the rest of the operation.
            operation.EnterSharingLock(_sharingLock);

            if (_sharedPartInstances == null)
            {
                _sharedPartInstances = new SmallSparseInitonlyArray();
                _instancesUndergoingInitialization = new SmallSparseInitonlyArray();
            }
            else if (_sharedPartInstances.TryGetValue(sharingId, out result))
            {
                return(result);
            }

            // Already being initialized _on the same thread_.
            if (_instancesUndergoingInitialization.TryGetValue(sharingId, out result))
            {
                return(result);
            }

            result = creator(this, operation);

            _instancesUndergoingInitialization.Add(sharingId, result);

            operation.AddPostCompositionAction(() =>
            {
                _sharedPartInstances.Add(sharingId, result);
            });

            return(result);
        }
        public bool TryGetValue(int index, out object value)
        {
            if (_elements == null)
            {
                value = null;
                return(false);
            }

            var elementIndex = index & ElementIndexMask;
            var e            = _elements[elementIndex];

            if (e != null && e.Index == index)
            {
                value = e.Value;
                return(true);
            }

            for (int offset = 1; offset <= LocalOffsetMax; ++offset)
            {
                e = _elements[(index + offset) & ElementIndexMask];
                if (e == null)
                {
                    value = null;
                    return(false);
                }

                if (e.Index == index)
                {
                    value = e.Value;
                    return(true);
                }
            }

            if (_overflow != null)
            {
                return(_overflow.TryGetValue(index, out value));
            }

            value = null;
            return(false);
        }