- static const unsigned ClusterSize = 4; // A cluster is 64 Bytes
-
-public:
- ~TranspositionTable() { free(mem); }
- void new_search() { ++generation; }
-
- const TTEntry* probe(const Key key) const;
- TTEntry* first_entry(const Key key) const;
- void refresh(const TTEntry* tte) const;
- void set_size(size_t mbSize);
- void clear();
- void store(const Key key, Value v, Bound type, Depth d, Move m, Value statV);
-
-private:
- uint32_t hashMask;
- TTEntry* table;
- void* mem;
- uint8_t generation; // Size must be not bigger than TTEntry::generation8
+ static constexpr int ClusterSize = 3;
+
+ struct Cluster {
+ TTEntry entry[ClusterSize];
+ char padding[2]; // Pad to 32 bytes
+ };
+
+ static_assert(sizeof(Cluster) == 32, "Unexpected Cluster size");
+
+ // Constants used to refresh the hash table periodically
+ static constexpr unsigned GENERATION_BITS = 3; // nb of bits reserved for other things
+ static constexpr int GENERATION_DELTA =
+ (1 << GENERATION_BITS); // increment for generation field
+ static constexpr int GENERATION_CYCLE = 255 + (1 << GENERATION_BITS); // cycle length
+ static constexpr int GENERATION_MASK =
+ (0xFF << GENERATION_BITS) & 0xFF; // mask to pull out generation number
+
+ public:
+ ~TranspositionTable() { aligned_large_pages_free(table); }
+ void new_search() { generation8 += GENERATION_DELTA; } // Lower bits are used for other things
+ TTEntry* probe(const Key key, bool& found) const;
+ int hashfull() const;
+ void resize(size_t mbSize);
+ void clear();
+
+ TTEntry* first_entry(const Key key) const {
+ return &table[mul_hi64(key, clusterCount)].entry[0];
+ }
+
+ private:
+ friend struct TTEntry;
+
+ size_t clusterCount;
+ Cluster* table;
+ uint8_t generation8; // Size must be not bigger than TTEntry::genBound8