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