PromotableMultiMapWithOrdinal.java
/*
* 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.arrow.vector.util;
import java.util.Collection;
import java.util.Set;
import org.apache.arrow.vector.complex.AbstractStructVector;
/**
* Implementation of MapWithOrdinal that allows for promotion to multimap when duplicate fields
* exist.
*
* @param <K> key type
* @param <V> value type
*/
public class PromotableMultiMapWithOrdinal<K, V> implements MapWithOrdinal<K, V> {
private final MapWithOrdinalImpl<K, V> mapWithOrdinal = new MapWithOrdinalImpl<>();
private final MultiMapWithOrdinal<K, V> multiMapWithOrdinal = new MultiMapWithOrdinal<>();
private final boolean promotable;
private AbstractStructVector.ConflictPolicy conflictPolicy;
private MapWithOrdinal<K, V> delegate;
/**
* Create promotable map.
*
* @param promotable if promotion is allowed, otherwise delegate to MapWithOrdinal.
* @param conflictPolicy how to handle name conflicts.
*/
public PromotableMultiMapWithOrdinal(
boolean promotable, AbstractStructVector.ConflictPolicy conflictPolicy) {
this.promotable = promotable;
this.conflictPolicy = conflictPolicy;
delegate = mapWithOrdinal;
}
private void promote() {
if (delegate == multiMapWithOrdinal
|| !promotable
|| conflictPolicy.equals(AbstractStructVector.ConflictPolicy.CONFLICT_REPLACE)) {
return;
}
for (K key : mapWithOrdinal.keys()) {
V value = mapWithOrdinal.get(key);
multiMapWithOrdinal.put(key, value, false);
}
mapWithOrdinal.clear();
delegate = multiMapWithOrdinal;
}
@Override
public V getByOrdinal(int id) {
return delegate.getByOrdinal(id);
}
@Override
public int getOrdinal(K key) {
return delegate.getOrdinal(key);
}
@Override
public int size() {
return delegate.size();
}
@Override
public boolean isEmpty() {
return delegate.isEmpty();
}
@Override
public V get(K key) {
return delegate.get(key);
}
@Override
public Collection<V> getAll(K key) {
return delegate.getAll(key);
}
@Override
public boolean put(K key, V value, boolean overwrite) {
if (delegate.containsKey(key)) {
promote();
}
return delegate.put(key, value, overwrite);
}
@Override
public Collection<V> values() {
return delegate.values();
}
@Override
public boolean containsKey(K key) {
return delegate.containsKey(key);
}
@Override
public boolean remove(K key, V value) {
return delegate.remove(key, value);
}
@Override
public boolean removeAll(K key) {
return delegate.removeAll(key);
}
@Override
public void clear() {
delegate.clear();
}
@Override
public Set<K> keys() {
return delegate.keys();
}
public void setConflictPolicy(AbstractStructVector.ConflictPolicy conflictPolicy) {
this.conflictPolicy = conflictPolicy;
}
}