2016-07-11 3 views
1

Je suis à la recherche d'un moyen efficace de mettre en œuvre une opération de comparaison et d'échange à Berkeley DB. En ce moment j'utilise une version très ancienne, mais à première vue, même la dernière version (distribuée à partir du site Web d'Oracle) n'a pas une seule méthode pour une telle opération.Comparez et remplacez Berkeley DB JE?

Je cherchais un certain type de méthode comme

replace(Transaction, Key, ExpectedValue, NewValue) 

avec la sémantique suivante: DB obtient la valeur associée à une clé donnée, si cette valeur existe et elle est égale à ExpectedValue cette valeur sera changé en NewValue, sinon la méthode renvoie un échec d'OperationStatus.

On dirait qu'il n'y a pas de méthode comme celle-là, donc je me demande comment cela est censé être fait de la manière la plus efficace.

En ce moment je suis en utilisant l'approche suivante: je

db.get(null, key) -> {currentValue, version} 
db.put(null, key, {currentValue, newRandomIdVersion}) 
db.get(null, key) 

Je compare la valeur et la version, si elles correspondent je mise à jour finale effacer ancienne version. Si une étape échoue, l'ensemble du processus redémarre. Je pense que c'est très sous-optimal - ai-je tort?

+0

Avez-vous essayé quelque chose? –

+0

En tant que première fissure, essayez d'utiliser une transaction et voyez si la performance est suffisante à l'échelle. –

+0

Voulez-vous dire simplement mettre à jour le compteur dans la transaction? Cela n'aiderait pas - les transactions concurrentes se contenteront de se surpasser. – Alex

Répondre

0

Ma solution en mise à jour à ma question est fausse - mais seulement une légère modification est nécessaire pour l'améliorer.

La solution pourrait être la suivante: créer un DB séparé pour stocker les verrous qui contiendront les associations de clés à un compteur. Cette base de données devrait autoriser les doublons triés (afin que Database.get renvoie la plus petite valeur associée à une clé donnée). Ensuite, utilisez un compteur monotone croissant croissant. Plusieurs threads essayant de faire le CAS obtiendront des valeurs de ce compteur et stockent des paires clé-valeur dans ce DB verrouillé. Thread cette valeur la plus faible associée à une clé, suppose qu'il a l'autorisation d'écrire et va de l'avant avec compare-and-swap pour l'enregistrement désiré, puis supprime son entrée de la DB de verrouillage, d'autres threads simplement réessayer.