@@ -14,32 +14,43 @@ WITH current_snippet AS (
1414 trigram_hashes = EXCLUDED .trigram_hashes , signature = EXCLUDED .signature ,
1515 independently_suspicious = EXCLUDED .independently_suspicious ,
1616 urls = EXCLUDED .urls , indexed_at = CURRENT_TIMESTAMP
17- RETURNING snippet_id, content_revision, algorithm_version
17+ RETURNING snippet_id, content_revision, algorithm_version, token_count
1818), bands AS (
19+ -- Only neighbor-eligible snippets get band rows: shorter ones never pass
20+ -- the token threshold, and their degenerate signatures would form hot bands.
1921 INSERT INTO spam_classifier_bands
2022 (snippet_id, content_revision, algorithm_version, band_number, band_value)
2123 SELECT stored .snippet_id , stored .content_revision , stored .algorithm_version ,
2224 (band .ordinality - 1 )::int , band .value
2325 FROM stored CROSS JOIN unnest(sqlc .arg (bands)::text []) WITH ORDINALITY AS band(value, ordinality)
26+ WHERE stored .token_count >= 20
2427 ON CONFLICT (snippet_id, content_revision, algorithm_version, band_number)
2528 DO UPDATE SET band_value = EXCLUDED .band_value
2629)
2730SELECT EXISTS(SELECT 1 FROM stored)::boolean AS stored;
2831
2932-- name: FindClassifierNeighbors :many
33+ -- Rank on the narrow band rows first; identical content shares every band, so
34+ -- hot band values can match tens of thousands of snippets. Joining the wide
35+ -- fingerprint rows before the LIMIT forced a large on-disk sort.
36+ WITH ranked AS (
37+ SELECT b .snippet_id , b .content_revision , b .algorithm_version ,
38+ count (* )::int AS matching_bands
39+ FROM spam_classifier_bands b
40+ WHERE b .algorithm_version = sqlc .arg (algorithm_version)::text
41+ AND b .band_value = ANY(sqlc .arg (bands)::text [])
42+ AND b .snippet_id <> sqlc .arg (snippet_id)::uuid
43+ GROUP BY b .snippet_id , b .content_revision , b .algorithm_version
44+ ORDER BY matching_bands DESC , b .content_revision DESC , b .snippet_id DESC
45+ LIMIT 200
46+ )
3047SELECT f .snippet_id , f .content_revision , s .slug , f .token_count ,
31- f .trigram_hashes , f .signature , f .independently_suspicious ,
32- count (* )::int AS matching_bands
33- FROM spam_classifier_bands b
48+ f .trigram_hashes , f .signature , f .independently_suspicious , r .matching_bands
49+ FROM ranked r
3450JOIN spam_classifier_fingerprints f USING (snippet_id, content_revision, algorithm_version)
3551JOIN snippets s ON s .id = f .snippet_id AND s .updated_at = f .content_revision
36- WHERE b .algorithm_version = sqlc .arg (algorithm_version)::text
37- AND b .band_value = ANY(sqlc .arg (bands)::text [])
38- AND b .snippet_id <> sqlc .arg (snippet_id)::uuid
39- AND f .token_count >= 20
40- GROUP BY f .snippet_id , f .content_revision , f .algorithm_version , s .slug
41- ORDER BY matching_bands DESC , f .content_revision DESC , f .snippet_id DESC
42- LIMIT 200 ;
52+ WHERE f .token_count >= 20
53+ ORDER BY r .matching_bands DESC , f .content_revision DESC , f .snippet_id DESC ;
4354
4455-- name: ListClassifierIndexBatch :many
4556SELECT s .id , s .slug , s .user_id , s .language , s .title , s .visibility , s .stdin ,
@@ -106,6 +117,7 @@ WITH progress AS MATERIALIZED (
106117 (band .ordinality - 1 )::int , band .value
107118 FROM stored JOIN input i ON i .snippet_id = stored .snippet_id
108119 CROSS JOIN unnest(i .bands ) WITH ORDINALITY AS band(value, ordinality)
120+ WHERE i .token_count >= 20
109121 ON CONFLICT (snippet_id, content_revision, algorithm_version, band_number)
110122 DO UPDATE SET band_value = EXCLUDED .band_value
111123), advanced AS (
0 commit comments