@@@ man wip
[mLib] / hash / t / hash-test.c
CommitLineData
b64eb60f
MW
1/* -*-c-*-
2 *
3 * Test driver for universal hashing
4 *
5 * (c) 2009 Straylight/Edgeware
6 */
7
8/*----- Licensing notice --------------------------------------------------*
9 *
10 * This file is part of the mLib utilities library.
11 *
12 * mLib is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU Library General Public License as
14 * published by the Free Software Foundation; either version 2 of the
15 * License, or (at your option) any later version.
16 *
17 * mLib is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Library General Public License for more details.
21 *
22 * You should have received a copy of the GNU Library General Public
23 * License along with mLib; if not, write to the Free
24 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25 * MA 02111-1307, USA.
26 */
27
28/*----- Header files ------------------------------------------------------*/
29
30#include "crc32.h"
31#include "unihash.h"
32#include "tvec.h"
33
34/*----- Main code ---------------------------------------------------------*/
35
36enum {
37 RH, NROUT,
38 RK = NROUT, RM, NREG
39};
40
41struct step { size_t s; };
42
43static void test_crc32(const struct tvec_reg *in, struct tvec_reg *out,
44 void *ctx)
45{
46 const struct step *step = ctx;
47 const unsigned char *p = in[RM].v.bytes.p; size_t sz = in[RM].v.bytes.sz;
48 uint32 h;
49
50 if (!step)
51 out[RH].v.u = crc32(0, p, sz);
52 else {
53 for (h = 0; sz > step->s; p += step->s, sz -= step->s)
54 h = crc32(h, p, step->s);
55 out[RH].v.u = crc32(h, p, sz);
56 }
57}
58
adec5584
MW
59static void before_hash(struct tvec_state *tv, void *ctx)
60 { tvec_allocbuffer(&tv->in[RM].v); }
61
b64eb60f
MW
62static void bench_crc32(const struct tvec_reg *in, struct tvec_reg *out,
63 void *ctx)
64 { crc32(0, in[RM].v.bytes.p, in[RM].v.bytes.sz); }
adec5584
MW
65static const struct tvec_env crc32_benchenv =
66 { 0, 0, 0, before_hash };
b64eb60f
MW
67
68static void test_unihash(const struct tvec_reg *in, struct tvec_reg *out,
69 void *ctx)
70{
71 const struct step *step = ctx;
72 unihash_info ui;
73 const unsigned char *p = in[RM].v.bytes.p; size_t sz = in[RM].v.bytes.sz;
74 uint32 h;
75
76 unihash_setkey(&ui, in[RK].v.u);
77 if (!step)
78 out[RH].v.u = unihash(&ui, p, sz);
79 else {
80 for (h = UNIHASH_INIT(&ui); sz > step->s; p += step->s, sz -= step->s)
81 h = unihash_hash(&ui, h, p, step->s);
82 out[RH].v.u = unihash_hash(&ui, h, p, sz);
83 }
84}
85
86static void bench_unihash(const struct tvec_reg *in, struct tvec_reg *out,
87 void *ctx)
88 { unihash_hash(ctx, 0, in[RM].v.bytes.p, in[RM].v.bytes.sz); }
c91413e6
MW
89static void setup_unihash(struct tvec_state *tv,
90 const struct tvec_env *env, void *pctx, void *ctx)
adec5584 91 { tvec_allocbuffer(&tv->in[RM].v); unihash_setkey(ctx, 0); }
e63124bc 92static const struct tvec_env unihash_benchenv =
adec5584 93 { sizeof(unihash_info), setup_unihash, 0, before_hash };
b64eb60f 94
e63124bc 95static void run_step(struct tvec_state *tv, tvec_testfn *fn, void *ctx)
b64eb60f
MW
96{
97 static const size_t steps[] = { 1, 5, 6, 7, 8, 23 };
98 struct step step;
99 size_t i;
100
e63124bc 101 fn(tv->in, tv->out, 0);
b64eb60f
MW
102 tvec_check(tv, "whole buffer");
103
104 for (i = 0; i < N(steps); i++) {
105 step.s = steps[i];
e63124bc 106 fn(tv->in, tv->out, &step);
b64eb60f
MW
107 tvec_check(tv, "step = %lu", (unsigned long)steps[i]);
108 }
109}
110
e63124bc
MW
111static const struct tvec_env step_testenv = { 0, 0, 0, 0, run_step, 0, 0 };
112
b64eb60f 113static const struct tvec_regdef unihash_regs[] = {
d056fbdf
MW
114 { "k", &tvty_uint, RK, 0, { &tvrange_u32 } },
115 { "m", &tvty_bytes, RM, 0 },
116 { "h", &tvty_uint, RH, 0, { &tvrange_u32 } },
db2bf411 117 TVEC_ENDREGS
b64eb60f
MW
118};
119
120static const struct tvec_regdef crc32_regs[] = {
d056fbdf
MW
121 { "m", &tvty_bytes, RM, 0 },
122 { "h", &tvty_uint, RH, 0, { &tvrange_u32 } },
db2bf411 123 TVEC_ENDREGS
b64eb60f
MW
124};
125
126static const struct tvec_regdef bench_regs[] = {
d056fbdf 127 { "msz", &tvty_buffer, RM, TVRF_ID },
db2bf411 128 TVEC_ENDREGS
b64eb60f
MW
129};
130
c91413e6 131static const struct tvec_benchenv crc32_bench =
adec5584 132 { TVEC_BENCHINIT, 1, -1, RM, &crc32_benchenv };
c91413e6 133static const struct tvec_benchenv unihash_bench =
e63124bc 134 { TVEC_BENCHINIT, 1, -1, RM, &unihash_benchenv };
b64eb60f
MW
135
136static const struct tvec_test tests[] = {
e63124bc
MW
137 { "crc32", crc32_regs, &step_testenv, test_crc32 },
138 { "unihash", unihash_regs, &step_testenv, test_unihash },
139 { "crc32-bench", bench_regs, &crc32_bench._env, bench_crc32 },
140 { "unihash-bench", bench_regs, &unihash_bench._env, bench_unihash },
db2bf411 141 TVEC_ENDTESTS
b64eb60f
MW
142};
143
c5e0e403 144static const struct tvec_config testconfig =
b64eb60f
MW
145 { tests, NROUT, NREG, sizeof(struct tvec_reg) };
146
147int main(int argc, char *argv[])
c5e0e403 148 { return (tvec_main(argc, argv, &testconfig, 0)); }
b64eb60f
MW
149
150/*----- That's all, folks -------------------------------------------------*/