private void AddToQueue(DateTime timestamp, double period) { // check if we're out of space and resize the queue if necessary if (runTimeQueueCount == runTimeQueue.Length) { ResizeQueue(); } // add to the tail location runTimeQueue[runTimeQueueTail] = new RunTimeEntry(period, timestamp); // increment the tail location runTimeQueueTail = (runTimeQueueTail + 1) % runTimeQueue.Length; // increment the size runTimeQueueCount++; // update the tracker variables sumPeriod += period; sumPeriodSq += period * period; if (period > maxPeriod) { maxPeriod = period; } // check if we just added the first element if (runTimeQueueCount == 1) { // update the oldest queue time oldestQueueTime = timestamp; } }
private void ResizeQueue() { int averageRunRate = 0; if (sumPeriod > 0) { // calculate average mark rate, round up to next integer averageRunRate = (int)Math.Ceiling(runTimeQueueCount / sumPeriod); } // check if the run rate is below the default if (averageRunRate < DefaultRate) { averageRunRate = DefaultRate; } // calculate the new target size int newQueueSize = averageRunRate * windowSize; // if we're resizing, we might as well do a big resize // we'll enforce the rule that we at least make the queue 1.5x as big int minQueueSize = 3 * runTimeQueue.Length / 2; if (newQueueSize < minQueueSize) { newQueueSize = minQueueSize; } // create the new queue RunTimeEntry[] newRunTimeQueue = new RunTimeEntry[newQueueSize]; // copy the old values into the new queue if (runTimeQueueCount > 0) { if (runTimeQueueHead < runTimeQueueTail) { // we can copy directly, no wrap around at the moment Array.Copy(runTimeQueue, runTimeQueueHead, newRunTimeQueue, 0, runTimeQueueCount); } else { // we need to copy in two parts // 1) head to end of array Array.Copy(runTimeQueue, runTimeQueueHead, newRunTimeQueue, 0, runTimeQueue.Length - runTimeQueueHead); // 2) start of array to tail Array.Copy(runTimeQueue, 0, newRunTimeQueue, runTimeQueue.Length - runTimeQueueHead, runTimeQueueTail); } } // set the new queue as the current queue runTimeQueue = newRunTimeQueue; // adjust the head/tail indicies runTimeQueueHead = 0; runTimeQueueTail = runTimeQueueCount; }