Пример #1
0
        public void Add(int index, object value)
        {
            if (_elements == null)
            {
                _elements = new Element[ElementsCapacity];
            }

            var newElement = new Element {
                Index = index, Value = value
            };

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

            if (e == null)
            {
                _elements[elementIndex] = newElement;
                return;
            }

            // This overload of IsTrue doesn't call String.Format unless required.
            // Do, not switch to other version as it affects performance.
            Assumes.IsTrue(e.Index != index, "An item with the key '{0}' has already been added.", index);

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

                Assumes.IsTrue(e.Index != index, "An item with the key '{0}' has already been added.", index);
            }

            if (_overflow == null)
            {
                _overflow = new SmallSparseInitonlyArray();
            }

            _overflow.Add(index, value);
        }
        public void Add(int index, object value)
        {
            if (_elements == null)
            {
                _elements = new Element[ElementsCapacity];
            }

            var newElement = new Element {
                Index = index, Value = value
            };

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

            if (e == null)
            {
                _elements[elementIndex] = newElement;
                return;
            }

            Assumes.IsTrue(e.Index != index, string.Format("An item with the key '{0}' has already been added.", index));

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

                Assumes.IsTrue(e.Index != index, string.Format("An item with the key '{0}' has already been added.", index));
            }

            if (_overflow == null)
            {
                _overflow = new SmallSparseInitonlyArray();
            }

            _overflow.Add(index, value);
        }
Пример #3
0
        public void Add(int index, object value)
        {
            if (_elements == null)
                _elements = new Element[ElementsCapacity];

            var newElement = new Element { Index = index, Value = value };

            var elementIndex = index & ElementIndexMask;
            var e = _elements[elementIndex];
            if (e == null)
            {
                _elements[elementIndex] = newElement;
                return;
            }

            // This overload of IsTrue doesn't call String.Format unless required.
            // Do, not switch to other version as it affects performance.
            Assumes.IsTrue(e.Index != index, "An item with the key '{0}' has already been added.", index);

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

                Assumes.IsTrue(e.Index != index, "An item with the key '{0}' has already been added.", index);
            }

            if (_overflow == null)
                _overflow = new SmallSparseInitonlyArray();

            _overflow.Add(index, value);
        }
Пример #4
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;
        }