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

org.apache.flink.runtime.state.HashMapSerializer Maven / Gradle / Ivy

There is a newer version: 1.13.6
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;

import org.apache.flink.annotation.Internal;
import org.apache.flink.api.common.typeutils.CompatibilityResult;
import org.apache.flink.api.common.typeutils.CompatibilityUtil;
import org.apache.flink.api.common.typeutils.TypeDeserializerAdapter;
import org.apache.flink.api.common.typeutils.TypeSerializer;
import org.apache.flink.api.common.typeutils.TypeSerializerConfigSnapshot;
import org.apache.flink.api.common.typeutils.UnloadableDummyTypeSerializer;
import org.apache.flink.api.common.typeutils.base.MapSerializerConfigSnapshot;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.core.memory.DataInputView;
import org.apache.flink.core.memory.DataOutputView;
import org.apache.flink.util.Preconditions;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * A serializer for {@link HashMap}. The serializer relies on a key serializer and a value serializer
 * for the serialization of the map's key-value pairs.
 *
 * 

The serialization format for the map is as follows: four bytes for the length of the map, * followed by the serialized representation of each key-value pair. To allow null values, each value * is prefixed by a null marker. * * @param The type of the keys in the map. * @param The type of the values in the map. */ @Internal public final class HashMapSerializer extends TypeSerializer> { private static final long serialVersionUID = -6885593032367050078L; /** The serializer for the keys in the map */ private final TypeSerializer keySerializer; /** The serializer for the values in the map */ private final TypeSerializer valueSerializer; /** * Creates a map serializer that uses the given serializers to serialize the key-value pairs in the map. * * @param keySerializer The serializer for the keys in the map * @param valueSerializer The serializer for the values in the map */ public HashMapSerializer(TypeSerializer keySerializer, TypeSerializer valueSerializer) { this.keySerializer = Preconditions.checkNotNull(keySerializer, "The key serializer cannot be null"); this.valueSerializer = Preconditions.checkNotNull(valueSerializer, "The value serializer cannot be null."); } // ------------------------------------------------------------------------ // HashMapSerializer specific properties // ------------------------------------------------------------------------ public TypeSerializer getKeySerializer() { return keySerializer; } public TypeSerializer getValueSerializer() { return valueSerializer; } // ------------------------------------------------------------------------ // Type Serializer implementation // ------------------------------------------------------------------------ @Override public boolean isImmutableType() { return false; } @Override public TypeSerializer> duplicate() { TypeSerializer duplicateKeySerializer = keySerializer.duplicate(); TypeSerializer duplicateValueSerializer = valueSerializer.duplicate(); return new HashMapSerializer<>(duplicateKeySerializer, duplicateValueSerializer); } @Override public HashMap createInstance() { return new HashMap<>(); } @Override public HashMap copy(HashMap from) { HashMap newHashMap = new HashMap<>(from.size()); for (Map.Entry entry : from.entrySet()) { K newKey = keySerializer.copy(entry.getKey()); V newValue = entry.getValue() == null ? null : valueSerializer.copy(entry.getValue()); newHashMap.put(newKey, newValue); } return newHashMap; } @Override public HashMap copy(HashMap from, HashMap reuse) { return copy(from); } @Override public int getLength() { return -1; // var length } @Override public void serialize(HashMap map, DataOutputView target) throws IOException { final int size = map.size(); target.writeInt(size); for (Map.Entry entry : map.entrySet()) { keySerializer.serialize(entry.getKey(), target); if (entry.getValue() == null) { target.writeBoolean(true); } else { target.writeBoolean(false); valueSerializer.serialize(entry.getValue(), target); } } } @Override public HashMap deserialize(DataInputView source) throws IOException { final int size = source.readInt(); final HashMap map = new HashMap<>(size); for (int i = 0; i < size; ++i) { K key = keySerializer.deserialize(source); boolean isNull = source.readBoolean(); V value = isNull ? null : valueSerializer.deserialize(source); map.put(key, value); } return map; } @Override public HashMap deserialize(HashMap reuse, DataInputView source) throws IOException { return deserialize(source); } @Override public void copy(DataInputView source, DataOutputView target) throws IOException { final int size = source.readInt(); target.writeInt(size); for (int i = 0; i < size; ++i) { keySerializer.copy(source, target); boolean isNull = source.readBoolean(); target.writeBoolean(isNull); if (!isNull) { valueSerializer.copy(source, target); } } } @Override public boolean equals(Object obj) { return obj == this || (obj != null && obj.getClass() == getClass() && keySerializer.equals(((HashMapSerializer) obj).getKeySerializer()) && valueSerializer.equals(((HashMapSerializer) obj).getValueSerializer())); } @Override public boolean canEqual(Object obj) { return (obj != null && obj.getClass() == getClass()); } @Override public int hashCode() { return keySerializer.hashCode() * 31 + valueSerializer.hashCode(); } // -------------------------------------------------------------------------------------------- // Serializer configuration snapshotting & compatibility // -------------------------------------------------------------------------------------------- @Override public TypeSerializerConfigSnapshot snapshotConfiguration() { return new MapSerializerConfigSnapshot<>(keySerializer, valueSerializer); } @Override public CompatibilityResult> ensureCompatibility(TypeSerializerConfigSnapshot configSnapshot) { if (configSnapshot instanceof MapSerializerConfigSnapshot) { List, TypeSerializerConfigSnapshot>> previousKvSerializersAndConfigs = ((MapSerializerConfigSnapshot) configSnapshot).getNestedSerializersAndConfigs(); CompatibilityResult keyCompatResult = CompatibilityUtil.resolveCompatibilityResult( previousKvSerializersAndConfigs.get(0).f0, UnloadableDummyTypeSerializer.class, previousKvSerializersAndConfigs.get(0).f1, keySerializer); CompatibilityResult valueCompatResult = CompatibilityUtil.resolveCompatibilityResult( previousKvSerializersAndConfigs.get(1).f0, UnloadableDummyTypeSerializer.class, previousKvSerializersAndConfigs.get(1).f1, valueSerializer); if (!keyCompatResult.isRequiresMigration() && !valueCompatResult.isRequiresMigration()) { return CompatibilityResult.compatible(); } else if (keyCompatResult.getConvertDeserializer() != null && valueCompatResult.getConvertDeserializer() != null) { return CompatibilityResult.requiresMigration( new HashMapSerializer<>( new TypeDeserializerAdapter<>(keyCompatResult.getConvertDeserializer()), new TypeDeserializerAdapter<>(valueCompatResult.getConvertDeserializer()))); } } return CompatibilityResult.requiresMigration(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy