Hay muchas cosas a considerar, pero en general basaría el mapeo relacional en su caso en el Row Data Gateway patrón (RDG). Si no tiene demasiados tipos de objetos diferentes, este enfoque de la arquitectura debería escalar lo suficientemente bien. RDG debería facilitar su implementación de almacenamiento en caché si restringe la contabilidad de caché a la clase Finder.
Si tiene tiempo y voluntad, consulte los Patrones de arquitectura de aplicaciones empresariales de Martin Fowler . Es un pozo de buena información.
Ahora a los detalles...
- identificar los datos por algún tipo de identificación
Por lo general, usaría alguna columna de enteros de incremento automático en la base de datos para esto. Puede usar unordered_map para extraer esos objetos del caché rápidamente. Dado que tiene todos los objetos en su caché, en aras de la optimización, también podría implementar algunos de los find*
funciones para buscar en el caché primero. Puede usar unordered_map/unordered_multimap para 'indexar' algunos de los datos, si su tiempo de búsqueda es muy restringido, o simplemente apéguese al viejo mapa/multimapa. Sin embargo, esto es duplicar el trabajo, y ya lo tienes gratis en la base de datos para este tipo de consultas.
- editar los datos/objetos almacenados en caché
Los datos sucios no deberían ser visibles para el resto del sistema hasta que los escriba en la base de datos. Una vez que inicie la actualización, y si todo sale según lo previsto, puede reemplazar el objeto en caché con el que usó para la actualización, o simplemente eliminar el objeto en caché y dejar que otros lectores lo recojan de la base de datos (lo que resultará en el almacenamiento en caché del objeto de nuevo). Puede implementar esto clonando el objeto Gateway original, pero la conclusión es que debe implementar alguna estrategia de bloqueo.
- eliminar datos/objetos antiguos y agregar nuevos datos/objetos
Aquí simplemente elimina el objeto del caché e intenta eliminarlo de la base de datos. Si la eliminación falla en la base de datos, otros lectores la almacenarán en caché. Solo asegúrese de que ningún cliente pueda acceder al mismo registro mientras está en el proceso de eliminación. Al agregar nuevos registros, simplemente crea una instancia del objeto Gateway, lo pasa al objeto de nivel de dominio y, cuando haya terminado con los cambios, llame a insert en el objeto Gateway. Puede colocar el nuevo objeto Gateway en la memoria caché o simplemente dejar que el primer lector lo coloque en la memoria caché.
- ordenar los datos por algún tipo de prioridad (último uso)
- ¿Cuál sería la mejor manera de almacenar en caché los datos/objetos en función de la información proporcionada Y POR QUÉ?
Se trata de seleccionar el mejor algoritmo de almacenamiento en caché. Esta no es una pregunta fácil de responder, pero LRU debería funcionar bien. Sin métricas reales, no hay una respuesta correcta, pero LRU es simple de implementar y si no cumple con sus requisitos, simplemente haga las métricas y decida un nuevo algoritmo. Asegúrese de que puede hacerlo sin problemas al tener una buena interfaz para el caché. Otra cosa a tener en cuenta es que sus objetos de nivel de dominio nunca deben depender de los límites de su caché. Si necesita 100 000 objetos, pero solo tiene 50 000 de caché, aún tiene los 100 000 objetos en la memoria, pero 50 000 de ellos están en la memoria caché. En otras palabras, sus objetos no deberían depender del estado de su caché, y tampoco debería importarles si tiene almacenamiento en caché.
A continuación, si todavía está descubriendo la idea de RDG, simplemente está almacenando en caché el objeto Gateway en su caché. Puede mantener instancias de los objetos Gateway en su caché por medio de shared_ptr, pero también debe considerar su estrategia de bloqueo (optimista frente a pesimista), si desea evitar escrituras sucias. Además, todos sus Gateways (uno para cada tabla) pueden heredar la misma interfaz, por lo que puede generalizar sus estrategias de guardar/cargar, y también, podría usar un solo grupo mientras mantiene las cosas simples. (Echa un vistazo a boost::pool. Tal vez pueda ayudarlo con la implementación del caché).
Un punto final:
¡El pastel es una mentira! :D No importa lo que decidas hacer, asegúrate de que se base en una cantidad decente de métricas de rendimiento. Si mejora el rendimiento en un 20% y pasó 2 meses haciéndolo, tal vez valga la pena pensar en agregar algunos gigas más de RAM a su hardware. Haga una prueba de concepto fácil de verificar, que le dará suficiente información sobre si la implementación de su caché vale la pena, y si no, pruebe algunas de las soluciones probadas y confiables disponibles (memcached o similar, como ya comentó @Layne).