Je conçois une base de données d'objets en mémoire pour un cas d'utilisation très spécifique. Il s'agit d'un rédacteur unique, mais il doit prendre en charge des lectures simultanées efficaces. Les lectures doivent être isolées. Il n'y a pas de langage de requête, la base de données ne prend en charge que:
- obtenir un objet / -s par attribut / ensemble d'attributs (il peut y avoir un support pour les expressions, par exemple
x.count < 5
) - obtenir l'attribut de l'objet
Une requête est un script impératif composé d'un nombre arbitraire des opérations ci-dessus. La taille des données sera << mémoire, donc tous les objets et indices sur la plupart des attributs devraient s'adapter confortablement sans permutation.
Ce dont j'ai besoin, c'est d'une structure de données pour l'index d'attribut de l'objet, qui peut être O (n) lors des écritures, ne prend pas en charge la concurrence d'accès en écriture, mais devrait idéalement prendre en charge les instantanés O (1) (peut-être copier lors de l'écriture) et O (logN). Idéalement, cela permettrait une concurrence élevée sur les lectures avec un partage structurel maximal entre les versions.
Je regardais les CTries , les BST simultanés et les arbres de jeu simultanés, mais je ne sais pas si je regarde vraiment dans la bonne direction ici. Les structures ci-dessus prêtent beaucoup d'attention à la complexité des inserts qui ne m'intéressent pas.
La question : existe-t-il une structure de données connue qui convient bien à mon cas d'utilisation, prêt à l'emploi?
EDIT : après réflexion, il semble qu'un arbre BST / Splay persistant fonctionnerait. Le rédacteur mettrait à jour la copie «principale» et les requêtes obtiendraient l'arborescence dès le début de l'exécution et la jetteraient une fois qu'elles seraient terminées. Cependant, je suis toujours intéressé s'il y a une meilleure solution.
Réponses:
Utilisez tout type de structure de données arborescente persistante / immuable (c'est-à-dire fonctionnelle). La clé est d'obtenir le bon verrouillage, comme l'a souligné @Raphael dans les commentaires.
La bonne chose à propos des structures de données arborescentes fonctionnelles / persistantes, c'est que vous obtenez des "instantanés" gratuitement. Supposons que vous utilisiez un treap (arbre de recherche binaire randomisé) pour votre structure de données. Voici un exemple de celui écrit en Go: https://github.com/steveyen/gtreap . L'auteur le décrit ainsi:
Vous utilisez un verrou pour protéger le pointeur vers la racine. Comme la structure des données est immuable, les lectures peuvent être effectuées simultanément et vous pouvez enregistrer des pointeurs sur d'anciens instantanés. Une lecture est:
Même si la recherche peut prendre un certain temps, vous ne maintenez le verrou que lors de la copie du pointeur, de sorte que les recherches peuvent avoir lieu simultanément.
Une écriture c'est:
Dans cette version, les écritures doivent maintenir le verrou pendant tout le processus de création de la nouvelle version de l'arborescence. Vous pouvez améliorer les performances de lecture (au prix de l'échec de la transaction d'écriture) en changeant l'écriture en quelque chose comme ceci:
Vous pourrez peut-être faire encore un peu mieux (le rendre "sans verrouillage") si votre langage de programmation a des variables atomiques avec une opération atomique de comparaison et d'échange. (Par exemple en utilisant des C ++ 11.
atomic<T*>
)la source
Microsoft a publié des détails sur leur nouvelle base de données en mémoire, il a des index qui ne bloquent pas les lectures pendant les écritures.
Par exemple:
Voir http://research.microsoft.com/en-us/projects/main-memory_dbs/ pour une liste de leurs publications.
la source