1 module test_murmur128;
2 
3 /** MD5 Checksum Routines Unittest (D module) */
4 import core.stdc.stdlib;
5 import std.datetime.stopwatch;
6 import std.digest;
7 import std.digest.murmurhash;
8 import std.file;
9 import std.format;
10 import std.range;
11 import std.stdint;
12 import std.stdio;
13 
14 import test_helpers;
15 import test_csv;
16 
17 /** Test and benchmark the mm3232 functions */
18 
19 int test_mm128(int argTimeLimit, bool writeCSV) {
20 	auto csvFileName = "./docs/benchmark_mm128.csv";
21 	auto csvFile = new TestCSVFile!Murmur128TestData(csvFileName);
22 
23 	auto timeLimitSW = StopWatch(AutoStart.yes);
24 	auto sw = StopWatch(AutoStart.no);
25 	const int rc = 0;
26 	float mbs_average = 0.0;
27 	int mbs_counts = 0;
28 
29 	foreach (int size; 4 .. 16) {
30 		stdout.flush(); // Flush contents of stdout to avoid half done outputs in CI Pipeline
31 		if (timeLimitSW.peek.total!"seconds" > argTimeLimit) {
32 			writeln("Time Limit execeeded, Abort test.");
33 			break;
34 		}
35 		foreach (ubyte i; 0 .. (256 / 32)) {
36 			int tsize = 2 ^^ 20 * size;
37 			auto test = new ubyte[tsize];
38 			test[] = cast(ubyte)(i * 32);
39 
40 			/* Test 1 */
41 			ubyte[16] hash1;
42 			{
43 				MurmurHash3!128 mm128;
44 				sw.reset;
45 				sw.start;
46 				mm128.start(); // Create a state
47 				for (int j = 0; j < tsize; j += tsize / 8) {
48 					mm128.put(test[j .. j + tsize / 8]); // Hash the file in chunks
49 				}
50 				hash1 = mm128.finish(); // Finalize the hash
51 				sw.stop;
52 			}
53 			auto time1 = sw.peek;
54 
55 			/* Test 2 */
56 			ubyte[16] hash3;
57 			{
58 				hash3 = digest!(MurmurHash3!128)(test);
59 			}
60 			auto time2 = sw.peek;
61 			mbs_average += getMegaBytePerSeconds(tsize, time2);
62 			mbs_counts++;
63 
64 			/* Status output */
65 			version (unittest) {
66 			} else {
67 				import app : argVerbose;
68 
69 				if (argVerbose)
70 					writefln("Input: size=0x%08x fill=0x%02x, hash %s, %8fs, %8fs, %10.6f MB/s, %10.6f MB/s",
71 						tsize, i, hash1.toHexString,
72 						getFloatSecond(time1), getFloatSecond(time2),
73 						getMegaBytePerSeconds(tsize, time1), getMegaBytePerSeconds(tsize, time2));
74 			}
75 			/* Prepare CSV output */
76 			auto testCsv = Murmur128TestData(tsize, i, hash3, time1, time2);
77 			csvFile.addEntry(testCsv);
78 
79 			/* Check hash results */
80 			assert(hash1 == hash3, "Hashes mismatch");
81 		}
82 	}
83 	timeLimitSW.stop;
84 
85 	writefln("%35.35s: Average %12.6f MB/s", __FUNCTION__, mbs_average / mbs_counts);
86 	if (writeCSV)
87 		csvFile.writeFile;
88 	return rc;
89 }