⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cache.java

📁 oscache-2.4.1-full
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
     * @param key    The key of the cache entry
     * @param policy Object that implements refresh policy logic
     * @param origin The origin of request (optional)
     * @return CacheEntry for the specified key.
     */
    protected CacheEntry getCacheEntry(String key, EntryRefreshPolicy policy, String origin) {
        CacheEntry cacheEntry = null;

        // Verify that the key is valid
        if ((key == null) || (key.length() == 0)) {
            throw new IllegalArgumentException("getCacheEntry called with an empty or null key");
        }

        cacheEntry = (CacheEntry) cacheMap.get(key);

        // if the cache entry does not exist, create a new one
        if (cacheEntry == null) {
            if (log.isDebugEnabled()) {
                log.debug("No cache entry exists for key='" + key + "', creating");
            }

            cacheEntry = new CacheEntry(key, policy);
        }

        return cacheEntry;
    }

    /**
     * Indicates whether or not the cache entry is stale.
     *
     * @param cacheEntry     The cache entry to test the freshness of.
     * @param refreshPeriod  The maximum allowable age of the entry, in seconds.
     * @param cronExpiry     A cron expression specifying absolute date(s) and/or time(s)
     * that the cache entry should expire at. If the cache entry was refreshed prior to
     * the most recent match for the cron expression, the entry will be considered stale.
     *
     * @return <code>true</code> if the entry is stale, <code>false</code> otherwise.
     */
    protected boolean isStale(CacheEntry cacheEntry, int refreshPeriod, String cronExpiry) {
        boolean result = cacheEntry.needsRefresh(refreshPeriod) || isFlushed(cacheEntry);

        if ((!result) && (cronExpiry != null) && (cronExpiry.length() > 0)) {
            try {
                FastCronParser parser = new FastCronParser(cronExpiry);
                result = result || parser.hasMoreRecentMatch(cacheEntry.getLastUpdate());
            } catch (ParseException e) {
                log.warn(e);
            }
        }

        return result;
    }

    /**
     * Get the updating cache entry from the update map. If one is not found,
     * create a new one (with state {@link EntryUpdateState#NOT_YET_UPDATING})
     * and add it to the map.
     *
     * @param key The cache key for this entry
     *
     * @return the CacheEntry that was found (or added to) the updatingEntries
     * map.
     */
    protected EntryUpdateState getUpdateState(String key) {
        EntryUpdateState updateState;

        synchronized (updateStates) {
            // Try to find the matching state object in the updating entry map.
            updateState = (EntryUpdateState) updateStates.get(key);

            if (updateState == null) {
                // It's not there so add it.
                updateState = new EntryUpdateState();
                updateStates.put(key, updateState);
            } else {
                //Otherwise indicate that we start using it to prevent its removal until all threads are done with it.
                updateState.incrementUsageCounter();
            }
        }

        return updateState;
    }

    /**
     * releases the usage that was made of the specified EntryUpdateState. When this reaches zero, the entry is removed from the map. 
     * @param state the state to release the usage of
     * @param key the associated key.
     */
    protected void releaseUpdateState(EntryUpdateState state, String key) {
        synchronized (updateStates) {
            int usageCounter = state.decrementUsageCounter();
            checkEntryStateUpdateUsage(key, state, usageCounter);
        }       
    }
    
    /**
     * Completely clears the cache.
     */
    protected void clear() {
        cacheMap.clear();
    }

    /**
     * Removes the update state for the specified key and notifies any other
     * threads that are waiting on this object. This is called automatically
     * by the {@link #putInCache} method, so it is possible that no EntryUpdateState was hold
     * when this method is called.
     *
     * @param key The cache key that is no longer being updated.
     */
    protected void completeUpdate(String key) {
        EntryUpdateState state;

        synchronized (updateStates) {
            state = (EntryUpdateState) updateStates.get(key);

            if (state != null) {
                synchronized (state) {
                    int usageCounter = state.completeUpdate();
                    state.notifyAll();
                    
                    checkEntryStateUpdateUsage(key, state, usageCounter);

                }
            } else {
                //If putInCache() was called directly (i.e. not as a result of a NeedRefreshException) then no EntryUpdateState would be found. 
            }
        }
    }

    /**
     * Completely removes a cache entry from the cache and its associated cache
     * groups.
     *
     * @param key The key of the entry to remove.
     */
    public void removeEntry(String key) {
        removeEntry(key, null);
    }

    /**
     * Completely removes a cache entry from the cache and its associated cache
     * groups.
     *
     * @param key    The key of the entry to remove.
     * @param origin The origin of this remove request.
     */
    protected void removeEntry(String key, String origin) {
        CacheEntry cacheEntry = (CacheEntry) cacheMap.get(key);
        cacheMap.remove(key);

        if (listenerList.getListenerCount() > 0) {
            CacheEntryEvent event = new CacheEntryEvent(this, cacheEntry, origin);
            dispatchCacheEntryEvent(CacheEntryEventType.ENTRY_REMOVED, event);
        }
    }

    /**
     * Dispatch a cache entry event to all registered listeners.
     *
     * @param eventType   The type of event (used to branch on the proper method)
     * @param event       The event that was fired
     */
    private void dispatchCacheEntryEvent(CacheEntryEventType eventType, CacheEntryEvent event) {
        // Guaranteed to return a non-null array
        Object[] listeners = listenerList.getListenerList();

        // Process the listeners last to first, notifying
        // those that are interested in this event
        for (int i = listeners.length - 2; i >= 0; i -= 2) {
            if (listeners[i+1] instanceof CacheEntryEventListener) {
                CacheEntryEventListener listener = (CacheEntryEventListener) listeners[i+1];
                if (eventType.equals(CacheEntryEventType.ENTRY_ADDED)) {
                    listener.cacheEntryAdded(event);
                } else if (eventType.equals(CacheEntryEventType.ENTRY_UPDATED)) {
                    listener.cacheEntryUpdated(event);
                } else if (eventType.equals(CacheEntryEventType.ENTRY_FLUSHED)) {
                    listener.cacheEntryFlushed(event);
                } else if (eventType.equals(CacheEntryEventType.ENTRY_REMOVED)) {
                    listener.cacheEntryRemoved(event);
                }
            }
        }
    }

    /**
     * Dispatch a cache group event to all registered listeners.
     *
     * @param eventType The type of event (this is used to branch to the correct method handler)
     * @param group     The cache group that the event applies to
     * @param origin      The origin of this event (optional)
     */
    private void dispatchCacheGroupEvent(CacheEntryEventType eventType, String group, String origin) {
        CacheGroupEvent event = new CacheGroupEvent(this, group, origin);

        // Guaranteed to return a non-null array
        Object[] listeners = listenerList.getListenerList();

        // Process the listeners last to first, notifying
        // those that are interested in this event
        for (int i = listeners.length - 2; i >= 0; i -= 2) {
            if (listeners[i+1] instanceof CacheEntryEventListener) {
                CacheEntryEventListener listener = (CacheEntryEventListener) listeners[i + 1];
                if (eventType.equals(CacheEntryEventType.GROUP_FLUSHED)) {
                    listener.cacheGroupFlushed(event);
                }
            }
        }
    }

    /**
     * Dispatch a cache map access event to all registered listeners.
     *
     * @param eventType     The type of event
     * @param entry         The entry that was affected.
     * @param origin        The origin of this event (optional)
     */
    private void dispatchCacheMapAccessEvent(CacheMapAccessEventType eventType, CacheEntry entry, String origin) {
        CacheMapAccessEvent event = new CacheMapAccessEvent(eventType, entry, origin);

        // Guaranteed to return a non-null array
        Object[] listeners = listenerList.getListenerList();

        // Process the listeners last to first, notifying
        // those that are interested in this event
        for (int i = listeners.length - 2; i >= 0; i -= 2) {
            if (listeners[i+1] instanceof CacheMapAccessEventListener) {
                CacheMapAccessEventListener listener = (CacheMapAccessEventListener) listeners[i + 1];
                listener.accessed(event);
            }
        }
    }

    /**
     * Dispatch a cache pattern event to all registered listeners.
     *
     * @param eventType The type of event (this is used to branch to the correct method handler)
     * @param pattern     The cache pattern that the event applies to
     * @param origin      The origin of this event (optional)
     */
    private void dispatchCachePatternEvent(CacheEntryEventType eventType, String pattern, String origin) {
        CachePatternEvent event = new CachePatternEvent(this, pattern, origin);

        // Guaranteed to return a non-null array
        Object[] listeners = listenerList.getListenerList();

        // Process the listeners last to first, notifying
        // those that are interested in this event
        for (int i = listeners.length - 2; i >= 0; i -= 2) {
            if (listeners[i+1] instanceof CacheEntryEventListener) {
                if (eventType.equals(CacheEntryEventType.PATTERN_FLUSHED)) {
                    CacheEntryEventListener listener = (CacheEntryEventListener) listeners[i+1];
                    listener.cachePatternFlushed(event);
                }
            }
        }
    }

    /**
     * Dispatches a cache-wide event to all registered listeners.
     *
     * @param eventType The type of event (this is used to branch to the correct method handler)
     * @param origin The origin of this event (optional)
     */
    private void dispatchCachewideEvent(CachewideEventType eventType, Date date, String origin) {
        CachewideEvent event = new CachewideEvent(this, date, origin);

        // Guaranteed to return a non-null array
        Object[] listeners = listenerList.getListenerList();

        // Process the listeners last to first, notifying
        // those that are interested in this event
        for (int i = listeners.length - 2; i >= 0; i -= 2) {
            if (listeners[i+1] instanceof CacheEntryEventListener) {
                if (eventType.equals(CachewideEventType.CACHE_FLUSHED)) {
                    CacheEntryEventListener listener = (CacheEntryEventListener) listeners[i+1];
                    listener.cacheFlushed(event);
                }
            }
        }
    }

    /**
     * Flush a cache entry. On completion of the flush, a
     * <tt>CacheEntryEventType.ENTRY_FLUSHED</tt> event is fired.
     *
     * @param entry The entry to flush
     * @param origin The origin of this flush event (optional)
     */
    private void flushEntry(CacheEntry entry, String origin) {
        String key = entry.getKey();

        // Flush the object itself
        entry.flush();

        if (!entry.isNew()) {
            // Update the entry's state in the map
            cacheMap.put(key, entry);
        }

        // Trigger an ENTRY_FLUSHED event. [CACHE-107] Do this for all flushes.
        if (listenerList.getListenerCount() > 0) {
            CacheEntryEvent event = new CacheEntryEvent(this, entry, origin);
            dispatchCacheEntryEvent(CacheEntryEventType.ENTRY_FLUSHED, event);
        }
    }
    
    /**
     * @return the total number of cache entries held in this cache. 
     */
    public int getSize() {
        synchronized(cacheMap) {
            return cacheMap.size();
        }
    }

    /**
     * Test support only: return the number of EntryUpdateState instances within the updateStates map. 
     */
    protected int getNbUpdateState() {
        synchronized(updateStates) {
            return updateStates.size();
        }
    }
    
    
    /**
     * Test support only: return the number of entries currently in the cache map
     * @deprecated use getSize() 
     */
    public int getNbEntries() {
        synchronized(cacheMap) {
            return cacheMap.size();
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -