/** @throws Exception If failed. */ public void testCreateFileColocated() throws Exception { GridGgfsPath path = new GridGgfsPath("/colocated"); UUID uuid = UUID.randomUUID(); GridUuid affKey; long idx = 0; while (true) { affKey = new GridUuid(uuid, idx); if (grid(0).mapKeyToNode(DATA_CACHE_NAME, affKey).id().equals(grid(0).localNode().id())) break; idx++; } try (GridGgfsOutputStream out = fs.create(path, 1024, true, affKey, 0, 1024, null)) { // Write 5M, should be enough to test distribution. for (int i = 0; i < 15; i++) out.write(new byte[1024 * 1024]); } GridGgfsFile info = fs.info(path); Collection<GridGgfsBlockLocation> affNodes = fs.affinity(path, 0, info.length()); assertEquals(1, affNodes.size()); Collection<UUID> nodeIds = F.first(affNodes).nodeIds(); assertEquals(1, nodeIds.size()); assertEquals(grid(0).localNode().id(), F.first(nodeIds)); }
/** * Eviction policy based on {@code First In First Out (FIFO)} algorithm. This implementation is very * efficient since it does not create any additional table-like data structures. The {@code FIFO} * ordering information is maintained by attaching ordering metadata to cache entries. */ public class GridCacheFifoEvictionPolicy<K, V> implements GridCacheEvictionPolicy<K, V>, GridCacheFifoEvictionPolicyMBean { /** Tag. */ private final String meta = UUID.randomUUID().toString(); /** Maximum size. */ private volatile int max = GridCacheConfiguration.DFLT_CACHE_SIZE; /** FIFO queue. */ private final ConcurrentLinkedDeque8<GridCacheEntry<K, V>> queue = new ConcurrentLinkedDeque8<>(); /** Constructs FIFO eviction policy with all defaults. */ public GridCacheFifoEvictionPolicy() { // No-op. } /** * Constructs FIFO eviction policy with maximum size. Empty entries are allowed. * * @param max Maximum allowed size of cache before entry will start getting evicted. */ public GridCacheFifoEvictionPolicy(int max) { A.ensure(max > 0, "max > 0"); this.max = max; } /** * Gets maximum allowed size of cache before entry will start getting evicted. * * @return Maximum allowed size of cache before entry will start getting evicted. */ @Override public int getMaxSize() { return max; } /** * Sets maximum allowed size of cache before entry will start getting evicted. * * @param max Maximum allowed size of cache before entry will start getting evicted. */ @Override public void setMaxSize(int max) { A.ensure(max > 0, "max > 0"); this.max = max; } /** {@inheritDoc} */ @Override public int getCurrentSize() { return queue.size(); } /** {@inheritDoc} */ @Override public String getMetaAttributeName() { return meta; } /** * Gets read-only view on internal {@code FIFO} queue in proper order. * * @return Read-only view ono internal {@code 'FIFO'} queue. */ public Collection<GridCacheEntry<K, V>> queue() { return Collections.unmodifiableCollection(queue); } /** {@inheritDoc} */ @Override public void onEntryAccessed(boolean rmv, GridCacheEntry<K, V> entry) { if (!rmv) { if (!entry.isCached()) return; // Shrink only if queue was changed. if (touch(entry)) shrink(); } else { Node<GridCacheEntry<K, V>> node = entry.removeMeta(meta); if (node != null) queue.unlinkx(node); } } /** * @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; } /** Shrinks FIFO queue to maximum allowed size. */ private void shrink() { int max = this.max; int startSize = queue.sizex(); for (int i = 0; i < startSize && queue.sizex() > max; i++) { GridCacheEntry<K, V> entry = queue.poll(); if (entry == null) break; if (!entry.evict()) { entry.removeMeta(meta); touch(entry); } } } /** * Checks entry for empty value. * * @param entry Entry to check. * @return {@code True} if entry is empty. */ private boolean empty(GridCacheEntry<K, V> entry) { try { return entry.peek(F.asList(GLOBAL)) == null; } catch (GridException e) { U.error(null, e.getMessage(), e); assert false : "Should never happen: " + e; return false; } } /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridCacheFifoEvictionPolicy.class, this); } }