From d71d20d86908480dfc294f46b82866a7c3802a9f Mon Sep 17 00:00:00 2001 From: sysops Date: Fri, 8 May 2026 22:53:20 +0200 Subject: [PATCH] =?UTF-8?q?fix(PROJ-35):=20hashMailID=20maskiert=20Top-Bit?= =?UTF-8?q?=20f=C3=BCr=20positive=20int64?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Vorheriger Fix (int64-Cast) erzeugte für die obere uint64-Hälfte negative Werte. Manticore weist negative IDs beim INSERT/REPLACE zurück ("Negative document ids are not allowed"), nur SELECT akzeptiert sie. Lösung: Bit-Mask 0x7FFFFFFFFFFFFFFF — Top-Bit immer 0, Result in [0, 2^63-1]. 63-Bit-Hash-Space reicht für jede realistische Mail-Anzahl. --- internal/index/manticore.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/internal/index/manticore.go b/internal/index/manticore.go index 1745141..7842be7 100644 --- a/internal/index/manticore.go +++ b/internal/index/manticore.go @@ -368,20 +368,20 @@ func (idx *manticoreIndex) Close() error { // ── helpers ──────────────────────────────────────────────────────────────── -// hashMailID returns a stable signed int64 row ID derived from the mail's -// SHA-256 string ID. Manticore's `id` column is bigint (signed int64); the -// mysql driver formats parameters as decimal strings, and Manticore rejects -// values outside the signed range with "number ... is out of range". +// hashMailID returns a stable positive int64 row ID derived from the mail's +// SHA-256 string ID. // -// We FNV-64a-hash the string and reinterpret the resulting uint64 as int64 -// (verlustfreier Bit-Cast). All bit patterns map 1:1, so already-indexed -// documents stay reachable — values whose top bit was set previously -// became negative IDs; their bit pattern is unchanged, only the SQL -// rendering differs and now matches what Manticore expects. +// Manticore's RT `id` column is signed bigint and rejects: +// - values > int64.MaxValue → "number ... is out of range" +// - negative values on INSERT/REPLACE → "Negative document ids are not allowed" +// +// We FNV-64a-hash the SHA-256 string and clear the top bit so the result is +// always in [0, 2^63-1]. The 63-bit collision space is more than enough for +// any realistic archive size. func hashMailID(id string) int64 { h := fnv.New64a() h.Write([]byte(id)) - return int64(h.Sum64()) + return int64(h.Sum64() & 0x7FFFFFFFFFFFFFFF) } // manticoreTableName returns the RT table name for a given tenant.