use of org.apache.ignite.internal.cache.query.index.sorted.inline.InlineIndexTree in project ignite by apache.
the class DefragIndexFactory method createIndexSegment.
/**
* {@inheritDoc}
*/
@Override
protected InlineIndexTree createIndexSegment(GridCacheContext<?, ?> cctx, SortedIndexDefinition def, RootPage rootPage, IoStatisticsHolder stats, InlineRecommender recommender, int segmentNum) throws Exception {
InlineIndexTree tree = new InlineIndexTree(def, cctx.group(), def.treeName(), offheap, offheap.reuseListForIndex(def.treeName()), newCachePageMemory, // Use old row handler to have access to inline index key types.
pageIoResolver(), rootPage.pageId().pageId(), rootPage.isAllocated(), oldIdx.inlineSize(), cctx.config().getSqlIndexMaxInlineSize(), def.keyTypeSettings(), null, stats, rowHndFactory, null);
final MetaPageInfo oldInfo = oldIdx.segment(segmentNum).metaInfo();
// Set IO wrappers for the new tree.
BPlusInnerIO<IndexRow> innerIO = (BPlusInnerIO<IndexRow>) wrap(tree.latestInnerIO(), tree.rowHandler());
BPlusLeafIO<IndexRow> leafIo = (BPlusLeafIO<IndexRow>) wrap(tree.latestLeafIO(), tree.rowHandler());
tree.setIos(new IOVersions<>(innerIO), new IOVersions<>(leafIo));
tree.copyMetaInfo(oldInfo);
tree.enableSequentialWriteMode();
return tree;
}
use of org.apache.ignite.internal.cache.query.index.sorted.inline.InlineIndexTree in project ignite by apache.
the class DurableBackgroundCleanupIndexTreeTask method execute.
/**
* Task execution.
*
* @param ctx Kernal context.
*/
private void execute(GridKernalContext ctx) {
List<InlineIndexTree> trees0 = trees;
if (trees0 == null) {
trees0 = new ArrayList<>(rootPages.size());
GridCacheContext cctx = ctx.cache().context().cacheContext(CU.cacheId(cacheName));
int grpId = CU.cacheGroupId(cacheName, cacheGrpName);
CacheGroupContext grpCtx = ctx.cache().cacheGroup(grpId);
// If group context is null, it means that group doesn't exist and we don't need this task anymore.
if (grpCtx == null)
return;
IgniteCacheOffheapManager offheap = grpCtx.offheap();
if (treeName != null) {
ctx.cache().context().database().checkpointReadLock();
try {
int cacheId = CU.cacheId(cacheName);
for (int segment = 0; segment < rootPages.size(); segment++) {
try {
RootPage rootPage = offheap.findRootPageForIndex(cacheId, treeName, segment);
if (rootPage != null && rootPages.get(segment) == rootPage.pageId().pageId())
offheap.dropRootPageForIndex(cacheId, treeName, segment);
} catch (IgniteCheckedException e) {
throw new IgniteException(e);
}
}
} finally {
ctx.cache().context().database().checkpointReadUnlock();
}
}
IoStatisticsHolderIndex stats = new IoStatisticsHolderIndex(SORTED_INDEX, cctx.name(), idxName, cctx.kernalContext().metric());
PageMemory pageMem = grpCtx.dataRegion().pageMemory();
for (int i = 0; i < rootPages.size(); i++) {
Long rootPage = rootPages.get(i);
assert rootPage != null;
if (skipDeletedRoot(grpId, pageMem, rootPage)) {
ctx.log(getClass()).warning(S.toString("Skipping deletion of the index tree", "cacheGrpName", cacheGrpName, false, "cacheName", cacheName, false, "idxName", idxName, false, "segment", i, false, "rootPageId", PageIdUtils.toDetailString(rootPage), false));
continue;
}
// because we just going to free memory pages that are occupied by tree structure.
try {
String treeName = "deletedTree_" + i + "_" + name();
InlineIndexTree tree = new InlineIndexTree(null, grpCtx, treeName, cctx.offheap(), cctx.offheap().reuseListForIndex(treeName), cctx.dataRegion().pageMemory(), PageIoResolver.DEFAULT_PAGE_IO_RESOLVER, rootPage, false, 0, 0, new IndexKeyTypeSettings(), null, stats, new NoopRowHandlerFactory(), null);
trees0.add(tree);
} catch (IgniteCheckedException e) {
throw new IgniteException(e);
}
}
}
ctx.cache().context().database().checkpointReadLock();
try {
for (int i = 0; i < trees0.size(); i++) {
BPlusTree tree = trees0.get(i);
try {
tree.destroy(null, true);
} catch (IgniteCheckedException e) {
throw new IgniteException(e);
}
}
} finally {
ctx.cache().context().database().checkpointReadUnlock();
}
}
use of org.apache.ignite.internal.cache.query.index.sorted.inline.InlineIndexTree in project ignite by apache.
the class DurableBackgroundCleanupIndexTreeTaskV2 method toRootPages.
/**
* Create index root pages based on its trees.
*
* @param trees Index trees.
* @return Index root pages. Mapping: segment number -> index root page.
*/
public static Map<Integer, RootPage> toRootPages(InlineIndexTree[] trees) {
if (F.isEmpty(trees))
return emptyMap();
else {
Map<Integer, RootPage> res = new HashMap<>();
for (int i = 0; i < trees.length; i++) {
InlineIndexTree tree = trees[i];
assert tree != null : "No tree for segment: " + i;
res.put(i, new RootPage(new FullPageId(tree.getMetaPageId(), tree.groupId()), tree.created()));
}
return res;
}
}
use of org.apache.ignite.internal.cache.query.index.sorted.inline.InlineIndexTree in project ignite by apache.
the class DurableBackgroundCleanupIndexTreeTaskV2 method destroyIndexTrees.
/**
* Destroying index trees.
*
* @param grpCtx Cache group context.
* @param rootPage Index root page.
* @param cacheName Cache name.
* @param treeName Name of underlying index tree name.
* @param segment Segment number.
* @return Total number of pages recycled from this tree.
* @throws IgniteCheckedException If failed.
*/
public static long destroyIndexTrees(CacheGroupContext grpCtx, RootPage rootPage, String cacheName, String treeName, int segment) throws IgniteCheckedException {
long pageCnt = 0;
grpCtx.shared().database().checkpointReadLock();
try {
InlineIndexTree tree = idxTreeFactory.create(grpCtx, rootPage, treeName);
pageCnt += tree.destroy(null, true);
if (grpCtx.offheap().dropRootPageForIndex(CU.cacheId(cacheName), treeName, segment) != null)
pageCnt++;
} finally {
grpCtx.shared().database().checkpointReadUnlock();
}
return pageCnt;
}
use of org.apache.ignite.internal.cache.query.index.sorted.inline.InlineIndexTree in project ignite by apache.
the class DropIndexTest method testCorrectTaskExecute.
/**
* Checking that the {@link DurableBackgroundCleanupIndexTreeTaskV2} will work correctly.
*
* @throws Exception If failed.
*/
@Test
public void testCorrectTaskExecute() throws Exception {
IgniteEx n = startGrid(0);
IgniteCache<Integer, Person> cache = n.cache(DEFAULT_CACHE_NAME);
populate(cache, 100);
String idxName = "IDX0";
createIdx(cache, idxName);
GridCacheContext<Integer, Person> cctx = cacheContext(cache);
Index idx = index(n, cache, idxName);
SortedIndexDefinition idxDef = indexDefinition(idx);
InlineIndexTree[] trees = segments(idx);
Map<Integer, RootPage> rootPages = toRootPages(trees);
for (int i = 0; i < trees.length; i++) {
InlineIndexTree tree = trees[i];
assertEquals(new FullPageId(tree.getMetaPageId(), tree.groupId()), rootPages.get(i).pageId());
}
String oldTreeName = idxDef.treeName();
String newTreeName = UUID.randomUUID().toString();
int segments = idxDef.segments();
assertFalse(findIndexRootPages(cctx.group(), cctx.name(), oldTreeName, segments).isEmpty());
assertTrue(findIndexRootPages(cctx.group(), cctx.name(), newTreeName, segments).isEmpty());
DurableBackgroundCleanupIndexTreeTaskV2 task = new DurableBackgroundCleanupIndexTreeTaskV2(cctx.group().name(), cctx.name(), idxName, oldTreeName, newTreeName, segments, trees);
assertTrue(task.name().startsWith(taskNamePrefix(cctx.name(), idxName)));
assertTrue(getFieldValue(task, "needToRen"));
GridFutureAdapter<Void> startFut = new GridFutureAdapter<>();
GridFutureAdapter<Void> endFut = new GridFutureAdapter<>();
idxTreeFactory = taskIndexTreeFactoryEx(startFut, endFut);
IgniteInternalFuture<DurableBackgroundTaskResult<Long>> taskFut = task.executeAsync(n.context());
startFut.get(getTestTimeout());
assertTrue(findIndexRootPages(cctx.group(), cctx.name(), oldTreeName, segments).isEmpty());
assertFalse(findIndexRootPages(cctx.group(), cctx.name(), newTreeName, segments).isEmpty());
endFut.onDone();
DurableBackgroundTaskResult<Long> res = taskFut.get(getTestTimeout());
assertTrue(res.completed());
assertNull(res.error());
assertTrue(res.result() >= 3);
assertTrue(findIndexRootPages(cctx.group(), cctx.name(), oldTreeName, segments).isEmpty());
assertTrue(findIndexRootPages(cctx.group(), cctx.name(), newTreeName, segments).isEmpty());
assertFalse(getFieldValue(task, "needToRen"));
}
Aggregations