2012-03-05 13 views
11

के जावा अमरूद संयोजन वहाँ उपलब्ध अमरूद के Cache और Multimap कार्यक्षमता के संयोजन के रूप में इस तरह के किसी भी बात है? अनिवार्य रूप से, मुझे एक संग्रह की आवश्यकता है जहां Cache में उपलब्ध समय के बाद प्रविष्टियां समाप्त हो जाएंगी लेकिन मेरे पास अनन्य कुंजी हैं और मुझे स्वतंत्र रूप से समाप्त होने वाली प्रविष्टियों की आवश्यकता है।मल्टीमैप और कैश

उत्तर

4

मुझे लगता है कि लुइस वासरमैन ने उपर्युक्त टिप्पणियों में से एक में जवाब प्रदान किया है, यानी Multimap और Cache के शेल्फ कॉम्बो का कोई ऑफ-द-शेल्फ कॉम्बो नहीं है। मैं समाधान नीचे छद्म कोड में उल्लिखित के साथ मेरी समस्या/आवश्यकताओं को हल किया है:

private Cache<Integer,Object> cache = CacheBuilder.newBuilder().SomeConfig.build(); 
private Multimap<Integer,Object> multimap = HashMultimap<Integer, Object>.create(); 
private AtomicInteger atomicid = new AtomicInteger(0); 

public void putInMultimap(int id, Object obj) { 
    int mapid = atomicid.addAndGet(1); 
    cache.put(mapid,obj); 
    multimap.put(id,mapid); 
} 
public List<Object> getFromMultimap(int id) { 
    Set<Integer> mapids = multimap.get(id); 
    List<Object> list = new ArrayList<Object>(); 
    for (int i : mapids) { 
     list.add(cache.getIfPresent(i)); 
    } 
    return list; 
} 

यह सरल 'समाधान' कुछ सीमाएँ हैं, लेकिन यह मेरे लिए ठीक काम करता है।

+1

आप लगातार बढ़ते मल्टीमैप से कैसे निपटते हैं? वर्तमान उत्तर में 'SomeConfig' भाग के लिए – neu242

+1

@ neu242 आप वहां' .removalListener 'कॉल जोड़ सकते हैं, जिसे कैश से कुछ भी बेदखल किया जाएगा, ताकि आप इसे मल्टीमैप से भी हटा सकें – Philipp

0

एक अमरूद कैश के साथ वहाँ कैश आत्म-पॉप्युलेट डिज़ाइन किया गया है कोई डाल विधि है,। एक कुंजी लुकअप से लौटाए गए मानों को रनटाइम पर गणना की जाती है। कॉमन्स कलेक्शन ट्रांसफॉर्मर फैक्ट्रियों द्वारा एक समान दृष्टिकोण लिया जाता है।

मुझे लगता है कि आप जो भी आसानी से खोज रहे हैं उसे लागू कर सकते हैं। यदि आप Kitty-Cache जैसे एक साधारण मानचित्र समर्थित उदाहरण को देखते हैं तो आप देख सकते हैं कि आप मानचित्र को मल्टीमैप के साथ बदल सकते हैं और तदनुसार अन्य विधियों को फिर से लिख सकते हैं। तो KittyCache.java में आंतरिक रूप से आप की तरह कुछ हो सकता था:

Multimap<K, CacheEntry<V>> cache; 

कैश के इस प्रकार के लिए चाल है कि कुछ भी नहीं है वास्तव में जब तक किसी को यह अनुरोध करता है को समाप्त हो रहा है।

+3

"एक समुद्री कैश के साथ कोई विधि नहीं है, कैश को स्वयं-पॉप्युलेट करने के लिए डिज़ाइन किया गया है" - यह सच नहीं है। यह सच है 'कैश' के पास कोई विधि नहीं है "और" लोडिंग कैश 'को स्वयं-पॉप्युलेट करने के लिए डिज़ाइन किया गया है, लेकिन आप हमेशा एक गैर-लोडिंग कैश का उपयोग कर सकते हैं और' cache.asMap() डाल सकते हैं। ।) 'अपनी प्रविष्टियों को जोड़ने के लिए। बेशक, यह आपको एक बहुतायत नहीं मिलता है। बस उस पहले कथन को सही करें। – Ray

+2

चूंकि गुवा 11.0 में एक [पुट विधि] है (http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/cache/Cache.html#put (के, वी)) में 'Cache'। आपके द्वारा प्रदान किया गया उदाहरण दिलचस्प है लेकिन मैं अनुरोधों पर समाप्ति पर भरोसा नहीं कर सकता, मैं 'कैश' में समाप्ति पर अधिसूचना प्राप्त करने के लिए' रिमूवल लिस्टनर 'को लागू करता हूं। – hgus1294

+1

इस सीधे रे डालने के लिए धन्यवाद। मैं उद्धरण दे रहा था: http://java.dzone.com/articles/google-guava-cache –

0

जब तक आप Cache और LoadingCache पर बात नहीं कर रहे हैं, तो आप Multimaps.newMultimap पर देख सकते हैं।

+0

दिलचस्प। मैंने कुछ परीक्षण किया लेकिन मैं स्वतंत्र रूप से समाप्त होने के लिए प्रविष्टियां नहीं प्राप्त कर सकता। मैंने एक 'कैश.एएसएपी() 'को' मल्टीमैप्स 'में पारित किया।newMultimap' आपके सुझाव के अनुसार और 'expireAfterWrite' के साथ 1000 एमएस के साथ कुछ त्वरित परीक्षण किया और निम्नलिखित परिदृश्य चलाया: 'map.put (1, ऑब्जेक्ट 1);' थ्रेड। सो (700) 'map.put (1, ऑब्जेक्ट 2); 'थ्रेड। सो (500)'। इस बिंदु पर मैं पहली प्रविष्टि को बेदखल करने की उम्मीद करता हूं लेकिन दूसरा रहता है लेकिन मुझे दोनों प्रविष्टियों को बेदखल कर दिया जाएगा। शायद मैं कुछ गलत कर रहा हूं लेकिन जब तक मैं व्यवहार को बदल नहीं सकता, यह मेरे लिए काम नहीं करता है। – hgus1294

संबंधित मुद्दे