public EventArgsItemsLoaded(int aStartIndex, IList <T> aItems, ERequestPriority aRequestPriority) : base() { iStartIndex = aStartIndex; iItems = aItems; iRequestPriority = aRequestPriority; }
public T Item(int aIndex, ERequestPriority aPriority) { Assert.Check(iOpened); Assert.Check(!iDisposed); Assert.Check(aIndex >= 0 && aIndex < iCount); T result = default(T); if (!iCache.TryGet(aIndex, out result)) { EnqueueRequest(aIndex, aPriority); } // readahead optimisation for foreground requests if (aPriority == ERequestPriority.Foreground && iReadAheadRanges > 0) { bool ascending = aIndex >= iLastRequest; iLastRequest = aIndex; ReadAhead(ascending, aIndex, iReadAheadRanges); } return(result); }
private void EnqueueRequest(int aIndex, ERequestPriority aPriority) { if (!iDisposed) { Assert.Check(iOpened); Assert.Check(aIndex >= 0 && aIndex < iCount); T item = default(T); if (!iCache.TryGet(aIndex, out item)) { lock (iQueueLock) { // get the correct start index for this request's chunk int startIndex = iRangeSize * (aIndex / iRangeSize); // first ensure that the request is not currently being executed if (iExecutingRequests.ContainsKey(startIndex)) { return; } // enqueue the request according to its priority (readahead requests are treated as slightly lower priority). int insertIndex = 0; int existingIndex = -1; RangeRequest existingRequest = null; for (int i = 0; i < iQueuedRequests.Count; i++) { RangeRequest current = iQueuedRequests[i]; if (current.Priority <= aPriority) { insertIndex++; } if (iQueuedRequests[i].StartIndex == startIndex) { existingIndex = i; existingRequest = current; } if (existingRequest != null && current.Priority > aPriority) { break; } } if (existingRequest != null) { // if it is already enqueued, but has been re-enqueued at a higher priority, move it up the queue if (insertIndex - 1 > existingIndex) { existingRequest.Priority = aPriority; iQueuedRequests.RemoveAt(existingIndex); iQueuedRequests.Insert(insertIndex - 1, existingRequest); } } else { Assert.Check(insertIndex <= iQueuedRequests.Count); iQueuedRequests.Insert(insertIndex, new RangeRequest() { Priority = aPriority, StartIndex = startIndex }); iDequeueScheduler.Schedule(new Scheduler.DCallback(DoDequeueRequest)); } } } } }