-public:
- TranspositionTable();
- ~TranspositionTable();
- void set_size(unsigned mbSize);
- void clear();
- void store(const Key posKey, Value v, ValueType type, Depth d, Move m);
- TTEntry* retrieve(const Key posKey) const;
- void prefetch(const Key posKey) const;
- void new_search();
- void insert_pv(const Position& pos, Move pv[]);
- void extract_pv(const Position& pos, Move pv[]);
- int full() const;
-
-private:
- inline TTEntry* first_entry(const Key posKey) const;
-
- // Be sure 'writes' is at least one cacheline away
- // from read only variables.
- unsigned char pad_before[64 - sizeof(unsigned)];
- unsigned writes; // heavy SMP read/write access here
- unsigned char pad_after[64];
-
- unsigned size;
- TTEntry* entries;
- uint8_t generation;
+ 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