Пример #1
0
        /// <summary>
        /// Adds a new key-value pair, or updates an existing one.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <param name="alreadyExists">Assigned to true if an existing key-value pair was
        /// updated, otherwise false. This should be considered undefined if false is returned.</param>
        /// <returns>True if the new key-value pair was added, or an existing one was updated.
        /// False only indicates failure to add a new key-value pair due to capacity limitations
        /// on the base <see cref="IPageStorage"/>.</returns>
        /// <exception cref="InvalidOperationException">Thrown if <see cref="IsReadOnly"/> is true or if this
        /// method is called from a thread that is currently enumerating via <see cref="GetEnumerator"/>.</exception>
        /// <remarks>
        /// This method will check whether a key-value pair already exists with the specified
        /// <paramref name="key"/>. If it does, then the value will be updated. Otherwise, a new key-value
        /// pair will be added. Addition of a new key-value pair may fail (as documented in the
        /// <see cref="TryAdd(TKey, TValue)"/> method's remarks) if inflation of the base
        /// <see cref="IPageStorage"/> fails. In this case, false will be returned and
        /// no key-value pairs will be changed (this is considered a graceful failure).
        /// </remarks>
        public bool TryAddOrUpdate(TKey key, TValue value, out bool alreadyExists)
        {
            if (IsReadOnly)
            {
                throw new InvalidOperationException("Cannot add a new key-value pair to, or update an existing one on, a read-only " + nameof(StorageDictionary <TKey, TValue>) + ".");
            }

            lock (locker)
            {
                if (isEnumerating_)
                {
                    throw new InvalidOperationException("Cannot add or update a key-value pair on the same thread that is currently enumerating this " + nameof(StorageDictionary <TKey, TValue>) + ".");
                }

                if (BTree.Insert(key, value, true, out alreadyExists))
                {
                    CachedPageStorage.Flush();//Ensure that data is written to base storage now
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Adds a new key-value pair.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <returns>True if addition was successful, false if it failed only due to capacity limitations
        /// on the base <see cref="IPageStorage"/>.</returns>
        /// <exception cref="InvalidOperationException">Thrown if <see cref="IsReadOnly"/> is true or if this
        /// method is called from a thread that is currently enumerating via <see cref="GetEnumerator"/>.</exception>
        /// <exception cref="ArgumentException">Thrown if the <paramref name="key"/> already exists in
        /// this <see cref="StorageDictionary{TKey, TValue}"/>.</exception>
        /// <remarks>
        /// This method will only add a new key-value pair, it will not update an existing one.
        /// The base <see cref="IPageStorage"/> may be inflated by this method if necessary (unless
        /// it is fixed-capacity). If inflation is required, but not possible or fails, then the
        /// new key-value pair will not be added and false will be returned (this is considered
        /// a graceful failure). If there is already a key-value pair with the specified
        /// <paramref name="key"/>, then an <see cref="ArgumentException"/> will be thrown and
        /// nothing will change. Any other failure will be reported by an <see cref="Exception"/>
        /// (of any type) being thrown, and may indicate data corruption.
        /// </remarks>
        public bool TryAdd(TKey key, TValue value)
        {
            if (IsReadOnly)
            {
                throw new InvalidOperationException("Cannot add to a read-only " + nameof(StorageDictionary <TKey, TValue>) + ".");
            }

            lock (locker)
            {
                if (isEnumerating_)
                {
                    throw new InvalidOperationException("Cannot add a key-value pair on the same thread that is currently enumerating this " + nameof(StorageDictionary <TKey, TValue>) + ".");
                }

                if (BTree.Insert(key, value, false, out bool alreadyExists))
                {
                    CachedPageStorage.Flush();//Ensure that data is written to base storage now
                    return(true);
                }
                else
                {
                    if (alreadyExists)
                    {
                        throw new ArgumentException("A key-value pair with the specified key already exists.", nameof(key));
                    }
                    else
                    {
                        return(false);//Insert failed due to storage limitation
                    }
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Updates the value of an existing key-value pair.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value to assign.</param>
        /// <exception cref="InvalidOperationException">Thrown if <see cref="IsReadOnly"/> is true or if this
        /// method is called from a thread that is currently enumerating via <see cref="GetEnumerator"/>.</exception>
        /// <exception cref="KeyNotFoundException">Thrown if there is no existing key-value pair with the
        /// specified <paramref name="key"/>.</exception>
        public void UpdateValue(TKey key, TValue value)
        {
            if (IsReadOnly)
            {
                throw new InvalidOperationException("Cannot update any key-value pair in a read-only " + nameof(StorageDictionary <TKey, TValue>) + ".");
            }

            lock (locker)
            {
                if (isEnumerating_)
                {
                    throw new InvalidOperationException("Cannot update a key-value pair on the same thread that is currently enumerating this " + nameof(StorageDictionary <TKey, TValue>) + ".");
                }

                if (BTree.TryGetValueOnNode(key, out _, out var onNode, out long indexOnNode, new CancellationToken(false)))
                {
                    onNode.SetValueAt(indexOnNode, value);
                    CachedPageStorage.Flush();//Ensure that data is written to base storage now
                }