Audyt duplikatow po phashu miniatur wykazal dwa rozne zjawiska, ktore wygladaly jak jedno. 1. Zdegenerowane phashe. 73 wartosci wystepowaly przy >=10 scenach kazda, lacznie przy 4375 scenach; rekordzistka byla dzielona przez 892 sceny o 892 roznych tytulach i 1886 roznych performerach. To zaslepki i czarne klatki, nie odciski scen. find_by_phash_within bierze najblizsza wartosc z calej tabeli, wiec taka zaslepka zawsze wygrywala z prawdziwym duplikatem (dist 0). Do tej pory bronila nas bramka dur_prox i nic sie nie skleilo, ale to zabezpieczenie drugiej linii. Blacklista jest tabela, nie jednorazowym DELETE, bo sam DELETE nic nie daje: zaslepka wraca przy kolejnym ingescie. Trzeba pamietac, ze wartosc jest bezuzyteczna. Job co 24h dopisuje nowe i czysci odciski. Po czyszczeniu zero grup >=10, najwieksza pozostala ma 9. 2. Realne duplikaty. 4647 scalonych. Przyczyna byla jedna: 97 procent par ma perverzije po dokladnie jednej stronie, bo pisze tytuly z prefiksem studia i performera, a reszta tubow daje goly tytul. Wbrew mojej pierwszej diagnozie NIE trzeba tu ruszac scoringu tytulu (token_set_ratio i tak radzi sobie z prefiksem, a sciezka phash idzie przed composite): 80 procent par to dlug sprzed 60+ dni, a biezacy wyciek to okolo 1 dziennie. Nadmiarowe wiersze: 18452 na 9449. merge_phash_exact_dupes.py dostal wykluczenie blacklisty. Bez tego byl grozny: sam klaster 892 scen dawal ~397 tys. par do rozwazenia. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
32 lines
1.4 KiB
Python
32 lines
1.4 KiB
Python
"""Zdegenerowane phashe — wartości, które NIE identyfikują sceny.
|
|
|
|
Audyt 2026-07-27: 73 wartości phasha występowały przy ≥10 scenach każda, łącznie
|
|
przy 4375 scenach. Rekordzistka miała **892 sceny o 892 różnych tytułach i 1886
|
|
różnych performerach** — to placeholder, czarna klatka albo intro, nie odcisk sceny.
|
|
|
|
Dlaczego to musi być tabela, a nie zwykłe skasowanie wierszy: sam `DELETE` nic nie
|
|
załatwia, bo przy kolejnych ingestach ta sama zaślepka wraca. Trzeba PAMIĘTAĆ, że
|
|
dana wartość jest bezużyteczna, i już nigdy po niej nie matchować.
|
|
|
|
Do tej pory obroniła nas bramka `dur_prox` w `scene_resolver` (te 892 sceny nadal
|
|
istnieją osobno, więc nic się nie skleiło), ale to zabezpieczenie drugiej linii:
|
|
wystarczy, żeby dwie niepowiązane sceny miały tę samą zaślepkę i zbliżoną długość.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
|
|
from sqlalchemy import DateTime, Integer, String, func
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from app.models.base import Base
|
|
|
|
|
|
class PhashBlacklist(Base):
|
|
__tablename__ = "phash_blacklist"
|
|
|
|
value: Mapped[str] = mapped_column(String(128), primary_key=True)
|
|
scene_count: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
detected_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True), server_default=func.now(), nullable=False
|
|
)
|