Exemplo n.º 1
0
 public EventArgsItemsLoaded(int aStartIndex, IList <T> aItems, ERequestPriority aRequestPriority)
     : base()
 {
     iStartIndex      = aStartIndex;
     iItems           = aItems;
     iRequestPriority = aRequestPriority;
 }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        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));
                        }
                    }
                }
            }
        }