blob: 04bda0db65de42f25cc2a0b47df648d02b770481 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ignite.internal.storage.pagememory;
import static org.apache.ignite.internal.pagememory.PageIdAllocator.FLAG_AUX;
import static org.apache.ignite.internal.util.IgniteUtils.closeAllManually;
import org.apache.ignite.internal.lang.IgniteInternalCheckedException;
import org.apache.ignite.internal.pagememory.DataRegion;
import org.apache.ignite.internal.pagememory.PageMemory;
import org.apache.ignite.internal.pagememory.configuration.schema.VolatilePageMemoryProfileConfiguration;
import org.apache.ignite.internal.pagememory.evict.PageEvictionTracker;
import org.apache.ignite.internal.pagememory.freelist.FreeListImpl;
import org.apache.ignite.internal.pagememory.inmemory.VolatilePageMemory;
import org.apache.ignite.internal.pagememory.io.PageIoRegistry;
import org.apache.ignite.internal.pagememory.metric.IoStatisticsHolderNoOp;
import org.apache.ignite.internal.pagememory.reuse.ReuseList;
import org.apache.ignite.internal.pagememory.util.PageLockListenerNoOp;
import org.apache.ignite.internal.storage.StorageException;
/**
* Implementation of {@link DataRegion} for in-memory case.
*/
public class VolatilePageMemoryDataRegion implements DataRegion<VolatilePageMemory> {
private static final int FREE_LIST_GROUP_ID = 0;
private static final int FREE_LIST_PARTITION_ID = 0;
private static final String FREE_LIST_NAME = String.format("VolatileFreeList_%d_%d", FREE_LIST_GROUP_ID, FREE_LIST_PARTITION_ID);
private final VolatilePageMemoryProfileConfiguration cfg;
private final PageIoRegistry ioRegistry;
private final int pageSize;
private final PageEvictionTracker pageEvictionTracker;
private volatile VolatilePageMemory pageMemory;
private volatile FreeListImpl freeList;
/**
* Constructor.
*
* @param cfg Data region configuration.
* @param ioRegistry IO registry.
* @param pageSize Page size in bytes.
* @param pageEvictionTracker Eviction tracker to use.
*/
public VolatilePageMemoryDataRegion(
VolatilePageMemoryProfileConfiguration cfg,
PageIoRegistry ioRegistry,
// TODO: IGNITE-17017 Move to common config
int pageSize,
PageEvictionTracker pageEvictionTracker) {
this.cfg = cfg;
this.ioRegistry = ioRegistry;
this.pageSize = pageSize;
this.pageEvictionTracker = pageEvictionTracker;
}
/**
* Starts the in-memory data region.
*/
public void start() {
VolatilePageMemory pageMemory = new VolatilePageMemory(cfg, ioRegistry, pageSize);
pageMemory.start();
try {
this.freeList = createFreeList(pageMemory);
} catch (IgniteInternalCheckedException e) {
throw new StorageException("Error creating free list", e);
}
this.pageMemory = pageMemory;
}
private FreeListImpl createFreeList(
PageMemory pageMemory
) throws IgniteInternalCheckedException {
long metaPageId = pageMemory.allocatePage(FREE_LIST_GROUP_ID, FREE_LIST_PARTITION_ID, FLAG_AUX);
return new FreeListImpl(
FREE_LIST_GROUP_ID,
FREE_LIST_PARTITION_ID,
FREE_LIST_NAME,
pageMemory,
null,
PageLockListenerNoOp.INSTANCE,
metaPageId,
true,
// Because in memory.
null,
pageEvictionTracker,
IoStatisticsHolderNoOp.INSTANCE
);
}
/**
* Starts the in-memory data region.
*/
public void stop() throws Exception {
closeAllManually(
freeList,
pageMemory != null ? () -> pageMemory.stop(true) : null
);
}
/** {@inheritDoc} */
@Override
public VolatilePageMemory pageMemory() {
checkDataRegionStarted();
return pageMemory;
}
public ReuseList reuseList() {
return freeList;
}
/**
* Returns version chain free list.
*
* @throws StorageException If the data region did not start.
*/
public FreeListImpl freeList() {
checkDataRegionStarted();
return freeList;
}
/**
* Checks that the data region has started.
*
* @throws StorageException If the data region did not start.
*/
private void checkDataRegionStarted() {
if (pageMemory == null) {
throw new StorageException("Data region not started");
}
}
}