/** * @param ccfg Cache configuration. * @param objs Extra components. * @return Components provided in cache configuration which can implement {@link GridLifecycleAware} interface. */ private Iterable<Object> lifecycleAwares(GridCacheConfiguration ccfg, Object...objs) { Collection<Object> ret = new ArrayList<>(7 + objs.length); ret.add(ccfg.getAffinity()); ret.add(ccfg.getAffinityMapper()); ret.add(ccfg.getCloner()); ret.add(ccfg.getEvictionFilter()); ret.add(ccfg.getEvictionPolicy()); ret.add(ccfg.getNearEvictionPolicy()); ret.add(ccfg.getInterceptor()); Collections.addAll(ret, objs); return ret; }
/** {@inheritDoc} */ @Override public int partitions() { return cctx.config().getAffinity().partitions(); }
/** {@inheritDoc} */ @Override public void start0() throws GridException { aff = new GridAffinityAssignmentCache(cctx, cctx.namex(), cctx.config().getAffinity(), cctx.config().getAffinityMapper(), cctx.config().getBackups()); // Generate internal keys for partitions. int partCnt = partitions(); partAffKeys = new GridPartitionLockKey[partCnt]; Collection<Integer> found = new HashSet<>(); long affKey = 0; while (true) { GridPartitionLockKey key = new GridPartitionLockKey(affKey); int part = aff.partition(key); if (found.add(part)) { // This is a key for not yet calculated partition. key.partitionId(part); partAffKeys[part] = key; if (found.size() == partCnt) break; } affKey++; if (affKey > partCnt * MAX_PARTITION_KEY_ATTEMPT_RATIO) throw new IllegalStateException("Failed to calculate partition affinity keys for given affinity " + "function [attemptCnt=" + affKey + ", found=" + found + ", cacheName=" + cctx.name() + ']'); } }
/** * @param cctx Cache context. */ public GridCachePreloaderAdapter(GridCacheContext<K, V> cctx) { assert cctx != null; this.cctx = cctx; log = cctx.logger(getClass()); aff = cctx.config().getAffinity(); finFut = new GridFinishedFuture(cctx.kernalContext()); }
/** {@inheritDoc} */ @Override public GridTuple3<GridAffinityMessage, GridAffinityMessage, GridAffinityAssignment> call() throws Exception { assert grid != null; assert log != null; GridKernal kernal = ((GridKernal)grid); GridCacheContext<Object, Object> cctx = kernal.internalCache(cacheName).context(); assert cctx != null; GridKernalContext ctx = kernal.context(); return F.t( affinityMessage(ctx, cctx.config().getAffinity()), affinityMessage(ctx, cctx.config().getAffinityMapper()), new GridAffinityAssignment(topVer, cctx.affinity().assignments(topVer))); }
/** * @return {@code True} if local node can calculate affinity on it's own for this partition map exchange. */ private boolean canCalculateAffinity() { GridCacheAffinityFunction affFunc = cctx.config().getAffinity(); // Do not request affinity from remote nodes if affinity function is not centralized. if (!U.hasAnnotation(affFunc, GridCacheCentralizedAffinityFunction.class)) return true; // If local node did not initiate exchange or local node is the only cache node in grid. Collection<GridNode> affNodes = CU.affinityNodes(cctx, exchId.topologyVersion()); return !exchId.nodeId().equals(cctx.localNodeId()) || (affNodes.size() == 1 && affNodes.contains(cctx.localNode())); }
/** * @param ccfg Cache configuration. * @return Data transfer object for affinity configuration properties. */ public static VisorAffinityConfig from(GridCacheConfiguration ccfg) { GridCacheAffinityFunction aff = ccfg.getAffinity(); Integer dfltReplicas = null; Boolean excludeNeighbors = null; if (aff instanceof GridCacheConsistentHashAffinityFunction) { GridCacheConsistentHashAffinityFunction hashAffFunc = (GridCacheConsistentHashAffinityFunction)aff; dfltReplicas = hashAffFunc.getDefaultReplicas(); excludeNeighbors = hashAffFunc.isExcludeNeighbors(); } VisorAffinityConfig cfg = new VisorAffinityConfig(); cfg.function(compactClass(aff)); cfg.mapper(compactClass(ccfg.getAffinityMapper())); cfg.partitionedBackups(ccfg.getBackups()); cfg.defaultReplicas(dfltReplicas); cfg.excludeNeighbors(excludeNeighbors); return cfg; }
/** * @param node Joining node. * @return Validation result or {@code null} in case of success. */ @Nullable private GridNodeValidationResult validateHashIdResolvers(GridNode node) { for (GridCacheAdapter cache : ctx.cache().internalCaches()) { GridCacheConfiguration cfg = cache.configuration(); if (cfg.getAffinity() instanceof GridCacheConsistentHashAffinityFunction) { GridCacheConsistentHashAffinityFunction aff = (GridCacheConsistentHashAffinityFunction)cfg.getAffinity(); GridCacheAffinityNodeHashResolver hashIdRslvr = aff.getHashIdResolver(); assert hashIdRslvr != null; Object nodeHashObj = hashIdRslvr.resolve(node); for (GridNode topNode : ctx.discovery().allNodes()) { Object topNodeHashObj = hashIdRslvr.resolve(topNode); if (nodeHashObj.hashCode() == topNodeHashObj.hashCode()) { String errMsg = "Failed to add node to topology because it has the same hash code for " + "partitioned affinity as one of existing nodes [cacheName=" + cache.name() + ", hashIdResolverClass=" + hashIdRslvr.getClass().getName() + ", existingNodeId=" + topNode.id() + ']'; String sndMsg = "Failed to add node to topology because it has the same hash code for " + "partitioned affinity as one of existing nodes [cacheName=" + cache.name() + ", hashIdResolverClass=" + hashIdRslvr.getClass().getName() + ", existingNodeId=" + topNode.id() + ']'; return new GridNodeValidationResult(topNode.id(), errMsg, sndMsg); } } } } return null; }
/** * Checks that affinity keys are enlisted in group transaction on start. * * @param keys Keys to check. * @throws GridException If sanity check failed. */ private void groupLockSanityCheck(Iterable<? extends K> keys) throws GridException { if (groupLock() && cctx.kernalContext().config().isCacheSanityCheckEnabled()) { // Note that affinity is called without mapper on purpose. int affinityPart = cctx.config().getAffinity().partition(grpLockKey); for (K key : keys) { if (partitionLock()) { int part = cctx.affinity().partition(key); if (affinityPart != part) throw new GridException("Failed to enlist key into group-lock transaction (given " + "key does not belong to locked partition) [key=" + key + ", affinityPart=" + affinityPart + ", part=" + part + ", groupLockKey=" + grpLockKey + ']'); } else { Object affinityKey = cctx.config().getAffinityMapper().affinityKey(key); if (!grpLockKey.equals(affinityKey)) throw new GridException("Failed to enlist key into group-lock transaction (affinity key was " + "not enlisted to transaction on start) [key=" + key + ", affinityKey=" + affinityKey + ", groupLockKey=" + grpLockKey + ']'); } } } }
int parts = cctx.config().getAffinity().partitions();
/** * @param cctx Cache context. */ private void cleanup(GridCacheContext cctx) { GridCacheConfiguration cfg = cctx.config(); cleanup(cfg, cfg.getEvictionPolicy(), false); cleanup(cfg, cfg.getNearEvictionPolicy(), true); cleanup(cfg, cfg.getAffinity(), false); cleanup(cfg, cfg.getAffinityMapper(), false); cleanup(cfg, cctx.jta().tmLookup(), false); cleanup(cfg, cfg.getCloner(), false); cleanup(cfg, cfg.getStore(), false); cctx.cleanup(); }
/** {@inheritDoc} */ @Override public boolean onDone(Long res, Throwable err) { if (err == null) cctx.affinity().cleanUpCache(res - 10); if (super.onDone(res, err) && !dummy && !forcePreload) { if (exchId.event() == GridEventType.EVT_NODE_FAILED || exchId.event() == GridEventType.EVT_NODE_LEFT) cctx.config().getAffinity().removeNode(exchId.nodeId()); if (log.isDebugEnabled()) log.debug("Completed partition exchange [localNode=" + cctx.nodeId() + ", exchange= " + this + ']'); initFut.onDone(err == null); GridTimeoutObject timeoutObj = this.timeoutObj; // Deschedule timeout object. if (timeoutObj != null) cctx.time().removeTimeoutObject(timeoutObj); ((GridDhtPreloader<K, V>)cctx.preloader()).onExchangeDone(this); return true; } return dummy; }
cctx.config().getAffinity(), cctx.config().getAffinityMapper(), new GridAffinityAssignment(topVer, cctx.affinity().assignments(topVer)),
cfg.getDistributionMode() != NEAR_ONLY); if (cfg.getAffinity() != null) perf.add("Decrease number of backups (set 'keyBackups' to 0)", cfg.getBackups() == 0);
/** * @param cfg Configuration. * @param objs Extra components. * @throws GridException If failed to inject. */ private void prepare(GridCacheConfiguration cfg, Object... objs) throws GridException { prepare(cfg, cfg.getEvictionPolicy(), false); prepare(cfg, cfg.getNearEvictionPolicy(), true); prepare(cfg, cfg.getAffinity(), false); prepare(cfg, cfg.getAffinityMapper(), false); prepare(cfg, cfg.getCloner(), false); prepare(cfg, cfg.getStore(), false); prepare(cfg, cfg.getEvictionFilter(), false); prepare(cfg, cfg.getInterceptor(), false); GridDrSenderCacheConfiguration drSndCfg = cfg.getDrSenderConfiguration(); if (drSndCfg != null) prepare(cfg, drSndCfg.getEntryFilter(), false); GridDrReceiverCacheConfiguration drRcvCfg = cfg.getDrReceiverConfiguration(); if (drRcvCfg != null) prepare(cfg, drRcvCfg.getConflictResolver(), false); for (Object obj : objs) prepare(cfg, obj, false); }
if (cc.getAffinity() instanceof GridCachePartitionFairAffinity) throw new GridException("REPLICATED cache can not be started with GridCachePartitionFairAffinity" + " [cacheName=" + cc.getName() + ']'); if (cc.getAffinity() instanceof GridCacheConsistentHashAffinityFunction) { GridCacheConsistentHashAffinityFunction aff = (GridCacheConsistentHashAffinityFunction)cc.getAffinity(); if (cc.getAffinity() instanceof GridCacheRendezvousAffinityFunction) { GridCacheRendezvousAffinityFunction aff = (GridCacheRendezvousAffinityFunction)cc.getAffinity(); if (cc.getCacheMode() == LOCAL && !cc.getAffinity().getClass().equals(LocalAffinityFunction.class)) U.warn(log, "GridCacheAffinityFunction configuration parameter will be ignored for local cache [cacheName=" + cc.getName() + ']');
cfg.setMemoryMode(DFLT_MEMORY_MODE); if (cfg.getAffinity() == null) { if (cfg.getCacheMode() == PARTITIONED) { GridCacheConsistentHashAffinityFunction aff = new GridCacheConsistentHashAffinityFunction(); if (cfg.getAffinity() instanceof GridCacheConsistentHashAffinityFunction) { GridCacheConsistentHashAffinityFunction aff = (GridCacheConsistentHashAffinityFunction)cfg.getAffinity();
GridCacheAffinityFunction aff = cfg.getAffinity();
aff = cc.getAffinity(); affMapper = cc.getAffinityMapper(); atomicityMode = cc.getAtomicityMode();