/** {@inheritDoc} */ @Override public Map<K, V> peekAll( @Nullable Collection<? extends K> keys, @Nullable GridPredicate<? super GridCacheEntry<K, V>>[] filter) { if (keys == null || keys.isEmpty()) return emptyMap(); final Collection<K> skipped = new GridLeanSet<K>(); final Map<K, V> map = peekAll0(keys, filter, skipped); if (map.size() + skipped.size() != keys.size()) { map.putAll( dht.peekAll( F.view( keys, new P1<K>() { @Override public boolean apply(K k) { return !map.containsKey(k) && !skipped.contains(k); } }), filter)); } return map; }
/** {@inheritDoc} */ @Override public V unswap(K key) throws GridException { ctx.denyOnFlags(F.asList(READ, SKIP_SWAP)); // Unswap only from DHT. Near cache does not have swap storage. return dht.unswap(key); }
/** {@inheritDoc} */ @Override public Map<K, V> peekAll( @Nullable Collection<? extends K> keys, @Nullable Collection<GridCachePeekMode> modes) throws GridException { if (keys == null || keys.isEmpty()) return emptyMap(); final Collection<K> skipped = new GridLeanSet<K>(); final Map<K, V> map = !modes.contains(PARTITIONED_ONLY) ? peekAll0(keys, modes, ctx.tm().localTxx(), skipped) : new GridLeanMap<K, V>(0); if (map.size() != keys.size() && !modes.contains(NEAR_ONLY)) { map.putAll( dht.peekAll( F.view( keys, new P1<K>() { @Override public boolean apply(K k) { return !map.containsKey(k) && !skipped.contains(k); } }), modes)); } return map; }
/** {@inheritDoc} */ @Override public void clearAll( Collection<? extends K> keys, @Nullable GridPredicate<? super GridCacheEntry<K, V>>[] filter) { super.clearAll(keys, filter); dht.clearAll(keys, filter); }
/** {@inheritDoc} */ @SuppressWarnings({"UnnecessarySuperQualifier"}) @Override public Set<GridCacheEntry<K, V>> entrySet( @Nullable Collection<? extends K> keys, @Nullable GridPredicate<? super GridCacheEntry<K, V>>[] filter) { return new EntrySet( super.entrySet(keys, nearHasKey, filter), dht.entrySet(keys, dhtHasKey, filter)); }
/** {@inheritDoc} */ @SuppressWarnings({"unchecked"}) @Override public GridFuture<?> reloadAllAsync() { GridCompoundFuture fut = new GridCompoundFuture(ctx.kernalContext()); fut.add(super.reloadAllAsync()); fut.add(dht.reloadAllAsync()); fut.markInitialized(); return fut; }
/** {@inheritDoc} */ @SuppressWarnings({"unchecked"}) @Override public GridFuture<?> reloadAllAsync( @Nullable GridPredicate<? super GridCacheEntry<K, V>>[] filter) { GridCompoundFuture fut = new GridCompoundFuture(ctx.kernalContext()); fut.add(super.reloadAllAsync()); fut.add(dht.reloadAllAsync(filter)); fut.markInitialized(); return fut; }
/** {@inheritDoc} */ @Override public V peek(K key, @Nullable GridPredicate<? super GridCacheEntry<K, V>>[] filter) { V val; try { val = peek0(true, key, SMART, filter); } catch (GridCacheFilterFailedException ignored) { if (log.isDebugEnabled()) log.debug("Filter validation failed for key: " + key); return null; } return val == null ? dht.peek(key, filter) : val; }
/** {@inheritDoc} */ @Override public V peek(K key, @Nullable Collection<GridCachePeekMode> modes) throws GridException { V val = null; if (!modes.contains(PARTITIONED_ONLY)) { try { val = peek0(true, key, modes, ctx.tm().txx()); } catch (GridCacheFilterFailedException ignored) { if (log.isDebugEnabled()) log.debug("Filter validation failed for key: " + key); return null; } } return val == null && !modes.contains(NEAR_ONLY) ? dht.peek(key, modes) : val; }
/** {@inheritDoc} */ @Override public void reloadAll() throws GridException { super.reloadAll(); dht.reloadAll(); }
/** {@inheritDoc} */ @Override public boolean isLocked(K key) { return super.isLocked(key) || dht.isLocked(key); }
/** {@inheritDoc} */ @Override public GridCachePreloader<K, V> preloader() { return dht.preloader(); }
/** {@inheritDoc} */ @Override public Set<GridCacheEntry<K, V>> primaryEntrySet( @Nullable GridPredicate<? super GridCacheEntry<K, V>>[] filter) { return new EntrySet(super.primaryEntrySet(filter), dht.primaryEntrySet(filter)); }
/** {@inheritDoc} */ @Override public void unlockAll( Collection<? extends K> keys, GridPredicate<? super GridCacheEntry<K, V>>[] filter) { if (keys.isEmpty()) return; try { GridCacheVersion ver = null; Collection<GridRichNode> affNodes = null; int keyCnt = -1; Map<GridRichNode, GridNearUnlockRequest<K, V>> map = null; Collection<K> locKeys = new LinkedList<K>(); GridCacheVersion obsoleteVer = ctx.versions().next(); for (K key : keys) { while (true) { GridDistributedCacheEntry<K, V> entry = peekExx(key); if (entry == null || !ctx.isAll(entry.wrap(false), filter)) break; // While. try { GridCacheMvccCandidate<K> cand = entry.candidate(ctx.nodeId(), Thread.currentThread().getId()); if (cand != null) { ver = cand.version(); if (affNodes == null) { affNodes = CU.allNodes(ctx, cand.topologyVersion()); keyCnt = (int) Math.ceil((double) keys.size() / affNodes.size()); map = new HashMap<GridRichNode, GridNearUnlockRequest<K, V>>(affNodes.size()); } // Send request to remove from remote nodes. GridRichNode primary = CU.primary0(ctx.affinity(key, affNodes)); GridNearUnlockRequest<K, V> req = map.get(primary); if (req == null) { map.put(primary, req = new GridNearUnlockRequest<K, V>(keyCnt)); req.version(ver); } // Remove candidate from local node first. GridCacheMvccCandidate<K> rmv = entry.removeLock(); if (rmv != null) { if (!rmv.reentry()) { if (ver != null && !ver.equals(rmv.version())) throw new GridException( "Failed to unlock (if keys were locked separately, " + "then they need to be unlocked separately): " + keys); if (!primary.isLocal()) { assert req != null; req.addKey(entry.key(), entry.getOrMarshalKeyBytes(), ctx); } else locKeys.add(key); if (log.isDebugEnabled()) log.debug("Removed lock (will distribute): " + rmv); } else if (log.isDebugEnabled()) log.debug( "Current thread still owns lock (or there are no other nodes)" + " [lock=" + rmv + ", curThreadId=" + Thread.currentThread().getId() + ']'); } // Try to evict near entry if it's dht-mapped locally. evictNearEntry(entry, obsoleteVer); } break; } catch (GridCacheEntryRemovedException ignore) { if (log.isDebugEnabled()) log.debug("Attempted to unlock removed entry (will retry): " + entry); } } } if (ver == null) return; for (Map.Entry<GridRichNode, GridNearUnlockRequest<K, V>> mapping : map.entrySet()) { GridRichNode n = mapping.getKey(); GridDistributedUnlockRequest<K, V> req = mapping.getValue(); if (n.isLocal()) dht.removeLocks(ctx.nodeId(), req.version(), locKeys, true); else if (!req.keyBytes().isEmpty()) // We don't wait for reply to this message. ctx.io().send(n, req); } } catch (GridException ex) { U.error(log, "Failed to unlock the lock for keys: " + keys, ex); } }
/** {@inheritDoc} */ @Override public GridFuture<?> loadCacheAsync(GridPredicate2<K, V> p, long ttl, Object[] args) { return dht.loadCacheAsync(p, ttl, args); }
/** {@inheritDoc} */ @Override public boolean containsKey(K key, GridPredicate<? super GridCacheEntry<K, V>>[] filter) { return super.containsKey(key, filter) || dht.containsKey(key, filter); }
/** {@inheritDoc} */ @Override public boolean evict(K key, @Nullable GridPredicate<? super GridCacheEntry<K, V>>[] filter) { // Use unary 'and' to make sure that both sides execute. return super.evict(key, filter) & dht.evict(key, filter); }
/** {@inheritDoc} */ @Override public void loadCache(GridPredicate2<K, V> p, long ttl, Object[] args) throws GridException { dht.loadCache(p, ttl, args); }
/** {@inheritDoc} */ @Override public boolean clear(K key, @Nullable GridPredicate<? super GridCacheEntry<K, V>>[] filter) { return super.clear(key, filter) | dht.clear(key, filter); }
@Override public boolean apply(K k) { return dht.peek(k) != null; }
/** {@inheritDoc} */ @Override public void clearAll(@Nullable GridPredicate<? super GridCacheEntry<K, V>>[] filter) { super.clearAll(filter); dht.clearAll(filter); }
/** * Removes locks regardless of whether they are owned or not for given version and keys. * * @param ver Lock version. * @param keys Keys. */ @SuppressWarnings({"unchecked"}) public void removeLocks(GridCacheVersion ver, Collection<? extends K> keys) { if (keys.isEmpty()) return; try { Collection<GridRichNode> affNodes = null; int keyCnt = -1; Map<GridNode, GridNearUnlockRequest<K, V>> map = null; for (K key : keys) { // Send request to remove from remote nodes. GridNearUnlockRequest<K, V> req = null; while (true) { GridDistributedCacheEntry<K, V> entry = peekExx(key); try { if (entry != null) { GridCacheMvccCandidate<K> cand = entry.candidate(ver); if (cand != null) { if (affNodes == null) { affNodes = CU.allNodes(ctx, cand.topologyVersion()); keyCnt = (int) Math.ceil((double) keys.size() / affNodes.size()); map = new HashMap<GridNode, GridNearUnlockRequest<K, V>>(affNodes.size()); } GridRichNode primary = CU.primary0(ctx.affinity(key, affNodes)); if (!primary.isLocal()) { req = map.get(primary); if (req == null) { map.put(primary, req = new GridNearUnlockRequest<K, V>(keyCnt)); req.version(ver); } } // Remove candidate from local node first. if (entry.removeLock(cand.version())) { if (primary.isLocal()) { dht.removeLocks(primary.id(), ver, F.asList(key), true); assert req == null; continue; } req.addKey(entry.key(), entry.getOrMarshalKeyBytes(), ctx); } } } break; } catch (GridCacheEntryRemovedException ignored) { if (log.isDebugEnabled()) log.debug( "Attempted to remove lock from removed entry (will retry) [rmvVer=" + ver + ", entry=" + entry + ']'); } } } if (map == null || map.isEmpty()) return; Collection<GridCacheVersion> committed = ctx.tm().committedVersions(ver); Collection<GridCacheVersion> rolledback = ctx.tm().rolledbackVersions(ver); for (Map.Entry<GridNode, GridNearUnlockRequest<K, V>> mapping : map.entrySet()) { GridNode n = mapping.getKey(); GridDistributedUnlockRequest<K, V> req = mapping.getValue(); if (!req.keyBytes().isEmpty()) { req.completedVersions(committed, rolledback); // We don't wait for reply to this message. ctx.io().send(n, req); } } } catch (GridException ex) { U.error(log, "Failed to unlock the lock for keys: " + keys, ex); } }
/** {@inheritDoc} */ @Override public int keySize() { return super.keySize() + dht.keySize(); }