All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.flink.runtime.state.gemini.engine.vm.EvictPolicySepImpl Maven / Gradle / Ivy

/*
 * 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.flink.runtime.state.gemini.engine.vm;

import org.apache.flink.runtime.state.gemini.engine.GRegion;
import org.apache.flink.runtime.state.gemini.engine.dbms.GContext;
import org.apache.flink.runtime.state.gemini.engine.handler.EvictHandlerSepImpl;
import org.apache.flink.runtime.state.gemini.engine.page.PageAddress;
import org.apache.flink.runtime.state.gemini.engine.rm.GByteBuffer;
import org.apache.flink.runtime.state.gemini.engine.rm.ReferenceCount.ReleaseType;

import org.apache.flink.shaded.netty4.io.netty.util.concurrent.EventExecutor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * EvictPolicy.
 */
public class EvictPolicySepImpl implements EvictPolicy {
	private static final Logger LOG = LoggerFactory.getLogger(EvictPolicySepImpl.class);
	private final CacheManager cacheManager;
	private final GContext gContext;
	private final Map evictHandlerMap = new HashMap<>();
	private final Object printObject = new Object();
	private final long loopInterval = 1000;
	private final int printTick = 10;

	public EvictPolicySepImpl(GContext gContext, CacheManager cacheManager) {
		this.gContext = gContext;
		this.cacheManager = cacheManager;
	}

	@Override
	public void run() {
		int tick = 0;
		while (this.gContext.isDBNormal()) {
			try {

				//we reuse the thread to do safe remove and check discarded or eviceted page's reference count.
				Iterator> iteratorDiscard = this.gContext.getSupervisor().getDiscardOrEvictPageReleaseManager().getDiscardedPageHaveReferenceMonitor().entrySet().iterator();
				while (iteratorDiscard.hasNext()) {
					Map.Entry gByteBuffer = iteratorDiscard.next();
					if (gByteBuffer.getKey().getCnt() <= 0) {
						iteratorDiscard.remove();
						//actually, gByteBuffer is probably added to Queue 2 times, means it's added to Queue before, but it's safe.
						this.gContext.getSupervisor().getDiscardOrEvictPageReleaseManager().addWaitSafeQueue(ReleaseType.Discard,
							gByteBuffer.getKey());
					}
				}

				Iterator> iteratorEvict = this.gContext.getSupervisor().getDiscardOrEvictPageReleaseManager().getEvictedPageHaveReferenceMonitor().entrySet().iterator();
				while (iteratorEvict.hasNext()) {
					Map.Entry gByteBuffer = iteratorEvict.next();
					if (gByteBuffer.getKey().getCnt() <= 0) {
						iteratorEvict.remove();
						//actually, gByteBuffer is probably added to Queue 2 times, means it's added to Queue before, but it's safe.
						this.gContext.getSupervisor().getDiscardOrEvictPageReleaseManager().addWaitSafeQueue(ReleaseType.Evict,
							gByteBuffer.getKey());
					}
				}

				GByteBuffer gByteBuffer;
				while ((gByteBuffer = this.gContext.getSupervisor().getDiscardOrEvictPageReleaseManager().getGByteBufferFromWaitQueue()) != null) {
					if (gByteBuffer.getCnt() > 0) {
						//well, despite of the real ReleaseType.
						this.gContext.getSupervisor().getDiscardOrEvictPageReleaseManager().addMonitorPageStillHaveReference(
							gByteBuffer,
							ReleaseType.Discard,
							"safeQueue");
						continue;
					}
					//accdessNum is incremental num. so we just check not equal.
					if (gByteBuffer.getSeqID() != this.gContext.getAccessNumber()) {
						//phisical free space.
						gByteBuffer.doFree();
					} else {
						break;
					}
				}

				if (tick++ >= printTick) {

					evictHandlerMap.values().forEach(handler -> LOG.info("Thread Mem WM {}", handler));
					LOG.info(
						"Mem WM:{}, Index WM:{}  {}  {}  ReadPageLRUSize={}/{} fileSize={}/{} Allocator1={} Allocator2={} discardMonitorSetSize={} evictMonitorSetSize={} TotalWaitQueueSize={}",
						this.cacheManager.getMemWaterMark(0),
						this.cacheManager.getIndexCapacityWaterMark(),
						this.cacheManager.getCacheStats(),
						this.gContext.getSupervisor().getWriteBufferManager(),
						this.gContext.getSupervisor().getFetchPolicy().getDataPageLRU().getTotalSize(),
						this.gContext.getSupervisor().getFetchPolicy().getDataPageLRU().size(),
						this.gContext.getSupervisor().getFileCache().getFileCacheStat().totalLocalWriteSize,
						this.gContext.getSupervisor().getFileCache().getFileCacheStat().totalLocalOriDataSize,
//					gContext.getSupervisor().getDefaultAllocator(),
						gContext.getSupervisor().getAllocator(),
						gContext.getSupervisor().getForReadAllocator(),
						this.gContext.getSupervisor().getDiscardOrEvictPageReleaseManager().getDiscardedPageHaveReferenceMonitor().size(),
						this.gContext.getSupervisor().getDiscardOrEvictPageReleaseManager().getEvictedPageHaveReferenceMonitor().size(),
						this.gContext.getSupervisor().getDiscardOrEvictPageReleaseManager().getTotalWaitQueueSize());

					tick = 0;
				}
				synchronized (printObject) {
					printObject.wait(loopInterval);
				}
			} catch (InterruptedException ie) {
				if (!this.gContext.isDBNormal()) {
					LOG.warn("GeminiDB is in abnormal status");
				} else {
					LOG.error("EvictPolicy has Exception={}", ie.getMessage(), ie);
				}
			} catch (Exception e) {
				LOG.error("EvictPolicy has Exception={}", e.getMessage(), e);
			}
		}
	}

	@Override
	public void removeInvalidPage(
		GRegion gRegion, int curIndex, int relatedIndex, List pageAddressList) {
		evictHandlerMap.get(gRegion.getExecutor()).removeInvalidPage(gRegion, curIndex, relatedIndex, pageAddressList);
	}

	@Override
	public void addEvictablePage(
		GRegion gRegion, PageAddress pageAddress) {
		evictHandlerMap.get(gRegion.getExecutor()).addEvictablePage(pageAddress, gRegion);
	}

	@Override
	public void addPageUsedMemory(GRegion gRegion, EventExecutor regionEventExecutor, int logicPageSize, boolean needEvict) {
		evictHandlerMap.get(regionEventExecutor).addPageUsedMemory(gRegion, logicPageSize, needEvict);
	}

	@Override
	public void addRegionEventExecutor(EventExecutor regionEventExecutor) {
		evictHandlerMap.putIfAbsent(regionEventExecutor,
			new EvictHandlerSepImpl(regionEventExecutor.toString(), gContext));
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy