Voici donc le problème que j'essaie de résoudre - j'ai un objet avec deux champs entiers que je veux cache maintenant le champ maintenant si j'utilise un Edit: J'apprécie les réponses ci-dessous, mais tout le monde semble manquer le point principal. Est-ce que ça va marcher? L'EHCache pourrait-il renvoyer deux objets différents pour le même cacheKey (disons si l'objet était sur le disque pendant l'appel et il est sérialisé deux fois, une fois pour chaque appel). P> P> x code> est Ce que je fais principalement correspondre - mais il peut y avoir des doublons auquel cas je veux revenir sur le deuxième champ (de sorte que cela.x = ça.x et this.y = ça.Y). Y ne peut avoir que 25 valeurs distinctes. Maintenant, je sais que je pouvais simplement combiner les deux comme une chaîne et utiliser cela comme clé de cache, mais je devrais alors essayer
x + [25 valeurs possibles] code> pour déterminer réellement si ce n'était pas dans le cache - Faire du cache manque très cher. Je pensais à essayer de stocker une liste
x code>, puis si leur était plus que l'une, itérale dans la liste et rechercher une correspondance sur
y code>. p>
Concurrentlist code> (ou un ensemble si je me soucie des doublons - ignore que pour l'instant) Les fils peuvent être en mesure de l'ajouter, puis de la remettre dans le cache sans conditions de course? Est-il possible que Ehcache renvoie deux objets de liste différents à deux threads, puis lorsqu'ils ajoutent leur nouvelle valeur à la liste et tentent de le remettre au cache, je pourrais obtenir des résultats indéterministes? Voyez-vous une meilleure façon de construire ce cache? P>
5 Réponses :
J'ai une approche différente pour vous, que je viens de lire dans un article sur les recherches de la portée géographique. P>
Mettez deux paires de la valeur de clé dans le cache: une avec seulement x comme clé et une avec X et Y comme clé. Lorsque vous regardez dans le cache, recherchez la clé X-and-y en premier. Si c'est là, vous avez trouvé un match parfait. Si ce n'est pas là, cherchez la clé X et peut éventuellement trouver une correspondance avec une valeur Y différente. P>
Le cache est d'environ 15 millions d'objets - je préfère donc ne pas le pousser à 30 millions à moins d'autre manière. Je vais garder cela à l'esprit cependant.
De plus, comment la cache utilise-t-elle juste «X» que la clé fonctionne même depuis que je peux avoir plusieurs objets avec la même valeur «X» (mais différente 'Y').
Vous pouvez utiliser la clé (x, -1) pour juste x
Le pire cas ce n'est pas mieux. Si je ne trouve pas x + y alors je recherche x - si je trouve x, je dois ensuite rechercher l'option x + y suivante (et via toutes les options jusqu'à ce que j'en trouve une).
Si vous utilisez une sorte de tri, disez que vous recherchez (x, y) et que vous ne le trouvez pas, mais (x, -1) existe (car certains y existent de telle sorte que (x, y) soit sur la carte). Alors vous pouvez aller itérateur foo = triedmap.tailmap (x, -1)). Valeurs (). Itérateur (); foo.next (); retour foo.next (); Un peu de hack, mais il peut être imprimé :). Je ne sais pas exactement comment fonctionne SoyedMap de Java, mais sortdmap.tailmap ((x, 0)). Le premier () pourrait fonctionner qui est beaucoup plus propre que ce que j'ai dit auparavant.
Seul le nombre de clés augmenterait, pas le nombre de valeurs, à moins que le cache ne prend des copies des objets. Le nombre de clés se développerait d'un facteur entre 1/25 et 1, car s'il y a plusieurs objets avec la même valeur x, une seule de ces éléments serait mis en cache avec la clé X uniquement.
Ma solution ne vous dirait pas encore s'il y a plusieurs objets avec le même x. Cela pourrait être ajouté au cache X uniquement sous forme de drapeau booléen, en supposant que les objets ne soient pas séparés séparément du cache, sinon on utiliserait un compteur.
Vous pouvez utiliser une carte contenant un jeu de tri tel que la valeur. La première carte pourrait indiquer sur X, puis vous pouvez choisir le premier élément à partir du jeu de tri où le tri est basé sur y. P>
Je suppose que l'API de la collection Google a eu beaucoup de choses soignées que vous pourriez utiliser, par exemple le SortEDsetMulmap: P>
Je créerais une méthode pour obtenir la valeur de votre objet. Utilisez un sémaphore pour restreindre l'accès à la méthode (ou utilisez synchronisée).
Dans votre méthode, testez les correspondances x uniquement, et si cela renvoie plusieurs résultats, Texte pour XY correspondances. p>
Une fois que l'objet est en dehors du cache, toute modification de l'objet modifiera la objet dans le cache également (puisqu'ils montrent le même instance). p>
Si vous souhaitez être très prudent, utilisez des méthodes synchronisées pour obtenir / définir les variables de membre dans le MyObject et inclure une serrure qui est l'instance MyObject. P>
public void setX( int x ) { synchronized( this ) { this.x = x; } }
X code> et y code>, c'est-à-dire. clé de classe {int x, y} code> li>
- implémente une opération de comparaison distincte pour vous "Commande lexicale" sur
x code> et y code>, li>
- Mettez-le dans une carte
code> li>
ul>
Il est absolument possible que vous obteniez deux instances différentes de votre liste (ou de tout sérialisable)! Essayez ceci: J'ai utilisé ce qui suit dans ehcache.xml: p> <cache name="smallCache"
maxElementsInMemory="1"
eternal="true"
overflowToDisk="true"
diskPersistent="true"
maxElementsOnDisk="200"
memoryStoreEvictionPolicy="LRU"
transactionalMode="off"
>
</cache>
Cela ne montre pas le cache renvoyant deux copies différentes de la liste, cela vous indique la tenue d'une, puis en lisant un de disque.
@Gandalf: Il suffit de faire la même chose deux fois: faites une autre rinçage () + fil.sleep (), puis la récupérez à nouveau. Vous aurez deux copies différentes.
@Gandalf: J'ai édité l'exemple d'autres autres (simulant plusieurs threads) pour le rendre absolument clair, comment le problème peut se produire. C'est un peu plus long maintenant, mais cela montre exactement ce que vous aviez peur de votre question. S'il vous plaît essayez-le avec maxelementsInmemory = "3", et voir la différence!
Y a-t-il une raison pour laquelle vous ne pouvez pas utiliser de hash comme clé?
Comme je l'ai dit dans la question qui signifierait une valeur donnée de X, je devrais vérifier le cache éventuellement 25 fois pour savoir que ce n'était pas dans la cache. Je veux faire correspondre sur x, peu importe la valeur de y - mais s'il y a plusieurs x, la meilleure valeur de y.
Oui, il est possible d'avoir une valeur ajoutée à deux reprises à l'aide de la méthode que vous avez mentionnée. Utilisez plutôt un concurrentMap.
Oui, je comprends que Keegan (je vais changer la question à refléter) - la vraie question est de savoir si une liste ou non peut être une liste (ou définie comme indiqué au fur et à mesure).
Qu'entendez-vous par la meilleure valeur de y?
Dépend de la structure de données que vous utilisez pour la carte à partir de X -> FOO et de la manière dont vous l'utilisez (où FOO est une concurrente ou une concurrence). En supposant que vous utilisiez une carte de sécurité du thread, tant que vous ne remplacez jamais une valeur existante (clé, valeur) et que vous insérez correctement dans la carte du thread-Safe Tout sera dandy.
Quel objet voulez-vous choisir s'il existe plusieurs objets avec le même x mais aucun d'entre eux ne correspond à la Y? De votre question, j'ai supposé que dans le cas de la duplication des valeurs X, vous choisissez celui avec la valeur Y donnée et avez une erreur de cache s'il n'y en a pas.