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

org.apache.flink.runtime.state.gemini.engine.hashtable.GRegionKMapImpl Maven / Gradle / Ivy

There is a newer version: 1.5.1
Show newest version
/*
 * 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.runtime.state.gemini.engine.GRegionContext;
import org.apache.flink.runtime.state.gemini.engine.memstore.GSValue;
import org.apache.flink.runtime.state.gemini.engine.memstore.GSValueMap;
import org.apache.flink.runtime.state.gemini.engine.memstore.WriteBufferKMapHashImpl;
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.PageStoreHashKMapImpl;

import org.apache.flink.shaded.guava18.com.google.common.collect.Maps;

import javax.annotation.Nullable;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.stream.Collectors;

/**
 * GRegionKMapImpl.
 * K is type of key.
 * V is type of value.
 */
public class GRegionKMapImpl extends AbstractGRegionKMapImpl> {

	public GRegionKMapImpl(GRegionContext gRegionContext) {
		super(gRegionContext, null);
	}

	public GRegionKMapImpl(GRegionContext gRegionContext, PageIndex pageIndex) {
		super(gRegionContext, pageIndex);
	}

	@Override
	void init(PageIndex pageIndex) {
		this.pageStore = new PageStoreHashKMapImpl<>(this, pageIndex, regionEventExecutor);
		this.writeBuffer = new WriteBufferKMapHashImpl<>(this, regionEventExecutor, pageStore);
	}

	@Override
	public void put(K key, Map value) {
		gContext.checkDBStatus();
		gContext.incAccessNumber();
		long seqID = gRegionContext.getNextSeqID();
		writeBuffer.put(key, Maps.transformEntries(value,
			(mk, mv) -> GSValue.of(mv, GValueType.PutValue, seqID)));
	}

	@Override
	public Map get(K key) {
		gContext.checkDBStatus();
		gContext.incAccessNumber();
		return internalGet(key, true);
	}

	@Nullable
	private Map mergeTwoMap(@Nullable Map> newer, Map> older, boolean checkReadCopy) {
		Map ret = new HashMap<>();
		if (older != null) {
			ret = older.entrySet().stream()
				.filter(e -> !GValueType.Delete.equals(e.getValue().getValueType()) && !gRegionContext.filterState(e.getValue().getSeqID()))
				.collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().getValue()));
		}
		if (newer != null) {
			for (Map.Entry> entry : newer.entrySet()) {
				if (gRegionContext.filterState(entry.getValue().getSeqID())) {
					continue;
				}
				if (entry.getValue().getValueType().equals(GValueType.Delete)) {
					ret.remove(entry.getKey());
				} else {
					MK mk = entry.getKey();
					MV mv = entry.getValue().getValue();
					ret.put(checkReadCopy ? copyMKIfNeeded(mk) : mk, checkReadCopy ? copyMVIfNeeded(mv) : mv);
				}
			}
		}

		return ret.isEmpty() ? null : ret;
	}

	private Map genMapFromGSValueMap(GSValueMap gsValueMap, boolean checkReadCopy) {
		Map> valueMap = gsValueMap.getValue();
		Map ret = new HashMap<>();
		if (valueMap != null) {
			for (SortedMap.Entry> entry : valueMap.entrySet()) {
				if (!GValueType.Delete.equals(entry.getValue().getValueType()) &&
					!gRegionContext.filterState(entry.getValue().getSeqID())) {
					MK mk = entry.getKey();
					MV mv = entry.getValue().getValue();
					ret.put(checkReadCopy ? copyMKIfNeeded(mk) : mk, checkReadCopy ? copyMVIfNeeded(mv) : mv);
				}
			}
		}
		return ret.isEmpty() ? null : ret;
	}

	@Override
	public Map getOrDefault(K key, Map defaultValue) {
		gContext.checkDBStatus();
		Map result = get(key);
		return (result == null || result.isEmpty()) ? defaultValue : result;
	}

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

	@Override
	public void getAll(Map> results) {
		gContext.checkDBStatus();
		//TODO provide better performance.
		gContext.incAccessNumber();
		Set allKeysIncludeDelete = new HashSet<>();
		writeBuffer.allKeysIncludeDeleted(allKeysIncludeDelete);
		pageStore.allKeysIncludeDeleted(allKeysIncludeDelete);

		for (K key : allKeysIncludeDelete) {
			Map mapResult = get(key);

			if (mapResult != null) {
				results.put(copyKeyIfNeeded(key), mapResult);
			}
		}
	}

	@Override
	protected Map internalGet(K key, boolean checkReadCopy) {
		GSValueMap gsValueMap = writeBuffer.get(key);
		if (gsValueMap != null) {
			switch (gsValueMap.getValueType()) {
				case Delete:
					return null;
				case PutMap:
					return genMapFromGSValueMap(gsValueMap, checkReadCopy);
				default:
					// nothing need to do.
			}
		}

		Map> mapResult = pageStore.get(key);
		return mergeTwoMap(gsValueMap == null ? null : gsValueMap.getValue(), mapResult, checkReadCopy);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy