在解决这个问题之后,似乎基于文件或磁盘的Map实现可能是解决我在此处提到的问题的正确解决方案。精简版:
Map
ConcurrentHashMap
在工作中,(强烈)建议我使用SQLite解决此问题,但是在问了上一个问题之后,我认为数据库不是适合此工作的合适工具。所以- 让我知道这听起来是否疯狂 -我认为更好的解决方案是将其Map存储在磁盘上。
坏主意:自己实施。更好的主意:使用别人的图书馆! 哪一个?
n
易于使用。 如果我能在本周末之前完成这项工作,那就太好了。 更好的是:一天结束。这将是 非常,非常 巨大的,如果我能一个JAR添加到我的类路径,改变new ConcurrentHashMap<Foo, Bar>();以new SomeDiskStoredMap<Foo, Bar>(); 和完成。
new ConcurrentHashMap<Foo, Bar>();
new SomeDiskStoredMap<Foo, Bar>();
良好的 可扩展性和性能。 最坏的情况:每天平均每秒每秒添加3次(平均)新条目。但是,插入操作并不总是那么顺利。(no inserts for an hour)然后可能是(insert 10,000 objects at once)。
(no inserts for an hour)
(insert 10,000 objects at once)
Ehcache和Berkeley DB现在都看起来很合理。在任一方向上有什么特别的建议吗?
更新(首次发布后约4年…):请注意,在较新版本的ehcache中,缓存项的持久性仅在付费产品中可用。感谢@boday指出这一点。
ehcache很棒。它将为您提供在内存,磁盘或具有溢出到磁盘的内存中实现映射所需的灵活性。如果为java.util.Map使用这个非常简单的包装器,那么使用它就非常简单:
import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; import net.sf.ehcache.Cache; import net.sf.ehcache.Element; import org.apache.log4j.Logger; import com.google.common.collect.Sets; public class EhCacheMapAdapter<K,V> implements Map<K,V> { @SuppressWarnings("unused") private final static Logger logger = Logger .getLogger(EhCacheMapAdapter.class); public Cache ehCache; public EhCacheMapAdapter(Cache ehCache) { super(); this.ehCache = ehCache; } // end constructor @Override public void clear() { ehCache.removeAll(); } // end method @Override public boolean containsKey(Object key) { return ehCache.isKeyInCache(key); } // end method @Override public boolean containsValue(Object value) { return ehCache.isValueInCache(value); } // end method @Override public Set<Entry<K, V>> entrySet() { throw new UnsupportedOperationException(); } // end method @SuppressWarnings("unchecked") @Override public V get(Object key) { if( key == null ) return null; Element element = ehCache.get(key); if( element == null ) return null; return (V)element.getObjectValue(); } // end method @Override public boolean isEmpty() { return ehCache.getSize() == 0; } // end method @SuppressWarnings("unchecked") @Override public Set<K> keySet() { List<K> l = ehCache.getKeys(); return Sets.newHashSet(l); } // end method @SuppressWarnings("unchecked") @Override public V put(K key, V value) { Object o = this.get(key); if( o != null ) return (V)o; Element e = new Element(key,value); ehCache.put(e); return null; } // end method @Override public V remove(Object key) { V retObj = null; if( this.containsKey(key) ) { retObj = this.get(key); } // end if ehCache.remove(key); return retObj; } // end method @Override public int size() { return ehCache.getSize(); } // end method @Override public Collection<V> values() { throw new UnsupportedOperationException(); } // end method @Override public void putAll(Map<? extends K, ? extends V> m) { for( K key : m.keySet() ) { this.put(key, m.get(key)); } // end for } // end method } // end class