Un archivio di immagini

Nel 1998, per un amico archeologo ho creato un archivio di immagini, a supporto della sua attività. Essendo passati ormai più di 20 anni, mi ero completamente dimenticato del lavoro fatto.

Un giorno andai a trovarlo e con estrema sorpresa, notai che stava usando un database per gestire le immagini. Quando gli chiesi che applicativo fosse, mi disse: “Ma come, non ti ricordi? Me lo hai fatto tu!”

Ebbene sì era il mio vecchio database di immagini, che era passato indenne da Windows 3.11 a Windows 10, e da Access 2 a Access “non lo so a che versione siamo adesso…”

E nel tempo la base di immagini era cresciuta fino a gestire qualcosa vicino alle 100.000 immagini!

Indicizzare i percorsi

Non ci crederete, ma ho iniziato a fare reverse engineering sul mio lavoro. L’idea base era quella di mettere le immagini in cartelle e di salvare nel database solo il percorso dell’immagine, non tutta l’immagine.

Questo ha permesso di passare da fotocamere da 2 MPixel a fotocamere da 20 MPixel senza fare esplodere il database.

Tenete conto che Access memorizza il database in un file solo, pertanto, non sarebbe pensabile un database con 100.000 immagini. Se considerate 10MB a foto, fanno 1TB di file.

Per identificare le foto ho usato semplicemente un contatore, e nuovamente, dato che il filesystem di Windows non gradisce più di 3-5000 file nella stessa cartella, avevo creato un albero facendo cartelle da 1000 foto. Pertanto anche 100.000 foto alla fine si riducono ad una cartella con 100 sottocartelle.

Pre-calcolare le anteprime

Avevo fatto alcuni esperimenti, e avevo notato come fosse insopportabile aspettare che il controllo Immagine di Access ci mettesse dei secondi per visualizzare le immagini di anteprima. Allora pensai di pre-calcolarle, ovvero di creare un albero con tutte le immagini di anteprima già riscalate a 1024×768. Non contento di questo, mi spinsi oltre, pre-calcolando anche dei thumbnail a non ricordo quanto, ma circa 200×150 pixels. In questo modo era possibile incorporare il thumbnail nella finestra di dialogo, e poi con un click vedere l’anteprima a tutto schermo, che al tempo voleva dire 1024×768.

Quindi con 3 alberi indipendenti, uno per in thumbnail, uno per le anteprime, uno per le immagini originali, mi ero assicurato la scalabilità del sistema nel tempo.

L’idea mi era venuta leggendo un articolo sulle olimpiadi di Nagano, del 1998, in cui si spiegava come IBM fosse riuscita a garantire un elevatissimo numero di accessi al sito internet dell’organizzazione, pre-calcolando le pagine HTML al posto di fare una query su database per ogni accesso.

Visto gli strumenti e le conoscenze di cui disponevo al tempo, la procedura di archiviazione di ogni singola immagine era estremamente manuale, ma funziona bene da 20 anni, pertanto, perchè cambiarla?

Se lo rifacessi con Qt?

Per lavoro mi occupo di elaborazione di immagini, pertanto il tema di gestire grandi quantità di immagini mi è rimasto.

Per esigenze di lavoro mi sono trovato a creare un archivio di immagini, dimensionato per gestire 1 Milione di immagini.

Memore dell’esperienza di 20 anni fa, ho deciso di precalcolare le anteprime. Certo adesso le dimensioni sono diverse.

La risoluzione di riferimento di uno schermo è passata da 1024×768 a 1920×1080, quindi è intervenuto quasi un fattore 4, e quanto alla dimensione dei dischi, si è passati da 500 MB a 500 GB, almeno, questa è la dimensione del disco SSD del mio portatile.

Inoltre la velocità di lettura è passata da 5/10MB/s a 500MB/s, ma l’idea delle anteprime precalcolate è ancora valida, perché permette di sfogliare le immagini alla massima velocità possibile.

Il database? SQLite

Ora non uso più Access, ma SQLite, che come Access salva il database in un solo file, e come nel caso di Access è un database: “in proccess” ovvero vive all’interno della mia applicazione, non è un processo esterno. Questo rende la comunicazione estremamente veloce e la latenza bassa.

Se siete curiosi, guardate la mia presentazione al Qt Day 2019:

Archiviare le anteprime nel database

Ecco questo aspetto invece l’ho cambiato. Ora le anteprime le salvo sul database, perchè in questo modo riesco a visualizzarle molto più velocemente, e perché la dimensione del file del database non è più un problema. Anche se ho 1.000.000 di immagini, e per ogni immagine alloco 100kB, si tratta di un file da 100GB, impensabile 20 anni fa quando i dischi erano da 500 MB, accettabile oggi in un NAS da 15 TB (150 volte più grande)

Arrivano i NAS

Ecco, appunto, il problema è il NAS. Mentre 20 anni fa i NAS praticamente non esistevano (a livello personale), oggi un archivio di immagini per forza di cose deve stare su un NAS. Questo permette di avere anche 15 TB di spazio di archiviazione, a prezzi economici, condiviso tra più utenti.

Ma il NAS è collegato alla rete che per quanto sia veloce, introduce una latenza fastidiosa. Questa latenza si applica per ogni volta che accedo al filesystem, pertanto se ogni volta che voglio vedere una immagine, per quanto piccola devo aprire 4 o 5 cartelle, capite bene che il problema non sono i 10kB del thumbnail o i 90kB dell’anteprima, ma sono le 4 o 5 cartelle.

Stiamo parlando di 50/100 ms, che si notano in termini di velocità, e di reattività del sistema.

E se ci mettessimo la VPN? Anche in questo caso la situazione è la stessa, solo che le latenze sono maggiori.

Se invece l’immagine è nel database, il problema non esiste, dato che il file del database è già aperto, da qualche parte c’è una copia in cache, il calcolo della posizione della mia immagine è semplicemente un off-set nel file, la lettura viaggia alla velocità massima permessa dalla mia connessione.

Se rifacessi il lavoro oggi, come lo farei?

L’architettura con le anteprime precalcolate resta molto attuale, ma metterei le anteprime direttamente nel database.

E con Qt renderei automatica la creazione delle anteprime e tutto il processo di archiviazione.

Per non parlare dei dati EXIF e della possibilità di ricostruire la posizione geografica della foto.

Credo che sarebbe divertente farlo… Magari lo propongo al mio amico, che dite?

D’altronde Qt è il futuro!