Search in sources :

Example 1 with Cacheable

use of org.apache.derby.iapi.services.cache.Cacheable in project derby by apache.

the class DataDictionaryImpl method getPermissions.

private Object getPermissions(PermissionsDescriptor key) throws StandardException {
    // RESOLVE get a READ COMMITTED (shared) lock on the permission row
    Cacheable entry = getPermissionsCache().find(key);
    if (entry == null)
        return null;
    Object perms = entry.getIdentity();
    getPermissionsCache().release(entry);
    return perms;
}
Also used : Cacheable(org.apache.derby.iapi.services.cache.Cacheable)

Example 2 with Cacheable

use of org.apache.derby.iapi.services.cache.Cacheable in project derby by apache.

the class ConcurrentCache method find.

// Implementation of the CacheManager interface
/**
 * Find an object in the cache. If it is not present, add it to the
 * cache. The returned object is kept until <code>release()</code> is
 * called.
 *
 * @param key identity of the object to find
 * @return the cached object, or <code>null</code> if it cannot be found
 */
public Cacheable find(Object key) throws StandardException {
    if (stopped) {
        return null;
    }
    CacheEntry entry = getEntry(key);
    Cacheable item;
    try {
        item = entry.getCacheable();
        if (item != null) {
            // The object is already cached. Increase the use count and
            // return it.
            entry.keep(true);
            countHit();
            return item;
        } else {
            // The object is not cached. Insert the entry into a free
            // slot and retrieve a reusable Cacheable.
            item = insertIntoFreeSlot(key, entry);
            countMiss();
        }
    } finally {
        entry.unlock();
    }
    // Set the identity without holding the lock on the entry. If we
    // hold the lock, we may run into a deadlock if the user code in
    // setIdentity() re-enters the buffer manager.
    Cacheable itemWithIdentity = null;
    try {
        itemWithIdentity = item.setIdentity(key);
    } finally {
        // Always invoke settingIdentityComplete(), also on error,
        // otherwise other threads may wait forever. If setIdentity()
        // fails, itemWithIdentity is going to be null.
        settingIdentityComplete(key, entry, itemWithIdentity);
    }
    return itemWithIdentity;
}
Also used : Cacheable(org.apache.derby.iapi.services.cache.Cacheable)

Example 3 with Cacheable

use of org.apache.derby.iapi.services.cache.Cacheable in project derby by apache.

the class ConcurrentCache method discard.

/**
 * Discard all unused objects that match a partial key. Dirty objects will
 * not be cleaned before their removal.
 *
 * @param partialKey the partial (or exact) key, or <code>null</code> to
 * match all keys
 * @return <code>true</code> if all matching objects were removed,
 * <code>false</code> otherwise
 */
public boolean discard(Matchable partialKey) {
    boolean allRemoved = true;
    for (CacheEntry entry : cache.values()) {
        entry.lock();
        try {
            Cacheable c = entry.getCacheable();
            if (c == null) {
                // not in the cache - no need to remove it
                continue;
            }
            if (partialKey != null && !partialKey.match(c.getIdentity())) {
                // not a match, don't remove it
                continue;
            }
            if (entry.isKept()) {
                // still in use, don't remove it
                allRemoved = false;
                continue;
            }
            removeEntry(c.getIdentity());
        } finally {
            entry.unlock();
        }
    }
    return allRemoved;
}
Also used : Cacheable(org.apache.derby.iapi.services.cache.Cacheable)

Example 4 with Cacheable

use of org.apache.derby.iapi.services.cache.Cacheable in project derby by apache.

the class ClockPolicy method rotateClock.

/**
 * Rotate the clock in order to find a free space for a new entry. If
 * <code>allowEvictions</code> is <code>true</code>, an not recently used
 * object might be evicted to make room for the new entry. Otherwise, only
 * unused entries are searched for. When evictions are allowed, entries are
 * marked as not recently used when the clock hand sweeps over them. The
 * search stops when a reusable entry is found, or when more than a certain
 * percentage of the entries have been visited. If there are
 * free (unused) entries, the search will continue until a reusable entry
 * is found, regardless of how many entries that need to be checked.
 *
 * @param entry the entry to insert
 * @param allowEvictions tells whether evictions are allowed (normally
 * <code>true</code> if the cache is full and <code>false</code> otherwise)
 * @return a holder that we can reuse, or <code>null</code> if we didn't
 * find one
 */
