]> mj.ucw.cz Git - libucw.git/commitdiff
Logging: Implemented rate limiting based on the Token Bucket Filter.
authorMartin Mares <mj@ucw.cz>
Fri, 20 Feb 2009 16:41:47 +0000 (17:41 +0100)
committerMartin Mares <mj@ucw.cz>
Fri, 20 Feb 2009 16:41:47 +0000 (17:41 +0100)
So far, it is a simple FP implementation. Maybe I will switch to integers later.

ucw/Makefile
ucw/tbf.c [new file with mode: 0644]
ucw/tbf.h [new file with mode: 0644]

index ccfc20ce972dc505b94e99f1d0376ae672a63e92..a696e7a74862d6b592dfa6734660207036435f72 100644 (file)
@@ -12,7 +12,7 @@ LIBUCW_MODS= \
        alloc alloc_str realloc bigalloc mempool mempool-str mempool-fmt eltpool \
        mmap partmap hashfunc \
        slists simple-lists bitsig \
-       log log-stream log-file log-syslog log-conf proctitle \
+       log log-stream log-file log-syslog log-conf proctitle tbf \
        conf-alloc conf-dump conf-input conf-intr conf-journal conf-parse conf-section \
        ipaccess \
        profile \
diff --git a/ucw/tbf.c b/ucw/tbf.c
new file mode 100644 (file)
index 0000000..7e4d474
--- /dev/null
+++ b/ucw/tbf.c
@@ -0,0 +1,56 @@
+/*
+ *     UCW Library -- Rate Limiting based on the Token Bucket Filter
+ *
+ *     (c) 2009 Martin Mares <mj@ucw.cz>
+ *
+ *     This software may be freely distributed and used according to the terms
+ *     of the GNU Lesser General Public License.
+ */
+
+#include "ucw/lib.h"
+#include "ucw/tbf.h"
+
+void
+tbf_init(struct token_bucket_filter *f)
+{
+  if (!f->burst)
+    f->burst = MAX(2*f->rate, 1);
+  f->last_hit = 0;
+  f->bucket = f->burst;
+}
+
+int
+tbf_limit(struct token_bucket_filter *f, timestamp_t now)
+{
+  timestamp_t delta_t = now - f->last_hit;
+  f->last_hit = now;
+
+  double b = f->bucket + f->rate * delta_t / 1000;
+  b = MIN(b, f->burst);
+  if (b >= 1)
+    {
+      f->bucket = b - 1;
+      return 1;
+    }
+  else
+    {
+      f->bucket = b;
+      return 0;
+    }
+}
+
+#ifdef TEST
+
+int main(void)
+{
+  struct token_bucket_filter t = { .rate = 1, .burst = 2 };
+  tbf_init(&t);
+  for (timestamp_t now = 0; now < 3000; now += 77)
+    {
+      int res = tbf_limit(&t, now);
+      msg(L_DEBUG, "t=%u result=%d bucket=%f", (uns) now, res, t.bucket);
+    }
+  return 0;
+}
+
+#endif
diff --git a/ucw/tbf.h b/ucw/tbf.h
new file mode 100644 (file)
index 0000000..1415479
--- /dev/null
+++ b/ucw/tbf.h
@@ -0,0 +1,23 @@
+/*
+ *     UCW Library -- Rate Limiting based on the Token Bucket Filter
+ *
+ *     (c) 2009 Martin Mares <mj@ucw.cz>
+ *
+ *     This software may be freely distributed and used according to the terms
+ *     of the GNU Lesser General Public License.
+ */
+
+#ifndef _UCW_TBF_H_
+#define _UCW_TBF_H_
+
+struct token_bucket_filter {
+  double rate;                         // Number of tokens per second
+  uns burst;                           // Capacity of the bucket
+  timestamp_t last_hit;                        // Internal state...
+  double bucket;
+};
+
+void tbf_init(struct token_bucket_filter *f);
+int tbf_limit(struct token_bucket_filter *f, timestamp_t now);
+
+#endif