Clover coverage report - PLT Utilities Test Coverage (plt-20120304-r5436)
Coverage timestamp: Sat Mar 3 2012 22:01:56 CST
file stats: LOC: 195   Methods: 16
NCLOC: 80   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ExternallySortedMultiMap.java 0% 0% 0% 0%
coverage
 1    /*BEGIN_COPYRIGHT_BLOCK*
 2   
 3    PLT Utilities BSD License
 4   
 5    Copyright (c) 2007-2010 JavaPLT group at Rice University
 6    All rights reserved.
 7   
 8    Developed by: Java Programming Languages Team
 9    Rice University
 10    http://www.cs.rice.edu/~javaplt/
 11   
 12    Redistribution and use in source and binary forms, with or without modification, are permitted
 13    provided that the following conditions are met:
 14   
 15    - Redistributions of source code must retain the above copyright notice, this list of conditions
 16    and the following disclaimer.
 17    - Redistributions in binary form must reproduce the above copyright notice, this list of
 18    conditions and the following disclaimer in the documentation and/or other materials provided
 19    with the distribution.
 20    - Neither the name of the JavaPLT group, Rice University, nor the names of the library's
 21    contributors may be used to endorse or promote products derived from this software without
 22    specific prior written permission.
 23   
 24    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 25    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 26    FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND
 27    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 28    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 29    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 30    IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 31    OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 32   
 33    *END_COPYRIGHT_BLOCK*/
 34   
 35    package edu.rice.cs.plt.collect;
 36   
 37    import java.util.*;
 38    import edu.rice.cs.plt.iter.EmptyIterator;
 39    import edu.rice.cs.plt.iter.ImmutableIterator;
 40    import edu.rice.cs.plt.iter.IterUtil;
 41   
 42    /**
 43    * Maps from a key to a set of values; a key may be added multiple times
 44    * with different values, and those values are collected in a set.
 45    * Each set is ordered according to some Comparable corresponding to each
 46    * value. The methods provided are modeled after the {@link java.util.Map} interface.
 47    * However, the container being modeled is not exactly a map, and some
 48    * of the Map methods do not make sense in this context. For example,
 49    * {@code put(key, value)} was replaced here by {@code put(key, value, orderBy)}.
 50    */
 51    public class ExternallySortedMultiMap<K, V, C extends Comparable<? super C>> {
 52   
 53    /** Maps from a key to a <em>non-empty</em> set. */
 54    private final Map<K, ExternallySortedSet<V, C>> _map;
 55   
 56    /**
 57    * Caches the value to eliminate the need to traverse the map.
 58    * <em>Must</em> be updated whenever changes are made to _map (thus, providing
 59    * indirect access to mutation on _map is generally a bad idea).
 60    */
 61    private int _size;
 62   
 63    /** Create an empty map. */
 64  0 public ExternallySortedMultiMap() {
 65  0 _map = new HashMap<K, ExternallySortedSet<V, C>>();
 66  0 _size = 0;
 67    }
 68   
 69    /** @return The current number of (key, value) pairs in the map. */
 70  0 public int size() { return _size; }
 71   
 72    /** @return The current number of (key, value) pairs in the map, or {@code bound} if it is less. */
 73  0 public int size(int bound) { return _size <= bound ? _size : bound; }
 74   
 75    /** @return {@code true} iff {@code size() == 0}. */
 76  0 public boolean isEmpty() { return _size == 0; }
 77   
 78    /** @return {@code true} iff the specified key is mapped to at least 1 value. */
 79  0 public boolean containsKey(K key) { return _map.containsKey(key); }
 80   
 81    /** @return {@code true} iff the specified value is associated with some key. */
 82  0 public boolean containsValue(V value) {
 83  0 for (ExternallySortedSet<V, C> set : _map.values()) {
 84  0 if (set.contains(value)) { return true; }
 85    }
 86  0 return false;
 87    }
 88   
 89    /** @return {@code true} iff the specified (key, value) pair is in the map. */
 90  0 public boolean contains(K key, V value) {
 91  0 ExternallySortedSet<V, C> set = _map.get(key);
 92  0 return (set != null) && (set.contains(value));
 93    }
 94   
 95    /**
 96    * @return A dynamically-updated view of the values associated with the given key, sorted
 97    * by their corresponding {@code orderBy} values. If the key maps to no values when
 98    * {@link Iterable#iterator()} is invoked, a 0-length iterator is returned.
 99    * {@link Iterator#remove()} is not supported.
 100    */
 101  0 public Iterable<V> get(final K key) {
 102  0 return new Iterable<V>() {
 103  0 public Iterator<V> iterator() {
 104  0 ExternallySortedSet<V, C> set = _map.get(key);
 105  0 if (set == null) { return EmptyIterator.make(); }
 106  0 else { return ImmutableIterator.make(set.iterator()); }
 107    }
 108    };
 109    }
 110   
 111    /**
 112    * Adds the (key, value) pair if it is not already present.
 113    * @return {@code true} iff the (key, value) pair is not already present in the map.
 114    */
 115  0 public boolean put(K key, V value, C orderBy) {
 116  0 ExternallySortedSet<V, C> set = _map.get(key);
 117  0 if (set == null) { set = new ExternallySortedSet<V, C>(); _map.put(key, set); }
 118  0 if (set.add(value, orderBy)) { _size++; return true; }
 119  0 else { return false; }
 120    }
 121   
 122    /**
 123    * Removes the (key, value) pair if it is present.
 124    * @return {@code true} iff the (key, value) pair was present in (and thus removed from)
 125    * the map.
 126    */
 127  0 public boolean remove(K key, V value) {
 128  0 ExternallySortedSet<V, C> set = _map.get(key);
 129  0 if (set == null) { return false; }
 130    else {
 131  0 if (set.remove(value)) {
 132  0 _size--;
 133  0 if (set.isEmpty()) { _map.remove(key); }
 134    }
 135    else {
 136  0 return false;
 137    }
 138    }
 139  0 return true;
 140    }
 141   
 142    /**
 143    * Removes all values associated with the specified key.
 144    * @return {@code true} iff the operation modifies the map.
 145    */
 146  0 public boolean removeKey(K key) {
 147  0 ExternallySortedSet<V, C> set = _map.get(key);
 148  0 if (set == null) { return false; }
 149  0 else { _map.remove(key); _size -= set.size(); return true; }
 150    }
 151   
 152    /**
 153    * Adds all (key, value) pairs represented by {@code map} to this map. If a mapping is already
 154    * present, adding it makes no modifications; otherwise, the pair is added, sorted according
 155    * to the {@code orderBy} value in {@code map}.
 156    * @return {@code true} iff the operation modified the map.
 157    */
 158  0 public boolean putAll(ExternallySortedMultiMap<? extends K, ? extends V, ? extends C> map) {
 159  0 boolean result = false;
 160  0 for (Map.Entry<? extends K, ? extends ExternallySortedSet<? extends V, ? extends C>> e :
 161    map._map.entrySet()) {
 162  0 ExternallySortedSet<V, C> set = _map.get(e.getKey());
 163  0 if (set == null) { set = new ExternallySortedSet<V, C>(); _map.put(e.getKey(), set); }
 164  0 _size -= set.size();
 165   
 166    // The following generates an incorrect type error (javac 5, fixed in javac 6):
 167    //result = result | set.addAll(e.getValue()); // "|" instead of "||" to avoid short-circuit
 168    // The workaround:
 169  0 @SuppressWarnings("unchecked") ExternallySortedSet s = e.getValue();
 170  0 @SuppressWarnings("unchecked") boolean newResult = set.addAll(s);
 171  0 result = result | newResult;
 172   
 173  0 _size += set.size();
 174    }
 175  0 return result;
 176    }
 177   
 178    /** Removes all elements from the map. */
 179  0 public void clear() { _map.clear(); _size = 0; }
 180   
 181    /**
 182    * @return A dynamically-updating iterable of all keys associated with at least one
 183    * value in this map. {@link Iterator#remove()} is not supported.
 184    */
 185  0 public Iterable<K> keys() {
 186  0 return IterUtil.immutable(_map.keySet());
 187    }
 188   
 189    /**
 190    * @return A dynamically-updating iterable of all values associated with any key
 191    * in this map. {@link Iterator#remove()} is not supported.
 192    */
 193  0 public Iterable<V> values() { return IterUtil.immutable(IterUtil.collapse(_map.values())); }
 194   
 195    }