< Summary

Class:Microsoft.Azure.Batch.PagedEnumeratorBase`1
Assembly:Microsoft.Azure.Batch
File(s):C:\Git\azure-sdk-for-net\sdk\batch\Microsoft.Azure.Batch\src\PagedEnumeratorBase.cs
Covered lines:30
Uncovered lines:2
Coverable lines:32
Total lines:155
Line coverage:93.7% (30 of 32)
Covered branches:12
Total branches:12
Branch coverage:100% (12 of 12)

Metrics

MethodCyclomatic complexity Line coverage Branch coverage
.ctor()-100%100%
System.Collections.IEnumerator.get_Current()-0%100%
MoveNext()-100%100%
MoveNextAsync()-100%100%
Reset()-100%100%
ResetAsync(...)-100%100%
Dispose()-100%100%

File(s)

C:\Git\azure-sdk-for-net\sdk\batch\Microsoft.Azure.Batch\src\PagedEnumeratorBase.cs

#LineLine coverage
 1// Copyright (c) Microsoft Corporation. All rights reserved.
 2// Licensed under the MIT License. See License.txt in the project root for license information.
 3
 4using Microsoft.Azure.Batch.Utils;
 5using System;
 6using System.Collections;
 7using System.Collections.Generic;
 8using System.Linq;
 9using System.Text;
 10using System.Threading.Tasks;
 11using System.Threading;
 12
 13namespace Microsoft.Azure.Batch
 14{
 15    /// <summary>
 16    /// Implementents sync and async enumerator based on async calls to server.
 17    /// </summary>
 18    internal abstract class PagedEnumeratorBase<EnumerationType> : IPagedEnumerator<EnumerationType>, IEnumerator<Enumer
 19    {
 20        private readonly IPagedEnumerator<EnumerationType> _implInstance; // simplifies complexities around explicit dec
 21
 22        // index into current batch
 23        internal int _currentIndex;
 24
 25        // current batch of objects returned by last call
 26        internal object[] _currentBatch;
 27
 28        // manages the skip token
 29        private SkipTokenHandler _skipHandler;
 30
 31#region // constructors
 32
 4033        internal PagedEnumeratorBase()
 34        {
 4035            _implInstance = this;
 36
 37            // sets up state variables to trigger first call
 4038            this.Reset();
 4039        }
 40
 41#endregion // constructors
 42
 43#region // abstract methods that must be implemented by inheriting class
 44
 45        // for IPagedEnumerator<T> and IEnumerator<T>
 46        public abstract EnumerationType Current  { get;}
 47
 48        protected abstract System.Threading.Tasks.Task GetNextBatchFromServerAsync(SkipTokenHandler skipHandler, Cancell
 49
 50
 51#endregion // abstract methods
 52
 53        object System.Collections.IEnumerator.Current // for IEnumerator
 54        {
 55            get
 56            {
 057                object cur = _implInstance.Current;
 58
 059                return cur;
 60            }
 61        }
 62
 63        public bool MoveNext()  // for IEnumerator and IEnumerator<T>
 64        {
 1865            Task<bool> asyncTask = MoveNextAsync();
 1866            bool result = asyncTask.WaitAndUnaggregateException();
 67
 1868            return result;
 69        }
 70
 71        public async Task<bool> MoveNextAsync(CancellationToken cancellationToken = default(CancellationToken))
 72        {
 73            try
 74            {
 75                // move to next item in current batch
 12176                ++_currentIndex;
 77
 78                // if the index fits in the current batch,  return true
 12179                if ((null != _currentBatch) && (_currentIndex < _currentBatch.Length)) // we have results in memory, jus
 80                {
 4981                    return true;
 82                }
 83
 84                // if we are out of data then return false
 7285                if (_skipHandler.AtLeastOneCallMade && !_skipHandler.ThereIsMoreData)
 86                {
 1287                    return false;
 88                }
 89
 90                // at this point we need to call for more data
 6091                System.Threading.Tasks.Task asyncTask = this.GetNextBatchFromServerAsync(_skipHandler, cancellationToken
 92
 93                // wait for it to complete
 6094                await asyncTask.ConfigureAwait(continueOnCapturedContext: false);
 95
 96                // if we have new data in cache, serve it up
 4597                if ((null != _currentBatch) && (_currentBatch.Length > 0))
 98                {
 3699                    _currentIndex = 0;
 100
 36101                    return true;
 102                }
 9103            }
 15104            catch
 105            {
 15106                throw; // set breakpoint here
 107            }
 108
 9109            return false;
 106110        }
 111
 112        public void Reset()
 113        {
 40114            Task asyncTask = ResetAsync();
 40115            asyncTask.WaitAndUnaggregateException();
 40116        }
 117
 118        public Task ResetAsync(CancellationToken cancellationToken = default(CancellationToken))
 119        {
 40120            _skipHandler = new SkipTokenHandler();
 40121            _currentIndex = -1;
 40122            _currentBatch = null;
 40123            return Async.CompletedTask;
 124        }
 125
 126        // IDisposable
 127        public void Dispose()
 128        {
 22129        }
 130    }
 131
 132    internal class SkipTokenHandler
 133    {
 134        private string _skipToken;
 135        private bool _hasBeenCalled = false;
 136
 137        public bool AtLeastOneCallMade { get { return _hasBeenCalled; } set { _hasBeenCalled = value; } }
 138
 139        public string SkipToken
 140        {
 141            get
 142            {
 143                return _skipToken;
 144            }
 145
 146            set
 147            {
 148                _skipToken = value;
 149                _hasBeenCalled = true;
 150            }
 151        }
 152
 153        public bool ThereIsMoreData { get { return !string.IsNullOrEmpty(_skipToken); } }
 154    }
 155}