use of org.apache.ignite.lang.IgniteBiTuple in project ignite by apache.
the class RendezvousAffinityFunction method assignPartition.
/**
* Returns collection of nodes (primary first) for specified partition.
*
* @param part Partition.
* @param nodes Nodes.
* @param backups Number of backups.
* @param neighborhoodCache Neighborhood.
* @return Assignment.
*/
public List<ClusterNode> assignPartition(int part, List<ClusterNode> nodes, int backups, @Nullable Map<UUID, Collection<ClusterNode>> neighborhoodCache) {
if (nodes.size() <= 1)
return nodes;
IgniteBiTuple<Long, ClusterNode>[] hashArr = (IgniteBiTuple<Long, ClusterNode>[]) new IgniteBiTuple[nodes.size()];
for (int i = 0; i < nodes.size(); i++) {
ClusterNode node = nodes.get(i);
Object nodeHash = resolveNodeHash(node);
long hash = hash(nodeHash.hashCode(), part);
hashArr[i] = F.t(hash, node);
}
final int primaryAndBackups = backups == Integer.MAX_VALUE ? nodes.size() : Math.min(backups + 1, nodes.size());
Iterable<ClusterNode> sortedNodes = new LazyLinearSortedContainer(hashArr, primaryAndBackups);
// REPLICATED cache case
if (backups == Integer.MAX_VALUE)
return replicatedAssign(nodes, sortedNodes);
Iterator<ClusterNode> it = sortedNodes.iterator();
List<ClusterNode> res = new ArrayList<>(primaryAndBackups);
Collection<ClusterNode> allNeighbors = new HashSet<>();
ClusterNode primary = it.next();
res.add(primary);
if (exclNeighbors)
allNeighbors.addAll(neighborhoodCache.get(primary.id()));
// Select backups.
if (backups > 0) {
while (it.hasNext() && res.size() < primaryAndBackups) {
ClusterNode node = it.next();
if (exclNeighbors) {
if (!allNeighbors.contains(node)) {
res.add(node);
allNeighbors.addAll(neighborhoodCache.get(node.id()));
}
} else if ((backupFilter != null && backupFilter.apply(primary, node)) || (affinityBackupFilter != null && affinityBackupFilter.apply(node, res)) || (affinityBackupFilter == null && backupFilter == null)) {
res.add(node);
if (exclNeighbors)
allNeighbors.addAll(neighborhoodCache.get(node.id()));
}
}
}
if (res.size() < primaryAndBackups && nodes.size() >= primaryAndBackups && exclNeighbors) {
// Need to iterate again in case if there are no nodes which pass exclude neighbors backups criteria.
it = sortedNodes.iterator();
it.next();
while (it.hasNext() && res.size() < primaryAndBackups) {
ClusterNode node = it.next();
if (!res.contains(node))
res.add(node);
}
if (!exclNeighborsWarn) {
LT.warn(log, "Affinity function excludeNeighbors property is ignored " + "because topology has no enough nodes to assign backups.", "Affinity function excludeNeighbors property is ignored " + "because topology has no enough nodes to assign backups.");
exclNeighborsWarn = true;
}
}
assert res.size() <= primaryAndBackups;
return res;
}
use of org.apache.ignite.lang.IgniteBiTuple in project ignite by apache.
the class IgniteKernal method getOrCreateCache0.
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
@Override
public <K, V> IgniteBiTuple<IgniteCache<K, V>, Boolean> getOrCreateCache0(CacheConfiguration<K, V> cacheCfg, boolean sql) {
A.notNull(cacheCfg, "cacheCfg");
CU.validateCacheName(cacheCfg.getName());
guard();
try {
checkClusterState();
Boolean res = false;
if (ctx.cache().cache(cacheCfg.getName()) == null) {
res = sql ? ctx.cache().dynamicStartSqlCache(cacheCfg).get() : ctx.cache().dynamicStartCache(cacheCfg, cacheCfg.getName(), null, false, true, true).get();
}
return new IgniteBiTuple<>((IgniteCache<K, V>) ctx.cache().publicJCache(cacheCfg.getName()), res);
} catch (IgniteCheckedException e) {
throw CU.convertToCacheException(e);
} finally {
unguard();
}
}
use of org.apache.ignite.lang.IgniteBiTuple in project ignite by apache.
the class JdbcConnection method loadConfiguration.
/**
* @param cfgUrl Config URL.
* @return Ignite config and Spring context.
*/
private IgniteBiTuple<IgniteConfiguration, ? extends GridSpringResourceContext> loadConfiguration(String cfgUrl) {
try {
IgniteBiTuple<Collection<IgniteConfiguration>, ? extends GridSpringResourceContext> cfgMap = IgnitionEx.loadConfigurations(cfgUrl);
IgniteConfiguration cfg = F.first(cfgMap.get1());
if (cfg.getIgniteInstanceName() == null)
cfg.setIgniteInstanceName("ignite-jdbc-driver-" + UUID.randomUUID().toString());
// Force client mode.
cfg.setClientMode(true);
return new IgniteBiTuple<>(cfg, cfgMap.getValue());
} catch (IgniteCheckedException e) {
throw new IgniteException(e);
}
}
use of org.apache.ignite.lang.IgniteBiTuple in project ignite by apache.
the class GridCacheAdapter method getAllAsync0.
/**
* @param keys Keys.
* @param readerArgs Near cache reader will be added if not null.
* @param readThrough Read-through flag.
* @param checkTx Check local transaction flag.
* @param subjId Subject ID.
* @param taskName Task name/
* @param deserializeBinary Deserialize binary flag.
* @param expiry Expiry policy.
* @param skipVals Skip values flag.
* @param keepCacheObjects Keep cache objects.
* @param canRemap Can remap flag.
* @param needVer If {@code true} returns values as tuples containing value and version.
* @return Future.
*/
protected final <K1, V1> IgniteInternalFuture<Map<K1, V1>> getAllAsync0(@Nullable final Collection<KeyCacheObject> keys, @Nullable final ReaderArguments readerArgs, final boolean readThrough, boolean checkTx, @Nullable final UUID subjId, final String taskName, final boolean deserializeBinary, @Nullable final IgniteCacheExpiryPolicy expiry, final boolean skipVals, final boolean keepCacheObjects, final boolean recovery, boolean canRemap, final boolean needVer) {
if (F.isEmpty(keys))
return new GridFinishedFuture<>(Collections.<K1, V1>emptyMap());
GridNearTxLocal tx = null;
if (checkTx) {
try {
checkJta();
} catch (IgniteCheckedException e) {
return new GridFinishedFuture<>(e);
}
tx = ctx.tm().threadLocalTx(ctx.systemTx() ? ctx : null);
}
if (tx == null || tx.implicit()) {
Map<KeyCacheObject, EntryGetResult> misses = null;
final AffinityTopologyVersion topVer = tx == null ? (canRemap ? ctx.affinity().affinityTopologyVersion() : ctx.shared().exchange().readyAffinityVersion()) : tx.topologyVersion();
try {
int keysSize = keys.size();
GridDhtTopologyFuture topFut = ctx.shared().exchange().lastFinishedFuture();
Throwable ex = topFut != null ? topFut.validateCache(ctx, recovery, /*read*/
true, null, keys) : null;
if (ex != null)
return new GridFinishedFuture<>(ex);
final Map<K1, V1> map = keysSize == 1 ? (Map<K1, V1>) new IgniteBiTuple<>() : U.<K1, V1>newHashMap(keysSize);
final boolean storeEnabled = !skipVals && readThrough && ctx.readThrough();
boolean readNoEntry = ctx.readNoEntry(expiry, readerArgs != null);
for (KeyCacheObject key : keys) {
while (true) {
try {
EntryGetResult res = null;
boolean evt = !skipVals;
boolean updateMetrics = !skipVals;
GridCacheEntryEx entry = null;
boolean skipEntry = readNoEntry;
if (readNoEntry) {
CacheDataRow row = ctx.offheap().read(key);
if (row != null) {
long expireTime = row.expireTime();
if (expireTime != 0) {
if (expireTime > U.currentTimeMillis()) {
res = new EntryGetWithTtlResult(row.value(), row.version(), false, expireTime, 0);
} else
skipEntry = false;
} else
res = new EntryGetResult(row.value(), row.version(), false);
}
if (res != null) {
if (evt) {
ctx.events().readEvent(key, null, row.value(), subjId, taskName, !deserializeBinary);
}
if (updateMetrics && ctx.cache().configuration().isStatisticsEnabled())
ctx.cache().metrics0().onRead(true);
} else if (storeEnabled)
skipEntry = false;
}
if (!skipEntry) {
entry = entryEx(key);
if (entry == null) {
if (!skipVals && ctx.config().isStatisticsEnabled())
ctx.cache().metrics0().onRead(false);
break;
}
if (storeEnabled) {
res = entry.innerGetAndReserveForLoad(updateMetrics, evt, subjId, taskName, expiry, !deserializeBinary, readerArgs);
assert res != null;
if (res.value() == null) {
if (misses == null)
misses = new HashMap<>();
misses.put(key, res);
res = null;
}
} else {
res = entry.innerGetVersioned(null, null, updateMetrics, evt, subjId, null, taskName, expiry, !deserializeBinary, readerArgs);
if (res == null)
ctx.evicts().touch(entry, topVer);
}
}
if (res != null) {
ctx.addResult(map, key, res, skipVals, keepCacheObjects, deserializeBinary, true, needVer);
if (entry != null && (tx == null || (!tx.implicit() && tx.isolation() == READ_COMMITTED)))
ctx.evicts().touch(entry, topVer);
if (keysSize == 1)
// Safe to return because no locks are required in READ_COMMITTED mode.
return new GridFinishedFuture<>(map);
}
break;
} catch (GridCacheEntryRemovedException ignored) {
if (log.isDebugEnabled())
log.debug("Got removed entry in getAllAsync(..) method (will retry): " + key);
}
}
}
if (storeEnabled && misses != null) {
final Map<KeyCacheObject, EntryGetResult> loadKeys = misses;
final IgniteTxLocalAdapter tx0 = tx;
final Collection<KeyCacheObject> loaded = new HashSet<>();
return new GridEmbeddedFuture(ctx.closures().callLocalSafe(ctx.projectSafe(new GPC<Map<K1, V1>>() {
@Override
public Map<K1, V1> call() throws Exception {
ctx.store().loadAll(null, /*tx*/
loadKeys.keySet(), new CI2<KeyCacheObject, Object>() {
@Override
public void apply(KeyCacheObject key, Object val) {
EntryGetResult res = loadKeys.get(key);
if (res == null || val == null)
return;
loaded.add(key);
CacheObject cacheVal = ctx.toCacheObject(val);
while (true) {
GridCacheEntryEx entry = null;
try {
ctx.shared().database().ensureFreeSpace(ctx.memoryPolicy());
entry = entryEx(key);
entry.unswap();
EntryGetResult verVal = entry.versionedValue(cacheVal, res.version(), null, expiry, readerArgs);
if (log.isDebugEnabled())
log.debug("Set value loaded from store into entry [" + "oldVer=" + res.version() + ", newVer=" + verVal.version() + ", " + "entry=" + entry + ']');
// Don't put key-value pair into result map if value is null.
if (verVal.value() != null) {
ctx.addResult(map, key, verVal, skipVals, keepCacheObjects, deserializeBinary, true, needVer);
}
if (tx0 == null || (!tx0.implicit() && tx0.isolation() == READ_COMMITTED))
ctx.evicts().touch(entry, topVer);
break;
} catch (GridCacheEntryRemovedException ignore) {
if (log.isDebugEnabled())
log.debug("Got removed entry during getAllAsync (will retry): " + entry);
} catch (IgniteCheckedException e) {
// Wrap errors (will be unwrapped).
throw new GridClosureException(e);
}
}
}
});
if (loaded.size() != loadKeys.size()) {
boolean needTouch = tx0 == null || (!tx0.implicit() && tx0.isolation() == READ_COMMITTED);
for (Map.Entry<KeyCacheObject, EntryGetResult> e : loadKeys.entrySet()) {
if (loaded.contains(e.getKey()))
continue;
if (needTouch || e.getValue().reserved()) {
GridCacheEntryEx entry = peekEx(e.getKey());
if (entry != null) {
if (e.getValue().reserved())
entry.clearReserveForLoad(e.getValue().version());
if (needTouch)
ctx.evicts().touch(entry, topVer);
}
}
}
}
return map;
}
}), true), new C2<Map<K, V>, Exception, IgniteInternalFuture<Map<K, V>>>() {
@Override
public IgniteInternalFuture<Map<K, V>> apply(Map<K, V> map, Exception e) {
if (e != null)
return new GridFinishedFuture<>(e);
if (tx0 == null || (!tx0.implicit() && tx0.isolation() == READ_COMMITTED)) {
Collection<KeyCacheObject> notFound = new HashSet<>(loadKeys.keySet());
notFound.removeAll(loaded);
// Touch entries that were not found in store.
for (KeyCacheObject key : notFound) {
GridCacheEntryEx entry = peekEx(key);
if (entry != null)
ctx.evicts().touch(entry, topVer);
}
}
// There were no misses.
return new GridFinishedFuture<>(Collections.<K, V>emptyMap());
}
}, new C2<Map<K1, V1>, Exception, Map<K1, V1>>() {
@Override
public Map<K1, V1> apply(Map<K1, V1> loaded, Exception e) {
if (e == null)
map.putAll(loaded);
return map;
}
});
} else
// Misses can be non-zero only if store is enabled.
assert misses == null;
return new GridFinishedFuture<>(map);
} catch (RuntimeException | AssertionError e) {
if (misses != null) {
for (KeyCacheObject key0 : misses.keySet()) ctx.evicts().touch(peekEx(key0), topVer);
}
return new GridFinishedFuture<>(e);
} catch (IgniteCheckedException e) {
return new GridFinishedFuture<>(e);
}
} else {
return asyncOp(tx, new AsyncOp<Map<K1, V1>>(keys) {
@Override
public IgniteInternalFuture<Map<K1, V1>> op(GridNearTxLocal tx, AffinityTopologyVersion readyTopVer) {
return tx.getAllAsync(ctx, readyTopVer, keys, deserializeBinary, skipVals, false, !readThrough, recovery, needVer);
}
}, ctx.operationContextPerCall(), /*retry*/
false);
}
}
use of org.apache.ignite.lang.IgniteBiTuple in project ignite by apache.
the class GridCacheQueryManager method runQuery.
/**
* Processes cache query request.
*
* @param qryInfo Query info.
*/
@SuppressWarnings("unchecked")
protected void runQuery(GridCacheQueryInfo qryInfo) {
assert qryInfo != null;
assert qryInfo.query().type() != SCAN || !qryInfo.local() : qryInfo;
if (!enterBusy()) {
if (cctx.localNodeId().equals(qryInfo.senderId()))
throw new IllegalStateException("Failed to process query request (grid is stopping).");
// Ignore remote requests when when node is stopping.
return;
}
try {
boolean loc = qryInfo.local();
QueryResult<K, V> res = null;
if (log.isDebugEnabled())
log.debug("Running query: " + qryInfo);
boolean rmvIter = true;
try {
// Preparing query closures.
IgniteClosure<Cache.Entry<K, V>, Object> trans = (IgniteClosure<Cache.Entry<K, V>, Object>) qryInfo.transformer();
IgniteReducer<Cache.Entry<K, V>, Object> rdc = (IgniteReducer<Cache.Entry<K, V>, Object>) qryInfo.reducer();
injectResources(trans);
injectResources(rdc);
GridCacheQueryAdapter<?> qry = qryInfo.query();
int pageSize = qry.pageSize();
boolean incBackups = qry.includeBackups();
String taskName = cctx.kernalContext().task().resolveTaskName(qry.taskHash());
IgniteSpiCloseableIterator<IgniteBiTuple<K, V>> iter;
GridCacheQueryType type;
res = loc ? executeQuery(qry, qryInfo.arguments(), loc, qry.subjectId(), taskName, recipient(qryInfo.senderId(), qryInfo.requestId())) : queryResult(qryInfo, taskName);
if (res == null)
return;
iter = res.iterator(recipient(qryInfo.senderId(), qryInfo.requestId()));
type = res.type();
final GridCacheAdapter<K, V> cache = cctx.cache();
if (log.isDebugEnabled())
log.debug("Received index iterator [iterHasNext=" + iter.hasNext() + ", cacheSize=" + cache.size() + ']');
int cnt = 0;
boolean stop = false;
boolean pageSent = false;
Collection<Object> data = new ArrayList<>(pageSize);
AffinityTopologyVersion topVer = cctx.affinity().affinityTopologyVersion();
final boolean statsEnabled = cctx.config().isStatisticsEnabled();
final boolean readEvt = cctx.gridEvents().isRecordable(EVT_CACHE_QUERY_OBJECT_READ);
while (!Thread.currentThread().isInterrupted() && iter.hasNext()) {
long start = statsEnabled ? System.nanoTime() : 0L;
IgniteBiTuple<K, V> row = iter.next();
// Query is cancelled.
if (row == null) {
onPageReady(loc, qryInfo, null, true, null);
break;
}
final K key = row.getKey();
// Other types are filtered in indexing manager.
if (!cctx.isReplicated() && qry.type() == SCAN && qry.partition() == null && cctx.config().getCacheMode() != LOCAL && !incBackups && !cctx.affinity().primaryByKey(cctx.localNode(), key, topVer)) {
if (log.isDebugEnabled())
log.debug("Ignoring backup element [row=" + row + ", cacheMode=" + cctx.config().getCacheMode() + ", incBackups=" + incBackups + ", primary=" + cctx.affinity().primaryByKey(cctx.localNode(), key, topVer) + ']');
continue;
}
V val = row.getValue();
if (log.isDebugEnabled()) {
ClusterNode primaryNode = cctx.affinity().primaryByKey(key, cctx.affinity().affinityTopologyVersion());
log.debug(S.toString("Record", "key", key, true, "val", val, true, "incBackups", incBackups, false, "priNode", primaryNode != null ? U.id8(primaryNode.id()) : null, false, "node", U.id8(cctx.localNode().id()), false));
}
if (val == null) {
if (log.isDebugEnabled())
log.debug(S.toString("Unsuitable record value", "val", val, true));
continue;
}
if (statsEnabled) {
CacheMetricsImpl metrics = cctx.cache().metrics0();
metrics.onRead(true);
metrics.addGetTimeNanos(System.nanoTime() - start);
}
K key0 = null;
V val0 = null;
if (readEvt) {
key0 = (K) cctx.unwrapBinaryIfNeeded(key, qry.keepBinary());
val0 = (V) cctx.unwrapBinaryIfNeeded(val, qry.keepBinary());
switch(type) {
case SQL:
cctx.gridEvents().record(new CacheQueryReadEvent<>(cctx.localNode(), "SQL query entry read.", EVT_CACHE_QUERY_OBJECT_READ, CacheQueryType.SQL.name(), cctx.name(), qry.queryClassName(), qry.clause(), null, null, qryInfo.arguments(), qry.subjectId(), taskName, key0, val0, null, null));
break;
case TEXT:
cctx.gridEvents().record(new CacheQueryReadEvent<>(cctx.localNode(), "Full text query entry read.", EVT_CACHE_QUERY_OBJECT_READ, CacheQueryType.FULL_TEXT.name(), cctx.name(), qry.queryClassName(), qry.clause(), null, null, null, qry.subjectId(), taskName, key0, val0, null, null));
break;
case SCAN:
cctx.gridEvents().record(new CacheQueryReadEvent<>(cctx.localNode(), "Scan query entry read.", EVT_CACHE_QUERY_OBJECT_READ, CacheQueryType.SCAN.name(), cctx.name(), null, null, qry.scanFilter(), null, null, qry.subjectId(), taskName, key0, val0, null, null));
break;
}
}
if (rdc != null || trans != null) {
if (key0 == null)
key0 = (K) cctx.unwrapBinaryIfNeeded(key, qry.keepBinary());
if (val0 == null)
val0 = (V) cctx.unwrapBinaryIfNeeded(val, qry.keepBinary());
Cache.Entry<K, V> entry = new CacheEntryImpl(key0, val0);
// Reduce.
if (rdc != null) {
if (!rdc.collect(entry) || !iter.hasNext()) {
onPageReady(loc, qryInfo, Collections.singletonList(rdc.reduce()), true, null);
pageSent = true;
break;
} else
continue;
}
data.add(trans != null ? trans.apply(entry) : !loc ? new GridCacheQueryResponseEntry<>(key, val) : F.t(key, val));
} else
data.add(!loc ? new GridCacheQueryResponseEntry<>(key, val) : F.t(key, val));
if (!loc) {
if (++cnt == pageSize || !iter.hasNext()) {
boolean finished = !iter.hasNext();
onPageReady(loc, qryInfo, data, finished, null);
pageSent = true;
if (!finished)
rmvIter = false;
if (!qryInfo.allPages())
return;
data = new ArrayList<>(pageSize);
if (stop)
// while
break;
}
}
}
if (!pageSent) {
if (rdc == null)
onPageReady(loc, qryInfo, data, true, null);
else
onPageReady(loc, qryInfo, Collections.singletonList(rdc.reduce()), true, null);
}
} catch (Throwable e) {
if (!X.hasCause(e, GridDhtUnreservedPartitionException.class))
U.error(log, "Failed to run query [qry=" + qryInfo + ", node=" + cctx.nodeId() + "]", e);
onPageReady(loc, qryInfo, null, true, e);
if (e instanceof Error)
throw (Error) e;
} finally {
if (loc) {
// Local iterators are always removed.
if (res != null) {
try {
res.closeIfNotShared(recipient(qryInfo.senderId(), qryInfo.requestId()));
} catch (IgniteCheckedException e) {
if (!X.hasCause(e, GridDhtUnreservedPartitionException.class))
U.error(log, "Failed to close local iterator [qry=" + qryInfo + ", node=" + cctx.nodeId() + "]", e);
}
}
} else if (rmvIter)
removeQueryResult(qryInfo.senderId(), qryInfo.requestId());
}
} finally {
leaveBusy();
}
}
Aggregations