Esempio n. 1
0
 public void Unlink(IListElement <T> listElement)
 {
     lock (this.updateLatch)
     {
         this.UnlinkUnsafe(listElement);
     }
 }
Esempio n. 2
0
 public bool IsLinked(IListElement <T> listElement)
 {
     lock (this.updateLatch)
     {
         return(this.IsLinkedUnsafe(listElement));
     }
 }
        public CategoryView()
        {
            InitializeComponent();

            _excludeCommand = new CheckBoxElement(excludeCategories);

            _addCategoryCommand          = new ButtonElement(addCategory);
            _addCategoryCommand.Execute += () =>
            {
                if (AddCategory(AvailableCategories.SelectedItem))
                {
                    AvailableCategories.SelectedItem = null;
                }
            };

            _removeCategoryCommand          = new ButtonElement(removeCategory);
            _removeCategoryCommand.Execute += () =>
            {
                if (RemoveCategory(SelectedCategories.SelectedItem))
                {
                    SelectedCategories.SelectedItem = null;
                }
            };

            _availableCategories        = new ListElement(availableCatagories);
            _availableCategories.Sorted = true;
            _availableCategories.MouseItemDoubleClick += (sender, args) => AddCategory(args.Value);
            _selectedCategories = new ListElement(selectedCatagories);
            _selectedCategories.MouseItemDoubleClick += (sender, args) => RemoveCategory(args.Value);
        }
Esempio n. 4
0
 public OperationLockContext(ReliableConcurrentQueue <T> queue, IListElement <T> listElement, UnlockSource unlockSource, ITransaction tx, DateTime startTime)
 {
     this.queue              = queue;
     this.ListElement        = listElement;
     this.UnlockSource       = unlockSource;
     this.Transaction        = tx;
     this.OperationStartTime = startTime;
 }
Esempio n. 5
0
 public void AddListElement(IListElement <T> listElement)
 {
     if (this.HasListElement(listElement))
     {
         TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.AddListElement", "!this.HasListElement(listElement)");
     }
     this.ListElements[listElement.Id] = (ListElement)listElement;
 }
Esempio n. 6
0
        public void AddListElement(IListElement <T> listElement)
        {
            var positionBeforeListElements = (int)this.writer.BaseStream.Position;

            this.writer.Write(listElement.Id);
            this.valueSerializer.Write(listElement.Value, this.writer);
            this.listElementsBytes += (int)this.writer.BaseStream.Position - positionBeforeListElements;
            this.ListElementsCount++;
        }
