4
4
#include " workchunks.h"
5
5
#include " rotations.h"
6
6
#include " canon.h"
7
+ #include < iostream>
7
8
/*
8
9
* This code supports pruning tables for arbitrary puzzles. Memory
9
10
* consumption is a power of two. Each table entry is two bits.
18
19
* The hash table permits collisions (stores the minimum).
19
20
*/
20
21
const int CACHELINESIZE = 64 ;
22
+ // BLOCKSIZE bits has one secondary entry and as many primary ones as fit.
23
+ // All of these values are log2 values. SECONDARYBITS should be greater than
24
+ // PRIMARYBITS.
25
+ // Given a hash value h that's been adjusted to fit in the range, we
26
+ // want to make sure the low bit is 0 if PRIMARYBITS is 1. Also, of
27
+ // the low (BLOCKSIZEBITS-PRIMARYBITS), we want to make sure the value
28
+ // is at least PRIMARYBITS.
29
+ // different way to ensure we set the low bits: pick off the low 16,
30
+ // subtract a shifted fraction of them, then add the new base.
31
+ #define BLOCKSIZEBITS (6 )
32
+ #define PRIMARYBITS (1 )
33
+ #define SECONDARYBITS (2 )
34
+ //
35
+ #define PRIMARYMASK ((1 <<(1 <<PRIMARYBITS))-1 )
36
+ #define SECONDARYMASK ((1 <<(1 <<SECONDARYBITS))-1 )
37
+ #define HSHIFT (6 - PRIMARYBITS)
38
+ #define HMUL (1 +PRIMARYBITS)
39
+ #define LOWHMASK ((1 <<HSHIFT)-1 )
40
+ #define LOWHMIN (1 <<(SECONDARYBITS-PRIMARYBITS)) ;
41
+ #define LOWCHECK ((1 <<(BLOCKSIZEBITS-PRIMARYBITS)) - (1 <<(SECONDARYBITS-PRIMARYBITS)))
42
+ #define LOWCLEARMASK ((1 << (BLOCKSIZEBITS-PRIMARYBITS)) - 1 )
43
+ //
21
44
const int COMPSIGNATURE = 23 ; // start and end of data files
22
45
const int UNCOMPSIGNATURE = 24 ; // start and end of data files
23
46
#define UNKNOWNPUZZLE " unknownpuzzle"
@@ -85,20 +108,45 @@ struct prunetable {
85
108
void checkextend (const puzdef &pd, int ignorelookups=0 ) ;
86
109
int lookuph (ull h) const {
87
110
h = indexhash (h) ;
88
- int v = 3 & (mem [h >> 5 ] >> ((h & 31 ) * 2 )) ;
89
- if (v == 3 )
90
- return (mem [(h >> 5 ) & ~7 ] & 15 ) - 1 ;
91
- else
111
+ int v = PRIMARYMASK & (mem[h >> HSHIFT] >> ((h & LOWHMASK) * HMUL)) ;
112
+ if (v == PRIMARYMASK) {
113
+ h &= ~LOWCLEARMASK ;
114
+ return (mem[h >> HSHIFT] & SECONDARYMASK) - 1 ;
115
+ } else
116
+ #if PRIMARYBITS == 1
92
117
return 2 - v + baseval ;
118
+ #else
119
+ return 2 + baseval ;
120
+ #endif
93
121
}
94
122
void prefetch (ull h) const {
95
- __builtin_prefetch (mem + ((indexhash (h )) >> 5 )) ;
123
+ __builtin_prefetch (mem+((indexhash (h)) >> HSHIFT )) ;
96
124
}
97
125
ull indexhash (ull lowb) const {
98
126
ull h = lowb ;
99
127
h -= h >> subshift ;
100
- h >>= memshift ;
101
- h ^= 0xff & ((((h & 0xfe ) - 2 ) >> 8 ) & (lowb | 2 )) ;
128
+ const ull BS = BLOCKSIZEBITS - SECONDARYBITS ;
129
+ const ull BP = BLOCKSIZEBITS - PRIMARYBITS ;
130
+ h = (h - ((h & ((1LL << (memshift + BP)) - 1 )) >> BS) -
131
+ (h & 1 ) + (1LL << (memshift + SECONDARYBITS - PRIMARYBITS))) >> memshift ;
132
+ if ((h & LOWCHECK) == 0 ) {
133
+ std::cout << " Fail with h " << std::hex << h << std::dec << std::endl << std::flush ;
134
+ h = lowb ;
135
+ std::cout << " Started with " << std::hex << lowb << std::dec << std::endl << std::flush ;
136
+ h -= h >> subshift ;
137
+ std::cout << " Next was " << std::hex << h << std::dec << std::endl << std::flush ;
138
+ std::cout << " Sub1 " << std::hex <<
139
+ ((h & ((1LL << (memshift + BP)) - 1 )) >> BS)
140
+ << std::dec << std::endl << std::flush ;
141
+ std::cout << " Sub2 " << std::hex <<
142
+ (h&1 )
143
+ << std::dec << std::endl << std::flush ;
144
+ std::cout << " Add " << std::hex <<
145
+ (1LL << (memshift + SECONDARYBITS - PRIMARYBITS))
146
+ << std::dec << std::endl << std::flush ;
147
+ exit (10 ) ;
148
+ }
149
+ // std::cout << "ih " << std::hex << h << std::dec << std::endl ;
102
150
return h ;
103
151
}
104
152
ull indexhash (int n, const setval sv) const {
@@ -112,11 +160,16 @@ struct prunetable {
112
160
} else {
113
161
h = indexhash (totsize, sv) ;
114
162
}
115
- int v = 3 & (mem [h >> 5 ] >> ((h & 31 ) * 2 )) ;
116
- if (v == 3 )
117
- return (mem [(h >> 5 ) & ~7 ] & 15 ) - 1 ;
118
- else
163
+ int v = PRIMARYMASK & (mem[h >> HSHIFT] >> ((h & LOWHMASK) * HMUL)) ;
164
+ if (v == PRIMARYMASK) {
165
+ h &= ~LOWCLEARMASK ;
166
+ return (mem[h >> HSHIFT] & SECONDARYMASK) - 1 ;
167
+ } else
168
+ #if PRIMARYBITS == 1
119
169
return 2 - v + baseval ;
170
+ #else
171
+ return 2 + baseval ;
172
+ #endif
120
173
}
121
174
void addlookups (ull lookups) {
122
175
lookupcnt += lookups ;
0 commit comments