enum TBType { KEY, WDL, DTZ }; // Used as template parameter
// Each table has a set of flags: all of them refer to DTZ tables, the last one to WDL tables
-enum TBFlag { STM = 1, Mapped = 2, WinPlies = 4, LossPlies = 8, SingleValue = 128 };
+enum TBFlag { STM = 1, Mapped = 2, WinPlies = 4, LossPlies = 8, LongDTZ = 16, SingleValue = 128 };
inline WDLScore operator-(WDLScore d) { return WDLScore(-int(d)); }
inline Square operator^=(Square& s, int i) { return s = Square(int(s) ^ i); }
uint8_t lr[3]; // The first 12 bits is the left-hand symbol, the second 12
// bits is the right-hand symbol. If symbol has length 1,
- // then the first byte is the stored value.
+ // then the first 12 bits are the stored value.
template<Side S>
Sym get() {
return S == Left ? ((lr[1] & 0xF) << 8) | lr[0] :
S == Right ? (lr[2] << 4) | (lr[1] >> 4) :
- S == Value ? lr[0] : (assert(false), Sym(-1));
+ S == Value ? ((lr[1] & 0xF) << 8) | lr[0] :
+ (assert(false), Sym(-1));
}
};
uint32_t k = idx / d->span;
// Then we read the corresponding SparseIndex[] entry
- uint32_t block = number<uint32_t, LittleEndian>(&d->sparseIndex[k].block);
- int offset = number<uint16_t, LittleEndian>(&d->sparseIndex[k].offset);
+ size_t block = number<uint32_t, LittleEndian>(&d->sparseIndex[k].block);
+ int offset = number<uint16_t, LittleEndian>(&d->sparseIndex[k].offset);
// Now compute the difference idx - I(k). From definition of k we know that
//
uint8_t* map = entry->map;
uint16_t* idx = entry->get(0, f)->map_idx;
- if (flags & TBFlag::Mapped)
- value = map[idx[WDLMap[wdl + 2]] + value];
+ if (flags & TBFlag::Mapped) {
+ if (flags & TBFlag::LongDTZ) {
+ value = ((uint16_t *)map)[idx[WDLMap[wdl + 2]] + value];
+ } else {
+ value = map[idx[WDLMap[wdl + 2]] + value];
+ }
+ }
// DTZ tables store distance to zero in number of moves or plies. We
// want to return plies, so we have convert to plies when needed.
e.map = data;
for (File f = FILE_A; f <= maxFile; ++f) {
- if (e.get(0, f)->flags & TBFlag::Mapped)
- for (int i = 0; i < 4; ++i) { // Sequence like 3,x,x,x,1,x,0,2,x,x
- e.get(0, f)->map_idx[i] = (uint16_t)(data - e.map + 1);
- data += *data + 1;
+ int flags = e.get(0, f)->flags;
+ if (flags & TBFlag::Mapped) {
+ if (flags & TBFlag::LongDTZ) {
+ data += (uintptr_t)data & 1; // Word alignment
+ for (int i = 0; i < 4; i++) {
+ e.get(0, f)->map_idx[i] = (uint16_t)((uint16_t *)data - (uint16_t *)e.map + 1);
+ data += 2 + 2 * number<uint16_t, LittleEndian>(data);
+ }
+ } else {
+ for (int i = 0; i < 4; ++i) { // Sequence like 3,x,x,x,1,x,0,2,x,x
+ e.get(0, f)->map_idx[i] = (uint16_t)(data - e.map + 1);
+ data += *data + 1;
+ }
}
+ }
}
return data += (uintptr_t)data & 1; // Word alignment