chiark / gitweb /
@@@ all the mess ever
[mLib] / hash / t / hash-test.c
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
36 enum {
37   RH, NROUT,
38   RK = NROUT, RM, NREG
39 };
40
41 struct step { size_t s; };
42
43 static 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
59 static void bench_crc32(const struct tvec_reg *in, struct tvec_reg *out,
60                         void *ctx)
61   { crc32(0, in[RM].v.bytes.p, in[RM].v.bytes.sz); }
62
63 static void test_unihash(const struct tvec_reg *in, struct tvec_reg *out,
64                          void *ctx)
65 {
66   const struct step *step = ctx;
67   unihash_info ui;
68   const unsigned char *p = in[RM].v.bytes.p; size_t sz = in[RM].v.bytes.sz;
69   uint32 h;
70
71   unihash_setkey(&ui, in[RK].v.u);
72   if (!step)
73     out[RH].v.u = unihash(&ui, p, sz);
74   else {
75     for (h = UNIHASH_INIT(&ui); sz > step->s; p += step->s, sz -= step->s)
76       h = unihash_hash(&ui, h, p, step->s);
77     out[RH].v.u = unihash_hash(&ui, h, p, sz);
78   }
79 }
80
81 static void bench_unihash(const struct tvec_reg *in, struct tvec_reg *out,
82                           void *ctx)
83   { unihash_hash(ctx, 0, in[RM].v.bytes.p, in[RM].v.bytes.sz); }
84
85 static int setup_unihash(const struct tvec_reg *in, struct tvec_reg *out,
86                          const union tvec_misc *arg, void *ctx)
87   { unihash_setkey(ctx, 0); return (0); }
88
89 static void run_step(struct tvec_state *tv)
90 {
91   static const size_t steps[] = { 1, 5, 6, 7, 8, 23 };
92   struct step step;
93   size_t i;
94
95   tv->test->fn(tv->in, tv->out, 0);
96   tvec_check(tv, "whole buffer");
97
98   for (i = 0; i < N(steps); i++) {
99     step.s = steps[i];
100     tv->test->fn(tv->in, tv->out, &step);
101     tvec_check(tv, "step = %lu", (unsigned long)steps[i]);
102   }
103 }
104
105 static const struct tvec_regdef unihash_regs[] = {
106   { "k", RK, &tvty_uint, 0, { &tvrange_u32 } },
107   { "m", RM, &tvty_bytes, 0 },
108   { "h", RH, &tvty_uint, 0, { &tvrange_u32 } },
109   { 0, 0, 0, 0 }
110 };
111
112 static const struct tvec_regdef crc32_regs[] = {
113   { "m", RM, &tvty_bytes, 0 },
114   { "h", RH, &tvty_uint, 0, { &tvrange_u32 } },
115   { 0, 0, 0, 0 }
116 };
117
118 static const struct tvec_regdef bench_regs[] = {
119   { "msz", RM, &tvty_buffer, TVRF_ID },
120   { 0, 0, 0, 0 }
121 };
122
123 static const struct tvec_bench crc32_bench = {
124   1, -1, RM,
125   0, 0, 0, 0, { 0 }
126 };
127
128 static const struct tvec_bench unihash_bench = {
129   1, -1, RM,
130   sizeof(unihash_info), setup_unihash, 0, 0, { 0 }
131 };
132
133 static const struct tvec_test tests[] = {
134   { "crc32",crc32_regs, 0, run_step, test_crc32 },
135   { "unihash", unihash_regs, 0, run_step, test_unihash },
136   { "crc32-bench", bench_regs, 0,
137     tvec_bench, bench_crc32, { &crc32_bench } },
138   { "unihash-bench", bench_regs, 0,
139     tvec_bench, bench_unihash, { &unihash_bench } },
140   { 0, 0, 0, 0, 0 }
141 };
142
143 static const struct tvec_info testinfo =
144   { tests, NROUT, NREG, sizeof(struct tvec_reg) };
145
146 int main(int argc, char *argv[])
147   { return (tvec_main(argc, argv, &testinfo, 0)); }
148
149 /*----- That's all, folks -------------------------------------------------*/