public void Enqueue_One()
        {
            // arrange
            var queue = new WorkQueue();
            var task  = new MockExecutionTask();

            // act
            var count = queue.Push(task);

            // assert
            Assert.Equal(1, count);
            Assert.False(queue.HasRunningTasks);
            Assert.False(queue.IsEmpty);
        }
        public void Enqueue_Two()
        {
            // arrange
            var queue = new WorkQueue();
            var task1 = new MockExecutionTask();
            var task2 = new MockExecutionTask();

            // act
            var count1 = queue.Push(task1);
            var count2 = queue.Push(task2);

            // assert
            Assert.Equal(1, count1);
            Assert.Equal(2, count2);
            Assert.False(queue.HasRunningTasks);
            Assert.False(queue.IsEmpty);
        }
        public void Clear()
        {
            // arrange
            var queue = new WorkQueue();
            var task1 = new MockExecutionTask();
            var task2 = new MockExecutionTask();

            queue.Push(task1);
            queue.Push(task2);

            // act
            queue.Clear();

            // assert
            Assert.Equal(0, queue.Count);
            Assert.False(queue.HasRunningTasks);
            Assert.True(queue.IsEmpty);
        }
        public void Take_One()
        {
            // arrange
            var queue = new WorkQueue();
            var task1 = new MockExecutionTask();
            var task2 = new MockExecutionTask();

            queue.Push(task1);
            queue.Push(task2);

            // act
            var success = queue.TryTake(out var task);

            // assert
            Assert.Same(task2, task);
            Assert.True(success);
            Assert.True(queue.HasRunningTasks);
            Assert.False(queue.IsEmpty);
        }
        public void Complete_All()
        {
            // arrange
            var queue = new WorkQueue();
            var task1 = new MockExecutionTask();
            var task2 = new MockExecutionTask();

            queue.Push(task1);
            queue.Push(task2);

            // act
            queue.TryTake(out var task);
            queue.Complete();
            queue.TryTake(out task);
            queue.Complete();

            // assert
            Assert.Same(task1, task);
            Assert.False(queue.HasRunningTasks);
            Assert.True(queue.IsEmpty);
        }
        public void CopyTo(WorkQueue work, WorkQueue serial, QueryPlanStateMachine stateMachine)
        {
            IExecutionTask?head = _head;

            _head = null;

            while (head is not null)
            {
                IExecutionTask current = head;
                head         = head.Next;
                current.Next = null;

                if (stateMachine.IsSuspended(current))
                {
                    AppendTask(ref _head, current);
                }
                else
                {
                    (current.IsSerial ? serial : work).Push(current);
                }
            }

            IsEmpty = _head is null;
        }