Updated Branches: refs/heads/trunk e85afdc5b -> 19a45370d
classes missing from previous commit Patch by Sam Overton; reviewed by jbellis for CASSANDRA-4121 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/19a45370 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/19a45370 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/19a45370 Branch: refs/heads/trunk Commit: 19a45370da1d46ffc6bc609181648170858af6d1 Parents: e85afdc Author: Eric Evans <eev...@apache.org> Authored: Mon Jul 9 16:11:21 2012 -0600 Committer: Eric Evans <eev...@apache.org> Committed: Mon Jul 9 16:11:21 2012 -0600 ---------------------------------------------------------------------- .../org/apache/cassandra/utils/BiMultiValMap.java | 124 +++++++++++++++ .../cassandra/utils/SortedBiMultiValMap.java | 58 +++++++ 2 files changed, 182 insertions(+), 0 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/19a45370/src/java/org/apache/cassandra/utils/BiMultiValMap.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/utils/BiMultiValMap.java b/src/java/org/apache/cassandra/utils/BiMultiValMap.java new file mode 100644 index 0000000..992d9cf --- /dev/null +++ b/src/java/org/apache/cassandra/utils/BiMultiValMap.java @@ -0,0 +1,124 @@ +package org.apache.cassandra.utils; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import com.google.common.collect.Multimaps; + +/** + * + * A variant of BiMap which does not enforce uniqueness of values. This means the inverse + * is a Multimap. + * + * @param <K> + * @param <V> + */ +public class BiMultiValMap<K, V> implements Map<K, V> +{ + protected final Map<K, V> forwardMap; + protected final Multimap<V, K> reverseMap; + + public BiMultiValMap() + { + this.forwardMap = new HashMap<K, V>(); + this.reverseMap = HashMultimap.<V, K>create(); + } + + protected BiMultiValMap(Map<K, V> forwardMap, Multimap<V, K> reverseMap) + { + this.forwardMap = forwardMap; + this.reverseMap = reverseMap; + } + + public BiMultiValMap(BiMultiValMap<K, V> map) + { + this(); + forwardMap.putAll(map); + reverseMap.putAll(map.inverse()); + } + + public Multimap<V, K> inverse() + { + return Multimaps.unmodifiableMultimap(reverseMap); + } + + public void clear() + { + forwardMap.clear(); + reverseMap.clear(); + } + + public boolean containsKey(Object key) + { + return forwardMap.containsKey(key); + } + + public boolean containsValue(Object value) + { + return reverseMap.containsKey(value); + } + + public Set<Map.Entry<K, V>> entrySet() + { + return forwardMap.entrySet(); + } + + public V get(Object key) + { + return forwardMap.get(key); + } + + public boolean isEmpty() + { + return forwardMap.isEmpty(); + } + + public Set<K> keySet() + { + return forwardMap.keySet(); + } + + public V put(K key, V value) + { + V oldVal = forwardMap.put(key, value); + if (oldVal != null) + reverseMap.remove(oldVal, key); + reverseMap.put(value, key); + return oldVal; + } + + public void putAll(Map<? extends K, ? extends V> m) + { + for (Map.Entry<? extends K, ? extends V> entry : m.entrySet()) + put(entry.getKey(), entry.getValue()); + } + + public V remove(Object key) + { + V oldVal = forwardMap.remove(key); + reverseMap.remove(oldVal, key); + return oldVal; + } + + public Collection<K> removeValue(V value) + { + Collection<K> keys = reverseMap.removeAll(value); + for (K key : keys) + forwardMap.remove(key); + return keys; + } + + public int size() + { + return forwardMap.size(); + } + + public Collection<V> values() + { + return reverseMap.keys(); + } +} http://git-wip-us.apache.org/repos/asf/cassandra/blob/19a45370/src/java/org/apache/cassandra/utils/SortedBiMultiValMap.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/utils/SortedBiMultiValMap.java b/src/java/org/apache/cassandra/utils/SortedBiMultiValMap.java new file mode 100644 index 0000000..7ba5e37 --- /dev/null +++ b/src/java/org/apache/cassandra/utils/SortedBiMultiValMap.java @@ -0,0 +1,58 @@ +package org.apache.cassandra.utils; + +import java.util.Comparator; +import java.util.SortedMap; +import java.util.TreeMap; + +import com.google.common.collect.SortedSetMultimap; +import com.google.common.collect.TreeMultimap; + +public class SortedBiMultiValMap<K, V> extends BiMultiValMap<K, V> +{ + protected SortedBiMultiValMap(SortedMap<K, V> forwardMap, SortedSetMultimap<V, K> reverseMap) + { + super(forwardMap, reverseMap); + } + + public static <K extends Comparable<K>, V extends Comparable<V>> SortedBiMultiValMap<K, V> create() + { + return new SortedBiMultiValMap<K, V>(new TreeMap<K,V>(), TreeMultimap.<V, K>create()); + } + + public static <K, V> SortedBiMultiValMap<K, V> create(Comparator<K> keyComparator, Comparator<V> valueComparator) + { + if (keyComparator == null) + keyComparator = defaultComparator(); + if (valueComparator == null) + valueComparator = defaultComparator(); + return new SortedBiMultiValMap<K, V>(new TreeMap<K,V>(keyComparator), TreeMultimap.<V, K>create(valueComparator, keyComparator)); + } + + public static <K extends Comparable<K>, V extends Comparable<V>> SortedBiMultiValMap<K, V> create(BiMultiValMap<K, V> map) + { + SortedBiMultiValMap<K, V> newMap = SortedBiMultiValMap.<K,V>create(); + newMap.forwardMap.putAll(map); + newMap.reverseMap.putAll(map.inverse()); + return newMap; + } + + public static <K, V> SortedBiMultiValMap<K, V> create(BiMultiValMap<K, V> map, Comparator<K> keyComparator, Comparator<V> valueComparator) + { + SortedBiMultiValMap<K, V> newMap = create(keyComparator, valueComparator); + newMap.forwardMap.putAll(map); + newMap.reverseMap.putAll(map.inverse()); + return newMap; + } + + private static <T> Comparator<T> defaultComparator() + { + return new Comparator<T>() + { + @SuppressWarnings("unchecked") + public int compare(T o1, T o2) + { + return ((Comparable<T>) o1).compareTo(o2); + } + }; + } +}