Esempio n. 7
0
        public void RemoveListElement(IListElement <T> listElement)
        {
            this.AssertUnlinked(listElement);

            ListElement removed;
            var         res = this.ListElements.TryRemove(listElement.Id, out removed);

            if (!res)
            {
                TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.RemoveListElement", "res");
            }
            if (removed != (ListElement)listElement)
            {
                TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.RemoveListElement", "removed == (ReliableQueueListElement)listElement");
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Whenever an element is linked
        /// Set the result of the first waiting dequeuer.
        /// Should be called under the update latch
        /// </summary>
        /// <returns>True if there was a dequeuer waiting and we could set its result, False otherwise</returns>
        private bool TryNotifyDequeuer(IListElement <T> listElement)
        {
            TaskCompletionSource <ConditionalValue <IListElement <T> > > res;

            // While we have a waiting dequeuer
            while (this.dequeuerQueue.TryDequeue(out res))
            {
                // If the dequeuers result can be set, then we are done, return true
                if (res.TrySetResult(new ConditionalValue <IListElement <T> >(true, listElement)))
                {
                    return(true);
                }
            }

            // There was no waiting dequeuer
            return(false);
        }
Esempio n. 9
0
        public static async Task <IEnumerable <IListElement <T> > > ReadAsync(Stream stream, IStateSerializer <T> stateSerializer, string traceType)
        {
            var listElementsCountSegment = new ArraySegment <byte>(new byte[sizeof(int)]);
            var listElementsBytesSegment = new ArraySegment <byte>(new byte[sizeof(int)]);

            var listElementsCount = await SerializationHelper.ReadIntAsync(listElementsCountSegment, stream).ConfigureAwait(false);

            if (listElementsCount < 0)
            {
                throw new InvalidDataException(string.Format("Unexpected listElementsCount: {0}", listElementsCount));
            }

            var listElementsBytes = await SerializationHelper.ReadIntAsync(listElementsBytesSegment, stream).ConfigureAwait(false);

            if (listElementsBytes < 0)
            {
                throw new InvalidDataException(string.Format("Unexpected listElementsBytes: {0}", listElementsBytes));
            }

            using (var reader = new InMemoryBinaryReader(new MemoryStream()))
            {
                reader.BaseStream.SetLength(listElementsBytes + sizeof(ulong));
                await
                SerializationHelper.ReadBytesAsync(new ArraySegment <byte>(reader.BaseStream.GetBuffer()), listElementsBytes + sizeof(ulong), stream)
                .ConfigureAwait(false);

                var listElements = new IListElement <T> [listElementsCount];
                for (var i = 0; i < listElementsCount; i++)
                {
                    var id    = reader.ReadInt64();
                    var value = stateSerializer.Read(reader); // if this tries to read beyond the end of the stream, listElementsBytes was incorrect (too small)
                    listElements[i] = DataStore <T> .CreateQueueListElement(id, value, traceType, ListElementState.EnqueueApplied);
                }

                var readCRC = reader.ReadUInt64();
                var calcCRC =
                    CRC64.ToCRC64(new[] { listElementsCountSegment, listElementsBytesSegment, new ArraySegment <byte>(reader.BaseStream.GetBuffer(), 0, listElementsBytes), });
                if (readCRC != calcCRC)
                {
                    throw new InvalidDataException(string.Format("CRC mismatch.  Read: {0} Calculated: {1}", readCRC, calcCRC));
                }

                return(listElements);
            }
        }
Esempio n. 10
0
        public void LinkTail(IListElement <T> listElement)
        {
            this.AssertUnlinked(listElement);

            lock (this.updateLatch)
            {
                switch (this.queueMode)
                {
                // IReliableConcurrentQueue
                case RCQMode.NonBlocking:
                {
                    this.LinkTailUnsafe(listElement);
                    break;
                }

                // IReliableConcurrentBlockingQueue
                case RCQMode.Blocking:
                {
                    bool waitingDeq = false;

                    if (this.dequeuersState == DequeuerState.OnPrimary)
                    {
                        waitingDeq = this.TryNotifyDequeuer(listElement);
                    }
                    else
                    {
                        this.AssertNoDequeuer();
                    }

                    if (!waitingDeq)
                    {
                        // If there was no dequeuer waiting, link the element
                        this.LinkTailUnsafe(listElement);
                    }
                    break;
                }

                default:
                    TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.LinkTail",
                                                              "Invalid QueueMode : {0}", this.queueMode);
                    break;
                }
            }
        }
Esempio n. 11
0
        private bool IsTail(IListElement <T> listElement)
        {
            if (this.Tail != listElement)
            {
                return(false);
            }

            if (listElement.Next != null)
            {
                TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.IsTail", "Tail must have null Next pointer");
            }

            if ((this.Head == listElement) != (listElement.Previous == null))
            {
                TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.IsTail", "If the listElement is also the head, it must not have a valid previous pointer.  Otherwise, it must have a valid previous pointer.");
            }

            return(true);
        }
Esempio n. 12
0
        private bool IsHead(IListElement <T> listElement)
        {
            if (this.Head != listElement)
            {
                return(false);
            }

            if (listElement.Previous != null)
            {
                TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.IsHead", "Head must have null Previous pointer");
            }

            if ((listElement == this.Tail) != (listElement.Next == null))
            {
                TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.IsHead", "If the listElement is also the tail, it must not have a valid next pointer.  Otherwise, it must have a valid next pointer.");
            }

            return(true);
        }
Esempio n. 13
0
        public void AssertLinked(IListElement <T> listElement)
        {
            if (listElement == null)
            {
                TestableAssertHelper.FailArgumentNull(this.traceType, "DataStore.AssertLinked", "listElement");
            }

            if (!this.IsLinked(listElement))
            {
                TestableAssertHelper.FailInvalidOperation(
                    this.traceType,
                    "DataStore.AssertLinked",
                    "listElement <id: {0}, next: {1}, previous: {2}, state: {3}> is not linked.",
                    listElement.Id,
                    listElement.Next != null ? listElement.Next.Id : ListElement.ForbiddenId,
                    listElement.Previous != null ? listElement.Previous.Id : ListElement.ForbiddenId,
                    listElement.State);
            }
        }
Esempio n. 14
0
        /// <summary>
        /// Should be called under the update latch
        /// <paramref name="listElement"/> must be unlinked, Caller must Assert on this
        /// </summary>
        /// <param name="listElement"></param>
        private void LinkTailUnsafe(IListElement <T> listElement)
        {
            var queueListElement = (ListElement)listElement;

            if (this.Tail == null)
            {
                if (this.Head != null)
                {
                    TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.LinkTailUnsafe", "this.Head == null");
                }

                if (this.LinkedCount != 0)
                {
                    TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.LinkTailUnsafe", "this.LinkedCount == 0");
                }

                this.head = queueListElement;
                this.tail = queueListElement;
            }
            else
            {
                if (this.Head == null)
                {
                    TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.LinkTailUnsafe", "this.Head != null");
                }
                if (this.LinkedCount == 0)
                {
                    TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.LinkTailUnsafe", "this.LinkedCount != 0");
                }

                this.tail.Next            = queueListElement;
                queueListElement.Previous = this.tail;
                this.tail = queueListElement;
            }

            this.LinkedCount++;
        }
Esempio n. 15
0
        /// <summary>
        /// Unlink a listElement from the list.  Must be called under the update lock.
        /// </summary>
        /// <param name="listElement"></param>
        private void UnlinkUnsafe(IListElement <T> listElement)
        {
            if (listElement == null)
            {
                TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.UnlinkUnsafe", "listElement != null");
            }
            if (this.LinkedCount == 0)
            {
                TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.UnlinkUnsafe", "this.LinkedCount != 0");
            }
            if (this.Head == null)
            {
                TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.UnlinkUnsafe", "this.Head != null");
            }
            if (this.Head.Previous != null)
            {
                TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.UnlinkUnsafe", "this.Head.Previous == null");
            }
            if (this.Tail == null)
            {
                TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.UnlinkUnsafe", "this.Tail != null");
            }
            if (this.Tail.Next != null)
            {
                TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.UnlinkUnsafe", "this.Tail.Next == null");
            }
            if (this.LinkedCount != 1 && listElement.Next == null && listElement.Previous == null)
            {
                TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.UnlinkUnsafe", "!(this.LinkedCount != 1 && listElement.Next == null && listElement.Previous == null)");
            }

            var queueListElement = (ListElement)listElement;

            if (listElement.Previous == null)
            {
                if (listElement != this.Head)
                {
                    TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.UnlinkUnsafe", "listElement == this.Head");
                }
                this.head = this.head.Next;
            }
            else
            {
                queueListElement.Previous.Next = queueListElement.Next;
            }

            if (listElement.Next == null)
            {
                if (listElement != this.Tail)
                {
                    TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.UnlinkUnsafe", "listElement == this.Tail");
                }
                this.tail = queueListElement.Previous;
            }
            else
            {
                queueListElement.Next.Previous = queueListElement.Previous;
            }

            queueListElement.Previous = null;
            queueListElement.Next     = null;

            this.LinkedCount--;
        }
Esempio n. 16
0
 public bool HasListElement(IListElement <T> listElement)
 {
     return(this.HasListElement(listElement.Id));
 }
Esempio n. 17
0
        private bool IsLinkedUnsafe(IListElement <T> listElement)
        {
            // The order of the following checks is significant

            // is this listElement in the dictionary at all
            if (!this.HasListElement(listElement))
            {
                if (listElement.Next != null)
                {
                    TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.IsLinkedUnsafe", "sanity: If this listElement is not in the dictionary, it must not have a valid next pointer.");
                }
                if (listElement.Previous != null)
                {
                    TestableAssertHelper.FailInvalidOperation(
                        this.traceType,
                        "DataStore.IsLinkedUnsafe",
                        "sanity: If this listElement is not in the dictionary, it must not have a valid previous pointer.");
                }
                return(false);
            }

            // is it linked at the head or the tail
            if (this.IsHead(listElement) || this.IsTail(listElement))
            {
                return(true);
            }

            // is it not linked at all
            if (listElement.Next == null && listElement.Previous == null)
            {
                return(false);
            }

            // is it linked in the middle
            if (listElement.Next != null && listElement.Previous != null)
            {
                if (!(this.HasListElement(listElement.Next)))
                {
                    TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.IsLinkedUnsafe", "sanity: listElement.Next must be in the dictionary.");
                }
                if (listElement.Next.Previous != listElement)
                {
                    TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.IsLinkedUnsafe", "sanity: listElement.Next.Previous must be listElement.");
                }
                if (!(this.HasListElement(listElement.Previous)))
                {
                    TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.IsLinkedUnsafe", "sanity: listElement.Previous must be in the dictionary.");
                }
                if (listElement.Previous.Next != listElement)
                {
                    TestableAssertHelper.FailInvalidOperation(this.traceType, "DataStore.IsLinkedUnsafe", "sanity: listElement.Previous.Next must be listElement.");
                }
                return(true);
            }

            // it is partially linked and thus incorrect
            TestableAssertHelper.FailInvalidOperation(
                this.traceType,
                "DataStore.IsLinkedUnsafe",
                "Invalid listElement state: <id: {0}, next: {1}, previous: {2}, state: {3}>",
                listElement.Id,
                listElement.Next != null ? listElement.Next.Id : ListElement.ForbiddenId,
                listElement.Previous != null ? listElement.Previous.Id : ListElement.ForbiddenId,
                listElement.State);

            throw new InvalidOperationException("Invalid listElement state: " + listElement); // unreachable
        }
 public static IListElement Setup(this IListElement element, Action <View> setup)
 {
     return(new SetupListElement(element, setup));
 }
Esempio n. 19
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ListElementExpression"/> class.
 /// </summary>
 /// <param name="element">The element.</param>
 public ListElementExpression([NotNull] IListElement element) : base(element)
 {
     _element = element;
 }