package com.tesora.dve.common;
/*
* #%L
* Tesora Inc.
* Database Virtualization Engine
* %%
* Copyright (C) 2011 - 2014 Tesora Inc.
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
import java.util.Collection;
import java.util.Map;
import java.util.Set;
public final class TwoDimensionalMultiMap<OuterKey, InnerKey, Value> {
private Map<OuterKey, MultiMap<InnerKey, Value>> backing;
private final MapFactory<InnerKey, Collection<Value>> innerMapFactory;
private final CollectionFactory<Value> valueStorageFactory;
public TwoDimensionalMultiMap() {
this(new HashMapFactory<OuterKey, MultiMap<InnerKey, Value>>(),
new HashMapFactory<InnerKey, Collection<Value>>(),
new ArrayListFactory<Value>());
}
public TwoDimensionalMultiMap(
final MapFactory<OuterKey, MultiMap<InnerKey, Value>> outerMapFactory,
final MapFactory<InnerKey, Collection<Value>> innerMapFactory,
final CollectionFactory<Value> valueStorageFactory) {
this.backing = outerMapFactory.create();
this.innerMapFactory = innerMapFactory;
this.valueStorageFactory = valueStorageFactory;
}
public boolean put(final OuterKey ok, final InnerKey ik, final Value value) {
final MultiMap<InnerKey, Value> inner = locateInternalValueStorage(ok);
return inner.put(ik, value);
}
public boolean putAll(final OuterKey ok, final InnerKey ik, final Collection<Value> values) {
final MultiMap<InnerKey, Value> inner = locateInternalValueStorage(ok);
return inner.putAll(ik, values);
}
public void putAll(final TwoDimensionalMultiMap<OuterKey, InnerKey, Value> other) {
for (final OuterKey ok : other.keySet()) {
final MultiMap<InnerKey, Value> inner = locateInternalValueStorage(ok);
inner.putAll(other.get(ok));
}
}
private MultiMap<InnerKey, Value> locateInternalValueStorage(final OuterKey ok) {
MultiMap<InnerKey, Value> inner = get(ok);
if (inner == null) {
inner = new MultiMap<InnerKey, Value>(innerMapFactory, valueStorageFactory);
backing.put(ok, inner);
}
return inner;
}
public MultiMap<InnerKey, Value> get(final OuterKey ok) {
return backing.get(ok);
}
public Collection<Value> get(final OuterKey ok, final InnerKey ik) {
final MultiMap<InnerKey, Value> inner = get(ok);
if (inner != null) {
return inner.get(ik);
}
return null;
}
public Set<OuterKey> keySet() {
return backing.keySet();
}
public void clear() {
backing.clear();
}
}