Example #1
0
        // runs, updates and commits itself, all in one.
        public void Run(IEnumerable <IShielded> trigger)
        {
            Shield.InTransaction(() =>
            {
                var oldItems = _items.Value;
                if (oldItems == null || !oldItems.Overlaps(trigger))
                {
                    return; // not subscribed anymore..
                }
                bool test     = false;
                var testItems = Shield.IsolatedRun(() => test = Test());

                if (test)
                {
                    Trans();
                }

                // _locals will have value if Trans() called Dispose on "itself".
                if (!_locals.HasValue && !testItems.SetEquals(oldItems))
                {
                    if (!testItems.Any())
                    {
                        // get rid of all entries first.
                        Remover(oldItems);
                        throw new InvalidOperationException(
                            "A conditional test function must access at least one shielded field.");
                    }
                    _items.Value = testItems;
                    UpdateEntries();
                }
            });
        }
Example #2
0
 /// <summary>
 /// Gets or sets the item with the specified key.
 /// If there are many with the same key, acts on the first one it finds!
 /// </summary>
 public TValue this[TKey key]
 {
     get
     {
         return(Shield.InTransaction(() => {
             var n = FindInternal(key);
             if (n == null)
             {
                 throw new KeyNotFoundException();
             }
             return n.Value.Value;
         }));
     }
     set
     {
         Shield.AssertInTransaction();
         // replaces the first occurrence...
         var n = FindInternal(key);
         if (n == null)
         {
             Add(key, value);
         }
         else
         {
             n.Modify((ref Node nInner) => nInner.Value = value);
         }
     }
 }
Example #3
0
        /// <summary>
        /// Executes the function in a transaction, and returns its final result.
        /// Transactions may, in case of conflicts, get repeated from beginning. Your
        /// delegate should be ready for this. If you wish to do IO or similar
        /// operations, which should not be repeated, pass them to
        /// <see cref="Shield.SideEffect"/>. Nesting InTransaction calls is allowed,
        /// the nested transactions are treated as normal parts of the outer transaction.
        /// </summary>
        public static T InTransaction <T>(Func <T> act)
        {
            T retVal = default(T);

            Shield.InTransaction(() => { retVal = act(); });
            return(retVal);
        }
Example #4
0
 public void Dispose()
 {
     Shield.InTransaction(() => {
         _items.Value = null;
         UpdateEntries();
     });
 }
Example #5
0
        /// <summary>
        /// Checks both the key and value, which may be useful due to the tree supporting multiple
        /// entries with the same key.
        /// </summary>
        public bool Contains(KeyValuePair <TKey, TValue> item)
        {
            var valueComp = EqualityComparer <TValue> .Default;

            return(Shield.InTransaction(() =>
                                        RangeInternal(item.Key, item.Key).Any(n =>
                                                                              valueComp.Equals(n.Value.Value, item.Value))));
        }
Example #6
0
 /// <summary>
 /// Copy the dictionary contents to an array. Involves enumerating, might not get all
 /// items which should have been visible at the time of your commit. This does not
 /// affect read-only transactions, or those writers that do not logically depend on
 /// seeing all items.
 /// </summary>
 public void CopyTo(KeyValuePair <TKey, TItem>[] array, int arrayIndex)
 {
     Shield.InTransaction(() => {
         foreach (KeyValuePair <TKey, TItem> kvp in this)
         {
             array[arrayIndex++] = kvp;
         }
     });
 }
Example #7
0
 /// <summary>
 /// Copy the sequence to an array.
 /// </summary>
 /// <param name="array">The array to copy to.</param>
 /// <param name="arrayIndex">Index in the array where to begin the copy.</param>
 public void CopyTo(T[] array, int arrayIndex)
 {
     Shield.InTransaction(() => {
         foreach (var v in this)
         {
             array[arrayIndex++] = v;
         }
     });
 }
Example #8
0
        /// <summary>
        /// Try to get any one of the values stored under the given key. There may be multiple items
        /// under the same key!
        /// </summary>
        public bool TryGetValue(TKey key, out TValue value)
        {
            bool res = false;

            value = Shield.InTransaction(() => {
                var n = FindInternal(key);
                res   = n != null;
                return(res ? n.Value.Value : default(TValue));
            });
            return(res);
        }
Example #9
0
 public CommitSubscription(CommitSubscriptionContext context, Func <bool> test, Action trans)
 {
     Context = context;
     Test    = test;
     Trans   = trans;
     Shield.InTransaction(() => {
         var items = Shield.IsolatedRun(() => Test());
         if (!items.Any())
         {
             throw new InvalidOperationException(
                 "Test function must access at least one shielded field.");
         }
         _items.Value = items;
         UpdateEntries();
     });
 }
Example #10
0
 /// <summary>
 /// Search the sequence for the given item.
 /// </summary>
 /// <returns>The index of the item in the sequence, or -1 if not found.</returns>
 public int IndexOf(T item, IEqualityComparer <T> comp = null)
 {
     if (comp == null)
     {
         comp = EqualityComparer <T> .Default;
     }
     return(Shield.InTransaction(() => {
         var curr = _head;
         int i = 0;
         while (curr.Value != null && !comp.Equals(curr.Value.Value, item))
         {
             i++;
             curr = curr.Value.Next;
         }
         return curr.Value == null ? -1 : i;
     }));
 }
Example #11
0
 private Shielded <Node> FindInternal(TKey key)
 {
     return(Shield.InTransaction(() => {
         var curr = _head.Value;
         int comparison;
         while (curr != null &&
                (comparison = _comparer.Compare(curr.Value.Key, key)) != 0)
         {
             if (comparison > 0)
             {
                 curr = curr.Value.Left;
             }
             else
             {
                 curr = curr.Value.Right;
             }
         }
         return curr;
     }));
 }
Example #12
0
 private Shielded <ItemKeeper> RefToIndex(int index, bool plusOne = false)
 {
     return(Shield.InTransaction(() => {
         if (index < 0)
         {
             throw new IndexOutOfRangeException();
         }
         var curr = _head;
         for (; index > 0; index--)
         {
             if (curr.Value == null)
             {
                 throw new IndexOutOfRangeException();
             }
             curr = curr.Value.Next;
         }
         if (!plusOne && curr.Value == null)
         {
             throw new IndexOutOfRangeException();
         }
         return curr;
     }));
 }