1/* Hash timing test harness 2 * 3 * Usage: mkhash opts count 4 * 5 * opts is a combination of the following flags (default "Dhs"): 6 * d store data view flat 7 * D store data view blocked 8 * m store map view flat 9 * M store map view blocked 10 * h use hashing 11 * H use hashing, after filling the view 12 * o use ordering 13 * 2 2-key hashing/ordering, instead of 1-key 14 * s time small (2-row add) commits, i.s.o. 1000 rows 15 * f do frequent commits, every 10 i.s.o. 1000 rows 16 * 17 * count is the total number of rows added, default is 250,000 18 * (it should be a multiple of 10,000 for proper reporting) 19 * 20 * % g++ -Dq4_INLINE mkhash.cpp -lmk4 21 * % for i in - d D dh Dh dmh Dmh do Do; do rm -f test.dat; a.out $i; done 22 * [...] 23 */ 24 25#include <mk4.h> 26#include <stdio.h> 27#include <stdlib.h> 28#include <string.h> 29 30#ifdef WIN32 31 #define WIN32_LEAN_AND_MEAN 32 #include <windows.h> 33 34 long ticks () 35 { 36 LARGE_INTEGER t; 37 38 static double f = 0.0; 39 if (f == 0.0) { 40 QueryPerformanceFrequency(&t); 41 f = (double) t.QuadPart / 1000000.0; 42 } 43 44 QueryPerformanceCounter(&t); 45 return (long) (f * t.QuadPart); 46 } 47#else 48 #include <sys/time.h> 49 #include <sys/types.h> 50 #include <sys/stat.h> 51 52 long ticks() 53 { 54 struct timeval tv; 55 struct timezone tz; 56 gettimeofday(&tv, &tz); 57 return tv.tv_sec * 1000000 + tv.tv_usec; 58 } 59#endif 60 61int main(int argc, char **argv) 62{ 63 char buf [25]; 64 c4_Row row; 65 long t; 66 int nkeys = 1; 67 68 //setvbuf(stdout, NULL, _IOLBF, BUFSIZ); 69 70 c4_Storage storage ("test.dat", true); 71 72 c4_StringProp pKey ("key"), pKey2 ("key2"); 73 c4_View data = pKey; 74 75 c4_IntProp pH ("_H"), pR ("_R"); 76 c4_View map = (pH, pR); 77 const char *s = argc > 1 ? argv[1] : "Dhs"; 78 79 if (strchr(s, '2')) { 80 // must create properties in same order as in the hash view (ouch!) 81 pKey (row) = ""; 82 pKey2 (row) = "abcdefghijklmnopqrstuvwxyz"; 83 nkeys = 2; 84 if (strchr(s, 'd')) 85 data = storage.GetAs("data[key:S,key2:S]"); 86 if (strchr(s, 'D')) { 87 data = storage.GetAs("data[_B[key:S,key2:S]]"); 88 data = data.Blocked(); 89 } 90 } else { 91 if (strchr(s, 'd')) 92 data = storage.GetAs("data[key:S]"); 93 if (strchr(s, 'D')) { 94 data = storage.GetAs("data[_B[key:S]]"); 95 data = data.Blocked(); 96 } 97 } 98 99 if (strchr(s, 'm')) 100 map = storage.GetAs("map[_H:I,_R:I]"); 101 if (strchr(s, 'M')) { 102 map = storage.GetAs("map[_B[_H:I,_R:I]]"); 103 map = map.Blocked(); 104 } 105 if (strchr(s, 'h')) 106 data = data.Hash(map, nkeys); 107 if (strchr(s, 'o')) 108 data = data.Ordered(nkeys); 109 int cfreq = strchr(s, 'f') ? 10 : 1000; 110 111 int limit = 250000; 112 if (argc > 2) 113 limit = atoi(argv[2]); 114 115 puts(s); 116 puts(" ROW ADD FIND COMMIT SIZE"); 117 118 for (int i = 1; i <= limit; ++i) { 119 sprintf(buf, "%10d%10d", 100000000 + i, 200000000 + i); 120 121 pKey (row) = buf; 122 123 t = ticks(); 124 data.Add(row); 125 long at = ticks() - t; 126 127 if ((i+2) % cfreq == 0 && strchr(s, 's')) 128 storage.Commit(); 129 130 if (i % cfreq == 0) { 131 t = ticks(); 132 storage.Commit(); 133 long ct = ticks() - t; 134 135 if (i % (limit/10) == 0) { 136 t = ticks(); 137 int n = data.Find(row); 138 long ft = ticks() - t; 139 140 if (n < 0) { puts(buf); return 1; } 141 142 printf("%9d %9d uS %9d uS %9d uS %9d bytes \n", 143 i, at, ft, ct, storage.Strategy().FileSize()); 144 } 145 } 146 } 147 148 if (strchr(s, 'H')) { 149 t = ticks(); 150 data = data.Hash(map, nkeys); 151 long ht = ticks() - t; 152 153 t = ticks(); 154 storage.Commit(); 155 long ct = ticks() - t; 156 157 printf("construct hash: %d uS, then commit: %d uS\n", ht, ct); 158 fflush(stdout); 159 } 160 161 return 0; 162} 163