/** * @param entry Entry to touch. * @return {@code True} if queue has been changed by this call. */ private boolean touch(GridCacheEntry<K, V> entry) { Node<GridCacheEntry<K, V>> node = entry.meta(meta); // Entry has not been enqueued yet. if (node == null) { while (true) { node = queue.offerLastx(entry); if (entry.putMetaIfAbsent(meta, 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; } return true; } // If node was unlinked by concurrent shrink() call, we must repeat the whole cycle. else if (!entry.removeMeta(meta, node)) return false; } } // Entry is already in queue. return false; }
/** * @param entry Entry to touch. * @return {@code True} if new node has been added to queue by this call. */ private boolean touch(GridCacheEntry<GridGgfsBlockKey, byte[]> entry) { byte[] val = entry.peek(); int blockSize = val != null ? val.length : 0; MetaEntry meta = entry.meta(META_NODE); // Entry has not been enqueued yet. if (meta == null) { while (true) { Node<GridCacheEntry<GridGgfsBlockKey, byte[]>> node = queue.offerLastx(entry); meta = new MetaEntry(node, blockSize); if (entry.putMetaIfAbsent(META_NODE, meta) != 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; } // Increment current size. changeSize(blockSize); return true; } // If node was unlinked by concurrent shrink() call, we must repeat the whole cycle. else if (!entry.removeMeta(META_NODE, node)) return false; } } else { int oldBlockSize = meta.size(); Node<GridCacheEntry<GridGgfsBlockKey, byte[]>> node = meta.node(); if (queue.unlinkx(node)) { // Move node to tail. Node<GridCacheEntry<GridGgfsBlockKey, byte[]>> newNode = queue.offerLastx(entry); int delta = blockSize - oldBlockSize; if (!entry.replaceMeta(META_NODE, meta, new MetaEntry(newNode, blockSize))) { // Was concurrently added, need to clear it from queue. if (queue.unlinkx(newNode)) delta -= blockSize; } if (delta != 0) { changeSize(delta); if (delta > 0) // Total size increased, so shrinking could be needed. return true; } } } // Entry is already in queue. return false; }