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

org.apache.flink.runtime.state.gemini.engine.hashtable.GRegionKVImpl 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.hashtable;

import org.apache.flink.api.common.typeutils.TypeSerializer;
import org.apache.flink.runtime.state.gemini.engine.GRegionContext;
import org.apache.flink.runtime.state.gemini.engine.GRegionID;
import org.apache.flink.runtime.state.gemini.engine.GeminiKV;
import org.apache.flink.runtime.state.gemini.engine.dbms.GContext;
import org.apache.flink.runtime.state.gemini.engine.memstore.GSValue;
import org.apache.flink.runtime.state.gemini.engine.memstore.WriteBuffer;
import org.apache.flink.runtime.state.gemini.engine.memstore.WriteBufferHashImpl;
import org.apache.flink.runtime.state.gemini.engine.page.GValueType;
import org.apache.flink.runtime.state.gemini.engine.page.PageIndex;
import org.apache.flink.runtime.state.gemini.engine.page.PageStore;
import org.apache.flink.runtime.state.gemini.engine.page.PageStoreHashKVImpl;
import org.apache.flink.util.Preconditions;

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

import java.util.HashMap;
import java.util.Map;

/**
 * GeminiKVRegion.
 * K is type of key.
 * V is type of value.
 */
public class GRegionKVImpl implements GeminiKV, HashGRegion {

	protected final GContext gContext;

	protected final GRegionContext gRegionContext;

	protected WriteBuffer writeBuffer;

	protected PageStore pageStore;

	protected final EventExecutor regionEventExecutor;

	private boolean readCopy;

	private TypeSerializer keySerializer;

	private TypeSerializer valueSerializer;

	@SuppressWarnings("unchecked")
	public GRegionKVImpl(GRegionContext gRegionContext) {
		this.gRegionContext = Preconditions.checkNotNull(gRegionContext);
		this.gContext = gRegionContext.getGContext();

		// TODO how to choose an event executor
		this.regionEventExecutor = gContext.getSupervisor().getRegionExecutorGroup().next();
		gRegionContext.getPageStoreStats().setRegionExecutor(regionEventExecutor);
		gContext.getSupervisor().getCacheManager().addRegionEventExecutor(this.regionEventExecutor);
		this.pageStore = new PageStoreHashKVImpl<>(this, regionEventExecutor);
		this.writeBuffer = new WriteBufferHashImpl<>(this, regionEventExecutor, pageStore);
		this.readCopy = gRegionContext.getGContext().getGConfiguration().isReadCopy();
		this.keySerializer = gRegionContext.getPageSerdeFlink().getKeySerde();
		this.valueSerializer = gRegionContext.getPageSerdeFlink().getValueSerde();
	}

	@SuppressWarnings("unchecked")
	public GRegionKVImpl(GRegionContext gRegionContext, PageIndex pageIndex) {
		this.gRegionContext = Preconditions.checkNotNull(gRegionContext);
		this.gContext = gRegionContext.getGContext();

		// TODO how to choose an event executor
		this.regionEventExecutor = gContext.getSupervisor().getRegionExecutorGroup().next();
		gRegionContext.getPageStoreStats().setRegionExecutor(regionEventExecutor);
		gContext.getSupervisor().getCacheManager().addRegionEventExecutor(this.regionEventExecutor);
		this.pageStore = new PageStoreHashKVImpl<>(this, pageIndex, regionEventExecutor);
		this.writeBuffer = new WriteBufferHashImpl<>(this, regionEventExecutor, pageStore);
		this.readCopy = gRegionContext.getGContext().getGConfiguration().isReadCopy();
		this.keySerializer = gRegionContext.getPageSerdeFlink().getKeySerde();
		this.valueSerializer = gRegionContext.getPageSerdeFlink().getValueSerde();
	}

	@Override
	public void put(K key, V value) {
		gContext.checkDBStatus();
		gContext.incAccessNumber();
		writeBuffer.put(key, value);
	}

	@Override
	public V get(K key) {
		gContext.checkDBStatus();
		gContext.incAccessNumber();
		GSValue value = writeBuffer.get(key);
		if (value != null) {
			if (value.getValueType() == GValueType.Delete || gRegionContext.filterState(value.getSeqID())) {
				return null;
			}
			return copyValueIfNeeded(value.getValue());
		}
		return pageStore.get(key);
	}

	@Override
	public V getOrDefault(K key, V defaultValue) {
		gContext.checkDBStatus();
		V value = get(key);
		return value == null ? defaultValue : value;
	}

	@Override
	public void remove(K key) {
		gContext.checkDBStatus();
		gContext.incAccessNumber();
		writeBuffer.removeKey(key);
	}

	@Override
	public Map getAll() {
		gContext.checkDBStatus();
		Map results = new HashMap<>();
		getAll(results);
		return results;
	}

	@Override
	public void getAll(Map results) {
		gContext.checkDBStatus();
		gContext.incAccessNumber();
		Map> container = new HashMap<>();
		writeBuffer.getAll(container);
		if (readCopy) {
			Map> map = new HashMap<>();
			for (Map.Entry> entry : container.entrySet()) {
				GSValue gsValue = entry.getValue();
				GSValue value = gsValue.getValueType() == GValueType.Delete ? gsValue :
					new GSValue<>(copyValueIfNeeded(gsValue.getValue()), gsValue.getValueType(), gsValue.getSeqID());
				map.put(copyKeyIfNeeded(entry.getKey()), value);
			}
			container = map;
		}
		pageStore.getAll(container);

		for (Map.Entry> entry : container.entrySet()) {
			GSValue gsValue = entry.getValue();
			if (gsValue.getValueType() != GValueType.Delete && !gRegionContext.filterState(gsValue.getSeqID())) {
				results.put(entry.getKey(), gsValue.getValue());
			}
		}
	}

	@Override
	public void removeAll() {
		gContext.checkDBStatus();
		gContext.incAccessNumber();
		long lastSeqID = gRegionContext.getLastSeqID();
		gRegionContext.setRemoveAllSeqID(lastSeqID);
		writeBuffer.reset();
	}

	@Override
	public Iterable keys() {
		gContext.checkDBStatus();
		return getAll().keySet();
	}

	@Override
	public boolean contains(K key) {
		gContext.checkDBStatus();
		gContext.incAccessNumber();
		GSValue value = writeBuffer.get(key);
		if (value != null) {
			if (value.getValueType() == GValueType.Delete || gRegionContext.filterState(value.getSeqID())) {
				return false;
			}
			return true;
		}
		return pageStore.get(key) != null;
	}

	@Override
	public GRegionContext getGRegionContext() {
		return this.gRegionContext;
	}

	@Override
	public PageStore getPageStore() {
		return pageStore;
	}

	@Override
	public GRegionID getRegionId() {
		return gRegionContext.getRegionId();
	}

	@Override
	public WriteBuffer getWriteBuffer() {
		return writeBuffer;
	}

	@Override
	public EventExecutor getExecutor() {
		return this.regionEventExecutor;
	}

	private K copyKeyIfNeeded(K key) {
		return readCopy ? keySerializer.copy(key) : key;
	}

	private V copyValueIfNeeded(V value) {
		return readCopy ? valueSerializer.copy(value) : value;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy