Если требуются 100% точность:
Есть связанный список всех запросов и 3 пунктов - за последний час, в последнюю минуту, и последний второй.
У вас будет 2 указателя в связанном списке - на минуту назад и еще на секунду.
Час назад будет в конце списка. Всякий раз, когда время последнего запроса больше, чем за час до текущего времени, удалите его из списка и уменьшите количество часов.
Мгновенный и второй указатели указывают на первый запрос, который произошел через минуту и секунду назад соответственно. Всякий раз, когда время запроса составляет более минуты/секунды до текущего времени, сдвиньте указатель и уменьшите счет минуты/секунды.
Когда приходит новый запрос, добавьте его ко всем 3 подсчетам и добавьте его в начало связанного списка.
Запросы на подсчеты будут просто включать возврат счетчиков.
Все вышеуказанные операции амортизируются постоянным временем.
Если меньше, чем 100% точность приемлема:
Пространственно-сложность для выше, может быть немного больше, в зависимости от того, сколько запросов в секунду вы обычно получаете; вы можете уменьшить это, слегка пожертвовав по точности следующим образом:
Есть связанный список, как указано выше, но только за последнюю секунду. Также есть 3 счета.
Затем введите круговой массив из 60 элементов, обозначающий количество отсчетов за каждую из последних 60 секунд. Всякий раз, когда секунда проходит, вычитайте последний (самый старый) элемент массива из подсчета минут и добавьте последний счетчик в массив.
Иметь аналогичную круговую матрицу за последние 60 минут.
Потеря точности: Счет минут может быть отключен всеми запросами в секунду, а количество часов может быть отключено всеми запросами в минуту.
Очевидно, что это не имеет смысла, если у вас есть только один запрос в секунду или меньше. В этом случае вы можете сохранить последнюю минуту в связанном списке и просто иметь круглый массив за последние 60 минут.
Есть и другие варианты этого - коэффициент точности в пространстве может быть отрегулирован по мере необходимости.
Таймера удалить старые элементы:
Если вы удалите старые элементы только тогда, когда новые элементы приходят, он будет амортизироваться постоянная время (некоторые операции могут занять больше времени, но это будет усреднить до постоянная времени).
Если вы хотите истинное постоянное время, вы можете дополнительно запустить таймер, который удаляет старые элементы, и каждый вызов этого (и, конечно, вставки и проверка числа) будет занимать постоянное время, поскольку вы удаляете большинство элементов, вставленных в постоянное время с момента последнего таймера.
Возможный дубликат [Эффективный способ вычисления количества обращений к серверу в течение последней минуты, в режиме реального времени] (http://stackoverflow.com/questions/11701008/efficient-way-to-compute-number-of -hits-to-a-server-in-the-last-minute-in-r) –