📄 abstractconcurrentreadcache.java
字号:
if (value != null) {
/** OpenSymphony BEGIN */
/* Previous code
return value;*/
if (NULL.equals(value)) {
// Memory cache disable, use disk
value = persistRetrieve(e.key);
if (value != null) {
itemRetrieved(key);
}
return value; // fix [CACHE-13]
} else {
itemRetrieved(key);
return value;
}
/** OpenSymphony END */
}
// Entry was invalidated during deletion. But it could
// have been re-inserted, so we must retraverse.
// To avoid useless contention, get lock to wait out modifications
// before retraversing.
synchronized (this) {
tab = table;
}
e = first = tab[index = hash & (tab.length - 1)];
} else {
e = e.next;
}
}
}
/**
* Returns a set view of the keys contained in this map.
* The set is backed by the map, so changes to the map are reflected in the set, and
* vice-versa. The set supports element removal, which removes the
* corresponding mapping from this map, via the <tt>Iterator.remove</tt>,
* <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
* <tt>clear</tt> operations. It does not support the <tt>add</tt> or
* <tt>addAll</tt> operations.
*
* @return a set view of the keys contained in this map.
*/
public Set keySet() {
Set ks = keySet;
if (ks != null) {
return ks;
} else {
return keySet = new AbstractSet() {
public Iterator iterator() {
return new KeyIterator();
}
public int size() {
return AbstractConcurrentReadCache.this.size();
}
public boolean contains(Object o) {
return AbstractConcurrentReadCache.this.containsKey(o);
}
public boolean remove(Object o) {
return AbstractConcurrentReadCache.this.remove(o) != null;
}
public void clear() {
AbstractConcurrentReadCache.this.clear();
}
};
}
}
/**
* Returns an enumeration of the keys in this table.
*
* @return an enumeration of the keys in this table.
* @see Enumeration
* @see #elements()
* @see #keySet()
* @see Map
*/
public Enumeration keys() {
return new KeyIterator();
}
/**
* Return the load factor
**/
public float loadFactor() {
return loadFactor;
}
/**
* Maps the specified <code>key</code> to the specified <code>value</code> in this table.
* Neither the key nor the
* value can be <code>null</code>. <p>
*
* The value can be retrieved by calling the <code>get</code> method
* with a key that is equal to the original key.
*
* @param key the table key.
* @param value the value.
* @return the previous value of the specified key in this table,
* or <code>null</code> if it did not have one.
* @exception NullPointerException if the key or value is
* <code>null</code>.
* @see Object#equals(Object)
* @see #get(Object)
*/
/** OpenSymphony BEGIN */
public Object put(Object key, Object value) {
// Call the internal put using persistance
return put(key, value, true);
}
/**
* Copies all of the mappings from the specified map to this one.
*
* These mappings replace any mappings that this map had for any of the
* keys currently in the specified Map.
*
* @param t Mappings to be stored in this map.
*/
public synchronized void putAll(Map t) {
for (Iterator it = t.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
Object key = entry.getKey();
Object value = entry.getValue();
put(key, value);
}
}
/**
* Removes the key (and its corresponding value) from this table.
* This method does nothing if the key is not in the table.
*
* @param key the key that needs to be removed.
* @return the value to which the key had been mapped in this table,
* or <code>null</code> if the key did not have a mapping.
*/
/** OpenSymphony BEGIN */
public Object remove(Object key) {
return remove(key, true, false);
}
/**
* Like <code>remove(Object)</code>, but ensures that the entry will be removed from the persistent store, too,
* even if overflowPersistence or unlimitedDiskcache are true.
*
* @param key the key that needs to be removed.
* @return the value to which the key had been mapped in this table,
* or <code>null</code> if the key did not have a mapping.
*/
public Object removeForce(Object key) {
return remove(key, true, true);
}
/**
* Returns the total number of cache entries held in this map.
*
* @return the number of key-value mappings in this map.
*/
public synchronized int size() {
return count;
}
/**
* Returns a collection view of the values contained in this map.
* The collection is backed by the map, so changes to the map are reflected in
* the collection, and vice-versa. The collection supports element
* removal, which removes the corresponding mapping from this map, via the
* <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
* <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
* It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
*
* @return a collection view of the values contained in this map.
*/
public Collection values() {
Collection vs = values;
if (vs != null) {
return vs;
} else {
return values = new AbstractCollection() {
public Iterator iterator() {
return new ValueIterator();
}
public int size() {
return AbstractConcurrentReadCache.this.size();
}
public boolean contains(Object o) {
return AbstractConcurrentReadCache.this.containsValue(o);
}
public void clear() {
AbstractConcurrentReadCache.this.clear();
}
};
}
}
/**
* Get ref to group.
* CACHE-127 Synchronized copying of the group entry set since
* the new HashSet(Collection c) constructor uses the iterator.
* This may slow things down but it is better than a
* ConcurrentModificationException. We might have to revisit the
* code if performance is too adversely impacted.
**/
protected synchronized final Set getGroupForReading(String groupName) {
Set group = (Set) getGroupsForReading().get(groupName);
if (group == null) return null;
return new HashSet(group);
}
/**
* Get ref to groups.
* The reference and the cells it
* accesses will be at least as fresh as from last
* use of barrierLock
**/
protected final Map getGroupsForReading() {
synchronized (barrierLock) {
return groups;
}
}
/**
* Get ref to table; the reference and the cells it
* accesses will be at least as fresh as from last
* use of barrierLock
**/
protected final Entry[] getTableForReading() {
synchronized (barrierLock) {
return table;
}
}
/**
* Force a memory synchronization that will cause
* all readers to see table. Call only when already
* holding main synch lock.
**/
protected final void recordModification(Object x) {
synchronized (barrierLock) {
lastWrite = x;
}
}
/**
* Helper method for entrySet remove.
**/
protected synchronized boolean findAndRemoveEntry(Map.Entry entry) {
Object key = entry.getKey();
Object v = get(key);
if ((v != null) && v.equals(entry.getValue())) {
remove(key);
return true;
} else {
return false;
}
}
/**
* Remove an object from the persistence.
* @param key The key of the object to remove
*/
protected void persistRemove(Object key) {
if (log.isDebugEnabled()) {
log.debug("PersistRemove called (key=" + key + ")");
}
if (persistenceListener != null) {
try {
persistenceListener.remove((String) key);
} catch (CachePersistenceException e) {
log.error("[oscache] Exception removing cache entry with key '" + key + "' from persistence", e);
}
}
}
/**
* Removes a cache group using the persistence listener.
* @param groupName The name of the group to remove
*/
protected void persistRemoveGroup(String groupName) {
if (log.isDebugEnabled()) {
log.debug("persistRemoveGroup called (groupName=" + groupName + ")");
}
if (persistenceListener != null) {
try {
persistenceListener.removeGroup(groupName);
} catch (CachePersistenceException e) {
log.error("[oscache] Exception removing group " + groupName, e);
}
}
}
/**
* Retrieve an object from the persistence listener.
* @param key The key of the object to retrieve
*/
protected Object persistRetrieve(Object key) {
if (log.isDebugEnabled()) {
log.debug("persistRetrieve called (key=" + key + ")");
}
Object entry = null;
if (persistenceListener != null) {
try {
entry = persistenceListener.retrieve((String) key);
} catch (CachePersistenceException e) {
/**
* It is normal that we get an exception occasionally.
* It happens when the item is invalidated (written or removed)
* during read. The logic is constructed so that read is retried.
*/
}
}
return entry;
}
/**
* Retrieves a cache group using the persistence listener.
* @param groupName The name of the group to retrieve
*/
protected Set persistRetrieveGroup(String groupName) {
if (log.isDebugEnabled()) {
log.debug("persistRetrieveGroup called (groupName=" + groupName + ")");
}
if (persistenceListener != null) {
try {
return persistenceListener.retrieveGroup(groupName);
} catch (CachePersistenceException e) {
log.error("[oscache] Exception retrieving group " + groupName, e);
}
}
return null;
}
/**
* Store an object in the cache using the persistence listener.
* @param key The object key
* @param obj The object to store
*/
protected void persistStore(Object key, Object obj) {
if (log.isDebugEnabled()) {
log.debug("persistStore called (key=" + key + ")");
}
if (persistenceListener != null) {
try {
persistenceListener.store((String) key, obj);
} catch (CachePersistenceException e) {
log.error("[oscache] Exception persisting " + key, e);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -