/** Shrinks queue to maximum allowed size. */ private void shrink() { long maxMem = this.maxMemSize; if (maxMem > 0) { long startMemSize = memSize.longValue(); if (startMemSize >= maxMem) for (long i = maxMem; i < startMemSize && memSize.longValue() > maxMem; ) { int size = shrink0(); if (size == -1) break; i += size; } } int max = this.max; if (max > 0) { int startSize = queue.sizex(); if (startSize >= max + (maxMem > 0 ? 1 : this.batchSize)) for (int i = max; i < startSize && queue.sizex() > max; i++) if (shrink0() == -1) break; } }
/** @param entry Entry to add. */ void onAdded(GridDhtCacheEntry entry) { GridDhtPartitionState state = state(); if (state == EVICTED) throw new GridDhtInvalidPartitionException( id, "Adding entry to invalid partition [part=" + id + ']'); map.put(entry.key(), entry); if (!entry.isInternal()) mapPubSize.increment(); }
/** @param entry Entry to remove. */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") void onRemoved(GridDhtCacheEntry entry) { assert entry.obsolete(); // Make sure to remove exactly this entry. synchronized (entry) { map.remove(entry.key(), entry); if (!entry.isInternal() && !entry.deleted()) mapPubSize.decrement(); } // Attempt to evict. tryEvict(true); }
/** {@inheritDoc} */ @Override public void onEntryAccessed(boolean rmv, EvictableEntry<K, V> entry) { if (!rmv) { if (!entry.isCached()) return; if (touch(entry)) shrink(); } else { Node<EvictableEntry<K, V>> node = entry.removeMeta(); if (node != null) { queue.unlinkx(node); memSize.add(-entry.size()); } } }
/** * Tries to remove one item from queue. * * @return number of bytes that was free. {@code -1} if queue is empty. */ private int shrink0() { EvictableEntry<K, V> entry = queue.poll(); if (entry == null) return -1; int size = 0; Node<EvictableEntry<K, V>> meta = entry.removeMeta(); if (meta != null) { size = entry.size(); memSize.add(-size); if (!entry.evict()) touch(entry); } return size; }
/** * @param entry Entry to touch. * @return {@code True} if new node has been added to queue by this call. */ private boolean touch(EvictableEntry<K, V> entry) { Node<EvictableEntry<K, V>> node = entry.meta(); // Entry has not been enqueued yet. if (node == null) { while (true) { node = queue.offerLastx(entry); if (entry.putMetaIfAbsent(node) != null) { // Was concurrently added, need to clear it from queue. queue.unlinkx(node); // Queue has not been changed. return false; } else if (node.item() != null) { if (!entry.isCached()) { // Was concurrently evicted, need to clear it from queue. queue.unlinkx(node); return false; } memSize.add(entry.size()); return true; } // If node was unlinked by concurrent shrink() call, we must repeat the whole cycle. else if (!entry.removeMeta(node)) return false; } } else if (queue.unlinkx(node)) { // Move node to tail. Node<EvictableEntry<K, V>> newNode = queue.offerLastx(entry); if (!entry.replaceMeta(node, newNode)) // Was concurrently added, need to clear it from queue. queue.unlinkx(newNode); } // Entry is already in queue. return false; }
/** {@inheritDoc} */ @Override public long getCurrentMemorySize() { return memSize.longValue(); }
/** Clears values for this partition. */ private void clearAll() { GridCacheVersion clearVer = cctx.versions().next(); boolean swap = cctx.isSwapOrOffheapEnabled(); boolean rec = cctx.events().isRecordable(EVT_CACHE_REBALANCE_OBJECT_UNLOADED); Iterator<GridDhtCacheEntry> it = map.values().iterator(); GridCloseableIterator<Map.Entry<byte[], GridCacheSwapEntry>> swapIt = null; if (swap && GridQueryProcessor.isEnabled(cctx.config())) { // Indexing needs to unswap cache values. Iterator<GridDhtCacheEntry> unswapIt = null; try { swapIt = cctx.swap().iterator(id); unswapIt = unswapIterator(swapIt); } catch (Exception e) { U.error(log, "Failed to clear swap for evicted partition: " + this, e); } if (unswapIt != null) it = F.concat(it, unswapIt); } try { while (it.hasNext()) { GridDhtCacheEntry cached = it.next(); try { if (cached.clearInternal(clearVer, swap)) { map.remove(cached.key(), cached); if (!cached.isInternal()) { mapPubSize.decrement(); if (rec) cctx.events() .addEvent( cached.partition(), cached.key(), cctx.localNodeId(), (IgniteUuid) null, null, EVT_CACHE_REBALANCE_OBJECT_UNLOADED, null, false, cached.rawGet(), cached.hasValue(), null, null, null); } } } catch (IgniteCheckedException e) { U.error(log, "Failed to clear cache entry for evicted partition: " + cached, e); } } } finally { U.close(swapIt, log); } }
/** @return Number of public (non-internal) entries in this partition. */ public int publicSize() { return mapPubSize.intValue(); }
/** Decrements public size of the map. */ public void decrementPublicSize() { mapPubSize.decrement(); }
/** Increments public size of the map. */ public void incrementPublicSize() { mapPubSize.increment(); }