Ci sono molte cose da considerare, ma in generale baserei la mappatura relazionale nel tuo caso su Row Data Gateway modello (RDG). Se non si dispone di troppi tipi di oggetti diversi, questo approccio all'architettura dovrebbe essere scalabile abbastanza bene. RDG dovrebbe facilitare l'implementazione della memorizzazione nella cache se limiti la contabilità della cache alla classe Finder.
Se hai tempo e voglia, dai un'occhiata ai Modelli di Enterprise Application Architecture di Martin Fowler . È un pozzo di buone informazioni.
Ora nello specifico...
- identificare i dati tramite una sorta di ID
In genere si utilizzerà una colonna intera con incremento automatico nel database per questo. Puoi usare unordered_map per estrarre rapidamente quegli oggetti dalla cache. Dato che hai tutti gli oggetti nella tua cache, per motivi di ottimizzazione, potresti anche implementare alcuni dei find*
funzioni per cercare prima nella cache. Puoi usare unordered_map/unordered_multimap per 'indicizzare' alcuni dei dati, se il tuo tempo di ricerca è molto limitato, o semplicemente attenersi alla buona vecchia mappa/multimappa. Tuttavia, questo sta raddoppiando il lavoro e hai già gratuitamente nel database questo tipo di query.
- modifica i dati/gli oggetti memorizzati nella cache
I dati sporchi non dovrebbero essere visibili al resto del sistema fino a quando non li scrivi effettivamente nel database. Una volta avviato l'aggiornamento, e se tutto va come previsto, puoi sostituire l'oggetto nella cache con quello che hai usato per l'aggiornamento, o semplicemente eliminare l'oggetto nella cache e lasciare che altri lettori lo raccolgano dal database (il che risulterà nella cache di nuovo l'oggetto). Puoi implementarlo clonando l'oggetto Gateway originale, ma la conclusione è che dovresti implementare una strategia di blocco.
- elimina vecchi dati/oggetti e aggiungi nuovi dati/oggetti
Qui elimini semplicemente l'oggetto dalla cache e provi a eliminarlo dal database. Se l'eliminazione non riesce nel database, altri lettori lo memorizzeranno nella cache. Assicurati solo che nessun client possa accedere allo stesso record mentre sei in fase di eliminazione. Quando si aggiungono nuovi record, è sufficiente creare un'istanza dell'oggetto Gateway, passarlo all'oggetto a livello di dominio e, al termine delle modifiche, chiamare insert sull'oggetto Gateway. Puoi mettere il nuovo oggetto Gateway nella cache o semplicemente lasciare che il primo lettore lo inserisca nella cache.
- ordina i dati in base a un qualche tipo di priorità (ultimo utilizzato)
- Quale sarebbe il modo migliore per memorizzare nella cache i dati/gli oggetti in base alle informazioni fornite E PERCHÉ?
Si tratta di selezionare il miglior algoritmo di memorizzazione nella cache. Questa non è una domanda facile a cui rispondere, ma LRU dovrebbe funzionare bene. Senza metriche effettive, non esiste una risposta giusta, ma LRU è semplice da implementare e se non soddisfa i tuoi requisiti, esegui semplicemente le metriche e decidi un nuovo algoritmo. Assicurati di poterlo fare senza problemi avendo una buona interfaccia per la cache. Un'altra cosa da tenere a mente è che i tuoi oggetti a livello di dominio non dovrebbero mai dipendere dai limiti della tua cache. Se hai bisogno di 100.000 oggetti, ma hai solo 50.000 cache, hai ancora tutti i 100.000 oggetti in memoria, ma 50.000 di essi sono nella cache. In altre parole, i tuoi oggetti non dovrebbero dipendere dallo stato della tua cache e inoltre non dovrebbe importare se hai una cache.
Successivamente, se stai ancora scoprendo l'idea di RDG, stai semplicemente memorizzando nella cache l'oggetto Gateway nella tua cache. Puoi mantenere le istanze degli oggetti Gateway nella tua cache per mezzo di shared_ptr, ma dovresti anche considerare la tua strategia di blocco (ottimista vs pessimista), se vuoi evitare scritture sporche. Inoltre, tutti i tuoi gateway (uno per ogni tabella) possono ereditare la stessa interfaccia, così puoi generalizzare le tue strategie di salvataggio/caricamento e, inoltre, saresti in grado di utilizzare un singolo pool mantenendo le cose semplici. (Dai un'occhiata a boost::pool. Forse può aiutarti con l'implementazione della cache.)
Un ultimo punto:
La torta è una bugia! :D Qualunque cosa tu decida di fare, assicurati che si basi su una discreta quantità di parametri di prestazione. Se migliori le prestazioni del 20% e hai impiegato 2 mesi a farlo, forse vale la pena pensare di aggiungere qualche giga di RAM in più al tuo hardware. Crea una prova concettuale facile e verificabile, che ti darà informazioni sufficienti se l'implementazione della tua cache paga e, in caso contrario, prova alcune delle soluzioni testate e affidabili disponibili (memcached o simili, come ha già commentato @Layne).