use of org.apache.ignite.internal.cache.query.index.sorted.SortedIndexDefinition in project ignite by apache.
the class IndexQueryProcessor method queryLocal.
/**
* Run query on local node.
*
* @return Query result that contains data iterator and related metadata.
*/
public <K, V> IndexQueryResult<K, V> queryLocal(GridCacheContext<K, V> cctx, IndexQueryDesc idxQryDesc, @Nullable IgniteBiPredicate<K, V> filter, IndexingQueryFilter cacheFilter, boolean keepBinary) throws IgniteCheckedException {
SortedSegmentedIndex idx = findSortedIndex(cctx, idxQryDesc);
IndexRangeQuery qry = prepareQuery(idx, idxQryDesc);
GridCursor<IndexRow> cursor = querySortedIndex(cctx, idx, cacheFilter, qry);
SortedIndexDefinition def = (SortedIndexDefinition) idxProc.indexDefinition(idx.id());
IndexQueryResultMeta meta = new IndexQueryResultMeta(def, qry.criteria.length);
// Map IndexRow to Cache Key-Value pair.
return new IndexQueryResult<>(meta, new GridCloseableIteratorAdapter<IgniteBiTuple<K, V>>() {
private IgniteBiTuple<K, V> currVal;
private final CacheObjectContext coctx = cctx.cacheObjectContext();
/**
* {@inheritDoc}
*/
@Override
protected boolean onHasNext() throws IgniteCheckedException {
if (currVal != null)
return true;
while (currVal == null && cursor.next()) {
IndexRow r = cursor.get();
K k = unwrap(r.cacheDataRow().key(), true);
V v = unwrap(r.cacheDataRow().value(), true);
if (filter != null) {
K k0 = keepBinary ? k : unwrap(r.cacheDataRow().key(), false);
V v0 = keepBinary ? v : unwrap(r.cacheDataRow().value(), false);
if (!filter.apply(k0, v0))
continue;
}
currVal = new IgniteBiTuple<>(k, v);
}
return currVal != null;
}
/**
* {@inheritDoc}
*/
@Override
protected IgniteBiTuple<K, V> onNext() {
if (currVal == null)
if (!hasNext())
throw new NoSuchElementException();
IgniteBiTuple<K, V> row = currVal;
currVal = null;
return row;
}
/**
*/
private <T> T unwrap(CacheObject o, boolean keepBinary) {
return (T) CacheObjectUtils.unwrapBinaryIfNeeded(coctx, o, keepBinary, false);
}
});
}
use of org.apache.ignite.internal.cache.query.index.sorted.SortedIndexDefinition in project ignite by apache.
the class IndexingDefragmentation method defragmentTable.
/**
* Defragment one given table.
*/
private boolean defragmentTable(CacheGroupContext newCtx, IntMap<LinkMap> mappingByPartition, CheckpointTimeoutLock cpLock, Runnable cancellationChecker, int pageSize, PageMemoryEx oldCachePageMem, PageMemory newCachePageMemory, long cpLockThreshold, AtomicLong lastCpLockTs, TableIndexes indexes) throws IgniteCheckedException {
cpLock.checkpointReadLock();
try {
TreeIterator treeIterator = new TreeIterator(pageSize);
GridCacheContext<?, ?> cctx = indexes.cctx;
cancellationChecker.run();
for (InlineIndex oldIdx : indexes.idxs) {
InlineIndexRowHandler oldRowHnd = oldIdx.segment(0).rowHandler();
SortedIndexDefinition idxDef = (SortedIndexDefinition) indexing.indexDefinition(oldIdx.id());
InlineIndexImpl newIdx = new DefragIndexFactory(newCtx.offheap(), newCachePageMemory, oldIdx).createIndex(cctx, idxDef).unwrap(InlineIndexImpl.class);
int segments = oldIdx.segmentsCount();
for (int i = 0; i < segments; ++i) {
treeIterator.iterate(oldIdx.segment(i), oldCachePageMem, (theTree, io, pageAddr, idx) -> {
cancellationChecker.run();
if (System.currentTimeMillis() - lastCpLockTs.get() >= cpLockThreshold) {
cpLock.checkpointReadUnlock();
cpLock.checkpointReadLock();
lastCpLockTs.set(System.currentTimeMillis());
}
assert 1 == io.getVersion() : "IO version " + io.getVersion() + " is not supported by current defragmentation algorithm." + " Please implement copying of tree in a new format.";
BPlusIO<IndexRow> h2IO = DefragIndexFactory.wrap(io, oldRowHnd);
IndexRow row = theTree.getRow(h2IO, pageAddr, idx);
if (row instanceof DefragIndexRowImpl) {
DefragIndexRowImpl r = (DefragIndexRowImpl) row;
CacheDataRow cacheDataRow = r.cacheDataRow();
int partition = cacheDataRow.partition();
long link = r.link();
LinkMap map = mappingByPartition.get(partition);
long newLink = map.get(link);
// Use old row handler, as MetaInfo is copied from old tree.
DefragIndexRowImpl newRow = DefragIndexRowImpl.create(oldRowHnd, newLink, r, ((MvccIO) io).storeMvccInfo());
newIdx.putIndexRow(newRow);
}
return true;
});
}
}
return true;
} catch (Throwable t) {
newCtx.cacheObjectContext().kernalContext().failure().process(new FailureContext(CRITICAL_ERROR, t));
throw t;
} finally {
cpLock.checkpointReadUnlock();
}
}
use of org.apache.ignite.internal.cache.query.index.sorted.SortedIndexDefinition in project ignite by apache.
the class RenameIndexTreeTest method testPersistRenamingIndexRootPage.
/**
* Checking that the renamed index root pages after the checkpoint will be
* correctly restored and found after the node is restarted.
*
* @throws Exception If failed.
*/
@Test
public void testPersistRenamingIndexRootPage() throws Exception {
IgniteEx n = startGrid(0);
IgniteCache<Integer, Person> cache = n.cache(DEFAULT_CACHE_NAME);
populate(cache, 100);
String idxName = "IDX0";
createIdx(cache, idxName);
SortedIndexDefinition idxDef = indexDefinition(index(n, cache, idxName));
String oldTreeName = idxDef.treeName();
String newTreeName = UUID.randomUUID().toString();
int segments = idxDef.segments();
assertEquals(segments, renameIndexRoot(cache, oldTreeName, newTreeName, segments).size());
forceCheckpoint();
stopGrid(0);
n = startGrid(0);
cache = n.cache(DEFAULT_CACHE_NAME);
assertExistIndexRoot(cache, oldTreeName, segments, true);
assertExistIndexRoot(cache, newTreeName, segments, true);
}
use of org.apache.ignite.internal.cache.query.index.sorted.SortedIndexDefinition in project ignite by apache.
the class RenameIndexTreeTest method testIndexRenameRootPageRecord.
/**
* Checking applying {@link IndexRenameRootPageRecord}.
*
* @throws Exception If failed.
*/
@Test
public void testIndexRenameRootPageRecord() throws Exception {
IgniteEx n = startGrid(0);
IgniteCache<Integer, Person> cache = n.cache(DEFAULT_CACHE_NAME);
populate(cache, 100);
String idxName = "IDX0";
createIdx(cache, idxName);
enableCheckpoints(n, getTestIgniteInstanceName(), false);
SortedIndexDefinition idxDef = indexDefinition(index(n, cache, idxName));
String oldTreeName = idxDef.treeName();
String newTreeName = UUID.randomUUID().toString();
int segments = idxDef.segments();
int cacheId = cacheContext(cache).cacheId();
IndexRenameRootPageRecord r = new IndexRenameRootPageRecord(cacheId, oldTreeName, newTreeName, segments);
walMgr(n).log(r);
Set<Integer> cacheIds = n.context().cache().cacheNames().stream().map(CU::cacheId).collect(toSet());
int fakeCacheId = cacheIds.stream().mapToInt(Integer::intValue).sum();
while (cacheIds.contains(fakeCacheId)) fakeCacheId++;
// Check that the node does not crash when trying to apply a logical record with a non-existing cacheId.
walMgr(n).log(new IndexRenameRootPageRecord(fakeCacheId, oldTreeName, newTreeName, segments));
stopGrid(0);
n = startGrid(0);
cache = n.cache(DEFAULT_CACHE_NAME);
assertExistIndexRoot(cache, oldTreeName, segments, false);
assertExistIndexRoot(cache, newTreeName, segments, true);
}
use of org.apache.ignite.internal.cache.query.index.sorted.SortedIndexDefinition in project ignite by apache.
the class IndexQueryProcessor method querySortedIndex.
/**
* Runs an index query.
*
* @return Result cursor.
*/
private GridCursor<IndexRow> querySortedIndex(GridCacheContext<?, ?> cctx, SortedSegmentedIndex idx, IndexingQueryFilter cacheFilter, IndexRangeQuery qry) throws IgniteCheckedException {
int segmentsCnt = cctx.isPartitioned() ? cctx.config().getQueryParallelism() : 1;
BPlusTree.TreeRowClosure<IndexRow, IndexRow> treeFilter = null;
// Also skips filtering if the current search is unbounded (both boundaries equal to null).
if (qry.criteria.length > 1 && !(qry.lower == null && qry.upper == null)) {
LinkedHashMap<String, IndexKeyDefinition> idxDef = idxProc.indexDefinition(idx.id()).indexKeyDefinitions();
treeFilter = new IndexQueryCriteriaClosure(qry, idxDef, ((SortedIndexDefinition) idxProc.indexDefinition(idx.id())).rowComparator());
}
IndexQueryContext qryCtx = new IndexQueryContext(cacheFilter, treeFilter, null);
if (segmentsCnt == 1)
return treeIndexRange(idx, 0, qry, qryCtx);
final GridCursor<IndexRow>[] segmentCursors = new GridCursor[segmentsCnt];
// Actually it just traverses BPlusTree to find boundaries. It's too fast to parallelize this.
for (int i = 0; i < segmentsCnt; i++) segmentCursors[i] = treeIndexRange(idx, i, qry, qryCtx);
return new SegmentedIndexCursor(segmentCursors, (SortedIndexDefinition) idxProc.indexDefinition(idx.id()));
}
Aggregations