Created
March 30, 2016 21:42
-
-
Save ray1729/e12485cec1249515126489107134a154 to your computer and use it in GitHub Desktop.
Simple time-based sliding window counter implementation in Clojure
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns sliding-window-counter.core | |
(:refer-clojure :exclude [inc])) | |
(defprotocol ICounter | |
(reset [this]) | |
(inc [this]) | |
(value [this])) | |
(defrecord SlidingWindowCounter [window-size bucket-size num-buckets buckets] | |
ICounter | |
(reset [this] | |
(assoc this :buckets {})) | |
(inc [this] | |
(let [bucket (quot (System/currentTimeMillis) bucket-size) | |
buckets (update buckets bucket (fnil clojure.core/inc 0)) | |
buckets (if (> (count buckets) num-buckets) | |
(let [k (apply min (keys buckets))] | |
(dissoc buckets k)) | |
buckets)] | |
(assoc this :buckets buckets))) | |
(value [this] | |
(let [cutoff (quot (- (System/currentTimeMillis) window-size) bucket-size)] | |
(reduce + 0 (map val (filter #(>= (key %) cutoff) buckets)))))) | |
(defn sliding-window-counter | |
[window-size num-buckets] | |
{:pre [(zero? (rem window-size num-buckets))]} | |
(let [bucket-size (quot window-size num-buckets)] | |
(->SlidingWindowCounter window-size bucket-size num-buckets {}))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment