/** * Check whether there is a resident entry for the given key. This * method does not adjust the internal state of the cache. * * @param key the key (may not be null) * @return true if there is a resident entry */ public boolean containsKey(long key) { int hash = getHash(key); return getSegment(hash).containsKey(key, hash); }
/** * Get the value for the given key if the entry is cached. This method * adjusts the internal state of the cache sometimes, to ensure commonly * used entries stay in the cache. * * @param key the key (may not be null) * @return the value, or null if there is no resident entry */ public V get(long key) { int hash = getHash(key); return getSegment(hash).get(key, hash); }
/** * Get the memory used for the given key. * * @param key the key (may not be null) * @return the memory, or 0 if there is no resident entry */ public int getMemory(long key) { int hash = getHash(key); return getSegment(hash).getMemory(key, hash); }
private void clearCache(ByteBuffer src, long position) { if (cache.size() > 0) { int len = src.remaining(); long p = getCachePos(position); while (len > 0) { cache.remove(p); p += CACHE_BLOCK_SIZE; len -= CACHE_BLOCK_SIZE; } } }
private Entry<V> find(long key) { int hash = getHash(key); return getSegment(hash).find(key, hash); }
/** * Ensure the last entry of the stack is cold. */ private void pruneStack() { while (true) { Entry<V> last = stack.stackPrev; // must stop at a hot entry or the stack head, // but the stack head itself is also hot, so we // don't have to test it if (last.isHot()) { break; } // the cold entry is still in the queue removeFromStack(last); } }
/** * Remove all entries. */ public void clear() { long max = getMaxItemSize(); for (int i = 0; i < segmentCount; i++) { segments[i] = new Segment<>( max, stackMoveDistance, 8, nonResidentQueueSize); } }
/** * Put the page in the cache. * * @param pos the page position * @param page the page * @param memory the memory used */ void cachePage(long pos, Page page, int memory) { if (cache != null) { cache.put(pos, page, memory); } }
/** * Get the amount of memory used for caching, in MB. * Note that this does not include the page chunk references cache, which is * 25% of the size of the page cache. * * @return the amount of memory used for caching */ public int getCacheSizeUsed() { if (cache == null) { return 0; } return (int) (cache.getUsedMemory() / 1024 / 1024); }
/** * Get the maximum cache size, in MB. * Note that this does not include the page chunk references cache, which is * 25% of the size of the page cache. * * @return the cache size */ public int getCacheSize() { if (cache == null) { return 0; } return (int) (cache.getMaxMemory() / 1024 / 1024); }
/** * Get the memory used for the given key. * * @param key the key (may not be null) * @param hash the hash * @return the memory, or 0 if there is no resident entry */ int getMemory(long key, int hash) { Entry<V> e = find(key, hash); return e == null ? 0 : e.memory; }
/** * Check whether the cache is empty. * * @return true if it is empty */ public boolean isEmpty() { return size() == 0; }
/** * Evict cold entries (resident and non-resident) until the memory limit * is reached. The new entry is added as a cold entry, except if it is * the only entry. */ private void evict() { do { evictBlock(); } while (usedMemory > maxMemory); }
private static <V> Entry<V> copy(Entry<V> old) { Entry<V> e = new Entry<>(); e.key = old.key; e.value = old.value; e.memory = old.memory; e.topMove = old.topMove; return e; }
/** * Get the value for the given key if the entry is cached. This method does * not modify the internal state. * * @param key the key (may not be null) * @return the value, or null if there is no resident entry */ public V peek(long key) { Entry<V> e = find(key); return e == null ? null : e.value; }
private void addToMap(Entry<V> e) { int index = getHash(e.key) & mask; e.mapNext = entries[index]; entries[index] = e; usedMemory += e.memory; mapSize++; }
private Segment<V> getSegment(int hash) { return segments[getSegmentIndex(hash)]; }
/** * Check whether there is a resident entry for the given key. This * method does not adjust the internal state of the cache. * * @param key the key (may not be null) * @param hash the hash * @return true if there is a resident entry */ boolean containsKey(long key, int hash) { Entry<V> e = find(key, hash); return e != null && e.value != null; }