private Holder rotateClock(CacheEntry entry, boolean allowEvictions) throws StandardException {
    // Calculate how many items we need to check before we give up
    // finding an evictable one. If we don't allow evictions, none should
    // be checked (however, we may search for unused entries in the loop
    // below).
    int itemsToCheck = 0;
    if (allowEvictions) {
        synchronized (clock) {
            itemsToCheck = Math.max(MIN_ITEMS_TO_CHECK, (int) (clock.size() * MAX_ROTATION));
        }
    }
    // if we know there are unused entries.
    while (itemsToCheck-- > 0 || freeEntries.get() > 0) {
        final Holder h = moveHand();
        if (h == null) {
            // reusable entry.
            return null;
        }
        final CacheEntry e = h.getEntry();
        if (e == null) {
            if (h.takeIfFree(entry)) {
                return h;
            }
            // getEntry() and takeIfFree(). Just move on to the next entry.
            continue;
        }
        if (!allowEvictions) {
            // Evictions are not allowed, so we can't reuse this entry.
            continue;
        }
        // This variable will hold a dirty cacheable that should be cleaned
        // after the try/finally block.
        final Cacheable dirty;
        e.lock();
        try {
            if (!isEvictable(e, h, true)) {
                continue;
            }
            // The entry is not in use, and has not been used for at least
            // one round on the clock. See if it needs to be cleaned.
            Cacheable c = e.getCacheable();
            if (!c.isDirty()) {
                // Not in use and not dirty. Take over the holder.
                h.switchEntry(entry);
                cacheManager.evictEntry(c.getIdentity());
                return h;
            }
            // Ask the background cleaner to clean the entry.
            BackgroundCleaner cleaner = cacheManager.getBackgroundCleaner();
            if (cleaner != null && cleaner.scheduleClean(e)) {
                // operation to finish.
                continue;
            }
            // There is no background cleaner, or the background cleaner
            // has no free capacity. Let's clean the object ourselves.
            // First, mark the entry as kept to prevent eviction until
            // we have cleaned it, but don't mark it as accessed (recently
            // used).
            e.keep(false);
            dirty = c;
        } finally {
            e.unlock();
        }
        // Clean the entry and unkeep it.
        cacheManager.cleanAndUnkeepEntry(e, dirty);
    // If no one has touched the entry while we were cleaning it, we
    // could reuse it at this point. The old buffer manager (Clock)
    // would however under high load normally move on to the next
    // entry in the clock instead of reusing the one it recently
    // cleaned. Some of the performance tests performed as part of
    // DERBY-2911 indicated that not reusing the entry that was just
    // cleaned made the replacement algorithm more efficient. For now
    // we try to stay as close to the old buffer manager as possible
    // and don't reuse the entry immediately.
    }
    return null;
}
Also used : Cacheable(org.apache.derby.iapi.services.cache.Cacheable)

Example 5 with Cacheable

use of org.apache.derby.iapi.services.cache.Cacheable in project derby by apache.

the class ClockPolicy method shrinkMe.

/**
 * Perform the shrinking of the clock. This method should only be called
 * by a single thread at a time.
 */
private void shrinkMe() {
    if (SanityManager.DEBUG) {
        SanityManager.ASSERT(isShrinking.get(), "Called shrinkMe() without ensuring exclusive access");
    }
    // Max number of candidates to look at (always at least 1).
    int maxLooks = Math.max(1, (int) (maxSize * PART_OF_CLOCK_FOR_SHRINK));
    // Since we don't scan the entire cache, start at the clock hand so
    // that we don't always scan the first 10% of the cache.
    int pos;
    synchronized (clock) {
        pos = hand;
    }
    while (maxLooks-- > 0) {
        final Holder h;
        final int size;
        // Fetch the next holder from the clock.
        synchronized (clock) {
            size = clock.size();
            if (pos >= size) {
                pos = 0;
            }
            h = clock.get(pos);
        }
        // The index of the holder we're looking at. Since no one else than
        // us can remove elements from the clock while we're in this
        // method, and new elements will be added at the end of the list,
        // the index for a holder does not change until we remove it.
        final int index = pos;
        // Let pos point at the index of the holder we'll look at in the
        // next iteration.
        pos++;
        // No need to shrink if the size isn't greater than maxSize.
        if (size <= maxSize) {
            break;
        }
        final CacheEntry e = h.getEntry();
        if (e == null) {
            // The holder does not hold an entry. Try to remove it.
            if (h.evictIfFree()) {
                removeHolder(index, h);
                // move position back because of the removal so that we
                // don't skip one clock element
                pos = index;
            }
            // to the next holder.
            continue;
        }
        e.lock();
        try {
            if (!isEvictable(e, h, false)) {
                continue;
            }
            final Cacheable c = e.getCacheable();
            if (c.isDirty()) {
                // Don't evict dirty entries.
                continue;
            }
            // mark as evicted to prevent reuse
            h.setEvicted();
            // remove from cache manager
            cacheManager.evictEntry(c.getIdentity());
            // remove from clock
            removeHolder(index, h);
            // move position back because of the removal so that we don't
            // skip one clock element
            pos = index;
        } finally {
            e.unlock();
        }
    }
}
Also used : Cacheable(org.apache.derby.iapi.services.cache.Cacheable)

Aggregations

Cacheable (org.apache.derby.iapi.services.cache.Cacheable)14 CacheManager (org.apache.derby.iapi.services.cache.CacheManager)2 PrivilegedActionException (java.security.PrivilegedActionException)1 GeneratedClass (org.apache.derby.iapi.services.loader.GeneratedClass)1 LogInstant (org.apache.derby.iapi.store.raw.log.LogInstant)1 GenericPreparedStatement (org.apache.derby.impl.sql.GenericPreparedStatement)1 StandardException (org.apache.derby.shared.common.error.StandardException)1