/*----- Header files ------------------------------------------------------*/
+#include "tvec.h"
+#include "tvec-bench.h"
+#include "tvec-types.h"
+
#include "crc32.h"
+#include "siphash.h"
#include "unihash.h"
-#include "tvec.h"
-/*----- Main code ---------------------------------------------------------*/
+/*----- Register allocation -----------------------------------------------*/
enum {
RH, NROUT,
RK = NROUT, RM, NREG
};
+/*----- Testing utilities -------------------------------------------------*/
+
struct step { size_t s; };
+static void run_step(struct tvec_state *tv, tvec_testfn *fn, void *ctx)
+{
+ static const size_t steps[] = { 1, 5, 6, 7, 8, 23 };
+ struct step step;
+ size_t i;
+
+ fn(tv->in, tv->out, 0);
+ tvec_check(tv, "whole buffer");
+
+ for (i = 0; i < N(steps); i++) {
+ step.s = steps[i];
+ fn(tv->in, tv->out, &step);
+ tvec_check(tv, "step = %lu", (unsigned long)steps[i]);
+ }
+}
+
+static const struct tvec_env step_testenv = { 0, 0, 0, 0, run_step, 0, 0 };
+
+static void before_hash(struct tvec_state *tv, void *ctx)
+ { tvec_allocbuffer(&tv->in[RM].v); }
+
+/*----- CRC32 -------------------------------------------------------------*/
+
+static const struct tvec_regdef bench_regs[] = {
+ { "msz", &tvty_buffer, RM, TVRF_ID },
+ TVEC_ENDREGS
+};
+
+static const struct tvec_regdef crc32_regs[] = {
+ { "m", &tvty_bytes, RM, 0 },
+ { "h", &tvty_uint, RH, 0, { &tvrange_u32 } },
+ TVEC_ENDREGS
+};
+
static void test_crc32(const struct tvec_reg *in, struct tvec_reg *out,
void *ctx)
{
}
}
-static void before_hash(struct tvec_state *tv, void *ctx)
- { tvec_allocbuffer(&tv->in[RM].v); }
+static const struct tvec_test crc32_test =
+ { "crc32", crc32_regs, &step_testenv, test_crc32 };
static void bench_crc32(const struct tvec_reg *in, struct tvec_reg *out,
void *ctx)
{ crc32(0, in[RM].v.bytes.p, in[RM].v.bytes.sz); }
+
static const struct tvec_env crc32_benchenv =
{ 0, 0, 0, before_hash };
+static const struct tvec_benchenv crc32_bench =
+ { TVEC_BENCHINIT, 1, -1, RM, &crc32_benchenv };
+static const struct tvec_test crc32_benchtest =
+ { "crc32-bench", bench_regs, &crc32_bench._env, bench_crc32 };
-static void test_unihash(const struct tvec_reg *in, struct tvec_reg *out,
+/*----- SipHash -----------------------------------------------------------*/
+
+static const struct tvec_urange
+ siphash_keyrange = { SIPHASH_KEYSZ, SIPHASH_KEYSZ },
+ siphash_hashrange = { 8, 8 };
+
+static const struct tvec_regdef siphash_regs[] = {
+ { "k", &tvty_bytes, RK, 0, { &siphash_keyrange } },
+ { "m", &tvty_bytes, RM, 0 },
+ { "h", &tvty_bytes, RH, 0, { &siphash_hashrange } },
+ TVEC_ENDREGS
+};
+
+static void test_siphash(const struct tvec_reg *in, struct tvec_reg *out,
void *ctx)
{
const struct step *step = ctx;
- unihash_info ui;
const unsigned char *p = in[RM].v.bytes.p; size_t sz = in[RM].v.bytes.sz;
- uint32 h;
+ struct siphash_key k;
+ struct siphash s;
+ kludge64 h;
- unihash_setkey(&ui, in[RK].v.u);
+ siphash_setkey(&k, in[RK].v.bytes.p);
if (!step)
- out[RH].v.u = unihash(&ui, p, sz);
+ h = siphash(&k, p, sz);
else {
- for (h = UNIHASH_INIT(&ui); sz > step->s; p += step->s, sz -= step->s)
- h = unihash_hash(&ui, h, p, step->s);
- out[RH].v.u = unihash_hash(&ui, h, p, sz);
+ siphash_init(&s, &k);
+ for (; sz > step->s; p += step->s, sz -= step->s)
+ siphash_hash(&s, p, step->s);
+ siphash_hash(&s, p, sz);
+ h = siphash_done(&s);
}
+ tvec_allocbytes(&out[RH].v, 8); STORE64_L_(out[RH].v.bytes.p, h);
}
-static void bench_unihash(const struct tvec_reg *in, struct tvec_reg *out,
- void *ctx)
- { unihash_hash(ctx, 0, in[RM].v.bytes.p, in[RM].v.bytes.sz); }
-static void setup_unihash(struct tvec_state *tv,
- const struct tvec_env *env, void *pctx, void *ctx)
- { tvec_allocbuffer(&tv->in[RM].v); unihash_setkey(ctx, 0); }
-static const struct tvec_env unihash_benchenv =
- { sizeof(unihash_info), setup_unihash, 0, before_hash };
+static const struct tvec_test siphash_test =
+ { "siphash", siphash_regs, &step_testenv, test_siphash };
-static void run_step(struct tvec_state *tv, tvec_testfn *fn, void *ctx)
+static void setup_siphash(struct tvec_state *tv,
+ const struct tvec_env *env, void *pctx, void *ctx)
{
- static const size_t steps[] = { 1, 5, 6, 7, 8, 23 };
- struct step step;
- size_t i;
+ struct siphash_key *k = ctx;
+ ASSIGN64(k->k0, 0); ASSIGN64(k->k1, 0);
+}
- fn(tv->in, tv->out, 0);
- tvec_check(tv, "whole buffer");
+static void bench_siphash(const struct tvec_reg *in, struct tvec_reg *out,
+ void *ctx)
+ { siphash(ctx, in[RM].v.bytes.p, in[RM].v.bytes.sz); }
- for (i = 0; i < N(steps); i++) {
- step.s = steps[i];
- fn(tv->in, tv->out, &step);
- tvec_check(tv, "step = %lu", (unsigned long)steps[i]);
- }
-}
+static const struct tvec_env siphash_benchenv =
+ { sizeof(struct siphash_key), setup_siphash, 0, before_hash };
+static const struct tvec_benchenv siphash_bench =
+ { TVEC_BENCHINIT, 1, -1, RM, &siphash_benchenv };
+static const struct tvec_test siphash_benchtest =
+ { "siphash-bench", bench_regs, &siphash_bench._env, bench_siphash };
-static const struct tvec_env step_testenv = { 0, 0, 0, 0, run_step, 0, 0 };
+/*----- Unihash -----------------------------------------------------------*/
static const struct tvec_regdef unihash_regs[] = {
{ "k", &tvty_uint, RK, 0, { &tvrange_u32 } },
TVEC_ENDREGS
};
-static const struct tvec_regdef crc32_regs[] = {
- { "m", &tvty_bytes, RM, 0 },
- { "h", &tvty_uint, RH, 0, { &tvrange_u32 } },
- TVEC_ENDREGS
-};
+static void test_unihash(const struct tvec_reg *in, struct tvec_reg *out,
+ void *ctx)
+{
+ const struct step *step = ctx;
+ unihash_info ui;
+ const unsigned char *p = in[RM].v.bytes.p; size_t sz = in[RM].v.bytes.sz;
+ uint32 h;
-static const struct tvec_regdef bench_regs[] = {
- { "msz", &tvty_buffer, RM, TVRF_ID },
- TVEC_ENDREGS
-};
+ unihash_setkey(&ui, in[RK].v.u);
+ if (!step)
+ out[RH].v.u = unihash(&ui, p, sz);
+ else {
+ for (h = UNIHASH_INIT(&ui); sz > step->s; p += step->s, sz -= step->s)
+ h = unihash_hash(&ui, h, p, step->s);
+ out[RH].v.u = unihash_hash(&ui, h, p, sz);
+ }
+}
-static const struct tvec_benchenv crc32_bench =
- { TVEC_BENCHINIT, 1, -1, RM, &crc32_benchenv };
+static const struct tvec_test unihash_test =
+ { "unihash", unihash_regs, &step_testenv, test_unihash };
+
+static void setup_unihash(struct tvec_state *tv,
+ const struct tvec_env *env, void *pctx, void *ctx)
+ { unihash_setkey(ctx, 0); }
+
+static void bench_unihash(const struct tvec_reg *in, struct tvec_reg *out,
+ void *ctx)
+ { unihash_hash(ctx, 0, in[RM].v.bytes.p, in[RM].v.bytes.sz); }
+
+static const struct tvec_env unihash_benchenv =
+ { sizeof(unihash_info), setup_unihash, 0, before_hash };
static const struct tvec_benchenv unihash_bench =
{ TVEC_BENCHINIT, 1, -1, RM, &unihash_benchenv };
+static const struct tvec_test unihash_benchtest =
+ { "unihash-bench", bench_regs, &unihash_bench._env, bench_unihash };
+
+/*----- Main program ------------------------------------------------------*/
-static const struct tvec_test tests[] = {
- { "crc32", crc32_regs, &step_testenv, test_crc32 },
- { "unihash", unihash_regs, &step_testenv, test_unihash },
- { "crc32-bench", bench_regs, &crc32_bench._env, bench_crc32 },
- { "unihash-bench", bench_regs, &unihash_bench._env, bench_unihash },
- TVEC_ENDTESTS
+static const struct tvec_test *const tests[] = {
+ &crc32_test, &crc32_benchtest,
+ &siphash_test, &siphash_benchtest,
+ &unihash_test, &unihash_benchtest,
+ 0
};
static const struct tvec_config testconfig =