-/// TTEntry struct is the 10 bytes transposition table entry, defined as below:
-///
-/// key 16 bit
-/// move 16 bit
-/// value 16 bit
-/// eval value 16 bit
-/// generation 5 bit
-/// pv node 1 bit
-/// bound type 2 bit
-/// depth 8 bit
-
-struct TTEntry {
-
- Move move() const { return (Move )move16; }
- Value value() const { return (Value)value16; }
- Value eval() const { return (Value)eval16; }
- Depth depth() const { return (Depth)depth8 + DEPTH_OFFSET; }
- bool is_pv() const { return (bool)(genBound8 & 0x4); }
- Bound bound() const { return (Bound)(genBound8 & 0x3); }
- void save(Key k, Value v, bool pv, Bound b, Depth d, Move m, Value ev);
-
-private:
- friend class TranspositionTable;
-
- uint16_t key16;
- uint16_t move16;
- int16_t value16;
- int16_t eval16;
- uint8_t genBound8;
- uint8_t depth8;
+namespace Stockfish {
+
+class ThreadPool;
+struct TTEntry;
+struct Cluster;
+
+// There is only one global hash table for the engine and all its threads. For chess in particular, we even allow racy
+// updates between threads to and from the TT, as taking the time to synchronize access would cost thinking time and
+// thus elo. As a hash table, collisions are possible and may cause chess playing issues (bizarre blunders, faulty mate
+// reports, etc). Fixing these also loses elo; however such risk decreases quickly with larger TT size.
+//
+// `probe` is the primary method: given a board position, we lookup its entry in the table, and return a tuple of:
+// 1) whether the entry already has this position
+// 2) a copy of the prior data (if any) (may be inconsistent due to read races)
+// 3) a writer object to this entry
+// The copied data and the writer are separated to maintain clear boundaries between local vs global objects.
+
+
+// A copy of the data already in the entry (possibly collided). `probe` may be racy, resulting in inconsistent data.
+struct TTData {
+ Move move;
+ Value value, eval;
+ Depth depth;
+ Bound bound;
+ bool is_pv;