11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2008 The Guava Authors 31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); 51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License. 61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at 71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0 91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software 111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS, 121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and 141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License. 151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.collect; 181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkNotNull; 201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.collect.Maps.safeContainsKey; 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.collect.Maps.safeGet; 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible; 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Predicate; 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Predicates; 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Supplier; 271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.Serializable; 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.AbstractCollection; 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.AbstractMap; 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.AbstractSet; 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collection; 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Iterator; 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.LinkedHashMap; 351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map; 361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map.Entry; 371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Set; 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport javax.annotation.Nullable; 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Table} implementation backed by a map that associates row keys with 431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * column key / value secondary maps. This class provides rapid access to 441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * records by the row key alone or by both keys, but not by just the column key. 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The views returned by {@link #column}, {@link #columnKeySet()}, and {@link 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * #columnMap()} have iterators that don't support {@code remove()}. Otherwise, 481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * all optional operations are supported. Null row keys, columns keys, and 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values are not supported. 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Lookups by row key are often faster than lookups by column key, because 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the data is stored in a {@code Map<R, Map<C, V>>}. A method call like {@code 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * column(columnKey).get(rowKey)} still runs quickly, since the row key is 541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * provided. However, {@code column(columnKey).size()} takes longer, since an 551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * iteration across all row keys occurs. 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note that this implementation is not synchronized. If multiple threads 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * access this table concurrently and one of the threads modifies the table, it 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * must be synchronized externally. 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Jared Levy 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertclass StandardTable<R, C, V> implements Table<R, C, V>, Serializable { 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtTransient final Map<R, Map<C, V>> backingMap; 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtTransient final Supplier<? extends Map<C, V>> factory; 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert StandardTable(Map<R, Map<C, V>> backingMap, 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Supplier<? extends Map<C, V>> factory) { 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.backingMap = backingMap; 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.factory = factory; 721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Accessors 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains( 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Nullable Object rowKey, @Nullable Object columnKey) { 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if ((rowKey == null) || (columnKey == null)) { 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<C, V> map = safeGet(backingMap, rowKey); 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map != null && safeContainsKey(map, columnKey); 831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsColumn(@Nullable Object columnKey) { 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (columnKey == null) { 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Map<C, V> map : backingMap.values()) { 901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (safeContainsKey(map, columnKey)) { 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsRow(@Nullable Object rowKey) { 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return rowKey != null && safeContainsKey(backingMap, rowKey); 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsValue(@Nullable Object value) { 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (value == null) { 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Map<C, V> map : backingMap.values()) { 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.containsValue(value)) { 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V get(@Nullable Object rowKey, @Nullable Object columnKey) { 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if ((rowKey == null) || (columnKey == null)) { 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return null; 1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<C, V> map = safeGet(backingMap, rowKey); 1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map == null ? null : safeGet(map, columnKey); 1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean isEmpty() { 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return backingMap.isEmpty(); 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int size = 0; 1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Map<C, V> map : backingMap.values()) { 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert size += map.size(); 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return size; 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean equals(@Nullable Object obj) { 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (obj == this) { 1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (obj instanceof Table) { 1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Table<?, ?, ?> other = (Table<?, ?, ?>) obj; 1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return cellSet().equals(other.cellSet()); 1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int hashCode() { 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return cellSet().hashCode(); 1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns the string representation {@code rowMap().toString()}. 1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public String toString() { 1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return rowMap().toString(); 1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Mutators 1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void clear() { 1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert backingMap.clear(); 1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private Map<C, V> getOrCreate(R rowKey) { 1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<C, V> map = backingMap.get(rowKey); 1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map == null) { 1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map = factory.get(); 1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert backingMap.put(rowKey, map); 1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map; 1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V put(R rowKey, C columnKey, V value) { 1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(rowKey); 1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(columnKey); 1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(value); 1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return getOrCreate(rowKey).put(columnKey, value); 1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void putAll( 1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Table<? extends R, ? extends C, ? extends V> table) { 1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Cell<? extends R, ? extends C, ? extends V> cell : table.cellSet()) { 1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert put(cell.getRowKey(), cell.getColumnKey(), cell.getValue()); 1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V remove( 1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Nullable Object rowKey, @Nullable Object columnKey) { 1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if ((rowKey == null) || (columnKey == null)) { 1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return null; 1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<C, V> map = safeGet(backingMap, rowKey); 1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map == null) { 1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return null; 1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V value = map.remove(columnKey); 1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.isEmpty()) { 1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert backingMap.remove(rowKey); 1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return value; 1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private Map<R, V> removeColumn(Object column) { 2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<R, V> output = new LinkedHashMap<R, V>(); 2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<Entry<R, Map<C, V>>> iterator 2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = backingMap.entrySet().iterator(); 2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (iterator.hasNext()) { 2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<R, Map<C, V>> entry = iterator.next(); 2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V value = entry.getValue().remove(column); 2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (value != null) { 2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert output.put(entry.getKey(), value); 2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (entry.getValue().isEmpty()) { 2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return output; 2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private boolean containsMapping( 2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object rowKey, Object columnKey, Object value) { 2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return value != null && value.equals(get(rowKey, columnKey)); 2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** Remove a row key / column key / value mapping, if present. */ 2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private boolean removeMapping(Object rowKey, Object columnKey, Object value) { 2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (containsMapping(rowKey, columnKey, value)) { 2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert remove(rowKey, columnKey); 2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Views 2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Abstract collection whose {@code isEmpty()} returns whether the table is 2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * empty and whose {@code clear()} clears all table mappings. 2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private abstract class TableCollection<T> extends AbstractCollection<T> { 2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean isEmpty() { 2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return backingMap.isEmpty(); 2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void clear() { 2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert backingMap.clear(); 2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Abstract set whose {@code isEmpty()} returns whether the table is empty and 2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * whose {@code clear()} clears all table mappings. 2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private abstract class TableSet<T> extends AbstractSet<T> { 2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean isEmpty() { 2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return backingMap.isEmpty(); 2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void clear() { 2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert backingMap.clear(); 2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private transient CellSet cellSet; 2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@inheritDoc} 2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The set's iterator traverses the mappings for the first row, the 2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * mappings for the second row, and so on. 2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Each cell is an immutable snapshot of a row key / column key / value 2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * mapping, taken at the time the cell is returned by a method call to the 2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * set or its iterator. 2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<Cell<R, C, V>> cellSet() { 2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CellSet result = cellSet; 2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (result == null) ? cellSet = new CellSet() : result; 2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class CellSet extends TableSet<Cell<R, C, V>> { 2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<Cell<R, C, V>> iterator() { 2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new CellIterator(); 2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return StandardTable.this.size(); 2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(Object obj) { 2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (obj instanceof Cell) { 2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Cell<?, ?, ?> cell = (Cell<?, ?, ?>) obj; 2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return containsMapping( 2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert cell.getRowKey(), cell.getColumnKey(), cell.getValue()); 2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object obj) { 2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (obj instanceof Cell) { 2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Cell<?, ?, ?> cell = (Cell<?, ?, ?>) obj; 2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return removeMapping( 3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert cell.getRowKey(), cell.getColumnKey(), cell.getValue()); 3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class CellIterator implements Iterator<Cell<R, C, V>> { 3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<Entry<R, Map<C, V>>> rowIterator 3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = backingMap.entrySet().iterator(); 3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<R, Map<C, V>> rowEntry; 3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<Entry<C, V>> columnIterator 3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = Iterators.emptyModifiableIterator(); 3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean hasNext() { 3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return rowIterator.hasNext() || columnIterator.hasNext(); 3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Cell<R, C, V> next() { 3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!columnIterator.hasNext()) { 3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert rowEntry = rowIterator.next(); 3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert columnIterator = rowEntry.getValue().entrySet().iterator(); 3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<C, V> columnEntry = columnIterator.next(); 3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Tables.immutableCell( 3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert rowEntry.getKey(), columnEntry.getKey(), columnEntry.getValue()); 3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void remove() { 3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert columnIterator.remove(); 3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (rowEntry.getValue().isEmpty()) { 3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert rowIterator.remove(); 3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Map<C, V> row(R rowKey) { 3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Row(rowKey); 3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class Row extends AbstractMap<C, V> { 3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final R rowKey; 3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Row(R rowKey) { 3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.rowKey = checkNotNull(rowKey); 3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<C, V> backingRowMap; 3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<C, V> backingRowMap() { 3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (backingRowMap == null 3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert || (backingRowMap.isEmpty() && backingMap.containsKey(rowKey))) 3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? backingRowMap = computeBackingRowMap() 3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert : backingRowMap; 3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<C, V> computeBackingRowMap() { 3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return backingMap.get(rowKey); 3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Call this every time we perform a removal. 3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert void maintainEmptyInvariant() { 3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (backingRowMap() != null && backingRowMap.isEmpty()) { 3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert backingMap.remove(rowKey); 3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert backingRowMap = null; 3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean containsKey(Object key) { 3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<C, V> backingRowMap = backingRowMap(); 3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (key != null && backingRowMap != null) 3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && Maps.safeContainsKey(backingRowMap, key); 3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V get(Object key) { 3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<C, V> backingRowMap = backingRowMap(); 3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (key != null && backingRowMap != null) 3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? Maps.safeGet(backingRowMap, key) 3791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert : null; 3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 3831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V put(C key, V value) { 3841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(key); 3851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(value); 3861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (backingRowMap != null && !backingRowMap.isEmpty()) { 3871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return backingRowMap.put(key, value); 3881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return StandardTable.this.put(rowKey, key, value); 3901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 3931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V remove(Object key) { 3941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 3951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<C, V> backingRowMap = backingRowMap(); 3961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (backingRowMap == null) { 3971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return null; 3981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V result = backingRowMap.remove(key); 4001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert maintainEmptyInvariant(); 4011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 4021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (ClassCastException e) { 4031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return null; 4041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void clear() { 4091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<C, V> backingRowMap = backingRowMap(); 4101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (backingRowMap != null) { 4111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert backingRowMap.clear(); 4121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert maintainEmptyInvariant(); 4141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<C> keySet; 4171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Set<C> keySet() { 4201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<C> result = keySet; 4211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 4221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return keySet = new Maps.KeySet<C, V>() { 4231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<C, V> map() { 4251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Row.this; 4261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 4281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 4301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<C, V>> entrySet; 4331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Set<Entry<C, V>> entrySet() { 4361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<C, V>> result = entrySet; 4371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 4381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entrySet = new RowEntrySet(); 4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 4411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class RowEntrySet extends Maps.EntrySet<C, V> { 4441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<C, V> map() { 4461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Row.this; 4471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public int size() { 4511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<C, V> map = backingRowMap(); 4521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (map == null) ? 0 : map.size(); 4531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Iterator<Entry<C, V>> iterator() { 4571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Map<C, V> map = backingRowMap(); 4581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map == null) { 4591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Iterators.emptyModifiableIterator(); 4601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<Entry<C, V>> iterator = map.entrySet().iterator(); 4621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Iterator<Entry<C, V>>() { 4631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean hasNext() { 4641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return iterator.hasNext(); 4651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Entry<C, V> next() { 4671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Entry<C, V> entry = iterator.next(); 4681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ForwardingMapEntry<C, V>() { 4691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Entry<C, V> delegate() { 4701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entry; 4711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V setValue(V value) { 4731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return super.setValue(checkNotNull(value)); 4741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean equals(Object object) { 4771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // TODO(user): identify why this affects GWT tests 4781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardEquals(object); 4791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 4811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void remove() { 4851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 4861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert maintainEmptyInvariant(); 4871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 4891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 4941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@inheritDoc} 4951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned map's views have iterators that don't support 4971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code remove()}. 4981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 4991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Map<R, V> column(C columnKey) { 5001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Column(columnKey); 5011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class Column extends Maps.ImprovedAbstractMap<R, V> { 5041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final C columnKey; 5051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Column(C columnKey) { 5071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.columnKey = checkNotNull(columnKey); 5081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V put(R key, V value) { 5111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return StandardTable.this.put(key, columnKey, value); 5121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V get(Object key) { 5151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return StandardTable.this.get(key, columnKey); 5161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsKey(Object key) { 5191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return StandardTable.this.contains(key, columnKey); 5201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V remove(Object key) { 5231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return StandardTable.this.remove(key, columnKey); 5241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<Entry<R, V>> createEntrySet() { 5271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new EntrySet(); 5281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Values columnValues; 5311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> values() { 5331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Values result = columnValues; 5341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (result == null) ? columnValues = new Values() : result; 5351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 5381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Removes all {@code Column} mappings whose row key and value satisfy the 5391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * given predicate. 5401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 5411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean removePredicate(Predicate<? super Entry<R, V>> predicate) { 5421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean changed = false; 5431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<Entry<R, Map<C, V>>> iterator 5441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = backingMap.entrySet().iterator(); 5451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (iterator.hasNext()) { 5461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<R, Map<C, V>> entry = iterator.next(); 5471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<C, V> map = entry.getValue(); 5481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V value = map.get(columnKey); 5491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (value != null 5501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && predicate.apply( 5511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new ImmutableEntry<R, V>(entry.getKey(), value))) { 5521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.remove(columnKey); 5531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed = true; 5541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.isEmpty()) { 5551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 5561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return changed; 5601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class EntrySet extends AbstractSet<Entry<R, V>> { 5631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<Entry<R, V>> iterator() { 5641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new EntrySetIterator(); 5651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 5681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int size = 0; 5691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Map<C, V> map : backingMap.values()) { 5701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.containsKey(columnKey)) { 5711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert size++; 5721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return size; 5751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean isEmpty() { 5781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return !containsColumn(columnKey); 5791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void clear() { 5821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<Entry<R, V>> predicate = Predicates.alwaysTrue(); 5831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert removePredicate(predicate); 5841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(Object o) { 5871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (o instanceof Entry) { 5881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<?, ?> entry = (Entry<?, ?>) o; 5891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return containsMapping(entry.getKey(), columnKey, entry.getValue()); 5901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 5921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object obj) { 5951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (obj instanceof Entry) { 5961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<?, ?> entry = (Entry<?, ?>) obj; 5971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return removeMapping(entry.getKey(), columnKey, entry.getValue()); 5981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 6001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean removeAll(Collection<?> c) { 6031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean changed = false; 6041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Object obj : c) { 6051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed |= remove(obj); 6061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return changed; 6081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean retainAll(Collection<?> c) { 6111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return removePredicate(Predicates.not(Predicates.in(c))); 6121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class EntrySetIterator extends AbstractIterator<Entry<R, V>> { 6161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<Entry<R, Map<C, V>>> iterator 6171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = backingMap.entrySet().iterator(); 6181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Entry<R, V> computeNext() { 6191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (iterator.hasNext()) { 6201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Entry<R, Map<C, V>> entry = iterator.next(); 6211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (entry.getValue().containsKey(columnKey)) { 6221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new AbstractMapEntry<R, V>() { 6231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public R getKey() { 6241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entry.getKey(); 6251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V getValue() { 6271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entry.getValue().get(columnKey); 6281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V setValue(V value) { 6301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entry.getValue().put(columnKey, checkNotNull(value)); 6311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 6331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return endOfData(); 6361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert KeySet keySet; 6401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<R> keySet() { 6421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert KeySet result = keySet; 6431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result == null ? keySet = new KeySet() : result; 6441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class KeySet extends AbstractSet<R> { 6471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<R> iterator() { 6481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return keyIteratorImpl(Column.this); 6491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 6521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entrySet().size(); 6531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean isEmpty() { 6561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return !containsColumn(columnKey); 6571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(Object obj) { 6601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return StandardTable.this.contains(obj, columnKey); 6611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object obj) { 6641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return StandardTable.this.remove(obj, columnKey) != null; 6651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void clear() { 6681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entrySet().clear(); 6691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean removeAll(final Collection<?> c) { 6721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean changed = false; 6731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Object obj : c) { 6741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed |= remove(obj); 6751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return changed; 6771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean retainAll(final Collection<?> c) { 6801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(c); 6811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<Entry<R, V>> predicate = new Predicate<Entry<R, V>>() { 6821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 6831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean apply(Entry<R, V> entry) { 6841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return !c.contains(entry.getKey()); 6851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 6871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return removePredicate(predicate); 6881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class Values extends AbstractCollection<V> { 6921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<V> iterator() { 6931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return valueIteratorImpl(Column.this); 6941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 6971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entrySet().size(); 6981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean isEmpty() { 7011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return !containsColumn(columnKey); 7021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void clear() { 7051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entrySet().clear(); 7061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object obj) { 7091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (obj == null) { 7101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 7111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<Map<C, V>> iterator = backingMap.values().iterator(); 7131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (iterator.hasNext()) { 7141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<C, V> map = iterator.next(); 7151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.entrySet().remove( 7161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new ImmutableEntry<C, Object>(columnKey, obj))) { 7171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.isEmpty()) { 7181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 7191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 7211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 7241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean removeAll(final Collection<?> c) { 7271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(c); 7281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<Entry<R, V>> predicate = new Predicate<Entry<R, V>>() { 7291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 7301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean apply(Entry<R, V> entry) { 7311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return c.contains(entry.getValue()); 7321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 7341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return removePredicate(predicate); 7351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean retainAll(final Collection<?> c) { 7381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(c); 7391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<Entry<R, V>> predicate = new Predicate<Entry<R, V>>() { 7401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 7411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean apply(Entry<R, V> entry) { 7421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return !c.contains(entry.getValue()); 7431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 7451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return removePredicate(predicate); 7461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private transient RowKeySet rowKeySet; 7511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<R> rowKeySet() { 7531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<R> result = rowKeySet; 7541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (result == null) ? rowKeySet = new RowKeySet() : result; 7551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class RowKeySet extends TableSet<R> { 7581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<R> iterator() { 7591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return keyIteratorImpl(rowMap()); 7601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 7631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return backingMap.size(); 7641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(Object obj) { 7671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return containsRow(obj); 7681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object obj) { 7711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (obj != null) && backingMap.remove(obj) != null; 7721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private transient Set<C> columnKeySet; 7761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 7781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@inheritDoc} 7791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned set has an iterator that does not support {@code remove()}. 7811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The set's iterator traverses the columns of the first row, the 7831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * columns of the second row, etc., skipping any columns that have 7841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * appeared previously. 7851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 7861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 7871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Set<C> columnKeySet() { 7881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<C> result = columnKeySet; 7891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (result == null) ? columnKeySet = new ColumnKeySet() : result; 7901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class ColumnKeySet extends TableSet<C> { 7931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<C> iterator() { 7941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return createColumnKeyIterator(); 7951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 7981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Iterators.size(iterator()); 7991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object obj) { 8021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (obj == null) { 8031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 8041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean changed = false; 8061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<Map<C, V>> iterator = backingMap.values().iterator(); 8071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (iterator.hasNext()) { 8081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<C, V> map = iterator.next(); 8091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.keySet().remove(obj)) { 8101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed = true; 8111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.isEmpty()) { 8121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 8131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return changed; 8171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean removeAll(Collection<?> c) { 8201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(c); 8211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean changed = false; 8221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<Map<C, V>> iterator = backingMap.values().iterator(); 8231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (iterator.hasNext()) { 8241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<C, V> map = iterator.next(); 8251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // map.keySet().removeAll(c) can throw a NPE when map is a TreeMap with 8261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // natural ordering and c contains a null. 8271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (Iterators.removeAll(map.keySet().iterator(), c)) { 8281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed = true; 8291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.isEmpty()) { 8301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 8311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return changed; 8351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean retainAll(Collection<?> c) { 8381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(c); 8391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean changed = false; 8401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<Map<C, V>> iterator = backingMap.values().iterator(); 8411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (iterator.hasNext()) { 8421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<C, V> map = iterator.next(); 8431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.keySet().retainAll(c)) { 8441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed = true; 8451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.isEmpty()) { 8461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 8471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return changed; 8511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(Object obj) { 8541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (obj == null) { 8551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 8561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Map<C, V> map : backingMap.values()) { 8581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.containsKey(obj)) { 8591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 8601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 8631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 8671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates an iterator that returns each column value with duplicates 8681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * omitted. 8691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 8701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<C> createColumnKeyIterator() { 8711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ColumnKeyIterator(); 8721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class ColumnKeyIterator extends AbstractIterator<C> { 8751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Use the same map type to support TreeMaps with comparators that aren't 8761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // consistent with equals(). 8771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Map<C, V> seen = factory.get(); 8781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<Map<C, V>> mapIterator = backingMap.values().iterator(); 8791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<Entry<C, V>> entryIterator = Iterators.emptyIterator(); 8801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected C computeNext() { 8821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (true) { 8831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (entryIterator.hasNext()) { 8841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<C, V> entry = entryIterator.next(); 8851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!seen.containsKey(entry.getKey())) { 8861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert seen.put(entry.getKey(), entry.getValue()); 8871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entry.getKey(); 8881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (mapIterator.hasNext()) { 8901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entryIterator = mapIterator.next().entrySet().iterator(); 8911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 8921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return endOfData(); 8931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private transient Values values; 8991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 9011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@inheritDoc} 9021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 9031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The collection's iterator traverses the values for the first row, 9041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the values for the second row, and so on. 9051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 9061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> values() { 9071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Values result = values; 9081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (result == null) ? values = new Values() : result; 9091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class Values extends TableCollection<V> { 9121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<V> iterator() { 9131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<Cell<R, C, V>> cellIterator = cellSet().iterator(); 9141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Iterator<V>() { 9151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean hasNext() { 9161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return cellIterator.hasNext(); 9171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V next() { 9191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return cellIterator.next().getValue(); 9201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void remove() { 9221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert cellIterator.remove(); 9231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 9251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 9281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return StandardTable.this.size(); 9291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private transient RowMap rowMap; 9331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Map<R, Map<C, V>> rowMap() { 9351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert RowMap result = rowMap; 9361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (result == null) ? rowMap = new RowMap() : result; 9371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class RowMap extends Maps.ImprovedAbstractMap<R, Map<C, V>> { 9401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsKey(Object key) { 9411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return containsRow(key); 9421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // performing cast only when key is in backing map and has the correct type 9451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 9461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Map<C, V> get(Object key) { 9471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return containsRow(key) ? row((R) key) : null; 9481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<R> keySet() { 9511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return rowKeySet(); 9521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Map<C, V> remove(Object key) { 9551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (key == null) ? null : backingMap.remove(key); 9561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Set<Entry<R, Map<C, V>>> createEntrySet() { 9591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new EntrySet(); 9601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class EntrySet extends TableSet<Entry<R, Map<C, V>>> { 9631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<Entry<R, Map<C, V>>> iterator() { 9641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new EntryIterator(); 9651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 9681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return backingMap.size(); 9691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(Object obj) { 9721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (obj instanceof Entry) { 9731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<?, ?> entry = (Entry<?, ?>) obj; 9741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entry.getKey() != null 9751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && entry.getValue() instanceof Map 9761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && Collections2.safeContains(backingMap.entrySet(), entry); 9771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 9791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object obj) { 9821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (obj instanceof Entry) { 9831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<?, ?> entry = (Entry<?, ?>) obj; 9841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entry.getKey() != null 9851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && entry.getValue() instanceof Map 9861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && backingMap.entrySet().remove(entry); 9871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 9891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class EntryIterator implements Iterator<Entry<R, Map<C, V>>> { 9931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<R> delegate = backingMap.keySet().iterator(); 9941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean hasNext() { 9961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate.hasNext(); 9971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Entry<R, Map<C, V>> next() { 10001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert R rowKey = delegate.next(); 10011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ImmutableEntry<R, Map<C, V>>(rowKey, row(rowKey)); 10021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void remove() { 10051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert delegate.remove(); 10061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private transient ColumnMap columnMap; 10111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Map<C, Map<R, V>> columnMap() { 10131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ColumnMap result = columnMap; 10141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (result == null) ? columnMap = new ColumnMap() : result; 10151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class ColumnMap extends Maps.ImprovedAbstractMap<C, Map<R, V>> { 10181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // The cast to C occurs only when the key is in the map, implying that it 10191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // has the correct type. 10201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 10211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Map<R, V> get(Object key) { 10221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return containsColumn(key) ? column((C) key) : null; 10231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsKey(Object key) { 10261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return containsColumn(key); 10271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Map<R, V> remove(Object key) { 10301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return containsColumn(key) ? removeColumn(key) : null; 10311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<Entry<C, Map<R, V>>> createEntrySet() { 10341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ColumnMapEntrySet(); 10351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<C> keySet() { 10381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return columnKeySet(); 10391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ColumnMapValues columnMapValues; 10421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<Map<R, V>> values() { 10441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ColumnMapValues result = columnMapValues; 10451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 10461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert (result == null) ? columnMapValues = new ColumnMapValues() : result; 10471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class ColumnMapEntrySet extends TableSet<Entry<C, Map<R, V>>> { 10501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<Entry<C, Map<R, V>>> iterator() { 10511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<C> columnIterator = columnKeySet().iterator(); 10521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new UnmodifiableIterator<Entry<C, Map<R, V>>>() { 10531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean hasNext() { 10541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return columnIterator.hasNext(); 10551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Entry<C, Map<R, V>> next() { 10571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert C columnKey = columnIterator.next(); 10581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ImmutableEntry<C, Map<R, V>>( 10591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert columnKey, column(columnKey)); 10601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 10621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 10651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return columnKeySet().size(); 10661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(Object obj) { 10691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (obj instanceof Entry) { 10701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<?, ?> entry = (Entry<?, ?>) obj; 10711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (containsColumn(entry.getKey())) { 10721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // The cast to C occurs only when the key is in the map, implying 10731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // that it has the correct type. 10741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 10751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert C columnKey = (C) entry.getKey(); 10761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return get(columnKey).equals(entry.getValue()); 10771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 10801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object obj) { 10831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (contains(obj)) { 10841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<?, ?> entry = (Entry<?, ?>) obj; 10851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert removeColumn(entry.getKey()); 10861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 10871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 10891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean removeAll(Collection<?> c) { 10921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean changed = false; 10931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Object obj : c) { 10941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed |= remove(obj); 10951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return changed; 10971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean retainAll(Collection<?> c) { 11001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean changed = false; 11011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (C columnKey : Lists.newArrayList(columnKeySet().iterator())) { 11021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!c.contains(new ImmutableEntry<C, Map<R, V>>( 11031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert columnKey, column(columnKey)))) { 11041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert removeColumn(columnKey); 11051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed = true; 11061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return changed; 11091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class ColumnMapValues extends TableCollection<Map<R, V>> { 11131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<Map<R, V>> iterator() { 11141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return valueIteratorImpl(ColumnMap.this); 11151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object obj) { 11181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Entry<C, Map<R, V>> entry : ColumnMap.this.entrySet()) { 11191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (entry.getValue().equals(obj)) { 11201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert removeColumn(entry.getKey()); 11211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 11221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 11251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean removeAll(Collection<?> c) { 11281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(c); 11291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean changed = false; 11301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (C columnKey : Lists.newArrayList(columnKeySet().iterator())) { 11311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (c.contains(column(columnKey))) { 11321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert removeColumn(columnKey); 11331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed = true; 11341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return changed; 11371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean retainAll(Collection<?> c) { 11401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(c); 11411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean changed = false; 11421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (C columnKey : Lists.newArrayList(columnKeySet().iterator())) { 11431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!c.contains(column(columnKey))) { 11441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert removeColumn(columnKey); 11451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed = true; 11461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return changed; 11491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 11521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return columnKeySet().size(); 11531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 11581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // TODO(kevinb): Move keyIteratorImpl and valueIteratorImpl to Maps, reuse 11601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 11621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Generates the iterator of a map's key set from the map's entry set 11631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * iterator. 11641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 11651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static <K, V> Iterator<K> keyIteratorImpl(Map<K, V> map) { 11661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<Entry<K, V>> entryIterator = map.entrySet().iterator(); 11671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Iterator<K>() { 11681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean hasNext() { 11691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entryIterator.hasNext(); 11701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public K next() { 11721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entryIterator.next().getKey(); 11731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void remove() { 11751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entryIterator.remove(); 11761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 11781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 11811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Generates the iterator of a map's value collection from the map's entry set 11821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * iterator. 11831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 11841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static <K, V> Iterator<V> valueIteratorImpl(Map<K, V> map) { 11851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<Entry<K, V>> entryIterator = map.entrySet().iterator(); 11861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Iterator<V>() { 11871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean hasNext() { 11881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entryIterator.hasNext(); 11891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V next() { 11911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entryIterator.next().getValue(); 11921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void remove() { 11941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entryIterator.remove(); 11951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 11971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 1199