コード例 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="BucketCircularArray{T}"/> class.
        /// </summary>
        /// <param name="size">The maximum number of buckets to store.</param>
        public BucketCircularArray(int size)
        {
            AtomicReferenceArray <T>     buckets   = new AtomicReferenceArray <T>(size + 1); // + 1 as extra room for the add/remove
            BucketCircularArrayListState listState = new BucketCircularArrayListState(buckets, 0, 0);

            this.state = new AtomicReference <BucketCircularArrayListState>(listState);
        }
コード例 #2
0
        /// <summary>
        /// Appends an item to the end of the circular array.
        /// </summary>
        /// <param name="item">The item to add.</param>
        public void AddLast(T item)
        {
            BucketCircularArrayListState currentState = this.state.Value;
            BucketCircularArrayListState newState     = currentState.AddBucket(item);

            // use CompareAndSet to set in case multiple threads are attempting (which shouldn't be the case
            // because since AddLast will ONLY be called by a single thread at a time due to protection
            // provided in GetCurrentBucket)
            if (this.state.CompareAndSet(currentState, newState))
            {
                // we succeeded
                return;
            }
            else
            {
                // we failed, someone else was adding or removing
                // instead of trying again and risking multiple AddLast concurrently (which shouldn't be the case)
                // we'll just return and let the other thread 'win' and if the timing is off the next call to GetCurrentBucket will fix things
                return;
            }
        }
コード例 #3
0
 /// <summary>
 /// Clears the array.
 /// </summary>
 public void Clear()
 {
     while (true)
     {
         // it should be very hard to not succeed the first pass thru since this is typically is only called from
         // a single thread protected by a tryLock, but there is at least 1 other place (at time of writing this comment)
         // where reset can be called from (CircuitBreaker.markSuccess after circuit was tripped) so it can
         // in an edge-case conflict.
         //
         // Instead of trying to determine if someone already successfully called clear() and we should skip
         // we will have both calls reset the circuit, even if that means losing data added in between the two
         // depending on thread scheduling.
         //
         // The rare scenario in which that would occur, we'll accept the possible data loss while clearing it
         // since the code has stated its desire to clear() anyways.
         BucketCircularArrayListState current  = this.state.Value;
         BucketCircularArrayListState newState = current.Clear();
         if (this.state.CompareAndSet(current, newState))
         {
             return;
         }
     }
 }