2012-03-05 34 views
11

Có bất kỳ thứ gì như kết hợp chức năng CacheMultimap của ổi có sẵn không? Về cơ bản, tôi cần một bộ sưu tập mà các mục hết hạn sau một thời gian nhất định như có sẵn trong Cache nhưng tôi có các khóa không phải là duy nhất và tôi cần các mục để hết hạn độc lập.Kết hợp Java ổi của Multimap và Cache

Trả lời

4

Tôi nghĩ rằng Louis Wasserman đã cung cấp câu trả lời trong một trong các nhận xét ở trên, tức là không có kết hợp off-the-shelf của MultimapCache khả dụng. Tôi đã giải quyết được vấn đề/yêu cầu của mình với giải pháp được nêu trong mã giả bên dưới:

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; 
} 

Giải pháp 'đơn giản' này có một số hạn chế nhưng nó hoạt động tốt cho tôi.

+1

Làm thế nào để bạn đối phó với multimap ngày càng phát triển? – neu242

+1

@ neu242 cho phần 'SomeConfig' trong câu trả lời hiện tại, bạn có thể thêm một cuộc gọi' .removalListener' ở đó, sẽ được gọi bất cứ khi nào có điều gì đó bị xóa khỏi bộ nhớ cache, để bạn cũng có thể xóa nó khỏi multimap – Philipp

0

Với bộ nhớ cache ổi không có đặt phương thức, bộ nhớ cache được thiết kế để tự điền. Các giá trị được trả về từ tra cứu khóa được tính theo thời gian chạy. Một cách tiếp cận tương tự được thực hiện bởi các nhà máy biến đổi bộ sưu tập của Commons.

Tôi nghĩ bạn có thể triển khai những gì bạn đang tìm kiếm khá dễ dàng. Nếu bạn nhìn vào một ví dụ Bản đồ được sao chép đơn giản như Kitty-Cache, bạn có thể thấy rằng bạn có thể thay thế Bản đồ bằng một Multimap và viết lại các phương thức khác cho phù hợp. Vì vậy, trong KittyCache.java nội bạn có thể có một cái gì đó như:

Multimap<K, CacheEntry<V>> cache; 

Bí quyết cho loại bộ nhớ cache là không có gì thực sự hết hiệu lực cho đến khi ai đó yêu cầu nó.

+3

"Với bộ nhớ cache ổi không có phương pháp đặt, bộ nhớ cache được thiết kế để tự điền" - điều này không đúng. Chính 'Cache' chính nó không có phương thức" put "và' LoadingCache' được thiết kế để tự điền, nhưng bạn luôn có thể sử dụng bộ đệm không tải, và gọi 'cache.asMap(). Put (.. .) 'để thêm các mục nhập của riêng bạn. Tất nhiên, điều này không giúp bạn có được một multimap. Chỉ cần sửa câu lệnh đầu tiên đó. – Ray

+2

Vì ổi 11.0 có [phương pháp đặt] (http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/cache/Cache.html#put (K, V)) trong 'Cache'. Ví dụ bạn cung cấp là thú vị nhưng tôi không thể dựa vào hết hạn theo yêu cầu, tôi thực hiện 'RemoveListener' để nhận thông báo về thời gian hết hạn trong' Cache'. – hgus1294

+1

Cảm ơn bạn đã đặt Ray trực tiếp này. Tôi đã trích dẫn: http://java.dzone.com/articles/google-guava-cache –

0

Miễn là bạn đang nói về Cache và không phải LoadingCache bạn có thể chuyển chế độ xem Cache.asMap() thành Multimaps.newMultimap.

+0

Thú vị. Tôi đã làm một số thử nghiệm nhưng tôi không thể nhận được các mục để hết hạn một cách độc lập. Tôi đã chuyển một 'Cache.asMap()' vào một 'Multimaps.newMultimap' theo đề xuất của bạn và đã thực hiện một số thử nghiệm nhanh với 'expireAfterWrite' được đặt thành 1000 ms và chạy kịch bản sau: ' map.put (1, Object1); '' Thread.Sleep (700) '' map.put (1, Object2), '' Thread.Sleep (500) '. Tại thời điểm này tôi mong đợi mục nhập đầu tiên bị trục xuất nhưng lần thứ hai vẫn còn nhưng tôi tìm thấy cả hai mục được đuổi ra. Có lẽ tôi đang làm điều gì đó sai, nhưng trừ khi tôi có thể thay đổi hành vi, nó không làm việc cho tôi. – hgus1294

Các vấn đề liên quan