diff --git a/filefilter.txt b/filefilter.txt index 68e5d1d2200d..fda512c6f166 100644 --- a/filefilter.txt +++ b/filefilter.txt @@ -7,5 +7,4 @@ - \com\navercorp\pinpoint\common\util\apache - \com\navercorp\pinpoint\common\util\jsr166 - \com\navercorp\pinpoint\profiler\util\jdk -- \com\navercorp\pinpoint\bootstrap\util\spring -- \com\google \ No newline at end of file +- \com\navercorp\pinpoint\bootstrap\util\spring \ No newline at end of file diff --git a/findbugs-exclude.xml b/findbugs-exclude.xml index 1202c34082eb..2982e613d3c7 100644 --- a/findbugs-exclude.xml +++ b/findbugs-exclude.xml @@ -2,8 +2,4 @@ - - - - \ No newline at end of file diff --git a/pom.xml b/pom.xml index 30e17414d9e1..bfd9f373e60d 100644 --- a/pom.xml +++ b/pom.xml @@ -66,7 +66,6 @@ test web hbase - thirdparty @@ -119,11 +118,6 @@ pinpoint-commons ${project.version} - - com.navercorp.pinpoint - pinpoint-google-guava - ${project.version} - com.navercorp.pinpoint pinpoint-commons-server @@ -829,9 +823,6 @@ com/navercorp/pinpoint/common/util/apache/**/*.java com/navercorp/pinpoint/common/util/jsr166/**/*.java com/navercorp/pinpoint/profiler/util/jdk/**/*.java - - - com/google/**/*.java @@ -898,9 +889,6 @@ com/navercorp/pinpoint/common/util/apache/**/*.java com/navercorp/pinpoint/common/util/jsr166/**/*.java com/navercorp/pinpoint/profiler/util/jdk/**/*.java - - - com/google/**/*.java @@ -990,9 +978,6 @@ com/navercorp/pinpoint/common/util/apache/**/*.java com/navercorp/pinpoint/common/util/jsr166/**/*.java com/navercorp/pinpoint/profiler/util/jdk/**/*.java - - - com/google/**/*.java @@ -1010,9 +995,6 @@ com/navercorp/pinpoint/common/util/apache/**/*.java com/navercorp/pinpoint/common/util/jsr166/**/*.java com/navercorp/pinpoint/profiler/util/jdk/**/*.java - - - com/google/**/*.java diff --git a/profiler-test/pom.xml b/profiler-test/pom.xml index 156b9bfb5ed5..6c3e083e0d85 100644 --- a/profiler-test/pom.xml +++ b/profiler-test/pom.xml @@ -68,8 +68,8 @@ pinpoint-rpc - com.navercorp.pinpoint - pinpoint-google-guava + com.google.guava + guava diff --git a/profiler/pom.xml b/profiler/pom.xml index 8f546bfe0f3a..49ca5bef351f 100644 --- a/profiler/pom.xml +++ b/profiler/pom.xml @@ -57,8 +57,8 @@ pinpoint-rpc - com.navercorp.pinpoint - pinpoint-google-guava + com.google.guava + guava com.google.inject diff --git a/thirdparty/.gitignore b/thirdparty/.gitignore deleted file mode 100644 index f6772784a0a9..000000000000 --- a/thirdparty/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/target/ -/.settings/ -/.classpath -/.project -/*.iml \ No newline at end of file diff --git a/thirdparty/README.md b/thirdparty/README.md deleted file mode 100644 index 0e68689a3b43..000000000000 --- a/thirdparty/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# thirdparty lib project - - google-guava \ No newline at end of file diff --git a/thirdparty/clover.license b/thirdparty/clover.license deleted file mode 100644 index 569fa6175b4c..000000000000 --- a/thirdparty/clover.license +++ /dev/null @@ -1,5 +0,0 @@ -RMRqrdbgbKFhbaVnDxHUdDQvrOQXxIBklnvcmahheubVC -mh2KM35CLkwUHS4DH7QVhxy52J5hnWbyEm6Cyd3KkF - 4.0.0 - - com.navercorp.pinpoint - pinpoint - ../.. - 1.6.1-SNAPSHOT - - - - pinpoint-google-guava - pinpoint-google-guava - jar - - - 1.6 - ${env.JAVA_7_HOME} - java16 - - - - - - - com.google.code.findbugs - jsr305 - 1.3.9 - provided - - - com.google.j2objc - j2objc-annotations - 1.1 - provided - - - org.codehaus.mojo - animal-sniffer-annotations - 1.14 - provided - - - - - - org.slf4j - slf4j-api - test - - - org.slf4j - slf4j-log4j12 - test - - - log4j - log4j - test - - - - - - - - - org.codehaus.mojo - build-helper-maven-plugin - 1.10 - - - generate-sources - add-source - - - src/main/java-logging - - - - - - - com.google.code.maven-replacer-plugin - replacer - 1.5.3 - - - generate-sources - - replace - - - - - ${encoding} - ${project.build.sourceDirectory}/ - - **/*.java - - - - - - - java.util.logging. - com.google.common.logging. - - - - - - - - - - - - - - - - - diff --git a/thirdparty/google-guava/src/main/java-logging/com/google/common/logging/Level.java b/thirdparty/google-guava/src/main/java-logging/com/google/common/logging/Level.java deleted file mode 100644 index d30ce5b282dc..000000000000 --- a/thirdparty/google-guava/src/main/java-logging/com/google/common/logging/Level.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2016 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package com.google.common.logging; - -/** - * compiler trick class - * @author Woonduk Kang(emeroad) - */ -public enum Level { - - OFF(Integer.MAX_VALUE), - SEVERE(1000), - WARNING(900), - CONFIG(700), - INFO(800), - FINE(500), - FINER(400), - FINEST(300), - ALL(Integer.MIN_VALUE); - - - - private final int level; - - Level(int level) { - this.level = level; - } - - public int intValue() { - return level; - } - - public String getName() { - return name(); - } -} diff --git a/thirdparty/google-guava/src/main/java-logging/com/google/common/logging/Logger.java b/thirdparty/google-guava/src/main/java-logging/com/google/common/logging/Logger.java deleted file mode 100644 index 5c02001e05a5..000000000000 --- a/thirdparty/google-guava/src/main/java-logging/com/google/common/logging/Logger.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright 2016 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package com.google.common.logging; - - -import java.io.PrintStream; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.text.MessageFormat; - -/** - * compiler trick class - * - * @author Woonduk Kang(emeroad) - */ -public class Logger { - - private static Level DEFAULT_LOG_LEVEL; - - private final String name; - private final String messagePattern; - private final Level level; - - private final PrintStream out; - private final PrintStream err; - - static { - setup(); - - } - - private static void setup() { - // TODO setup log level - DEFAULT_LOG_LEVEL = Level.INFO; - } - - public static Logger getLogger(String name) { - return new Logger(name, DEFAULT_LOG_LEVEL); - } - - public Logger(String name, Level level) { - this(name, level, System.out, System.err); - } - - Logger(String name, Level level, PrintStream out, PrintStream err) { - this.name = name; - this.level = level; - this.messagePattern = "{0,date,yyyy-MM-dd HH:mm:ss} [{1}](" + name + ") {2}{3}"; - this.out = out; - this.err = err; - } - - public String getName() { - return name; - } - - public void log(Level level, String msg) { - if (!isLoggable(level)) { - return; - } - doLog(level, msg, null, null); - } - - public void log(Level level, String msg, Throwable throwable) { - if (!isLoggable(level)) { - return; - } - doLog(level, msg, null, throwable); - } - - public void log(Level level, String msg, Object params[]) { - if (!isLoggable(level)) { - return; - } - doLog(level, msg, params, null); - } - - - - public void log(Level level, String msg, Object param1) { - if (!isLoggable(level)) { - return; - } - doLog(level, msg, new Object[]{param1}, null); - } - - private void doLog(Level level, String msg, Object[] params, Throwable throwable) { - - String format = messageFormat(msg, params); - - String exceptionMessage = toString(throwable); - String logMessage = logFormat(level, format, exceptionMessage); - - PrintStream printStream = getPrintStream(level); - printStream.println(logMessage); - - } - - private PrintStream getPrintStream(Level level) { - if (level.intValue() >= Level.WARNING.intValue()) { - return this.err; - } else { - return this.out; - } - } - - public boolean isLoggable(Level level) { - if (level.intValue() < this.level.intValue()) { - return false; - } - return true; - } - - public void info(String msg) { - Level logLevel = Level.INFO; - if (!isLoggable(logLevel)) { - return; - } - doLog(Level.INFO, msg, null, null); - } - - public void warning(String msg) { - if (!isLoggable(Level.WARNING)) { - return; - } - doLog(Level.WARNING, msg, null, null); - } - - private String messageFormat(String format, Object[] parameter) { - if (parameter == null || parameter.length == 0) { - return format; - } - // emulation java util.logging - if (format.indexOf("{0") >= 0 || format.indexOf("{1") >= 0 || format.indexOf("{2") >= 0 || format.indexOf("{3") >= 0) { - return MessageFormat.format(format, parameter); - } - - return format; - } - private String logFormat(Level logLevel, String msg, String exceptionMessage) { - exceptionMessage = defaultString(exceptionMessage, ""); - - final long date = System.currentTimeMillis(); - return MessageFormat.format(messagePattern, date, logLevel.getName(), msg, exceptionMessage); - } - - private String toString(Throwable throwable) { - if (throwable == null) { - return ""; - } - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - pw.println(); - throwable.printStackTrace(pw); - pw.close(); - return sw.toString(); - } - - private String defaultString(String exceptionMessage, String defaultValue) { - if (exceptionMessage == null) { - return defaultValue; - } - return exceptionMessage; - } - -} diff --git a/thirdparty/google-guava/src/main/java-logging/com/google/common/logging/package-info.java b/thirdparty/google-guava/src/main/java-logging/com/google/common/logging/package-info.java deleted file mode 100644 index c61b39bbe60f..000000000000 --- a/thirdparty/google-guava/src/main/java-logging/com/google/common/logging/package-info.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2016 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package com.google.common.logging;/* - - -/** - * compiler trick package - */ - diff --git a/thirdparty/google-guava/src/main/java/com/google/common/annotations/Beta.java b/thirdparty/google-guava/src/main/java/com/google/common/annotations/Beta.java deleted file mode 100644 index 5eefe9abd0ce..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/annotations/Beta.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2010 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.annotations; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Signifies that a public API (public class, method or field) is subject to - * incompatible changes, or even removal, in a future release. An API bearing - * this annotation is exempt from any compatibility guarantees made by its - * containing library. Note that the presence of this annotation implies nothing - * about the quality or performance of the API in question, only the fact that - * it is not "API-frozen." - * - *

It is generally safe for applications to depend on beta APIs, at - * the cost of some extra work during upgrades. However it is generally - * inadvisable for libraries (which get included on users' CLASSPATHs, - * outside the library developers' control) to do so. - * - * - * @author Kevin Bourrillion - */ -@Retention(RetentionPolicy.CLASS) -@Target({ - ElementType.ANNOTATION_TYPE, - ElementType.CONSTRUCTOR, - ElementType.FIELD, - ElementType.METHOD, - ElementType.TYPE}) -@Documented -@GwtCompatible -public @interface Beta {} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/annotations/GwtCompatible.java b/thirdparty/google-guava/src/main/java/com/google/common/annotations/GwtCompatible.java deleted file mode 100644 index 85bfa4df127f..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/annotations/GwtCompatible.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.annotations; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * The presence of this annotation on a type indicates that the type may be - * used with the - * Google Web Toolkit (GWT). - * When applied to a method, the return type of the method is GWT compatible. - * It's useful to indicate that an instance created by factory methods has a GWT - * serializable type. In the following example, - * - *

- * {@literal @}GwtCompatible
- * class Lists {
- *   ...
- *   {@literal @}GwtCompatible(serializable = true)
- *   static <E> List<E> newArrayList(E... elements) {
- *     ...
- *   }
- * }
- * 
- *

The return value of {@code Lists.newArrayList(E[])} has GWT - * serializable type. It is also useful in specifying contracts of interface - * methods. In the following example, - * - *

- * {@literal @}GwtCompatible
- * interface ListFactory {
- *   ...
- *   {@literal @}GwtCompatible(serializable = true)
- *   <E> List<E> newArrayList(E... elements);
- * }
- * 
- *

The {@code newArrayList(E[])} method of all implementations of {@code - * ListFactory} is expected to return a value with a GWT serializable type. - * - *

Note that a {@code GwtCompatible} type may have some {@link - * GwtIncompatible} methods. - * - * @author Charles Fry - * @author Hayward Chan - */ -@Retention(RetentionPolicy.CLASS) -@Target({ ElementType.TYPE, ElementType.METHOD }) -@Documented -@GwtCompatible -public @interface GwtCompatible { - - /** - * When {@code true}, the annotated type or the type of the method return - * value is GWT serializable. - * - * @see - * Documentation about GWT serialization - */ - boolean serializable() default false; - - /** - * When {@code true}, the annotated type is emulated in GWT. The emulated - * source (also known as super-source) is different from the implementation - * used by the JVM. - * - * @see - * Documentation about GWT emulated source - */ - boolean emulated() default false; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/annotations/GwtIncompatible.java b/thirdparty/google-guava/src/main/java/com/google/common/annotations/GwtIncompatible.java deleted file mode 100644 index a56d746c8c08..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/annotations/GwtIncompatible.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.annotations; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * The presence of this annotation on a method indicates that the method may - * not be used with the - * Google Web Toolkit (GWT), - * even though its type is annotated as {@link GwtCompatible} and accessible in - * GWT. They can cause GWT compilation errors or simply unexpected exceptions - * when used in GWT. - * - *

Note that this annotation should only be applied to methods, fields, or - * inner classes of types which are annotated as {@link GwtCompatible}. - * - * @author Charles Fry - */ -@Retention(RetentionPolicy.CLASS) -@Target({ - ElementType.TYPE, ElementType.METHOD, - ElementType.CONSTRUCTOR, ElementType.FIELD }) -@Documented -@GwtCompatible -public @interface GwtIncompatible { - /** - * Describes why the annotated element is incompatible with GWT. Since this is - * generally due to a dependence on a type/method which GWT doesn't support, - * it is sufficient to simply reference the unsupported type/method. E.g. - * "Class.isInstance". - */ - String value(); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/annotations/VisibleForTesting.java b/thirdparty/google-guava/src/main/java/com/google/common/annotations/VisibleForTesting.java deleted file mode 100644 index 6f867db3adb7..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/annotations/VisibleForTesting.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2006 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.annotations; - -/** - * Annotates a program element that exists, or is more widely visible than - * otherwise necessary, only for use in test code. - * - * @author Johannes Henkel - */ -@GwtCompatible -public @interface VisibleForTesting { -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/annotations/package-info.java b/thirdparty/google-guava/src/main/java/com/google/common/annotations/package-info.java deleted file mode 100644 index 2bf8b218c78d..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/annotations/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2010 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Common annotation types. This package is a part of the open-source - * Guava libraries. - */ -package com.google.common.annotations; diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Absent.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Absent.java deleted file mode 100644 index a60762187e4f..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Absent.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Collections; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * Implementation of an {@link Optional} not containing a reference. - */ -@GwtCompatible -final class Absent extends Optional { - static final Absent INSTANCE = new Absent(); - - @SuppressWarnings("unchecked") // implementation is "fully variant" - static Optional withType() { - return (Optional) INSTANCE; - } - - private Absent() {} - - @Override - public boolean isPresent() { - return false; - } - - @Override - public T get() { - throw new IllegalStateException("Optional.get() cannot be called on an absent value"); - } - - @Override - public T or(T defaultValue) { - return checkNotNull(defaultValue, "use Optional.orNull() instead of Optional.or(null)"); - } - - @SuppressWarnings("unchecked") // safe covariant cast - @Override - public Optional or(Optional secondChoice) { - return (Optional) checkNotNull(secondChoice); - } - - @Override - public T or(Supplier supplier) { - return checkNotNull( - supplier.get(), "use Optional.orNull() instead of a Supplier that returns null"); - } - - @Override - @Nullable - public T orNull() { - return null; - } - - @Override - public Set asSet() { - return Collections.emptySet(); - } - - @Override - public Optional transform(Function function) { - checkNotNull(function); - return Optional.absent(); - } - - @Override - public boolean equals(@Nullable Object object) { - return object == this; - } - - @Override - public int hashCode() { - return 0x79a31aac; - } - - @Override - public String toString() { - return "Optional.absent()"; - } - - private Object readResolve() { - return INSTANCE; - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/AbstractIterator.java b/thirdparty/google-guava/src/main/java/com/google/common/base/AbstractIterator.java deleted file mode 100644 index 7b29fea1d530..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/AbstractIterator.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * Note this class is a copy of - * {@link com.google.common.collect.AbstractIterator} (for dependency reasons). - */ -@GwtCompatible -abstract class AbstractIterator implements Iterator { - private State state = State.NOT_READY; - - protected AbstractIterator() {} - - private enum State { - READY, - NOT_READY, - DONE, - FAILED, - } - - private T next; - - protected abstract T computeNext(); - - protected final T endOfData() { - state = State.DONE; - return null; - } - - @Override - public final boolean hasNext() { - checkState(state != State.FAILED); - switch (state) { - case READY: - return true; - case DONE: - return false; - default: - } - return tryToComputeNext(); - } - - private boolean tryToComputeNext() { - state = State.FAILED; // temporary pessimism - next = computeNext(); - if (state != State.DONE) { - state = State.READY; - return true; - } - return false; - } - - @Override - public final T next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - state = State.NOT_READY; - T result = next; - next = null; - return result; - } - - @Override - public final void remove() { - throw new UnsupportedOperationException(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Ascii.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Ascii.java deleted file mode 100644 index 9024290ba54a..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Ascii.java +++ /dev/null @@ -1,669 +0,0 @@ -/* - * Copyright (C) 2010 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import javax.annotation.CheckReturnValue; - -/** - * Static methods pertaining to ASCII characters (those in the range of values - * {@code 0x00} through {@code 0x7F}), and to strings containing such - * characters. - * - *

ASCII utilities also exist in other classes of this package: - *

    - * - *
  • {@link Charsets#US_ASCII} specifies the {@code Charset} of ASCII characters. - *
  • {@link CharMatcher#ASCII} matches ASCII characters and provides text processing methods - * which operate only on the ASCII characters of a string. - *
- * - * @author Craig Berry - * @author Gregory Kick - * @since 7.0 - */ -@CheckReturnValue -@GwtCompatible -public final class Ascii { - - private Ascii() {} - - /* The ASCII control characters, per RFC 20. */ - /** - * Null ('\0'): The all-zeros character which may serve to accomplish - * time fill and media fill. Normally used as a C string terminator. - *

Although RFC 20 names this as "Null", note that it is distinct - * from the C/C++ "NULL" pointer. - * - * @since 8.0 - */ - public static final byte NUL = 0; - - /** - * Start of Heading: A communication control character used at - * the beginning of a sequence of characters which constitute a - * machine-sensible address or routing information. Such a sequence is - * referred to as the "heading." An STX character has the effect of - * terminating a heading. - * - * @since 8.0 - */ - public static final byte SOH = 1; - - /** - * Start of Text: A communication control character which - * precedes a sequence of characters that is to be treated as an entity - * and entirely transmitted through to the ultimate destination. Such a - * sequence is referred to as "text." STX may be used to terminate a - * sequence of characters started by SOH. - * - * @since 8.0 - */ - public static final byte STX = 2; - - /** - * End of Text: A communication control character used to - * terminate a sequence of characters started with STX and transmitted - * as an entity. - * - * @since 8.0 - */ - public static final byte ETX = 3; - - /** - * End of Transmission: A communication control character used - * to indicate the conclusion of a transmission, which may have - * contained one or more texts and any associated headings. - * - * @since 8.0 - */ - public static final byte EOT = 4; - - /** - * Enquiry: A communication control character used in data - * communication systems as a request for a response from a remote - * station. It may be used as a "Who Are You" (WRU) to obtain - * identification, or may be used to obtain station status, or both. - * - * @since 8.0 - */ - public static final byte ENQ = 5; - - /** - * Acknowledge: A communication control character transmitted - * by a receiver as an affirmative response to a sender. - * - * @since 8.0 - */ - public static final byte ACK = 6; - - /** - * Bell ('\a'): A character for use when there is a need to call for - * human attention. It may control alarm or attention devices. - * - * @since 8.0 - */ - public static final byte BEL = 7; - - /** - * Backspace ('\b'): A format effector which controls the movement of - * the printing position one printing space backward on the same - * printing line. (Applicable also to display devices.) - * - * @since 8.0 - */ - public static final byte BS = 8; - - /** - * Horizontal Tabulation ('\t'): A format effector which controls the - * movement of the printing position to the next in a series of - * predetermined positions along the printing line. (Applicable also to - * display devices and the skip function on punched cards.) - * - * @since 8.0 - */ - public static final byte HT = 9; - - /** - * Line Feed ('\n'): A format effector which controls the movement of - * the printing position to the next printing line. (Applicable also to - * display devices.) Where appropriate, this character may have the - * meaning "New Line" (NL), a format effector which controls the - * movement of the printing point to the first printing position on the - * next printing line. Use of this convention requires agreement - * between sender and recipient of data. - * - * @since 8.0 - */ - public static final byte LF = 10; - - /** - * Alternate name for {@link #LF}. ({@code LF} is preferred.) - * - * @since 8.0 - */ - public static final byte NL = 10; - - /** - * Vertical Tabulation ('\v'): A format effector which controls the - * movement of the printing position to the next in a series of - * predetermined printing lines. (Applicable also to display devices.) - * - * @since 8.0 - */ - public static final byte VT = 11; - - /** - * Form Feed ('\f'): A format effector which controls the movement of - * the printing position to the first pre-determined printing line on - * the next form or page. (Applicable also to display devices.) - * - * @since 8.0 - */ - public static final byte FF = 12; - - /** - * Carriage Return ('\r'): A format effector which controls the - * movement of the printing position to the first printing position on - * the same printing line. (Applicable also to display devices.) - * - * @since 8.0 - */ - public static final byte CR = 13; - - /** - * Shift Out: A control character indicating that the code - * combinations which follow shall be interpreted as outside of the - * character set of the standard code table until a Shift In character - * is reached. - * - * @since 8.0 - */ - public static final byte SO = 14; - - /** - * Shift In: A control character indicating that the code - * combinations which follow shall be interpreted according to the - * standard code table. - * - * @since 8.0 - */ - public static final byte SI = 15; - - /** - * Data Link Escape: A communication control character which - * will change the meaning of a limited number of contiguously following - * characters. It is used exclusively to provide supplementary controls - * in data communication networks. - * - * @since 8.0 - */ - public static final byte DLE = 16; - - /** - * Device Control 1. Characters for the control - * of ancillary devices associated with data processing or - * telecommunication systems, more especially switching devices "on" or - * "off." (If a single "stop" control is required to interrupt or turn - * off ancillary devices, DC4 is the preferred assignment.) - * - * @since 8.0 - */ - public static final byte DC1 = 17; // aka XON - - /** - * Transmission On: Although originally defined as DC1, this ASCII - * control character is now better known as the XON code used for software - * flow control in serial communications. The main use is restarting - * the transmission after the communication has been stopped by the XOFF - * control code. - * - * @since 8.0 - */ - public static final byte XON = 17; // aka DC1 - - /** - * Device Control 2. Characters for the control - * of ancillary devices associated with data processing or - * telecommunication systems, more especially switching devices "on" or - * "off." (If a single "stop" control is required to interrupt or turn - * off ancillary devices, DC4 is the preferred assignment.) - * - * @since 8.0 - */ - public static final byte DC2 = 18; - - /** - * Device Control 3. Characters for the control - * of ancillary devices associated with data processing or - * telecommunication systems, more especially switching devices "on" or - * "off." (If a single "stop" control is required to interrupt or turn - * off ancillary devices, DC4 is the preferred assignment.) - * - * @since 8.0 - */ - public static final byte DC3 = 19; // aka XOFF - - /** - * Transmission off. See {@link #XON} for explanation. - * - * @since 8.0 - */ - public static final byte XOFF = 19; // aka DC3 - - /** - * Device Control 4. Characters for the control - * of ancillary devices associated with data processing or - * telecommunication systems, more especially switching devices "on" or - * "off." (If a single "stop" control is required to interrupt or turn - * off ancillary devices, DC4 is the preferred assignment.) - * - * @since 8.0 - */ - public static final byte DC4 = 20; - - /** - * Negative Acknowledge: A communication control character - * transmitted by a receiver as a negative response to the sender. - * - * @since 8.0 - */ - public static final byte NAK = 21; - - /** - * Synchronous Idle: A communication control character used by - * a synchronous transmission system in the absence of any other - * character to provide a signal from which synchronism may be achieved - * or retained. - * - * @since 8.0 - */ - public static final byte SYN = 22; - - /** - * End of Transmission Block: A communication control character - * used to indicate the end of a block of data for communication - * purposes. ETB is used for blocking data where the block structure is - * not necessarily related to the processing format. - * - * @since 8.0 - */ - public static final byte ETB = 23; - - /** - * Cancel: A control character used to indicate that the data - * with which it is sent is in error or is to be disregarded. - * - * @since 8.0 - */ - public static final byte CAN = 24; - - /** - * End of Medium: A control character associated with the sent - * data which may be used to identify the physical end of the medium, or - * the end of the used, or wanted, portion of information recorded on a - * medium. (The position of this character does not necessarily - * correspond to the physical end of the medium.) - * - * @since 8.0 - */ - public static final byte EM = 25; - - /** - * Substitute: A character that may be substituted for a - * character which is determined to be invalid or in error. - * - * @since 8.0 - */ - public static final byte SUB = 26; - - /** - * Escape: A control character intended to provide code - * extension (supplementary characters) in general information - * interchange. The Escape character itself is a prefix affecting the - * interpretation of a limited number of contiguously following - * characters. - * - * @since 8.0 - */ - public static final byte ESC = 27; - - /** - * File Separator: These four information separators may be - * used within data in optional fashion, except that their hierarchical - * relationship shall be: FS is the most inclusive, then GS, then RS, - * and US is least inclusive. (The content and length of a File, Group, - * Record, or Unit are not specified.) - * - * @since 8.0 - */ - public static final byte FS = 28; - - /** - * Group Separator: These four information separators may be - * used within data in optional fashion, except that their hierarchical - * relationship shall be: FS is the most inclusive, then GS, then RS, - * and US is least inclusive. (The content and length of a File, Group, - * Record, or Unit are not specified.) - * - * @since 8.0 - */ - public static final byte GS = 29; - - /** - * Record Separator: These four information separators may be - * used within data in optional fashion, except that their hierarchical - * relationship shall be: FS is the most inclusive, then GS, then RS, - * and US is least inclusive. (The content and length of a File, Group, - * Record, or Unit are not specified.) - * - * @since 8.0 - */ - public static final byte RS = 30; - - /** - * Unit Separator: These four information separators may be - * used within data in optional fashion, except that their hierarchical - * relationship shall be: FS is the most inclusive, then GS, then RS, - * and US is least inclusive. (The content and length of a File, Group, - * Record, or Unit are not specified.) - * - * @since 8.0 - */ - public static final byte US = 31; - - /** - * Space: A normally non-printing graphic character used to - * separate words. It is also a format effector which controls the - * movement of the printing position, one printing position forward. - * (Applicable also to display devices.) - * - * @since 8.0 - */ - public static final byte SP = 32; - - /** - * Alternate name for {@link #SP}. - * - * @since 8.0 - */ - public static final byte SPACE = 32; - - /** - * Delete: This character is used primarily to "erase" or - * "obliterate" erroneous or unwanted characters in perforated tape. - * - * @since 8.0 - */ - public static final byte DEL = 127; - - /** - * The minimum value of an ASCII character. - * - * @since 9.0 (was type {@code int} before 12.0) - */ - public static final char MIN = 0; - - /** - * The maximum value of an ASCII character. - * - * @since 9.0 (was type {@code int} before 12.0) - */ - public static final char MAX = 127; - - /** - * Returns a copy of the input string in which all {@linkplain #isUpperCase(char) uppercase ASCII - * characters} have been converted to lowercase. All other characters are copied without - * modification. - */ - public static String toLowerCase(String string) { - int length = string.length(); - for (int i = 0; i < length; i++) { - if (isUpperCase(string.charAt(i))) { - char[] chars = string.toCharArray(); - for (; i < length; i++) { - char c = chars[i]; - if (isUpperCase(c)) { - chars[i] = (char) (c ^ 0x20); - } - } - return String.valueOf(chars); - } - } - return string; - } - - /** - * Returns a copy of the input character sequence in which all {@linkplain #isUpperCase(char) - * uppercase ASCII characters} have been converted to lowercase. All other characters are copied - * without modification. - * - * @since 14.0 - */ - public static String toLowerCase(CharSequence chars) { - if (chars instanceof String) { - return toLowerCase((String) chars); - } - int length = chars.length(); - StringBuilder builder = new StringBuilder(length); - for (int i = 0; i < length; i++) { - builder.append(toLowerCase(chars.charAt(i))); - } - return builder.toString(); - } - - /** - * If the argument is an {@linkplain #isUpperCase(char) uppercase ASCII character} returns the - * lowercase equivalent. Otherwise returns the argument. - */ - public static char toLowerCase(char c) { - return isUpperCase(c) ? (char) (c ^ 0x20) : c; - } - - /** - * Returns a copy of the input string in which all {@linkplain #isLowerCase(char) lowercase ASCII - * characters} have been converted to uppercase. All other characters are copied without - * modification. - */ - public static String toUpperCase(String string) { - int length = string.length(); - for (int i = 0; i < length; i++) { - if (isLowerCase(string.charAt(i))) { - char[] chars = string.toCharArray(); - for (; i < length; i++) { - char c = chars[i]; - if (isLowerCase(c)) { - chars[i] = (char) (c & 0x5f); - } - } - return String.valueOf(chars); - } - } - return string; - } - - /** - * Returns a copy of the input character sequence in which all {@linkplain #isLowerCase(char) - * lowercase ASCII characters} have been converted to uppercase. All other characters are copied - * without modification. - * - * @since 14.0 - */ - public static String toUpperCase(CharSequence chars) { - if (chars instanceof String) { - return toUpperCase((String) chars); - } - int length = chars.length(); - StringBuilder builder = new StringBuilder(length); - for (int i = 0; i < length; i++) { - builder.append(toUpperCase(chars.charAt(i))); - } - return builder.toString(); - } - - /** - * If the argument is a {@linkplain #isLowerCase(char) lowercase ASCII character} returns the - * uppercase equivalent. Otherwise returns the argument. - */ - public static char toUpperCase(char c) { - return isLowerCase(c) ? (char) (c & 0x5f) : c; - } - - /** - * Indicates whether {@code c} is one of the twenty-six lowercase ASCII alphabetic characters - * between {@code 'a'} and {@code 'z'} inclusive. All others (including non-ASCII characters) - * return {@code false}. - */ - public static boolean isLowerCase(char c) { - // Note: This was benchmarked against the alternate expression "(char)(c - 'a') < 26" (Nov '13) - // and found to perform at least as well, or better. - return (c >= 'a') && (c <= 'z'); - } - - /** - * Indicates whether {@code c} is one of the twenty-six uppercase ASCII alphabetic characters - * between {@code 'A'} and {@code 'Z'} inclusive. All others (including non-ASCII characters) - * return {@code false}. - */ - public static boolean isUpperCase(char c) { - return (c >= 'A') && (c <= 'Z'); - } - - /** - * Truncates the given character sequence to the given maximum length. If the length of the - * sequence is greater than {@code maxLength}, the returned string will be exactly - * {@code maxLength} chars in length and will end with the given {@code truncationIndicator}. - * Otherwise, the sequence will be returned as a string with no changes to the content. - * - *

Examples: - * - *

   {@code
-   *   Ascii.truncate("foobar", 7, "..."); // returns "foobar"
-   *   Ascii.truncate("foobar", 5, "..."); // returns "fo..." }
- * - *

Note: This method may work with certain non-ASCII text but is not safe for - * use with arbitrary Unicode text. It is mostly intended for use with text that is known to be - * safe for use with it (such as all-ASCII text) and for simple debugging text. When using this - * method, consider the following: - * - *

    - *
  • it may split surrogate pairs
  • - *
  • it may split characters and combining characters
  • - *
  • it does not consider word boundaries
  • - *
  • if truncating for display to users, there are other considerations that must be taken - * into account
  • - *
  • the appropriate truncation indicator may be locale-dependent
  • - *
  • it is safe to use non-ASCII characters in the truncation indicator
  • - *
- * - * - * @throws IllegalArgumentException if {@code maxLength} is less than the length of - * {@code truncationIndicator} - * @since 16.0 - */ - @Beta - public static String truncate(CharSequence seq, int maxLength, String truncationIndicator) { - checkNotNull(seq); - - // length to truncate the sequence to, not including the truncation indicator - int truncationLength = maxLength - truncationIndicator.length(); - - // in this worst case, this allows a maxLength equal to the length of the truncationIndicator, - // meaning that a string will be truncated to just the truncation indicator itself - checkArgument( - truncationLength >= 0, - "maxLength (%s) must be >= length of the truncation indicator (%s)", - maxLength, - truncationIndicator.length()); - - if (seq.length() <= maxLength) { - String string = seq.toString(); - if (string.length() <= maxLength) { - return string; - } - // if the length of the toString() result was > maxLength for some reason, truncate that - seq = string; - } - - return new StringBuilder(maxLength) - .append(seq, 0, truncationLength) - .append(truncationIndicator) - .toString(); - } - - /** - * Indicates whether the contents of the given character sequences {@code s1} and {@code s2} are - * equal, ignoring the case of any ASCII alphabetic characters between {@code 'a'} and {@code 'z'} - * or {@code 'A'} and {@code 'Z'} inclusive. - * - *

This method is significantly faster than {@link String#equalsIgnoreCase} and should be used - * in preference if at least one of the parameters is known to contain only ASCII characters. - * - *

Note however that this method does not always behave identically to expressions such as: - *

    - *
  • {@code string.toUpperCase().equals("UPPER CASE ASCII")} - *
  • {@code string.toLowerCase().equals("lower case ascii")} - *
- *

due to case-folding of some non-ASCII characters (which does not occur in - * {@link String#equalsIgnoreCase}). However in almost all cases that ASCII strings are used, - * the author probably wanted the behavior provided by this method rather than the subtle and - * sometimes surprising behavior of {@code toUpperCase()} and {@code toLowerCase()}. - * - * @since 16.0 - */ - @Beta - public static boolean equalsIgnoreCase(CharSequence s1, CharSequence s2) { - // Calling length() is the null pointer check (so do it before we can exit early). - int length = s1.length(); - if (s1 == s2) { - return true; - } - if (length != s2.length()) { - return false; - } - for (int i = 0; i < length; i++) { - char c1 = s1.charAt(i); - char c2 = s2.charAt(i); - if (c1 == c2) { - continue; - } - int alphaIndex = getAlphaIndex(c1); - // This was also benchmarked using '&' to avoid branching (but always evaluate the rhs), - // however this showed no obvious improvement. - if (alphaIndex < 26 && alphaIndex == getAlphaIndex(c2)) { - continue; - } - return false; - } - return true; - } - - /** - * Returns the non-negative index value of the alpha character {@code c}, regardless of case. - * Ie, 'a'/'A' returns 0 and 'z'/'Z' returns 25. Non-alpha characters return a value of 26 or - * greater. - */ - private static int getAlphaIndex(char c) { - // Fold upper-case ASCII to lower-case and make zero-indexed and unsigned (by casting to char). - return (char) ((c | 0x20) - 'a'); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/CaseFormat.java b/thirdparty/google-guava/src/main/java/com/google/common/base/CaseFormat.java deleted file mode 100644 index c074de26ae1b..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/CaseFormat.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (C) 2006 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * Utility class for converting between various ASCII case formats. Behavior is undefined for - * non-ASCII input. - * - * @author Mike Bostock - * @since 1.0 - */ -@CheckReturnValue -@GwtCompatible -public enum CaseFormat { - /** - * Hyphenated variable naming convention, e.g., "lower-hyphen". - */ - LOWER_HYPHEN(CharMatcher.is('-'), "-") { - @Override - String normalizeWord(String word) { - return Ascii.toLowerCase(word); - } - - @Override - String convert(CaseFormat format, String s) { - if (format == LOWER_UNDERSCORE) { - return s.replace('-', '_'); - } - if (format == UPPER_UNDERSCORE) { - return Ascii.toUpperCase(s.replace('-', '_')); - } - return super.convert(format, s); - } - }, - - /** - * C++ variable naming convention, e.g., "lower_underscore". - */ - LOWER_UNDERSCORE(CharMatcher.is('_'), "_") { - @Override - String normalizeWord(String word) { - return Ascii.toLowerCase(word); - } - - @Override - String convert(CaseFormat format, String s) { - if (format == LOWER_HYPHEN) { - return s.replace('_', '-'); - } - if (format == UPPER_UNDERSCORE) { - return Ascii.toUpperCase(s); - } - return super.convert(format, s); - } - }, - - /** - * Java variable naming convention, e.g., "lowerCamel". - */ - LOWER_CAMEL(CharMatcher.inRange('A', 'Z'), "") { - @Override - String normalizeWord(String word) { - return firstCharOnlyToUpper(word); - } - }, - - /** - * Java and C++ class naming convention, e.g., "UpperCamel". - */ - UPPER_CAMEL(CharMatcher.inRange('A', 'Z'), "") { - @Override - String normalizeWord(String word) { - return firstCharOnlyToUpper(word); - } - }, - - /** - * Java and C++ constant naming convention, e.g., "UPPER_UNDERSCORE". - */ - UPPER_UNDERSCORE(CharMatcher.is('_'), "_") { - @Override - String normalizeWord(String word) { - return Ascii.toUpperCase(word); - } - - @Override - String convert(CaseFormat format, String s) { - if (format == LOWER_HYPHEN) { - return Ascii.toLowerCase(s.replace('_', '-')); - } - if (format == LOWER_UNDERSCORE) { - return Ascii.toLowerCase(s); - } - return super.convert(format, s); - } - }; - - private final CharMatcher wordBoundary; - private final String wordSeparator; - - CaseFormat(CharMatcher wordBoundary, String wordSeparator) { - this.wordBoundary = wordBoundary; - this.wordSeparator = wordSeparator; - } - - /** - * Converts the specified {@code String str} from this format to the specified {@code format}. A - * "best effort" approach is taken; if {@code str} does not conform to the assumed format, then - * the behavior of this method is undefined but we make a reasonable effort at converting anyway. - */ - public final String to(CaseFormat format, String str) { - checkNotNull(format); - checkNotNull(str); - return (format == this) ? str : convert(format, str); - } - - /** - * Enum values can override for performance reasons. - */ - String convert(CaseFormat format, String s) { - // deal with camel conversion - StringBuilder out = null; - int i = 0; - int j = -1; - while ((j = wordBoundary.indexIn(s, ++j)) != -1) { - if (i == 0) { - // include some extra space for separators - out = new StringBuilder(s.length() + 4 * wordSeparator.length()); - out.append(format.normalizeFirstWord(s.substring(i, j))); - } else { - out.append(format.normalizeWord(s.substring(i, j))); - } - out.append(format.wordSeparator); - i = j + wordSeparator.length(); - } - return (i == 0) - ? format.normalizeFirstWord(s) - : out.append(format.normalizeWord(s.substring(i))).toString(); - } - - /** - * Returns a {@code Converter} that converts strings from this format to {@code targetFormat}. - * - * @since 16.0 - */ - @Beta - public Converter converterTo(CaseFormat targetFormat) { - return new StringConverter(this, targetFormat); - } - - private static final class StringConverter extends Converter - implements Serializable { - - private final CaseFormat sourceFormat; - private final CaseFormat targetFormat; - - StringConverter(CaseFormat sourceFormat, CaseFormat targetFormat) { - this.sourceFormat = checkNotNull(sourceFormat); - this.targetFormat = checkNotNull(targetFormat); - } - - @Override - protected String doForward(String s) { - return sourceFormat.to(targetFormat, s); - } - - @Override - protected String doBackward(String s) { - return targetFormat.to(sourceFormat, s); - } - - @Override - public boolean equals(@Nullable Object object) { - if (object instanceof StringConverter) { - StringConverter that = (StringConverter) object; - return sourceFormat.equals(that.sourceFormat) && targetFormat.equals(that.targetFormat); - } - return false; - } - - @Override - public int hashCode() { - return sourceFormat.hashCode() ^ targetFormat.hashCode(); - } - - @Override - public String toString() { - return sourceFormat + ".converterTo(" + targetFormat + ")"; - } - - private static final long serialVersionUID = 0L; - } - - abstract String normalizeWord(String word); - - private String normalizeFirstWord(String word) { - return (this == LOWER_CAMEL) ? Ascii.toLowerCase(word) : normalizeWord(word); - } - - private static String firstCharOnlyToUpper(String word) { - return (word.isEmpty()) - ? word - : new StringBuilder(word.length()) - .append(Ascii.toUpperCase(word.charAt(0))) - .append(Ascii.toLowerCase(word.substring(1))) - .toString(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/CharMatcher.java b/thirdparty/google-guava/src/main/java/com/google/common/base/CharMatcher.java deleted file mode 100644 index 7e732dd9ece8..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/CharMatcher.java +++ /dev/null @@ -1,1826 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkPositionIndex; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.annotations.VisibleForTesting; - -import java.util.Arrays; -import java.util.BitSet; - -import javax.annotation.CheckReturnValue; - -/** - * Determines a true or false value for any Java {@code char} value, just as {@link Predicate} does - * for any {@link Object}. Also offers basic text processing methods based on this function. - * Implementations are strongly encouraged to be side-effect-free and immutable. - * - *

Throughout the documentation of this class, the phrase "matching character" is used to mean - * "any character {@code c} for which {@code this.matches(c)} returns {@code true}". - * - *

Note: This class deals only with {@code char} values; it does not understand - * supplementary Unicode code points in the range {@code 0x10000} to {@code 0x10FFFF}. Such logical - * characters are encoded into a {@code String} using surrogate pairs, and a {@code CharMatcher} - * treats these just as two separate characters. - * - *

Example usages:

- *   String trimmed = {@link #whitespace() whitespace()}.{@link #trimFrom trimFrom}(userInput);
- *   if ({@link #ascii() ascii()}.{@link #matchesAllOf matchesAllOf}(s)) { ... }
- * - *

See the Guava User Guide article on - * {@code CharMatcher}. - * - * @author Kevin Bourrillion - * @since 1.0 - */ -@Beta // Possibly change from chars to code points; decide constants vs. methods -@GwtCompatible(emulated = true) -public abstract class CharMatcher implements Predicate { - - // Constant matcher factory methods - - /** - * Matches any character. - * - * @since 19.0 (since 1.0 as constant {@code ANY}) - */ - public static CharMatcher any() { - return Any.INSTANCE; - } - - /** - * Matches no characters. - * - * @since 19.0 (since 1.0 as constant {@code NONE}) - */ - public static CharMatcher none() { - return None.INSTANCE; - } - - /** - * Determines whether a character is whitespace according to the latest Unicode standard, as - * illustrated here. - * This is not the same definition used by other Java APIs. (See a comparison of several - * definitions of "whitespace".) - * - *

Note: as the Unicode definition evolves, we will modify this matcher to keep it up - * to date. - * - * @since 19.0 (since 1.0 as constant {@code WHITESPACE}) - */ - public static CharMatcher whitespace() { - return Whitespace.INSTANCE; - } - - /** - * Determines whether a character is a breaking whitespace (that is, a whitespace which can be - * interpreted as a break between words for formatting purposes). See {@link #whitespace()} for a - * discussion of that term. - * - * @since 19.0 (since 2.0 as constant {@code BREAKING_WHITESPACE}) - */ - public static CharMatcher breakingWhitespace() { - return BreakingWhitespace.INSTANCE; - } - - /** - * Determines whether a character is ASCII, meaning that its code point is less than 128. - * - * @since 19.0 (since 1.0 as constant {@code ASCII}) - */ - public static CharMatcher ascii() { - return Ascii.INSTANCE; - } - - /** - * Determines whether a character is a digit according to - * Unicode. - * If you only care to match ASCII digits, you can use {@code inRange('0', '9')}. - * - * @since 19.0 (since 1.0 as constant {@code DIGIT}) - */ - public static CharMatcher digit() { - return Digit.INSTANCE; - } - - /** - * Determines whether a character is a digit according to {@linkplain Character#isDigit(char) - * Java's definition}. If you only care to match ASCII digits, you can use {@code inRange('0', - * '9')}. - * - * @since 19.0 (since 1.0 as constant {@code JAVA_DIGIT}) - */ - public static CharMatcher javaDigit() { - return JavaDigit.INSTANCE; - } - - /** - * Determines whether a character is a letter according to {@linkplain Character#isLetter(char) - * Java's definition}. If you only care to match letters of the Latin alphabet, you can use {@code - * inRange('a', 'z').or(inRange('A', 'Z'))}. - * - * @since 19.0 (since 1.0 as constant {@code JAVA_LETTER}) - */ - public static CharMatcher javaLetter() { - return JavaLetter.INSTANCE; - } - - /** - * Determines whether a character is a letter or digit according to {@linkplain - * Character#isLetterOrDigit(char) Java's definition}. - * - * @since 19.0 (since 1.0 as constant {@code JAVA_LETTER_OR_DIGIT}). - */ - public static CharMatcher javaLetterOrDigit() { - return JavaLetterOrDigit.INSTANCE; - } - - /** - * Determines whether a character is upper case according to {@linkplain - * Character#isUpperCase(char) Java's definition}. - * - * @since 19.0 (since 1.0 as constant {@code JAVA_UPPER_CASE}) - */ - public static CharMatcher javaUpperCase() { - return JavaUpperCase.INSTANCE; - } - - /** - * Determines whether a character is lower case according to {@linkplain - * Character#isLowerCase(char) Java's definition}. - * - * @since 19.0 (since 1.0 as constant {@code JAVA_LOWER_CASE}) - */ - public static CharMatcher javaLowerCase() { - return JavaLowerCase.INSTANCE; - } - - /** - * Determines whether a character is an ISO control character as specified by {@link - * Character#isISOControl(char)}. - * - * @since 19.0 (since 1.0 as constant {@code JAVA_ISO_CONTROL}) - */ - public static CharMatcher javaIsoControl() { - return JavaIsoControl.INSTANCE; - } - - /** - * Determines whether a character is invisible; that is, if its Unicode category is any of - * SPACE_SEPARATOR, LINE_SEPARATOR, PARAGRAPH_SEPARATOR, CONTROL, FORMAT, SURROGATE, and - * PRIVATE_USE according to ICU4J. - * - * @since 19.0 (since 1.0 as constant {@code INVISIBLE}) - */ - public static CharMatcher invisible() { - return Invisible.INSTANCE; - } - - /** - * Determines whether a character is single-width (not double-width). When in doubt, this matcher - * errs on the side of returning {@code false} (that is, it tends to assume a character is - * double-width). - * - *

Note: as the reference file evolves, we will modify this matcher to keep it up to - * date. - * - * @since 19.0 (since 1.0 as constant {@code SINGLE_WIDTH}) - */ - public static CharMatcher singleWidth() { - return SingleWidth.INSTANCE; - } - - // Legacy constants - // TODO(cgdecker): Deprecate these so they can be removed eventually - - /** - * Determines whether a character is whitespace according to the latest Unicode standard, as - * illustrated here. - * This is not the same definition used by other Java APIs. (See a comparison of several - * definitions of "whitespace".) - * - *

Note: as the Unicode definition evolves, we will modify this constant to keep it up - * to date. - */ - public static final CharMatcher WHITESPACE = whitespace(); - - /** - * Determines whether a character is a breaking whitespace (that is, a whitespace which can be - * interpreted as a break between words for formatting purposes). See {@link #WHITESPACE} for a - * discussion of that term. - * - * @since 2.0 - */ - public static final CharMatcher BREAKING_WHITESPACE = breakingWhitespace(); - - /** - * Determines whether a character is ASCII, meaning that its code point is less than 128. - */ - public static final CharMatcher ASCII = ascii(); - - /** - * Determines whether a character is a digit according to - * Unicode. - * If you only care to match ASCII digits, you can use {@code inRange('0', '9')}. - */ - public static final CharMatcher DIGIT = digit(); - - /** - * Determines whether a character is a digit according to {@linkplain Character#isDigit(char) - * Java's definition}. If you only care to match ASCII digits, you can use {@code - * inRange('0', '9')}. - */ - public static final CharMatcher JAVA_DIGIT = javaDigit(); - - /** - * Determines whether a character is a letter according to {@linkplain Character#isLetter(char) - * Java's definition}. If you only care to match letters of the Latin alphabet, you can use {@code - * inRange('a', 'z').or(inRange('A', 'Z'))}. - */ - public static final CharMatcher JAVA_LETTER = javaLetter(); - - /** - * Determines whether a character is a letter or digit according to {@linkplain - * Character#isLetterOrDigit(char) Java's definition}. - */ - public static final CharMatcher JAVA_LETTER_OR_DIGIT = javaLetterOrDigit(); - - /** - * Determines whether a character is upper case according to {@linkplain - * Character#isUpperCase(char) Java's definition}. - */ - public static final CharMatcher JAVA_UPPER_CASE = javaUpperCase(); - - /** - * Determines whether a character is lower case according to {@linkplain - * Character#isLowerCase(char) Java's definition}. - */ - public static final CharMatcher JAVA_LOWER_CASE = javaLowerCase(); - - /** - * Determines whether a character is an ISO control character as specified by {@link - * Character#isISOControl(char)}. - */ - public static final CharMatcher JAVA_ISO_CONTROL = javaIsoControl(); - - /** - * Determines whether a character is invisible; that is, if its Unicode category is any of - * SPACE_SEPARATOR, LINE_SEPARATOR, PARAGRAPH_SEPARATOR, CONTROL, FORMAT, SURROGATE, and - * PRIVATE_USE according to ICU4J. - */ - public static final CharMatcher INVISIBLE = invisible(); - - /** - * Determines whether a character is single-width (not double-width). When in doubt, this matcher - * errs on the side of returning {@code false} (that is, it tends to assume a character is - * double-width). - * - *

Note: as the reference file evolves, we will modify this constant to keep it up to - * date. - */ - public static final CharMatcher SINGLE_WIDTH = singleWidth(); - - /** Matches any character. */ - public static final CharMatcher ANY = any(); - - /** Matches no characters. */ - public static final CharMatcher NONE = none(); - - // Static factories - - /** - * Returns a {@code char} matcher that matches only one specified character. - */ - public static CharMatcher is(final char match) { - return new Is(match); - } - - /** - * Returns a {@code char} matcher that matches any character except the one specified. - * - *

To negate another {@code CharMatcher}, use {@link #negate()}. - */ - public static CharMatcher isNot(final char match) { - return new IsNot(match); - } - - /** - * Returns a {@code char} matcher that matches any character present in the given character - * sequence. - */ - public static CharMatcher anyOf(final CharSequence sequence) { - switch (sequence.length()) { - case 0: - return none(); - case 1: - return is(sequence.charAt(0)); - case 2: - return isEither(sequence.charAt(0), sequence.charAt(1)); - default: - // TODO(lowasser): is it potentially worth just going ahead and building a precomputed - // matcher? - return new AnyOf(sequence); - } - } - - /** - * Returns a {@code char} matcher that matches any character not present in the given character - * sequence. - */ - public static CharMatcher noneOf(CharSequence sequence) { - return anyOf(sequence).negate(); - } - - /** - * Returns a {@code char} matcher that matches any character in a given range (both endpoints are - * inclusive). For example, to match any lowercase letter of the English alphabet, use {@code - * CharMatcher.inRange('a', 'z')}. - * - * @throws IllegalArgumentException if {@code endInclusive < startInclusive} - */ - public static CharMatcher inRange(final char startInclusive, final char endInclusive) { - return new InRange(startInclusive, endInclusive); - } - - /** - * Returns a matcher with identical behavior to the given {@link Character}-based predicate, but - * which operates on primitive {@code char} instances instead. - */ - public static CharMatcher forPredicate(final Predicate predicate) { - return predicate instanceof CharMatcher ? (CharMatcher) predicate : new ForPredicate(predicate); - } - - // Constructors - - /** - * Constructor for use by subclasses. When subclassing, you may want to override - * {@code toString()} to provide a useful description. - */ - protected CharMatcher() {} - - // Abstract methods - - /** Determines a true or false value for the given character. */ - public abstract boolean matches(char c); - - // Non-static factories - - /** - * Returns a matcher that matches any character not matched by this matcher. - */ - public CharMatcher negate() { - return new Negated(this); - } - - /** - * Returns a matcher that matches any character matched by both this matcher and {@code other}. - */ - public CharMatcher and(CharMatcher other) { - return new And(this, other); - } - - /** - * Returns a matcher that matches any character matched by either this matcher or {@code other}. - */ - public CharMatcher or(CharMatcher other) { - return new Or(this, other); - } - - /** - * Returns a {@code char} matcher functionally equivalent to this one, but which may be faster to - * query than the original; your mileage may vary. Precomputation takes time and is likely to be - * worthwhile only if the precomputed matcher is queried many thousands of times. - * - *

This method has no effect (returns {@code this}) when called in GWT: it's unclear whether a - * precomputed matcher is faster, but it certainly consumes more memory, which doesn't seem like a - * worthwhile tradeoff in a browser. - */ - public CharMatcher precomputed() { - return Platform.precomputeCharMatcher(this); - } - - private static final int DISTINCT_CHARS = Character.MAX_VALUE - Character.MIN_VALUE + 1; - - /** - * This is the actual implementation of {@link #precomputed}, but we bounce calls through a - * method on {@link Platform} so that we can have different behavior in GWT. - * - *

This implementation tries to be smart in a number of ways. It recognizes cases where - * the negation is cheaper to precompute than the matcher itself; it tries to build small - * hash tables for matchers that only match a few characters, and so on. In the worst-case - * scenario, it constructs an eight-kilobyte bit array and queries that. - * In many situations this produces a matcher which is faster to query than the original. - */ - @GwtIncompatible("java.util.BitSet") - CharMatcher precomputedInternal() { - final BitSet table = new BitSet(); - setBits(table); - int totalCharacters = table.cardinality(); - if (totalCharacters * 2 <= DISTINCT_CHARS) { - return precomputedPositive(totalCharacters, table, toString()); - } else { - // TODO(lowasser): is it worth it to worry about the last character of large matchers? - table.flip(Character.MIN_VALUE, Character.MAX_VALUE + 1); - int negatedCharacters = DISTINCT_CHARS - totalCharacters; - String suffix = ".negate()"; - final String description = toString(); - String negatedDescription = - description.endsWith(suffix) - ? description.substring(0, description.length() - suffix.length()) - : description + suffix; - return new NegatedFastMatcher( - precomputedPositive(negatedCharacters, table, negatedDescription)) { - @Override - public String toString() { - return description; - } - }; - } - } - - /** - * Helper method for {@link #precomputedInternal} that doesn't test if the negation is cheaper. - */ - @GwtIncompatible("java.util.BitSet") - private static CharMatcher precomputedPositive( - int totalCharacters, BitSet table, String description) { - switch (totalCharacters) { - case 0: - return none(); - case 1: - return is((char) table.nextSetBit(0)); - case 2: - char c1 = (char) table.nextSetBit(0); - char c2 = (char) table.nextSetBit(c1 + 1); - return isEither(c1, c2); - default: - return isSmall(totalCharacters, table.length()) - ? SmallCharMatcher.from(table, description) - : new BitSetMatcher(table, description); - } - } - - @GwtIncompatible("SmallCharMatcher") - private static boolean isSmall(int totalCharacters, int tableLength) { - return totalCharacters <= SmallCharMatcher.MAX_SIZE - && tableLength > (totalCharacters * 4 * Character.SIZE); - // err on the side of BitSetMatcher - } - - /** - * Sets bits in {@code table} matched by this matcher. - */ - @GwtIncompatible("java.util.BitSet") - void setBits(BitSet table) { - for (int c = Character.MAX_VALUE; c >= Character.MIN_VALUE; c--) { - if (matches((char) c)) { - table.set(c); - } - } - } - - // Text processing routines - - /** - * Returns {@code true} if a character sequence contains at least one matching character. - * Equivalent to {@code !matchesNoneOf(sequence)}. - * - *

The default implementation iterates over the sequence, invoking {@link #matches} for each - * character, until this returns {@code true} or the end is reached. - * - * @param sequence the character sequence to examine, possibly empty - * @return {@code true} if this matcher matches at least one character in the sequence - * @since 8.0 - */ - public boolean matchesAnyOf(CharSequence sequence) { - return !matchesNoneOf(sequence); - } - - /** - * Returns {@code true} if a character sequence contains only matching characters. - * - *

The default implementation iterates over the sequence, invoking {@link #matches} for each - * character, until this returns {@code false} or the end is reached. - * - * @param sequence the character sequence to examine, possibly empty - * @return {@code true} if this matcher matches every character in the sequence, including when - * the sequence is empty - */ - public boolean matchesAllOf(CharSequence sequence) { - for (int i = sequence.length() - 1; i >= 0; i--) { - if (!matches(sequence.charAt(i))) { - return false; - } - } - return true; - } - - /** - * Returns {@code true} if a character sequence contains no matching characters. Equivalent to - * {@code !matchesAnyOf(sequence)}. - * - *

The default implementation iterates over the sequence, invoking {@link #matches} for each - * character, until this returns {@code false} or the end is reached. - * - * @param sequence the character sequence to examine, possibly empty - * @return {@code true} if this matcher matches every character in the sequence, including when - * the sequence is empty - */ - public boolean matchesNoneOf(CharSequence sequence) { - return indexIn(sequence) == -1; - } - - /** - * Returns the index of the first matching character in a character sequence, or {@code -1} if no - * matching character is present. - * - *

The default implementation iterates over the sequence in forward order calling {@link - * #matches} for each character. - * - * @param sequence the character sequence to examine from the beginning - * @return an index, or {@code -1} if no character matches - */ - public int indexIn(CharSequence sequence) { - return indexIn(sequence, 0); - } - - /** - * Returns the index of the first matching character in a character sequence, starting from a - * given position, or {@code -1} if no character matches after that position. - * - *

The default implementation iterates over the sequence in forward order, beginning at {@code - * start}, calling {@link #matches} for each character. - * - * @param sequence the character sequence to examine - * @param start the first index to examine; must be nonnegative and no greater than {@code - * sequence.length()} - * @return the index of the first matching character, guaranteed to be no less than {@code start}, - * or {@code -1} if no character matches - * @throws IndexOutOfBoundsException if start is negative or greater than {@code - * sequence.length()} - */ - public int indexIn(CharSequence sequence, int start) { - int length = sequence.length(); - checkPositionIndex(start, length); - for (int i = start; i < length; i++) { - if (matches(sequence.charAt(i))) { - return i; - } - } - return -1; - } - - /** - * Returns the index of the last matching character in a character sequence, or {@code -1} if no - * matching character is present. - * - *

The default implementation iterates over the sequence in reverse order calling {@link - * #matches} for each character. - * - * @param sequence the character sequence to examine from the end - * @return an index, or {@code -1} if no character matches - */ - public int lastIndexIn(CharSequence sequence) { - for (int i = sequence.length() - 1; i >= 0; i--) { - if (matches(sequence.charAt(i))) { - return i; - } - } - return -1; - } - - /** - * Returns the number of matching characters found in a character sequence. - */ - public int countIn(CharSequence sequence) { - int count = 0; - for (int i = 0; i < sequence.length(); i++) { - if (matches(sequence.charAt(i))) { - count++; - } - } - return count; - } - - /** - * Returns a string containing all non-matching characters of a character sequence, in order. For - * example:

   {@code
-   *
-   *   CharMatcher.is('a').removeFrom("bazaar")}
- * - * ... returns {@code "bzr"}. - */ - @CheckReturnValue - public String removeFrom(CharSequence sequence) { - String string = sequence.toString(); - int pos = indexIn(string); - if (pos == -1) { - return string; - } - - char[] chars = string.toCharArray(); - int spread = 1; - - // This unusual loop comes from extensive benchmarking - OUT: - while (true) { - pos++; - while (true) { - if (pos == chars.length) { - break OUT; - } - if (matches(chars[pos])) { - break; - } - chars[pos - spread] = chars[pos]; - pos++; - } - spread++; - } - return new String(chars, 0, pos - spread); - } - - /** - * Returns a string containing all matching characters of a character sequence, in order. For - * example:
   {@code
-   *
-   *   CharMatcher.is('a').retainFrom("bazaar")}
- * - * ... returns {@code "aaa"}. - */ - @CheckReturnValue - public String retainFrom(CharSequence sequence) { - return negate().removeFrom(sequence); - } - - /** - * Returns a string copy of the input character sequence, with each character that matches this - * matcher replaced by a given replacement character. For example:
   {@code
-   *
-   *   CharMatcher.is('a').replaceFrom("radar", 'o')}
- * - * ... returns {@code "rodor"}. - * - *

The default implementation uses {@link #indexIn(CharSequence)} to find the first matching - * character, then iterates the remainder of the sequence calling {@link #matches(char)} for each - * character. - * - * @param sequence the character sequence to replace matching characters in - * @param replacement the character to append to the result string in place of each matching - * character in {@code sequence} - * @return the new string - */ - @CheckReturnValue - public String replaceFrom(CharSequence sequence, char replacement) { - String string = sequence.toString(); - int pos = indexIn(string); - if (pos == -1) { - return string; - } - char[] chars = string.toCharArray(); - chars[pos] = replacement; - for (int i = pos + 1; i < chars.length; i++) { - if (matches(chars[i])) { - chars[i] = replacement; - } - } - return new String(chars); - } - - /** - * Returns a string copy of the input character sequence, with each character that matches this - * matcher replaced by a given replacement sequence. For example:

   {@code
-   *
-   *   CharMatcher.is('a').replaceFrom("yaha", "oo")}
- * - * ... returns {@code "yoohoo"}. - * - *

Note: If the replacement is a fixed string with only one character, you are better - * off calling {@link #replaceFrom(CharSequence, char)} directly. - * - * @param sequence the character sequence to replace matching characters in - * @param replacement the characters to append to the result string in place of each matching - * character in {@code sequence} - * @return the new string - */ - @CheckReturnValue - public String replaceFrom(CharSequence sequence, CharSequence replacement) { - int replacementLen = replacement.length(); - if (replacementLen == 0) { - return removeFrom(sequence); - } - if (replacementLen == 1) { - return replaceFrom(sequence, replacement.charAt(0)); - } - - String string = sequence.toString(); - int pos = indexIn(string); - if (pos == -1) { - return string; - } - - int len = string.length(); - StringBuilder buf = new StringBuilder((len * 3 / 2) + 16); - - int oldpos = 0; - do { - buf.append(string, oldpos, pos); - buf.append(replacement); - oldpos = pos + 1; - pos = indexIn(string, oldpos); - } while (pos != -1); - - buf.append(string, oldpos, len); - return buf.toString(); - } - - /** - * Returns a substring of the input character sequence that omits all characters this matcher - * matches from the beginning and from the end of the string. For example:

   {@code
-   *
-   *   CharMatcher.anyOf("ab").trimFrom("abacatbab")}
- * - * ... returns {@code "cat"}. - * - *

Note that:

   {@code
-   *
-   *   CharMatcher.inRange('\0', ' ').trimFrom(str)}
- * - * ... is equivalent to {@link String#trim()}. - */ - @CheckReturnValue - public String trimFrom(CharSequence sequence) { - int len = sequence.length(); - int first; - int last; - - for (first = 0; first < len; first++) { - if (!matches(sequence.charAt(first))) { - break; - } - } - for (last = len - 1; last > first; last--) { - if (!matches(sequence.charAt(last))) { - break; - } - } - - return sequence.subSequence(first, last + 1).toString(); - } - - /** - * Returns a substring of the input character sequence that omits all characters this matcher - * matches from the beginning of the string. For example:
 {@code
-   *
-   *   CharMatcher.anyOf("ab").trimLeadingFrom("abacatbab")}
- * - * ... returns {@code "catbab"}. - */ - @CheckReturnValue - public String trimLeadingFrom(CharSequence sequence) { - int len = sequence.length(); - for (int first = 0; first < len; first++) { - if (!matches(sequence.charAt(first))) { - return sequence.subSequence(first, len).toString(); - } - } - return ""; - } - - /** - * Returns a substring of the input character sequence that omits all characters this matcher - * matches from the end of the string. For example:
 {@code
-   *
-   *   CharMatcher.anyOf("ab").trimTrailingFrom("abacatbab")}
- * - * ... returns {@code "abacat"}. - */ - @CheckReturnValue - public String trimTrailingFrom(CharSequence sequence) { - int len = sequence.length(); - for (int last = len - 1; last >= 0; last--) { - if (!matches(sequence.charAt(last))) { - return sequence.subSequence(0, last + 1).toString(); - } - } - return ""; - } - - /** - * Returns a string copy of the input character sequence, with each group of consecutive - * characters that match this matcher replaced by a single replacement character. For example: - *
   {@code
-   *
-   *   CharMatcher.anyOf("eko").collapseFrom("bookkeeper", '-')}
- * - * ... returns {@code "b-p-r"}. - * - *

The default implementation uses {@link #indexIn(CharSequence)} to find the first matching - * character, then iterates the remainder of the sequence calling {@link #matches(char)} for each - * character. - * - * @param sequence the character sequence to replace matching groups of characters in - * @param replacement the character to append to the result string in place of each group of - * matching characters in {@code sequence} - * @return the new string - */ - @CheckReturnValue - public String collapseFrom(CharSequence sequence, char replacement) { - // This implementation avoids unnecessary allocation. - int len = sequence.length(); - for (int i = 0; i < len; i++) { - char c = sequence.charAt(i); - if (matches(c)) { - if (c == replacement && (i == len - 1 || !matches(sequence.charAt(i + 1)))) { - // a no-op replacement - i++; - } else { - StringBuilder builder = - new StringBuilder(len).append(sequence.subSequence(0, i)).append(replacement); - return finishCollapseFrom(sequence, i + 1, len, replacement, builder, true); - } - } - } - // no replacement needed - return sequence.toString(); - } - - /** - * Collapses groups of matching characters exactly as {@link #collapseFrom} does, except that - * groups of matching characters at the start or end of the sequence are removed without - * replacement. - */ - @CheckReturnValue - public String trimAndCollapseFrom(CharSequence sequence, char replacement) { - // This implementation avoids unnecessary allocation. - int len = sequence.length(); - int first = 0; - int last = len - 1; - - while (first < len && matches(sequence.charAt(first))) { - first++; - } - - while (last > first && matches(sequence.charAt(last))) { - last--; - } - - return (first == 0 && last == len - 1) - ? collapseFrom(sequence, replacement) - : finishCollapseFrom( - sequence, first, last + 1, replacement, new StringBuilder(last + 1 - first), false); - } - - private String finishCollapseFrom( - CharSequence sequence, - int start, - int end, - char replacement, - StringBuilder builder, - boolean inMatchingGroup) { - for (int i = start; i < end; i++) { - char c = sequence.charAt(i); - if (matches(c)) { - if (!inMatchingGroup) { - builder.append(replacement); - inMatchingGroup = true; - } - } else { - builder.append(c); - inMatchingGroup = false; - } - } - return builder.toString(); - } - - /** - * @deprecated Provided only to satisfy the {@link Predicate} interface; use {@link #matches} - * instead. - */ - @Deprecated - @Override - public boolean apply(Character character) { - return matches(character); - } - - /** - * Returns a string representation of this {@code CharMatcher}, such as - * {@code CharMatcher.or(WHITESPACE, JAVA_DIGIT)}. - */ - @Override - public String toString() { - return super.toString(); - } - - /** - * Returns the Java Unicode escape sequence for the given character, in the form "\u12AB" where - * "12AB" is the four hexadecimal digits representing the 16 bits of the UTF-16 character. - */ - private static String showCharacter(char c) { - String hex = "0123456789ABCDEF"; - char[] tmp = {'\\', 'u', '\0', '\0', '\0', '\0'}; - for (int i = 0; i < 4; i++) { - tmp[5 - i] = hex.charAt(c & 0xF); - c = (char) (c >> 4); - } - return String.copyValueOf(tmp); - } - - // Fast matchers - - /** A matcher for which precomputation will not yield any significant benefit. */ - abstract static class FastMatcher extends CharMatcher { - - @Override - public final CharMatcher precomputed() { - return this; - } - - @Override - public CharMatcher negate() { - return new NegatedFastMatcher(this); - } - } - - /** {@link FastMatcher} which overrides {@code toString()} with a custom name. */ - abstract static class NamedFastMatcher extends FastMatcher { - - private final String description; - - NamedFastMatcher(String description) { - this.description = checkNotNull(description); - } - - @Override - public final String toString() { - return description; - } - } - - /** Negation of a {@link FastMatcher}. */ - static class NegatedFastMatcher extends Negated { - - NegatedFastMatcher(CharMatcher original) { - super(original); - } - - @Override - public final CharMatcher precomputed() { - return this; - } - } - - /** Fast matcher using a {@link BitSet} table of matching characters. */ - @GwtIncompatible("java.util.BitSet") - private static final class BitSetMatcher extends NamedFastMatcher { - - private final BitSet table; - - private BitSetMatcher(BitSet table, String description) { - super(description); - if (table.length() + Long.SIZE < table.size()) { - table = (BitSet) table.clone(); - // If only we could actually call BitSet.trimToSize() ourselves... - } - this.table = table; - } - - @Override - public boolean matches(char c) { - return table.get(c); - } - - @Override - void setBits(BitSet bitSet) { - bitSet.or(table); - } - } - - // Static constant implementation classes - - /** Implementation of {@link #any()}. */ - private static final class Any extends NamedFastMatcher { - - static final Any INSTANCE = new Any(); - - private Any() { - super("CharMatcher.any()"); - } - - @Override - public boolean matches(char c) { - return true; - } - - @Override - public int indexIn(CharSequence sequence) { - return (sequence.length() == 0) ? -1 : 0; - } - - @Override - public int indexIn(CharSequence sequence, int start) { - int length = sequence.length(); - checkPositionIndex(start, length); - return (start == length) ? -1 : start; - } - - @Override - public int lastIndexIn(CharSequence sequence) { - return sequence.length() - 1; - } - - @Override - public boolean matchesAllOf(CharSequence sequence) { - checkNotNull(sequence); - return true; - } - - @Override - public boolean matchesNoneOf(CharSequence sequence) { - return sequence.length() == 0; - } - - @Override - public String removeFrom(CharSequence sequence) { - checkNotNull(sequence); - return ""; - } - - @Override - public String replaceFrom(CharSequence sequence, char replacement) { - char[] array = new char[sequence.length()]; - Arrays.fill(array, replacement); - return new String(array); - } - - @Override - public String replaceFrom(CharSequence sequence, CharSequence replacement) { - StringBuilder result = new StringBuilder(sequence.length() * replacement.length()); - for (int i = 0; i < sequence.length(); i++) { - result.append(replacement); - } - return result.toString(); - } - - @Override - public String collapseFrom(CharSequence sequence, char replacement) { - return (sequence.length() == 0) ? "" : String.valueOf(replacement); - } - - @Override - public String trimFrom(CharSequence sequence) { - checkNotNull(sequence); - return ""; - } - - @Override - public int countIn(CharSequence sequence) { - return sequence.length(); - } - - @Override - public CharMatcher and(CharMatcher other) { - return checkNotNull(other); - } - - @Override - public CharMatcher or(CharMatcher other) { - checkNotNull(other); - return this; - } - - @Override - public CharMatcher negate() { - return none(); - } - } - - /** Implementation of {@link #none()}. */ - private static final class None extends NamedFastMatcher { - - static final None INSTANCE = new None(); - - private None() { - super("CharMatcher.none()"); - } - - @Override - public boolean matches(char c) { - return false; - } - - @Override - public int indexIn(CharSequence sequence) { - checkNotNull(sequence); - return -1; - } - - @Override - public int indexIn(CharSequence sequence, int start) { - int length = sequence.length(); - checkPositionIndex(start, length); - return -1; - } - - @Override - public int lastIndexIn(CharSequence sequence) { - checkNotNull(sequence); - return -1; - } - - @Override - public boolean matchesAllOf(CharSequence sequence) { - return sequence.length() == 0; - } - - @Override - public boolean matchesNoneOf(CharSequence sequence) { - checkNotNull(sequence); - return true; - } - - @Override - public String removeFrom(CharSequence sequence) { - return sequence.toString(); - } - - @Override - public String replaceFrom(CharSequence sequence, char replacement) { - return sequence.toString(); - } - - @Override - public String replaceFrom(CharSequence sequence, CharSequence replacement) { - checkNotNull(replacement); - return sequence.toString(); - } - - @Override - public String collapseFrom(CharSequence sequence, char replacement) { - return sequence.toString(); - } - - @Override - public String trimFrom(CharSequence sequence) { - return sequence.toString(); - } - - @Override - public String trimLeadingFrom(CharSequence sequence) { - return sequence.toString(); - } - - @Override - public String trimTrailingFrom(CharSequence sequence) { - return sequence.toString(); - } - - @Override - public int countIn(CharSequence sequence) { - checkNotNull(sequence); - return 0; - } - - @Override - public CharMatcher and(CharMatcher other) { - checkNotNull(other); - return this; - } - - @Override - public CharMatcher or(CharMatcher other) { - return checkNotNull(other); - } - - @Override - public CharMatcher negate() { - return any(); - } - } - - /** Implementation of {@link #whitespace()}. */ - @VisibleForTesting - static final class Whitespace extends NamedFastMatcher { - - static final String TABLE = - "\u2002\u3000\r\u0085\u200A\u2005\u2000\u3000" - + "\u2029\u000B\u3000\u2008\u2003\u205F\u3000\u1680" - + "\u0009\u0020\u2006\u2001\u202F\u00A0\u000C\u2009" - + "\u3000\u2004\u3000\u3000\u2028\n\u2007\u3000"; - static final int MULTIPLIER = 1682554634; - static final int SHIFT = Integer.numberOfLeadingZeros(TABLE.length() - 1); - - static final Whitespace INSTANCE = new Whitespace(); - - Whitespace() { - super("CharMatcher.whitespace()"); - } - - @Override - public boolean matches(char c) { - return TABLE.charAt((MULTIPLIER * c) >>> SHIFT) == c; - } - - @GwtIncompatible("java.util.BitSet") - @Override - void setBits(BitSet table) { - for (int i = 0; i < TABLE.length(); i++) { - table.set(TABLE.charAt(i)); - } - } - } - - /** Implementation of {@link #breakingWhitespace()}. */ - private static final class BreakingWhitespace extends CharMatcher { - - static final CharMatcher INSTANCE = new BreakingWhitespace(); - - @Override - public boolean matches(char c) { - switch (c) { - case '\t': - case '\n': - case '\013': - case '\f': - case '\r': - case ' ': - case '\u0085': - case '\u1680': - case '\u2028': - case '\u2029': - case '\u205f': - case '\u3000': - return true; - case '\u2007': - return false; - default: - return c >= '\u2000' && c <= '\u200a'; - } - } - - @Override - public String toString() { - return "CharMatcher.breakingWhitespace()"; - } - } - - /** Implementation of {@link #ascii()}. */ - private static final class Ascii extends NamedFastMatcher { - - static final Ascii INSTANCE = new Ascii(); - - Ascii() { - super("CharMatcher.ascii()"); - } - - @Override - public boolean matches(char c) { - return c <= '\u007f'; - } - } - - /** Implementation that matches characters that fall within multiple ranges. */ - private static class RangesMatcher extends CharMatcher { - - private final String description; - private final char[] rangeStarts; - private final char[] rangeEnds; - - RangesMatcher(String description, char[] rangeStarts, char[] rangeEnds) { - this.description = description; - this.rangeStarts = rangeStarts; - this.rangeEnds = rangeEnds; - checkArgument(rangeStarts.length == rangeEnds.length); - for (int i = 0; i < rangeStarts.length; i++) { - checkArgument(rangeStarts[i] <= rangeEnds[i]); - if (i + 1 < rangeStarts.length) { - checkArgument(rangeEnds[i] < rangeStarts[i + 1]); - } - } - } - - @Override - public boolean matches(char c) { - int index = Arrays.binarySearch(rangeStarts, c); - if (index >= 0) { - return true; - } else { - index = ~index - 1; - return index >= 0 && c <= rangeEnds[index]; - } - } - - @Override - public String toString() { - return description; - } - } - - /** Implementation of {@link #digit()}. */ - private static final class Digit extends RangesMatcher { - - // Must be in ascending order. - private static final String ZEROES = - "0\u0660\u06f0\u07c0\u0966\u09e6\u0a66\u0ae6\u0b66" - + "\u0be6\u0c66\u0ce6\u0d66\u0e50\u0ed0\u0f20\u1040\u1090\u17e0\u1810" - + "\u1946\u19d0\u1b50\u1bb0\u1c40\u1c50\ua620\ua8d0\ua900\uaa50\uff10"; - - private static char[] zeroes() { - return ZEROES.toCharArray(); - } - - private static char[] nines() { - char[] nines = new char[ZEROES.length()]; - for (int i = 0; i < ZEROES.length(); i++) { - nines[i] = (char) (ZEROES.charAt(i) + 9); - } - return nines; - } - - static final Digit INSTANCE = new Digit(); - - private Digit() { - super("CharMatcher.digit()", zeroes(), nines()); - } - } - - /** Implementation of {@link #javaDigit()}. */ - private static final class JavaDigit extends CharMatcher { - - static final JavaDigit INSTANCE = new JavaDigit(); - - @Override - public boolean matches(char c) { - return Character.isDigit(c); - } - - @Override - public String toString() { - return "CharMatcher.javaDigit()"; - } - } - - /** Implementation of {@link #javaLetter()}. */ - private static final class JavaLetter extends CharMatcher { - - static final JavaLetter INSTANCE = new JavaLetter(); - - @Override - public boolean matches(char c) { - return Character.isLetter(c); - } - - @Override - public String toString() { - return "CharMatcher.javaLetter()"; - } - } - - /** Implementation of {@link #javaLetterOrDigit()}. */ - private static final class JavaLetterOrDigit extends CharMatcher { - - static final JavaLetterOrDigit INSTANCE = new JavaLetterOrDigit(); - - @Override - public boolean matches(char c) { - return Character.isLetterOrDigit(c); - } - - @Override - public String toString() { - return "CharMatcher.javaLetterOrDigit()"; - } - } - - /** Implementation of {@link #javaUpperCase()}. */ - private static final class JavaUpperCase extends CharMatcher { - - static final JavaUpperCase INSTANCE = new JavaUpperCase(); - - @Override - public boolean matches(char c) { - return Character.isUpperCase(c); - } - - @Override - public String toString() { - return "CharMatcher.javaUpperCase()"; - } - } - - /** Implementation of {@link #javaLowerCase()}. */ - private static final class JavaLowerCase extends CharMatcher { - - static final JavaLowerCase INSTANCE = new JavaLowerCase(); - - @Override - public boolean matches(char c) { - return Character.isLowerCase(c); - } - - @Override - public String toString() { - return "CharMatcher.javaLowerCase()"; - } - } - - /** Implementation of {@link #javaIsoControl()}. */ - private static final class JavaIsoControl extends NamedFastMatcher { - - static final JavaIsoControl INSTANCE = new JavaIsoControl(); - - private JavaIsoControl() { - super("CharMatcher.javaIsoControl()"); - } - - @Override - public boolean matches(char c) { - return c <= '\u001f' || (c >= '\u007f' && c <= '\u009f'); - } - } - - /** Implementation of {@link #invisible()}. */ - private static final class Invisible extends RangesMatcher { - - private static final String RANGE_STARTS = - "\u0000\u007f\u00ad\u0600\u061c\u06dd\u070f\u1680\u180e\u2000\u2028\u205f\u2066\u2067" - + "\u2068\u2069\u206a\u3000\ud800\ufeff\ufff9\ufffa"; - private static final String RANGE_ENDS = - "\u0020\u00a0\u00ad\u0604\u061c\u06dd\u070f\u1680\u180e\u200f\u202f\u2064\u2066\u2067" - + "\u2068\u2069\u206f\u3000\uf8ff\ufeff\ufff9\ufffb"; - - static final Invisible INSTANCE = new Invisible(); - - private Invisible() { - super( - "CharMatcher.invisible()", - RANGE_STARTS.toCharArray(), - RANGE_ENDS.toCharArray()); - } - } - - /** Implementation of {@link #singleWidth()}. */ - private static final class SingleWidth extends RangesMatcher { - - static final SingleWidth INSTANCE = new SingleWidth(); - - private SingleWidth() { - super( - "CharMatcher.singleWidth()", - "\u0000\u05be\u05d0\u05f3\u0600\u0750\u0e00\u1e00\u2100\ufb50\ufe70\uff61".toCharArray(), - "\u04f9\u05be\u05ea\u05f4\u06ff\u077f\u0e7f\u20af\u213a\ufdff\ufeff\uffdc".toCharArray()); - } - } - - // Non-static factory implementation classes - - /** Implementation of {@link #negate()}. */ - private static class Negated extends CharMatcher { - - final CharMatcher original; - - Negated(CharMatcher original) { - this.original = checkNotNull(original); - } - - @Override - public boolean matches(char c) { - return !original.matches(c); - } - - @Override - public boolean matchesAllOf(CharSequence sequence) { - return original.matchesNoneOf(sequence); - } - - @Override - public boolean matchesNoneOf(CharSequence sequence) { - return original.matchesAllOf(sequence); - } - - @Override - public int countIn(CharSequence sequence) { - return sequence.length() - original.countIn(sequence); - } - - @GwtIncompatible("java.util.BitSet") - @Override - void setBits(BitSet table) { - BitSet tmp = new BitSet(); - original.setBits(tmp); - tmp.flip(Character.MIN_VALUE, Character.MAX_VALUE + 1); - table.or(tmp); - } - - @Override - public CharMatcher negate() { - return original; - } - - @Override - public String toString() { - return original + ".negate()"; - } - } - - /** Implementation of {@link #and(CharMatcher)}. */ - private static final class And extends CharMatcher { - - final CharMatcher first; - final CharMatcher second; - - And(CharMatcher a, CharMatcher b) { - first = checkNotNull(a); - second = checkNotNull(b); - } - - @Override - public boolean matches(char c) { - return first.matches(c) && second.matches(c); - } - - @GwtIncompatible("java.util.BitSet") - @Override - void setBits(BitSet table) { - BitSet tmp1 = new BitSet(); - first.setBits(tmp1); - BitSet tmp2 = new BitSet(); - second.setBits(tmp2); - tmp1.and(tmp2); - table.or(tmp1); - } - - @Override - public String toString() { - return "CharMatcher.and(" + first + ", " + second + ")"; - } - } - - /** Implementation of {@link #or(CharMatcher)}. */ - private static final class Or extends CharMatcher { - - final CharMatcher first; - final CharMatcher second; - - Or(CharMatcher a, CharMatcher b) { - first = checkNotNull(a); - second = checkNotNull(b); - } - - @GwtIncompatible("java.util.BitSet") - @Override - void setBits(BitSet table) { - first.setBits(table); - second.setBits(table); - } - - @Override - public boolean matches(char c) { - return first.matches(c) || second.matches(c); - } - - @Override - public String toString() { - return "CharMatcher.or(" + first + ", " + second + ")"; - } - } - - // Static factory implementations - - /** Implementation of {@link #is(char)}. */ - private static final class Is extends FastMatcher { - - private final char match; - - Is(char match) { - this.match = match; - } - - @Override - public boolean matches(char c) { - return c == match; - } - - @Override - public String replaceFrom(CharSequence sequence, char replacement) { - return sequence.toString().replace(match, replacement); - } - - @Override - public CharMatcher and(CharMatcher other) { - return other.matches(match) ? this : none(); - } - - @Override - public CharMatcher or(CharMatcher other) { - return other.matches(match) ? other : super.or(other); - } - - @Override - public CharMatcher negate() { - return isNot(match); - } - - @GwtIncompatible("java.util.BitSet") - @Override - void setBits(BitSet table) { - table.set(match); - } - - @Override - public String toString() { - return "CharMatcher.is('" + showCharacter(match) + "')"; - } - } - - /** Implementation of {@link #isNot(char)}. */ - private static final class IsNot extends FastMatcher { - - private final char match; - - IsNot(char match) { - this.match = match; - } - - @Override - public boolean matches(char c) { - return c != match; - } - - @Override - public CharMatcher and(CharMatcher other) { - return other.matches(match) ? super.and(other) : other; - } - - @Override - public CharMatcher or(CharMatcher other) { - return other.matches(match) ? any() : this; - } - - @GwtIncompatible("java.util.BitSet") - @Override - void setBits(BitSet table) { - table.set(0, match); - table.set(match + 1, Character.MAX_VALUE + 1); - } - - @Override - public CharMatcher negate() { - return is(match); - } - - @Override - public String toString() { - return "CharMatcher.isNot('" + showCharacter(match) + "')"; - } - } - - private static CharMatcher.IsEither isEither(char c1, char c2) { - return new CharMatcher.IsEither(c1, c2); - } - - /** Implementation of {@link #anyOf(CharSequence)} for exactly two characters. */ - private static final class IsEither extends FastMatcher { - - private final char match1; - private final char match2; - - IsEither(char match1, char match2) { - this.match1 = match1; - this.match2 = match2; - } - - @Override - public boolean matches(char c) { - return c == match1 || c == match2; - } - - @GwtIncompatible("java.util.BitSet") - @Override - void setBits(BitSet table) { - table.set(match1); - table.set(match2); - } - - @Override - public String toString() { - return "CharMatcher.anyOf(\"" + showCharacter(match1) + showCharacter(match2) + "\")"; - } - } - - /** Implementation of {@link #anyOf(CharSequence)} for three or more characters. */ - private static final class AnyOf extends CharMatcher { - - private final char[] chars; - - public AnyOf(CharSequence chars) { - this.chars = chars.toString().toCharArray(); - Arrays.sort(this.chars); - } - - @Override - public boolean matches(char c) { - return Arrays.binarySearch(chars, c) >= 0; - } - - @Override - @GwtIncompatible("java.util.BitSet") - void setBits(BitSet table) { - for (char c : chars) { - table.set(c); - } - } - - @Override - public String toString() { - StringBuilder description = new StringBuilder("CharMatcher.anyOf(\""); - for (char c : chars) { - description.append(showCharacter(c)); - } - description.append("\")"); - return description.toString(); - } - } - - /** Implementation of {@link #inRange(char, char)}. */ - private static final class InRange extends FastMatcher { - - private final char startInclusive; - private final char endInclusive; - - InRange(char startInclusive, char endInclusive) { - checkArgument(endInclusive >= startInclusive); - this.startInclusive = startInclusive; - this.endInclusive = endInclusive; - } - - @Override - public boolean matches(char c) { - return startInclusive <= c && c <= endInclusive; - } - - @GwtIncompatible("java.util.BitSet") - @Override - void setBits(BitSet table) { - table.set(startInclusive, endInclusive + 1); - } - - @Override - public String toString() { - return "CharMatcher.inRange('" - + showCharacter(startInclusive) - + "', '" - + showCharacter(endInclusive) - + "')"; - } - } - - /** Implementation of {@link #forPredicate(Predicate)}. */ - private static final class ForPredicate extends CharMatcher { - - private final Predicate predicate; - - ForPredicate(Predicate predicate) { - this.predicate = checkNotNull(predicate); - } - - @Override - public boolean matches(char c) { - return predicate.apply(c); - } - - @SuppressWarnings("deprecation") // intentional; deprecation is for callers primarily - @Override - public boolean apply(Character character) { - return predicate.apply(checkNotNull(character)); - } - - @Override - public String toString() { - return "CharMatcher.forPredicate(" + predicate + ")"; - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Charsets.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Charsets.java deleted file mode 100644 index 9aba5c486416..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Charsets.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; - -import java.nio.charset.Charset; - -/** - * Contains constant definitions for the six standard {@link Charset} instances, which are - * guaranteed to be supported by all Java platform implementations. - * - *

Assuming you're free to choose, note that {@link #UTF_8} is widely preferred. - * - *

See the Guava User Guide article on - * {@code Charsets}. - * - * @author Mike Bostock - * @since 1.0 - */ -@GwtCompatible(emulated = true) -public final class Charsets { - private Charsets() {} - - /** - * US-ASCII: seven-bit ASCII, the Basic Latin block of the Unicode character set (ISO646-US). - * - *

Note for Java 7 and later: this constant should be treated as deprecated; use - * {@link java.nio.charset.StandardCharsets#US_ASCII} instead. - * - */ - @GwtIncompatible("Non-UTF-8 Charset") - public static final Charset US_ASCII = Charset.forName("US-ASCII"); - - /** - * ISO-8859-1: ISO Latin Alphabet Number 1 (ISO-LATIN-1). - * - *

Note for Java 7 and later: this constant should be treated as deprecated; use - * {@link java.nio.charset.StandardCharsets#ISO_8859_1} instead. - * - */ - @GwtIncompatible("Non-UTF-8 Charset") - public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); - - /** - * UTF-8: eight-bit UCS Transformation Format. - * - *

Note for Java 7 and later: this constant should be treated as deprecated; use - * {@link java.nio.charset.StandardCharsets#UTF_8} instead. - * - */ - public static final Charset UTF_8 = Charset.forName("UTF-8"); - - /** - * UTF-16BE: sixteen-bit UCS Transformation Format, big-endian byte order. - * - *

Note for Java 7 and later: this constant should be treated as deprecated; use - * {@link java.nio.charset.StandardCharsets#UTF_16BE} instead. - * - */ - @GwtIncompatible("Non-UTF-8 Charset") - public static final Charset UTF_16BE = Charset.forName("UTF-16BE"); - - /** - * UTF-16LE: sixteen-bit UCS Transformation Format, little-endian byte order. - * - *

Note for Java 7 and later: this constant should be treated as deprecated; use - * {@link java.nio.charset.StandardCharsets#UTF_16LE} instead. - * - */ - @GwtIncompatible("Non-UTF-8 Charset") - public static final Charset UTF_16LE = Charset.forName("UTF-16LE"); - - /** - * UTF-16: sixteen-bit UCS Transformation Format, byte order identified by an optional byte-order - * mark. - * - *

Note for Java 7 and later: this constant should be treated as deprecated; use - * {@link java.nio.charset.StandardCharsets#UTF_16} instead. - * - */ - @GwtIncompatible("Non-UTF-8 Charset") - public static final Charset UTF_16 = Charset.forName("UTF-16"); - - /* - * Please do not add new Charset references to this class, unless those character encodings are - * part of the set required to be supported by all Java platform implementations! Any Charsets - * initialized here may cause unexpected delays when this class is loaded. See the Charset - * Javadocs for the list of built-in character encodings. - */ -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Converter.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Converter.java deleted file mode 100644 index 40ca53aff203..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Converter.java +++ /dev/null @@ -1,523 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; -import java.util.Iterator; - -import javax.annotation.Nullable; - -/** - * A function from {@code A} to {@code B} with an associated reverse function from {@code B} - * to {@code A}; used for converting back and forth between different representations of the same - * information. - * - *

Invertibility

- * - *

The reverse operation may be a strict inverse (meaning that {@code - * converter.reverse().convert(converter.convert(a)).equals(a)} is always true). However, it is - * very common (perhaps more common) for round-trip conversion to be lossy. Consider - * an example round-trip using {@link com.google.common.primitives.Doubles#stringConverter}: - * - *

    - *
  1. {@code stringConverter().convert("1.00")} returns the {@code Double} value {@code 1.0} - *
  2. {@code stringConverter().reverse().convert(1.0)} returns the string {@code "1.0"} -- - * not the same string ({@code "1.00"}) we started with - *
- * - *

Note that it should still be the case that the round-tripped and original objects are - * similar. - * - *

Nullability

- * - *

A converter always converts {@code null} to {@code null} and non-null references to non-null - * references. It would not make sense to consider {@code null} and a non-null reference to be - * "different representations of the same information", since one is distinguishable from - * missing information and the other is not. The {@link #convert} method handles this null - * behavior for all converters; implementations of {@link #doForward} and {@link #doBackward} are - * guaranteed to never be passed {@code null}, and must never return {@code null}. - * - - *

Common ways to use

- * - *

Getting a converter: - * - *

    - *
  • Use a provided converter implementation, such as {@link Enums#stringConverter}, {@link - * com.google.common.primitives.Ints#stringConverter Ints.stringConverter} or the {@linkplain - * #reverse reverse} views of these. - *
  • Convert between specific preset values using {@link - * com.google.common.collect.Maps#asConverter Maps.asConverter}. For example, use this to create - * a "fake" converter for a unit test. It is unnecessary (and confusing) to mock the - * {@code Converter} type using a mocking framework. - *
  • Extend this class and implement its {@link #doForward} and {@link #doBackward} methods. - *
  • If using Java 8, you may prefer to pass two lambda expressions or method references to {@link - * #from}. - *
- * - *

Using a converter: - * - *

    - *
  • Convert one instance in the "forward" direction using {@code converter.convert(a)}. - *
  • Convert multiple instances "forward" using {@code converter.convertAll(as)}. - *
  • Convert in the "backward" direction using {@code converter.reverse().convert(b)} or {@code - * converter.reverse().convertAll(bs)}. - *
  • Use {@code converter} or {@code converter.reverse()} anywhere a {@link Function} is accepted - *
  • Do not call {@link #doForward} or {@link #doBackward} directly; these exist only to be - * overridden. - *
- * - *

Example

- * - *
   {@code
- *
- *   return new Converter() {
- *     @Override
- *     protected String doForward(Integer i) {
- *       return Integer.toHexString(i);
- *     }
- *
- *     @Override
- *     protected Integer doBackward(String s) {
- *       return parseUnsignedInt(s, 16);
- *     }
- *   };}
- * - *

An alternative using Java 8:

   {@code
- *
- *   return Converter.from(Integer::toHexString, s -> parseUnsignedInt(s, 16));}
- * - * @author Mike Ward - * @author Kurt Alfred Kluever - * @author Gregory Kick - * @since 16.0 - */ -@Beta -@GwtCompatible -public abstract class Converter implements Function { - private final boolean handleNullAutomatically; - - // We lazily cache the reverse view to avoid allocating on every call to reverse(). - private transient Converter reverse; - - /** Constructor for use by subclasses. */ - protected Converter() { - this(true); - } - - /** - * Constructor used only by {@code LegacyConverter} to suspend automatic null-handling. - */ - Converter(boolean handleNullAutomatically) { - this.handleNullAutomatically = handleNullAutomatically; - } - - // SPI methods (what subclasses must implement) - - /** - * Returns a representation of {@code a} as an instance of type {@code B}. If {@code a} cannot be - * converted, an unchecked exception (such as {@link IllegalArgumentException}) should be thrown. - * - * @param a the instance to convert; will never be null - * @return the converted instance; must not be null - */ - protected abstract B doForward(A a); - - /** - * Returns a representation of {@code b} as an instance of type {@code A}. If {@code b} cannot be - * converted, an unchecked exception (such as {@link IllegalArgumentException}) should be thrown. - * - * @param b the instance to convert; will never be null - * @return the converted instance; must not be null - * @throws UnsupportedOperationException if backward conversion is not implemented; this should be - * very rare. Note that if backward conversion is not only unimplemented but - * unimplementable (for example, consider a {@code Converter}), - * then this is not logically a {@code Converter} at all, and should just implement {@link - * Function}. - */ - protected abstract A doBackward(B b); - - // API (consumer-side) methods - - /** - * Returns a representation of {@code a} as an instance of type {@code B}. - * - * @return the converted value; is null if and only if {@code a} is null - */ - @Nullable - public final B convert(@Nullable A a) { - return correctedDoForward(a); - } - - @Nullable - B correctedDoForward(@Nullable A a) { - if (handleNullAutomatically) { - // TODO(kevinb): we shouldn't be checking for a null result at runtime. Assert? - return a == null ? null : checkNotNull(doForward(a)); - } else { - return doForward(a); - } - } - - @Nullable - A correctedDoBackward(@Nullable B b) { - if (handleNullAutomatically) { - // TODO(kevinb): we shouldn't be checking for a null result at runtime. Assert? - return b == null ? null : checkNotNull(doBackward(b)); - } else { - return doBackward(b); - } - } - - /** - * Returns an iterable that applies {@code convert} to each element of {@code fromIterable}. The - * conversion is done lazily. - * - *

The returned iterable's iterator supports {@code remove()} if the input iterator does. After - * a successful {@code remove()} call, {@code fromIterable} no longer contains the corresponding - * element. - */ - public Iterable convertAll(final Iterable fromIterable) { - checkNotNull(fromIterable, "fromIterable"); - return new Iterable() { - @Override - public Iterator iterator() { - return new Iterator() { - private final Iterator fromIterator = fromIterable.iterator(); - - @Override - public boolean hasNext() { - return fromIterator.hasNext(); - } - - @Override - public B next() { - return convert(fromIterator.next()); - } - - @Override - public void remove() { - fromIterator.remove(); - } - }; - } - }; - } - - /** - * Returns the reversed view of this converter, which converts {@code this.convert(a)} back to a - * value roughly equivalent to {@code a}. - * - *

The returned converter is serializable if {@code this} converter is. - */ - // TODO(kak): Make this method final - public Converter reverse() { - Converter result = reverse; - return (result == null) ? reverse = new ReverseConverter(this) : result; - } - - private static final class ReverseConverter extends Converter - implements Serializable { - final Converter original; - - ReverseConverter(Converter original) { - this.original = original; - } - - /* - * These gymnastics are a little confusing. Basically this class has neither legacy nor - * non-legacy behavior; it just needs to let the behavior of the backing converter shine - * through. So, we override the correctedDo* methods, after which the do* methods should never - * be reached. - */ - - @Override - protected A doForward(B b) { - throw new AssertionError(); - } - - @Override - protected B doBackward(A a) { - throw new AssertionError(); - } - - @Override - @Nullable - A correctedDoForward(@Nullable B b) { - return original.correctedDoBackward(b); - } - - @Override - @Nullable - B correctedDoBackward(@Nullable A a) { - return original.correctedDoForward(a); - } - - @Override - public Converter reverse() { - return original; - } - - @Override - public boolean equals(@Nullable Object object) { - if (object instanceof ReverseConverter) { - ReverseConverter that = (ReverseConverter) object; - return this.original.equals(that.original); - } - return false; - } - - @Override - public int hashCode() { - return ~original.hashCode(); - } - - @Override - public String toString() { - return original + ".reverse()"; - } - - private static final long serialVersionUID = 0L; - } - - /** - * Returns a converter whose {@code convert} method applies {@code secondConverter} to the result - * of this converter. Its {@code reverse} method applies the converters in reverse order. - * - *

The returned converter is serializable if {@code this} converter and {@code secondConverter} - * are. - */ - public final Converter andThen(Converter secondConverter) { - return doAndThen(secondConverter); - } - - /** - * Package-private non-final implementation of andThen() so only we can override it. - */ - Converter doAndThen(Converter secondConverter) { - return new ConverterComposition(this, checkNotNull(secondConverter)); - } - - private static final class ConverterComposition extends Converter - implements Serializable { - final Converter first; - final Converter second; - - ConverterComposition(Converter first, Converter second) { - this.first = first; - this.second = second; - } - - /* - * These gymnastics are a little confusing. Basically this class has neither legacy nor - * non-legacy behavior; it just needs to let the behaviors of the backing converters shine - * through (which might even differ from each other!). So, we override the correctedDo* methods, - * after which the do* methods should never be reached. - */ - - @Override - protected C doForward(A a) { - throw new AssertionError(); - } - - @Override - protected A doBackward(C c) { - throw new AssertionError(); - } - - @Override - @Nullable - C correctedDoForward(@Nullable A a) { - return second.correctedDoForward(first.correctedDoForward(a)); - } - - @Override - @Nullable - A correctedDoBackward(@Nullable C c) { - return first.correctedDoBackward(second.correctedDoBackward(c)); - } - - @Override - public boolean equals(@Nullable Object object) { - if (object instanceof ConverterComposition) { - ConverterComposition that = (ConverterComposition) object; - return this.first.equals(that.first) && this.second.equals(that.second); - } - return false; - } - - @Override - public int hashCode() { - return 31 * first.hashCode() + second.hashCode(); - } - - @Override - public String toString() { - return first + ".andThen(" + second + ")"; - } - - private static final long serialVersionUID = 0L; - } - - /** - * @deprecated Provided to satisfy the {@code Function} interface; use {@link #convert} instead. - */ - @Deprecated - @Override - @Nullable - public final B apply(@Nullable A a) { - return convert(a); - } - - /** - * Indicates whether another object is equal to this converter. - * - *

Most implementations will have no reason to override the behavior of {@link Object#equals}. - * However, an implementation may also choose to return {@code true} whenever {@code object} is a - * {@link Converter} that it considers interchangeable with this one. "Interchangeable" - * typically means that {@code Objects.equal(this.convert(a), that.convert(a))} is true for - * all {@code a} of type {@code A} (and similarly for {@code reverse}). Note that a {@code false} - * result from this method does not imply that the converters are known not to be - * interchangeable. - */ - @Override - public boolean equals(@Nullable Object object) { - return super.equals(object); - } - - // Static converters - - /** - * Returns a converter based on existing forward and backward functions. Note that it is - * unnecessary to create new classes implementing {@code Function} just to pass them in - * here. Instead, simply subclass {@code Converter} and implement its {@link #doForward} and - * {@link #doBackward} methods directly. - * - *

These functions will never be passed {@code null} and must not under any circumstances - * return {@code null}. If a value cannot be converted, the function should throw an unchecked - * exception (typically, but not necessarily, {@link IllegalArgumentException}). - * - *

The returned converter is serializable if both provided functions are. - * - * @since 17.0 - */ - public static Converter from( - Function forwardFunction, - Function backwardFunction) { - return new FunctionBasedConverter(forwardFunction, backwardFunction); - } - - private static final class FunctionBasedConverter extends Converter - implements Serializable { - private final Function forwardFunction; - private final Function backwardFunction; - - private FunctionBasedConverter( - Function forwardFunction, - Function backwardFunction) { - this.forwardFunction = checkNotNull(forwardFunction); - this.backwardFunction = checkNotNull(backwardFunction); - } - - @Override - protected B doForward(A a) { - return forwardFunction.apply(a); - } - - @Override - protected A doBackward(B b) { - return backwardFunction.apply(b); - } - - @Override - public boolean equals(@Nullable Object object) { - if (object instanceof FunctionBasedConverter) { - FunctionBasedConverter that = (FunctionBasedConverter) object; - return this.forwardFunction.equals(that.forwardFunction) - && this.backwardFunction.equals(that.backwardFunction); - } - return false; - } - - @Override - public int hashCode() { - return forwardFunction.hashCode() * 31 + backwardFunction.hashCode(); - } - - @Override - public String toString() { - return "Converter.from(" + forwardFunction + ", " + backwardFunction + ")"; - } - } - - /** - * Returns a serializable converter that always converts or reverses an object to itself. - */ - @SuppressWarnings("unchecked") // implementation is "fully variant" - public static Converter identity() { - return (IdentityConverter) IdentityConverter.INSTANCE; - } - - /** - * A converter that always converts or reverses an object to itself. Note that T is now a - * "pass-through type". - */ - private static final class IdentityConverter extends Converter implements Serializable { - static final IdentityConverter INSTANCE = new IdentityConverter(); - - @Override - protected T doForward(T t) { - return t; - } - - @Override - protected T doBackward(T t) { - return t; - } - - @Override - public IdentityConverter reverse() { - return this; - } - - @Override - Converter doAndThen(Converter otherConverter) { - return checkNotNull(otherConverter, "otherConverter"); - } - - /* - * We *could* override convertAll() to return its input, but it's a rather pointless - * optimization and opened up a weird type-safety problem. - */ - - @Override - public String toString() { - return "Converter.identity()"; - } - - private Object readResolve() { - return INSTANCE; - } - - private static final long serialVersionUID = 0L; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Defaults.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Defaults.java deleted file mode 100644 index bfc22cf0097e..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Defaults.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * This class provides default values for all Java types, as defined by the JLS. - * - * @author Ben Yu - * @since 1.0 - */ -@CheckReturnValue -public final class Defaults { - private Defaults() {} - - private static final Map, Object> DEFAULTS; - - static { - // Only add to this map via put(Map, Class, T) - Map, Object> map = new HashMap, Object>(); - put(map, boolean.class, false); - put(map, char.class, '\0'); - put(map, byte.class, (byte) 0); - put(map, short.class, (short) 0); - put(map, int.class, 0); - put(map, long.class, 0L); - put(map, float.class, 0f); - put(map, double.class, 0d); - DEFAULTS = Collections.unmodifiableMap(map); - } - - private static void put(Map, Object> map, Class type, T value) { - map.put(type, value); - } - - /** - * Returns the default value of {@code type} as defined by JLS --- {@code 0} for numbers, {@code - * false} for {@code boolean} and {@code '\0'} for {@code char}. For non-primitive types and - * {@code void}, {@code null} is returned. - */ - @Nullable - public static T defaultValue(Class type) { - // Primitives.wrap(type).cast(...) would avoid the warning, but we can't use that from here - @SuppressWarnings("unchecked") // the put method enforces this key-value relationship - T t = (T) DEFAULTS.get(checkNotNull(type)); - return t; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Enums.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Enums.java deleted file mode 100644 index cbbe08fc277f..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Enums.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; - -import java.io.Serializable; -import java.lang.ref.WeakReference; -import java.lang.reflect.Field; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.Map; -import java.util.WeakHashMap; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * Utility methods for working with {@link Enum} instances. - * - * @author Steve McKay - * - * @since 9.0 - */ -@CheckReturnValue -@GwtCompatible(emulated = true) -@Beta -public final class Enums { - - private Enums() {} - - /** - * Returns the {@link Field} in which {@code enumValue} is defined. For example, to get the - * {@code Description} annotation on the {@code GOLF} constant of enum {@code Sport}, use - * {@code Enums.getField(Sport.GOLF).getAnnotation(Description.class)}. - * - * @since 12.0 - */ - @GwtIncompatible("reflection") - public static Field getField(Enum enumValue) { - Class clazz = enumValue.getDeclaringClass(); - try { - return clazz.getDeclaredField(enumValue.name()); - } catch (NoSuchFieldException impossible) { - throw new AssertionError(impossible); - } - } - - /** - * Returns an optional enum constant for the given type, using {@link Enum#valueOf}. If the - * constant does not exist, {@link Optional#absent} is returned. A common use case is for parsing - * user input or falling back to a default enum constant. For example, - * {@code Enums.getIfPresent(Country.class, countryInput).or(Country.DEFAULT);} - * - * @since 12.0 - */ - public static > Optional getIfPresent(Class enumClass, String value) { - checkNotNull(enumClass); - checkNotNull(value); - return Platform.getEnumIfPresent(enumClass, value); - } - - @GwtIncompatible("java.lang.ref.WeakReference") - private static final Map>, Map>>> - enumConstantCache = - new WeakHashMap< - Class>, Map>>>(); - - @GwtIncompatible("java.lang.ref.WeakReference") - private static > Map>> populateCache( - Class enumClass) { - Map>> result = - new HashMap>>(); - for (T enumInstance : EnumSet.allOf(enumClass)) { - result.put(enumInstance.name(), new WeakReference>(enumInstance)); - } - enumConstantCache.put(enumClass, result); - return result; - } - - @GwtIncompatible("java.lang.ref.WeakReference") - static > Map>> getEnumConstants( - Class enumClass) { - synchronized (enumConstantCache) { - Map>> constants = enumConstantCache.get(enumClass); - if (constants == null) { - constants = populateCache(enumClass); - } - return constants; - } - } - - /** - * Returns a converter that converts between strings and {@code enum} values of type - * {@code enumClass} using {@link Enum#valueOf(Class, String)} and {@link Enum#name()}. The - * converter will throw an {@code IllegalArgumentException} if the argument is not the name of - * any enum constant in the specified enum. - * - * @since 16.0 - */ - public static > Converter stringConverter(final Class enumClass) { - return new StringConverter(enumClass); - } - - private static final class StringConverter> extends Converter - implements Serializable { - - private final Class enumClass; - - StringConverter(Class enumClass) { - this.enumClass = checkNotNull(enumClass); - } - - @Override - protected T doForward(String value) { - return Enum.valueOf(enumClass, value); - } - - @Override - protected String doBackward(T enumValue) { - return enumValue.name(); - } - - @Override - public boolean equals(@Nullable Object object) { - if (object instanceof StringConverter) { - StringConverter that = (StringConverter) object; - return this.enumClass.equals(that.enumClass); - } - return false; - } - - @Override - public int hashCode() { - return enumClass.hashCode(); - } - - @Override - public String toString() { - return "Enums.stringConverter(" + enumClass.getName() + ".class)"; - } - - private static final long serialVersionUID = 0L; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Equivalence.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Equivalence.java deleted file mode 100644 index 344454f2dd7d..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Equivalence.java +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright (C) 2010 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * A strategy for determining whether two instances are considered equivalent. Examples of - * equivalences are the {@linkplain #identity() identity equivalence} and {@linkplain #equals equals - * equivalence}. - * - * @author Bob Lee - * @author Ben Yu - * @author Gregory Kick - * @since 10.0 (mostly source-compatible since 4.0) - */ -@CheckReturnValue -@GwtCompatible -public abstract class Equivalence { - /** - * Constructor for use by subclasses. - */ - protected Equivalence() {} - - /** - * Returns {@code true} if the given objects are considered equivalent. - * - *

The {@code equivalent} method implements an equivalence relation on object references: - * - *

    - *
  • It is reflexive: for any reference {@code x}, including null, {@code - * equivalent(x, x)} returns {@code true}. - *
  • It is symmetric: for any references {@code x} and {@code y}, {@code - * equivalent(x, y) == equivalent(y, x)}. - *
  • It is transitive: for any references {@code x}, {@code y}, and {@code z}, if - * {@code equivalent(x, y)} returns {@code true} and {@code equivalent(y, z)} returns {@code - * true}, then {@code equivalent(x, z)} returns {@code true}. - *
  • It is consistent: for any references {@code x} and {@code y}, multiple invocations - * of {@code equivalent(x, y)} consistently return {@code true} or consistently return {@code - * false} (provided that neither {@code x} nor {@code y} is modified). - *
- */ - public final boolean equivalent(@Nullable T a, @Nullable T b) { - if (a == b) { - return true; - } - if (a == null || b == null) { - return false; - } - return doEquivalent(a, b); - } - - /** - * Returns {@code true} if {@code a} and {@code b} are considered equivalent. - * - *

Called by {@link #equivalent}. {@code a} and {@code b} are not the same - * object and are not nulls. - * - * @since 10.0 (previously, subclasses would override equivalent()) - */ - protected abstract boolean doEquivalent(T a, T b); - - /** - * Returns a hash code for {@code t}. - * - *

The {@code hash} has the following properties: - *

    - *
  • It is consistent: for any reference {@code x}, multiple invocations of - * {@code hash(x}} consistently return the same value provided {@code x} remains unchanged - * according to the definition of the equivalence. The hash need not remain consistent from - * one execution of an application to another execution of the same application. - *
  • It is distributable across equivalence: for any references {@code x} and {@code y}, - * if {@code equivalent(x, y)}, then {@code hash(x) == hash(y)}. It is not necessary - * that the hash be distributable across inequivalence. If {@code equivalence(x, y)} - * is false, {@code hash(x) == hash(y)} may still be true. - *
  • {@code hash(null)} is {@code 0}. - *
- */ - public final int hash(@Nullable T t) { - if (t == null) { - return 0; - } - return doHash(t); - } - - /** - * Returns a hash code for non-null object {@code t}. - * - *

Called by {@link #hash}. - * - * @since 10.0 (previously, subclasses would override hash()) - */ - protected abstract int doHash(T t); - - /** - * Returns a new equivalence relation for {@code F} which evaluates equivalence by first applying - * {@code function} to the argument, then evaluating using {@code this}. That is, for any pair of - * non-null objects {@code x} and {@code y}, {@code - * equivalence.onResultOf(function).equivalent(a, b)} is true if and only if {@code - * equivalence.equivalent(function.apply(a), function.apply(b))} is true. - * - *

For example: - * - *

   {@code
-   *    Equivalence SAME_AGE = Equivalence.equals().onResultOf(GET_PERSON_AGE);}
- * - *

{@code function} will never be invoked with a null value. - * - *

Note that {@code function} must be consistent according to {@code this} equivalence - * relation. That is, invoking {@link Function#apply} multiple times for a given value must return - * equivalent results. - * For example, {@code Equivalence.identity().onResultOf(Functions.toStringFunction())} is broken - * because it's not guaranteed that {@link Object#toString}) always returns the same string - * instance. - * - * @since 10.0 - */ - public final Equivalence onResultOf(Function function) { - return new FunctionalEquivalence(function, this); - } - - /** - * Returns a wrapper of {@code reference} that implements - * {@link Wrapper#equals(Object) Object.equals()} such that - * {@code wrap(a).equals(wrap(b))} if and only if {@code equivalent(a, b)}. - * - * @since 10.0 - */ - public final Wrapper wrap(@Nullable S reference) { - return new Wrapper(this, reference); - } - - /** - * Wraps an object so that {@link #equals(Object)} and {@link #hashCode()} delegate to an - * {@link Equivalence}. - * - *

For example, given an {@link Equivalence} for {@link String strings} named {@code equiv} - * that tests equivalence using their lengths: - * - *

   {@code
-   *   equiv.wrap("a").equals(equiv.wrap("b")) // true
-   *   equiv.wrap("a").equals(equiv.wrap("hello")) // false}
- * - *

Note in particular that an equivalence wrapper is never equal to the object it wraps. - * - *

   {@code
-   *   equiv.wrap(obj).equals(obj) // always false}
- * - * @since 10.0 - */ - public static final class Wrapper implements Serializable { - private final Equivalence equivalence; - @Nullable private final T reference; - - private Wrapper(Equivalence equivalence, @Nullable T reference) { - this.equivalence = checkNotNull(equivalence); - this.reference = reference; - } - - /** Returns the (possibly null) reference wrapped by this instance. */ - @Nullable - public T get() { - return reference; - } - - /** - * Returns {@code true} if {@link Equivalence#equivalent(Object, Object)} applied to the wrapped - * references is {@code true} and both wrappers use the {@link Object#equals(Object) same} - * equivalence. - */ - @Override - public boolean equals(@Nullable Object obj) { - if (obj == this) { - return true; - } - if (obj instanceof Wrapper) { - Wrapper that = (Wrapper) obj; // note: not necessarily a Wrapper - - if (this.equivalence.equals(that.equivalence)) { - /* - * We'll accept that as sufficient "proof" that either equivalence should be able to - * handle either reference, so it's safe to circumvent compile-time type checking. - */ - @SuppressWarnings("unchecked") - Equivalence equivalence = (Equivalence) this.equivalence; - return equivalence.equivalent(this.reference, that.reference); - } - } - return false; - } - - /** - * Returns the result of {@link Equivalence#hash(Object)} applied to the wrapped reference. - */ - @Override - public int hashCode() { - return equivalence.hash(reference); - } - - /** - * Returns a string representation for this equivalence wrapper. The form of this string - * representation is not specified. - */ - @Override - public String toString() { - return equivalence + ".wrap(" + reference + ")"; - } - - private static final long serialVersionUID = 0; - } - - /** - * Returns an equivalence over iterables based on the equivalence of their elements. More - * specifically, two iterables are considered equivalent if they both contain the same number of - * elements, and each pair of corresponding elements is equivalent according to - * {@code this}. Null iterables are equivalent to one another. - * - *

Note that this method performs a similar function for equivalences as {@link - * com.google.common.collect.Ordering#lexicographical} does for orderings. - * - * @since 10.0 - */ - @GwtCompatible(serializable = true) - public final Equivalence> pairwise() { - // Ideally, the returned equivalence would support Iterable. However, - // the need for this is so rare that it's not worth making callers deal with the ugly wildcard. - return new PairwiseEquivalence(this); - } - - /** - * Returns a predicate that evaluates to true if and only if the input is - * equivalent to {@code target} according to this equivalence relation. - * - * @since 10.0 - */ - @Beta - public final Predicate equivalentTo(@Nullable T target) { - return new EquivalentToPredicate(this, target); - } - - private static final class EquivalentToPredicate implements Predicate, Serializable { - - private final Equivalence equivalence; - @Nullable private final T target; - - EquivalentToPredicate(Equivalence equivalence, @Nullable T target) { - this.equivalence = checkNotNull(equivalence); - this.target = target; - } - - @Override - public boolean apply(@Nullable T input) { - return equivalence.equivalent(input, target); - } - - @Override - public boolean equals(@Nullable Object obj) { - if (this == obj) { - return true; - } - if (obj instanceof EquivalentToPredicate) { - EquivalentToPredicate that = (EquivalentToPredicate) obj; - return equivalence.equals(that.equivalence) && Objects.equal(target, that.target); - } - return false; - } - - @Override - public int hashCode() { - return Objects.hashCode(equivalence, target); - } - - @Override - public String toString() { - return equivalence + ".equivalentTo(" + target + ")"; - } - - private static final long serialVersionUID = 0; - } - - /** - * Returns an equivalence that delegates to {@link Object#equals} and {@link Object#hashCode}. - * {@link Equivalence#equivalent} returns {@code true} if both values are null, or if neither - * value is null and {@link Object#equals} returns {@code true}. {@link Equivalence#hash} returns - * {@code 0} if passed a null value. - * - * @since 13.0 - * @since 8.0 (in Equivalences with null-friendly behavior) - * @since 4.0 (in Equivalences) - */ - public static Equivalence equals() { - return Equals.INSTANCE; - } - - /** - * Returns an equivalence that uses {@code ==} to compare values and {@link - * System#identityHashCode(Object)} to compute the hash code. {@link Equivalence#equivalent} - * returns {@code true} if {@code a == b}, including in the case that a and b are both null. - * - * @since 13.0 - * @since 4.0 (in Equivalences) - */ - public static Equivalence identity() { - return Identity.INSTANCE; - } - - static final class Equals extends Equivalence implements Serializable { - - static final Equals INSTANCE = new Equals(); - - @Override - protected boolean doEquivalent(Object a, Object b) { - return a.equals(b); - } - - @Override - protected int doHash(Object o) { - return o.hashCode(); - } - - private Object readResolve() { - return INSTANCE; - } - - private static final long serialVersionUID = 1; - } - - static final class Identity extends Equivalence implements Serializable { - - static final Identity INSTANCE = new Identity(); - - @Override - protected boolean doEquivalent(Object a, Object b) { - return false; - } - - @Override - protected int doHash(Object o) { - return System.identityHashCode(o); - } - - private Object readResolve() { - return INSTANCE; - } - - private static final long serialVersionUID = 1; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/FinalizablePhantomReference.java b/thirdparty/google-guava/src/main/java/com/google/common/base/FinalizablePhantomReference.java deleted file mode 100644 index 952143e3cc02..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/FinalizablePhantomReference.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import java.lang.ref.PhantomReference; -import java.lang.ref.ReferenceQueue; - -/** - * Phantom reference with a {@code finalizeReferent()} method which a background thread invokes - * after the garbage collector reclaims the referent. This is a simpler alternative to using a - * {@link ReferenceQueue}. - * - *

Unlike a normal phantom reference, this reference will be cleared automatically. - * - * @author Bob Lee - * @since 2.0 - */ -public abstract class FinalizablePhantomReference extends PhantomReference - implements FinalizableReference { - /** - * Constructs a new finalizable phantom reference. - * - * @param referent to phantom reference - * @param queue that should finalize the referent - */ - protected FinalizablePhantomReference(T referent, FinalizableReferenceQueue queue) { - super(referent, queue.queue); - queue.cleanUp(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/FinalizableReference.java b/thirdparty/google-guava/src/main/java/com/google/common/base/FinalizableReference.java deleted file mode 100644 index acc6efc02e5d..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/FinalizableReference.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -/** - * Implemented by references that have code to run after garbage collection of their referents. - * - * @see FinalizableReferenceQueue - * @author Bob Lee - * @since 2.0 - */ -public interface FinalizableReference { - /** - * Invoked on a background thread after the referent has been garbage collected unless security - * restrictions prevented starting a background thread, in which case this method is invoked when - * new references are created. - */ - void finalizeReferent(); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/FinalizableReferenceQueue.java b/thirdparty/google-guava/src/main/java/com/google/common/base/FinalizableReferenceQueue.java deleted file mode 100644 index b98cd975547c..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/FinalizableReferenceQueue.java +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import com.google.common.annotations.VisibleForTesting; - -import java.io.Closeable; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.lang.ref.PhantomReference; -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.lang.reflect.Method; -import java.net.URL; -import java.net.URLClassLoader; -import com.google.common.logging.Level; -import com.google.common.logging.Logger; - -import javax.annotation.Nullable; - -/** - * A reference queue with an associated background thread that dequeues references and invokes - * {@link FinalizableReference#finalizeReferent()} on them. - * - *

Keep a strong reference to this object until all of the associated referents have been - * finalized. If this object is garbage collected earlier, the backing thread will not invoke {@code - * finalizeReferent()} on the remaining references. - * - *

As an example of how this is used, imagine you have a class {@code MyServer} that creates a - * a {@link java.net.ServerSocket ServerSocket}, and you would like to ensure that the - * {@code ServerSocket} is closed even if the {@code MyServer} object is garbage-collected without - * calling its {@code close} method. You could use a finalizer to accomplish this, but - * that has a number of well-known problems. Here is how you might use this class instead: - * - *

- * public class MyServer implements Closeable {
- *   private static final FinalizableReferenceQueue frq = new FinalizableReferenceQueue();
- *   // You might also share this between several objects.
- *
- *   private static final Set<Reference<?>> references = Sets.newConcurrentHashSet();
- *   // This ensures that the FinalizablePhantomReference itself is not garbage-collected.
- *
- *   private final ServerSocket serverSocket;
- *
- *   private MyServer(...) {
- *     ...
- *     this.serverSocket = new ServerSocket(...);
- *     ...
- *   }
- *
- *   public static MyServer create(...) {
- *     MyServer myServer = new MyServer(...);
- *     final ServerSocket serverSocket = myServer.serverSocket;
- *     Reference<?> reference = new FinalizablePhantomReference<MyServer>(myServer, frq) {
- *       @Override public void finalizeReferent() {
- *         references.remove(this):
- *         if (!serverSocket.isClosed()) {
- *           ...log a message about how nobody called close()...
- *           try {
- *             serverSocket.close();
- *           } catch (IOException e) {
- *             ...
- *           }
- *         }
- *       }
- *     };
- *     references.add(reference);
- *     return myServer;
- *   }
- *
- *   @Override public void close() {
- *     serverSocket.close();
- *   }
- * }
- * 
- * - * @author Bob Lee - * @since 2.0 - */ -public class FinalizableReferenceQueue implements Closeable { - /* - * The Finalizer thread keeps a phantom reference to this object. When the client (for example, a - * map built by MapMaker) no longer has a strong reference to this object, the garbage collector - * will reclaim it and enqueue the phantom reference. The enqueued reference will trigger the - * Finalizer to stop. - * - * If this library is loaded in the system class loader, FinalizableReferenceQueue can load - * Finalizer directly with no problems. - * - * If this library is loaded in an application class loader, it's important that Finalizer not - * have a strong reference back to the class loader. Otherwise, you could have a graph like this: - * - * Finalizer Thread runs instance of -> Finalizer.class loaded by -> Application class loader - * which loaded -> ReferenceMap.class which has a static -> FinalizableReferenceQueue instance - * - * Even if no other references to classes from the application class loader remain, the Finalizer - * thread keeps an indirect strong reference to the queue in ReferenceMap, which keeps the - * Finalizer running, and as a result, the application class loader can never be reclaimed. - * - * This means that dynamically loaded web applications and OSGi bundles can't be unloaded. - * - * If the library is loaded in an application class loader, we try to break the cycle by loading - * Finalizer in its own independent class loader: - * - * System class loader -> Application class loader -> ReferenceMap -> FinalizableReferenceQueue - * -> etc. -> Decoupled class loader -> Finalizer - * - * Now, Finalizer no longer keeps an indirect strong reference to the static - * FinalizableReferenceQueue field in ReferenceMap. The application class loader can be reclaimed - * at which point the Finalizer thread will stop and its decoupled class loader can also be - * reclaimed. - * - * If any of this fails along the way, we fall back to loading Finalizer directly in the - * application class loader. - */ - - private static final Logger logger = Logger.getLogger(FinalizableReferenceQueue.class.getName()); - - private static final String FINALIZER_CLASS_NAME = "com.google.common.base.internal.Finalizer"; - - /** Reference to Finalizer.startFinalizer(). */ - private static final Method startFinalizer; - - static { - Class finalizer = - loadFinalizer(new SystemLoader(), new DecoupledLoader(), new DirectLoader()); - startFinalizer = getStartFinalizer(finalizer); - } - - /** - * The actual reference queue that our background thread will poll. - */ - final ReferenceQueue queue; - - final PhantomReference frqRef; - - /** - * Whether or not the background thread started successfully. - */ - final boolean threadStarted; - - /** - * Constructs a new queue. - */ - public FinalizableReferenceQueue() { - // We could start the finalizer lazily, but I'd rather it blow up early. - queue = new ReferenceQueue(); - frqRef = new PhantomReference(this, queue); - boolean threadStarted = false; - try { - startFinalizer.invoke(null, FinalizableReference.class, queue, frqRef); - threadStarted = true; - } catch (IllegalAccessException impossible) { - throw new AssertionError(impossible); // startFinalizer() is public - } catch (Throwable t) { - logger.log( - Level.INFO, - "Failed to start reference finalizer thread." - + " Reference cleanup will only occur when new references are created.", - t); - } - - this.threadStarted = threadStarted; - } - - @Override - public void close() { - frqRef.enqueue(); - cleanUp(); - } - - /** - * Repeatedly dequeues references from the queue and invokes {@link - * FinalizableReference#finalizeReferent()} on them until the queue is empty. This method is a - * no-op if the background thread was created successfully. - */ - void cleanUp() { - if (threadStarted) { - return; - } - - Reference reference; - while ((reference = queue.poll()) != null) { - /* - * This is for the benefit of phantom references. Weak and soft references will have already - * been cleared by this point. - */ - reference.clear(); - try { - ((FinalizableReference) reference).finalizeReferent(); - } catch (Throwable t) { - logger.log(Level.SEVERE, "Error cleaning up after reference.", t); - } - } - } - - /** - * Iterates through the given loaders until it finds one that can load Finalizer. - * - * @return Finalizer.class - */ - private static Class loadFinalizer(FinalizerLoader... loaders) { - for (FinalizerLoader loader : loaders) { - Class finalizer = loader.loadFinalizer(); - if (finalizer != null) { - return finalizer; - } - } - - throw new AssertionError(); - } - - /** - * Loads Finalizer.class. - */ - interface FinalizerLoader { - - /** - * Returns Finalizer.class or null if this loader shouldn't or can't load it. - * - * @throws SecurityException if we don't have the appropriate privileges - */ - @Nullable - Class loadFinalizer(); - } - - /** - * Tries to load Finalizer from the system class loader. If Finalizer is in the system class path, - * we needn't create a separate loader. - */ - static class SystemLoader implements FinalizerLoader { - // This is used by the ClassLoader-leak test in FinalizableReferenceQueueTest to disable - // finding Finalizer on the system class path even if it is there. - @VisibleForTesting static boolean disabled; - - @Override - public Class loadFinalizer() { - if (disabled) { - return null; - } - ClassLoader systemLoader; - try { - systemLoader = ClassLoader.getSystemClassLoader(); - } catch (SecurityException e) { - logger.info("Not allowed to access system class loader."); - return null; - } - if (systemLoader != null) { - try { - return systemLoader.loadClass(FINALIZER_CLASS_NAME); - } catch (ClassNotFoundException e) { - // Ignore. Finalizer is simply in a child class loader. - return null; - } - } else { - return null; - } - } - } - - /** - * Try to load Finalizer in its own class loader. If Finalizer's thread had a direct reference to - * our class loader (which could be that of a dynamically loaded web application or OSGi bundle), - * it would prevent our class loader from getting garbage collected. - */ - static class DecoupledLoader implements FinalizerLoader { - private static final String LOADING_ERROR = - "Could not load Finalizer in its own class loader. Loading Finalizer in the current class " - + "loader instead. As a result, you will not be able to garbage collect this class " - + "loader. To support reclaiming this class loader, either resolve the underlying " - + "issue, or move Guava to your system class path."; - - @Override - public Class loadFinalizer() { - try { - /* - * We use URLClassLoader because it's the only concrete class loader implementation in the - * JDK. If we used our own ClassLoader subclass, Finalizer would indirectly reference this - * class loader: - * - * Finalizer.class -> CustomClassLoader -> CustomClassLoader.class -> This class loader - * - * System class loader will (and must) be the parent. - */ - ClassLoader finalizerLoader = newLoader(getBaseUrl()); - return finalizerLoader.loadClass(FINALIZER_CLASS_NAME); - } catch (Exception e) { - logger.log(Level.WARNING, LOADING_ERROR, e); - return null; - } - } - - /** - * Gets URL for base of path containing Finalizer.class. - */ - URL getBaseUrl() throws IOException { - // Find URL pointing to Finalizer.class file. - String finalizerPath = FINALIZER_CLASS_NAME.replace('.', '/') + ".class"; - URL finalizerUrl = getClass().getClassLoader().getResource(finalizerPath); - if (finalizerUrl == null) { - throw new FileNotFoundException(finalizerPath); - } - - // Find URL pointing to base of class path. - String urlString = finalizerUrl.toString(); - if (!urlString.endsWith(finalizerPath)) { - throw new IOException("Unsupported path style: " + urlString); - } - urlString = urlString.substring(0, urlString.length() - finalizerPath.length()); - return new URL(finalizerUrl, urlString); - } - - /** Creates a class loader with the given base URL as its classpath. */ - URLClassLoader newLoader(URL base) { - // We use the bootstrap class loader as the parent because Finalizer by design uses - // only standard Java classes. That also means that FinalizableReferenceQueueTest - // doesn't pick up the wrong version of the Finalizer class. - return new URLClassLoader(new URL[] {base}, null); - } - } - - /** - * Loads Finalizer directly using the current class loader. We won't be able to garbage collect - * this class loader, but at least the world doesn't end. - */ - static class DirectLoader implements FinalizerLoader { - @Override - public Class loadFinalizer() { - try { - return Class.forName(FINALIZER_CLASS_NAME); - } catch (ClassNotFoundException e) { - throw new AssertionError(e); - } - } - } - - /** - * Looks up Finalizer.startFinalizer(). - */ - static Method getStartFinalizer(Class finalizer) { - try { - return finalizer.getMethod( - "startFinalizer", Class.class, ReferenceQueue.class, PhantomReference.class); - } catch (NoSuchMethodException e) { - throw new AssertionError(e); - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/FinalizableSoftReference.java b/thirdparty/google-guava/src/main/java/com/google/common/base/FinalizableSoftReference.java deleted file mode 100644 index 74726c142da7..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/FinalizableSoftReference.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import java.lang.ref.ReferenceQueue; -import java.lang.ref.SoftReference; - -/** - * Soft reference with a {@code finalizeReferent()} method which a background thread invokes after - * the garbage collector reclaims the referent. This is a simpler alternative to using a {@link - * ReferenceQueue}. - * - * @author Bob Lee - * @since 2.0 - */ -public abstract class FinalizableSoftReference extends SoftReference - implements FinalizableReference { - /** - * Constructs a new finalizable soft reference. - * - * @param referent to softly reference - * @param queue that should finalize the referent - */ - protected FinalizableSoftReference(T referent, FinalizableReferenceQueue queue) { - super(referent, queue.queue); - queue.cleanUp(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/FinalizableWeakReference.java b/thirdparty/google-guava/src/main/java/com/google/common/base/FinalizableWeakReference.java deleted file mode 100644 index d128df52c83e..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/FinalizableWeakReference.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; - -/** - * Weak reference with a {@code finalizeReferent()} method which a background thread invokes after - * the garbage collector reclaims the referent. This is a simpler alternative to using a {@link - * ReferenceQueue}. - * - * @author Bob Lee - * @since 2.0 - */ -public abstract class FinalizableWeakReference extends WeakReference - implements FinalizableReference { - /** - * Constructs a new finalizable weak reference. - * - * @param referent to weakly reference - * @param queue that should finalize the referent - */ - protected FinalizableWeakReference(T referent, FinalizableReferenceQueue queue) { - super(referent, queue.queue); - queue.cleanUp(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Function.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Function.java deleted file mode 100644 index f39e2eab57ac..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Function.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import com.google.common.annotations.GwtCompatible; - -import javax.annotation.Nullable; - -/** - * Determines an output value based on an input value. - * - *

The {@link Functions} class provides common functions and related utilites. - * - *

See the Guava User Guide article on the use of {@code - * Function}. - * - * @author Kevin Bourrillion - * @since 2.0 - */ -@GwtCompatible -public interface Function { - /** - * Returns the result of applying this function to {@code input}. This method is generally - * expected, but not absolutely required, to have the following properties: - * - *

    - *
  • Its execution does not cause any observable side effects. - *
  • The computation is consistent with equals; that is, {@link Objects#equal - * Objects.equal}{@code (a, b)} implies that {@code Objects.equal(function.apply(a), - * function.apply(b))}. - *
- * - * @throws NullPointerException if {@code input} is null and this function does not accept null - * arguments - */ - @Nullable - T apply(@Nullable F input); - - /** - * Indicates whether another object is equal to this function. - * - *

Most implementations will have no reason to override the behavior of {@link Object#equals}. - * However, an implementation may also choose to return {@code true} whenever {@code object} is a - * {@link Function} that it considers interchangeable with this one. "Interchangeable" - * typically means that {@code Objects.equal(this.apply(f), that.apply(f))} is true for all - * {@code f} of type {@code F}. Note that a {@code false} result from this method does not imply - * that the functions are known not to be interchangeable. - */ - @Override - boolean equals(@Nullable Object object); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/FunctionalEquivalence.java b/thirdparty/google-guava/src/main/java/com/google/common/base/FunctionalEquivalence.java deleted file mode 100644 index c28f6b95d651..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/FunctionalEquivalence.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.base; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; - -import javax.annotation.Nullable; - -/** - * Equivalence applied on functional result. - * - * @author Bob Lee - * @since 10.0 - */ -@Beta -@GwtCompatible -final class FunctionalEquivalence extends Equivalence implements Serializable { - - private static final long serialVersionUID = 0; - - private final Function function; - private final Equivalence resultEquivalence; - - FunctionalEquivalence(Function function, Equivalence resultEquivalence) { - this.function = checkNotNull(function); - this.resultEquivalence = checkNotNull(resultEquivalence); - } - - @Override - protected boolean doEquivalent(F a, F b) { - return resultEquivalence.equivalent(function.apply(a), function.apply(b)); - } - - @Override - protected int doHash(F a) { - return resultEquivalence.hash(function.apply(a)); - } - - @Override - public boolean equals(@Nullable Object obj) { - if (obj == this) { - return true; - } - if (obj instanceof FunctionalEquivalence) { - FunctionalEquivalence that = (FunctionalEquivalence) obj; - return function.equals(that.function) && resultEquivalence.equals(that.resultEquivalence); - } - return false; - } - - @Override - public int hashCode() { - return Objects.hashCode(function, resultEquivalence); - } - - @Override - public String toString() { - return resultEquivalence + ".onResultOf(" + function + ")"; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Functions.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Functions.java deleted file mode 100644 index da5626d6a8d4..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Functions.java +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; -import java.util.Map; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * Static utility methods pertaining to {@code Function} instances. - * - *

All methods return serializable functions as long as they're given serializable parameters. - * - *

See the Guava User Guide article on the use of {@code - * Function}. - * - * @author Mike Bostock - * @author Jared Levy - * @since 2.0 - */ -@GwtCompatible -@CheckReturnValue -public final class Functions { - private Functions() {} - - /** - * Returns a function that calls {@code toString()} on its argument. The function does not accept - * nulls; it will throw a {@link NullPointerException} when applied to {@code null}. - * - *

Warning: The returned function may not be consistent with equals (as - * documented at {@link Function#apply}). For example, this function yields different results for - * the two equal instances {@code ImmutableSet.of(1, 2)} and {@code ImmutableSet.of(2, 1)}. - */ - public static Function toStringFunction() { - return ToStringFunction.INSTANCE; - } - - // enum singleton pattern - private enum ToStringFunction implements Function { - INSTANCE; - - @Override - public String apply(Object o) { - checkNotNull(o); // eager for GWT. - return o.toString(); - } - - @Override - public String toString() { - return "Functions.toStringFunction()"; - } - } - - /** - * Returns the identity function. - */ - // implementation is "fully variant"; E has become a "pass-through" type - @SuppressWarnings("unchecked") - public static Function identity() { - return (Function) IdentityFunction.INSTANCE; - } - - // enum singleton pattern - private enum IdentityFunction implements Function { - INSTANCE; - - @Override - @Nullable - public Object apply(@Nullable Object o) { - return o; - } - - @Override - public String toString() { - return "Functions.identity()"; - } - } - - /** - * Returns a function which performs a map lookup. The returned function throws an {@link - * IllegalArgumentException} if given a key that does not exist in the map. See also {@link - * #forMap(Map, Object)}, which returns a default value in this case. - * - *

Note: if {@code map} is a {@link com.google.common.collect.BiMap BiMap} (or can be one), you - * can use {@link com.google.common.collect.Maps#asConverter Maps.asConverter} instead to get a - * function that also supports reverse conversion. - */ - public static Function forMap(Map map) { - return new FunctionForMapNoDefault(map); - } - - private static class FunctionForMapNoDefault implements Function, Serializable { - final Map map; - - FunctionForMapNoDefault(Map map) { - this.map = checkNotNull(map); - } - - @Override - public V apply(@Nullable K key) { - V result = map.get(key); - checkArgument(result != null || map.containsKey(key), "Key '%s' not present in map", key); - return result; - } - - @Override - public boolean equals(@Nullable Object o) { - if (o instanceof FunctionForMapNoDefault) { - FunctionForMapNoDefault that = (FunctionForMapNoDefault) o; - return map.equals(that.map); - } - return false; - } - - @Override - public int hashCode() { - return map.hashCode(); - } - - @Override - public String toString() { - return "Functions.forMap(" + map + ")"; - } - - private static final long serialVersionUID = 0; - } - - /** - * Returns a function which performs a map lookup with a default value. The function created by - * this method returns {@code defaultValue} for all inputs that do not belong to the map's key - * set. See also {@link #forMap(Map)}, which throws an exception in this case. - * - * @param map source map that determines the function behavior - * @param defaultValue the value to return for inputs that aren't map keys - * @return function that returns {@code map.get(a)} when {@code a} is a key, or {@code - * defaultValue} otherwise - */ - public static Function forMap(Map map, @Nullable V defaultValue) { - return new ForMapWithDefault(map, defaultValue); - } - - private static class ForMapWithDefault implements Function, Serializable { - final Map map; - final V defaultValue; - - ForMapWithDefault(Map map, @Nullable V defaultValue) { - this.map = checkNotNull(map); - this.defaultValue = defaultValue; - } - - @Override - public V apply(@Nullable K key) { - V result = map.get(key); - return (result != null || map.containsKey(key)) ? result : defaultValue; - } - - @Override - public boolean equals(@Nullable Object o) { - if (o instanceof ForMapWithDefault) { - ForMapWithDefault that = (ForMapWithDefault) o; - return map.equals(that.map) && Objects.equal(defaultValue, that.defaultValue); - } - return false; - } - - @Override - public int hashCode() { - return Objects.hashCode(map, defaultValue); - } - - @Override - public String toString() { - // TODO(cpovirk): maybe remove "defaultValue=" to make this look like the method call does - return "Functions.forMap(" + map + ", defaultValue=" + defaultValue + ")"; - } - - private static final long serialVersionUID = 0; - } - - /** - * Returns the composition of two functions. For {@code f: A->B} and {@code g: B->C}, composition - * is defined as the function h such that {@code h(a) == g(f(a))} for each {@code a}. - * - * @param g the second function to apply - * @param f the first function to apply - * @return the composition of {@code f} and {@code g} - * @see function composition - */ - public static Function compose(Function g, Function f) { - return new FunctionComposition(g, f); - } - - private static class FunctionComposition implements Function, Serializable { - private final Function g; - private final Function f; - - public FunctionComposition(Function g, Function f) { - this.g = checkNotNull(g); - this.f = checkNotNull(f); - } - - @Override - public C apply(@Nullable A a) { - return g.apply(f.apply(a)); - } - - @Override - public boolean equals(@Nullable Object obj) { - if (obj instanceof FunctionComposition) { - FunctionComposition that = (FunctionComposition) obj; - return f.equals(that.f) && g.equals(that.g); - } - return false; - } - - @Override - public int hashCode() { - return f.hashCode() ^ g.hashCode(); - } - - @Override - public String toString() { - // TODO(cpovirk): maybe make this look like the method call does ("Functions.compose(...)") - return g + "(" + f + ")"; - } - - private static final long serialVersionUID = 0; - } - - /** - * Creates a function that returns the same boolean output as the given predicate for all inputs. - * - *

The returned function is consistent with equals (as documented at {@link - * Function#apply}) if and only if {@code predicate} is itself consistent with equals. - */ - public static Function forPredicate(Predicate predicate) { - return new PredicateFunction(predicate); - } - - /** @see Functions#forPredicate */ - private static class PredicateFunction implements Function, Serializable { - private final Predicate predicate; - - private PredicateFunction(Predicate predicate) { - this.predicate = checkNotNull(predicate); - } - - @Override - public Boolean apply(@Nullable T t) { - return predicate.apply(t); - } - - @Override - public boolean equals(@Nullable Object obj) { - if (obj instanceof PredicateFunction) { - PredicateFunction that = (PredicateFunction) obj; - return predicate.equals(that.predicate); - } - return false; - } - - @Override - public int hashCode() { - return predicate.hashCode(); - } - - @Override - public String toString() { - return "Functions.forPredicate(" + predicate + ")"; - } - - private static final long serialVersionUID = 0; - } - - /** - * Creates a function that returns {@code value} for any input. - * - * @param value the constant value for the function to return - * @return a function that always returns {@code value} - */ - public static Function constant(@Nullable E value) { - return new ConstantFunction(value); - } - - private static class ConstantFunction implements Function, Serializable { - private final E value; - - public ConstantFunction(@Nullable E value) { - this.value = value; - } - - @Override - public E apply(@Nullable Object from) { - return value; - } - - @Override - public boolean equals(@Nullable Object obj) { - if (obj instanceof ConstantFunction) { - ConstantFunction that = (ConstantFunction) obj; - return Objects.equal(value, that.value); - } - return false; - } - - @Override - public int hashCode() { - return (value == null) ? 0 : value.hashCode(); - } - - @Override - public String toString() { - return "Functions.constant(" + value + ")"; - } - - private static final long serialVersionUID = 0; - } - - /** - * Returns a function that always returns the result of invoking {@link Supplier#get} on {@code - * supplier}, regardless of its input. - * - * @since 10.0 - */ - @Beta - public static Function forSupplier(Supplier supplier) { - return new SupplierFunction(supplier); - } - - /** @see Functions#forSupplier*/ - private static class SupplierFunction implements Function, Serializable { - - private final Supplier supplier; - - private SupplierFunction(Supplier supplier) { - this.supplier = checkNotNull(supplier); - } - - @Override - public T apply(@Nullable Object input) { - return supplier.get(); - } - - @Override - public boolean equals(@Nullable Object obj) { - if (obj instanceof SupplierFunction) { - SupplierFunction that = (SupplierFunction) obj; - return this.supplier.equals(that.supplier); - } - return false; - } - - @Override - public int hashCode() { - return supplier.hashCode(); - } - - @Override - public String toString() { - return "Functions.forSupplier(" + supplier + ")"; - } - - private static final long serialVersionUID = 0; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Joiner.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Joiner.java deleted file mode 100644 index df78e3bb13fb..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Joiner.java +++ /dev/null @@ -1,473 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import java.io.IOException; -import java.util.AbstractList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * An object which joins pieces of text (specified as an array, {@link Iterable}, varargs or even a - * {@link Map}) with a separator. It either appends the results to an {@link Appendable} or returns - * them as a {@link String}. Example:

   {@code
- *
- *   Joiner joiner = Joiner.on("; ").skipNulls();
- *    . . .
- *   return joiner.join("Harry", null, "Ron", "Hermione");}
- * - *

This returns the string {@code "Harry; Ron; Hermione"}. Note that all input elements are - * converted to strings using {@link Object#toString()} before being appended. - * - *

If neither {@link #skipNulls()} nor {@link #useForNull(String)} is specified, the joining - * methods will throw {@link NullPointerException} if any given element is null. - * - *

Warning: joiner instances are always immutable; a configuration method such as {@code - * useForNull} has no effect on the instance it is invoked on! You must store and use the new joiner - * instance returned by the method. This makes joiners thread-safe, and safe to store as {@code - * static final} constants.

   {@code
- *
- *   // Bad! Do not do this!
- *   Joiner joiner = Joiner.on(',');
- *   joiner.skipNulls(); // does nothing!
- *   return joiner.join("wrong", null, "wrong");}
- * - *

See the Guava User Guide article on {@code Joiner}. - * - * @author Kevin Bourrillion - * @since 2.0 - */ -@GwtCompatible -public class Joiner { - /** - * Returns a joiner which automatically places {@code separator} between consecutive elements. - */ - @CheckReturnValue - public static Joiner on(String separator) { - return new Joiner(separator); - } - - /** - * Returns a joiner which automatically places {@code separator} between consecutive elements. - */ - @CheckReturnValue - public static Joiner on(char separator) { - return new Joiner(String.valueOf(separator)); - } - - private final String separator; - - private Joiner(String separator) { - this.separator = checkNotNull(separator); - } - - private Joiner(Joiner prototype) { - this.separator = prototype.separator; - } - - /** - * Appends the string representation of each of {@code parts}, using the previously configured - * separator between each, to {@code appendable}. - */ - public A appendTo(A appendable, Iterable parts) throws IOException { - return appendTo(appendable, parts.iterator()); - } - - /** - * Appends the string representation of each of {@code parts}, using the previously configured - * separator between each, to {@code appendable}. - * - * @since 11.0 - */ - public A appendTo(A appendable, Iterator parts) throws IOException { - checkNotNull(appendable); - if (parts.hasNext()) { - appendable.append(toString(parts.next())); - while (parts.hasNext()) { - appendable.append(separator); - appendable.append(toString(parts.next())); - } - } - return appendable; - } - - /** - * Appends the string representation of each of {@code parts}, using the previously configured - * separator between each, to {@code appendable}. - */ - public final A appendTo(A appendable, Object[] parts) throws IOException { - return appendTo(appendable, Arrays.asList(parts)); - } - - /** - * Appends to {@code appendable} the string representation of each of the remaining arguments. - */ - public final A appendTo( - A appendable, @Nullable Object first, @Nullable Object second, Object... rest) - throws IOException { - return appendTo(appendable, iterable(first, second, rest)); - } - - /** - * Appends the string representation of each of {@code parts}, using the previously configured - * separator between each, to {@code builder}. Identical to {@link #appendTo(Appendable, - * Iterable)}, except that it does not throw {@link IOException}. - */ - public final StringBuilder appendTo(StringBuilder builder, Iterable parts) { - return appendTo(builder, parts.iterator()); - } - - /** - * Appends the string representation of each of {@code parts}, using the previously configured - * separator between each, to {@code builder}. Identical to {@link #appendTo(Appendable, - * Iterable)}, except that it does not throw {@link IOException}. - * - * @since 11.0 - */ - public final StringBuilder appendTo(StringBuilder builder, Iterator parts) { - try { - appendTo((Appendable) builder, parts); - } catch (IOException impossible) { - throw new AssertionError(impossible); - } - return builder; - } - - /** - * Appends the string representation of each of {@code parts}, using the previously configured - * separator between each, to {@code builder}. Identical to {@link #appendTo(Appendable, - * Iterable)}, except that it does not throw {@link IOException}. - */ - public final StringBuilder appendTo(StringBuilder builder, Object[] parts) { - return appendTo(builder, Arrays.asList(parts)); - } - - /** - * Appends to {@code builder} the string representation of each of the remaining arguments. - * Identical to {@link #appendTo(Appendable, Object, Object, Object...)}, except that it does not - * throw {@link IOException}. - */ - public final StringBuilder appendTo( - StringBuilder builder, @Nullable Object first, @Nullable Object second, Object... rest) { - return appendTo(builder, iterable(first, second, rest)); - } - - /** - * Returns a string containing the string representation of each of {@code parts}, using the - * previously configured separator between each. - */ - @CheckReturnValue - public final String join(Iterable parts) { - return join(parts.iterator()); - } - - /** - * Returns a string containing the string representation of each of {@code parts}, using the - * previously configured separator between each. - * - * @since 11.0 - */ - @CheckReturnValue - public final String join(Iterator parts) { - return appendTo(new StringBuilder(), parts).toString(); - } - - /** - * Returns a string containing the string representation of each of {@code parts}, using the - * previously configured separator between each. - */ - @CheckReturnValue - public final String join(Object[] parts) { - return join(Arrays.asList(parts)); - } - - /** - * Returns a string containing the string representation of each argument, using the previously - * configured separator between each. - */ - @CheckReturnValue - public final String join(@Nullable Object first, @Nullable Object second, Object... rest) { - return join(iterable(first, second, rest)); - } - - /** - * Returns a joiner with the same behavior as this one, except automatically substituting {@code - * nullText} for any provided null elements. - */ - @CheckReturnValue - public Joiner useForNull(final String nullText) { - checkNotNull(nullText); - return new Joiner(this) { - @Override - CharSequence toString(@Nullable Object part) { - return (part == null) ? nullText : Joiner.this.toString(part); - } - - @Override - public Joiner useForNull(String nullText) { - throw new UnsupportedOperationException("already specified useForNull"); - } - - @Override - public Joiner skipNulls() { - throw new UnsupportedOperationException("already specified useForNull"); - } - }; - } - - /** - * Returns a joiner with the same behavior as this joiner, except automatically skipping over any - * provided null elements. - */ - @CheckReturnValue - public Joiner skipNulls() { - return new Joiner(this) { - @Override - public A appendTo(A appendable, Iterator parts) throws IOException { - checkNotNull(appendable, "appendable"); - checkNotNull(parts, "parts"); - while (parts.hasNext()) { - Object part = parts.next(); - if (part != null) { - appendable.append(Joiner.this.toString(part)); - break; - } - } - while (parts.hasNext()) { - Object part = parts.next(); - if (part != null) { - appendable.append(separator); - appendable.append(Joiner.this.toString(part)); - } - } - return appendable; - } - - @Override - public Joiner useForNull(String nullText) { - throw new UnsupportedOperationException("already specified skipNulls"); - } - - @Override - public MapJoiner withKeyValueSeparator(String kvs) { - throw new UnsupportedOperationException("can't use .skipNulls() with maps"); - } - }; - } - - /** - * Returns a {@code MapJoiner} using the given key-value separator, and the same configuration as - * this {@code Joiner} otherwise. - */ - @CheckReturnValue - public MapJoiner withKeyValueSeparator(String keyValueSeparator) { - return new MapJoiner(this, keyValueSeparator); - } - - /** - * An object that joins map entries in the same manner as {@code Joiner} joins iterables and - * arrays. Like {@code Joiner}, it is thread-safe and immutable. - * - *

In addition to operating on {@code Map} instances, {@code MapJoiner} can operate on {@code - * Multimap} entries in two distinct modes: - * - *

- * - * @since 2.0 - */ - public static final class MapJoiner { - private final Joiner joiner; - private final String keyValueSeparator; - - private MapJoiner(Joiner joiner, String keyValueSeparator) { - this.joiner = joiner; // only "this" is ever passed, so don't checkNotNull - this.keyValueSeparator = checkNotNull(keyValueSeparator); - } - - /** - * Appends the string representation of each entry of {@code map}, using the previously - * configured separator and key-value separator, to {@code appendable}. - */ - public A appendTo(A appendable, Map map) throws IOException { - return appendTo(appendable, map.entrySet()); - } - - /** - * Appends the string representation of each entry of {@code map}, using the previously - * configured separator and key-value separator, to {@code builder}. Identical to {@link - * #appendTo(Appendable, Map)}, except that it does not throw {@link IOException}. - */ - public StringBuilder appendTo(StringBuilder builder, Map map) { - return appendTo(builder, map.entrySet()); - } - - /** - * Returns a string containing the string representation of each entry of {@code map}, using the - * previously configured separator and key-value separator. - */ - @CheckReturnValue - public String join(Map map) { - return join(map.entrySet()); - } - - /** - * Appends the string representation of each entry in {@code entries}, using the previously - * configured separator and key-value separator, to {@code appendable}. - * - * @since 10.0 - */ - @Beta - public A appendTo(A appendable, Iterable> entries) - throws IOException { - return appendTo(appendable, entries.iterator()); - } - - /** - * Appends the string representation of each entry in {@code entries}, using the previously - * configured separator and key-value separator, to {@code appendable}. - * - * @since 11.0 - */ - @Beta - public A appendTo(A appendable, Iterator> parts) - throws IOException { - checkNotNull(appendable); - if (parts.hasNext()) { - Entry entry = parts.next(); - appendable.append(joiner.toString(entry.getKey())); - appendable.append(keyValueSeparator); - appendable.append(joiner.toString(entry.getValue())); - while (parts.hasNext()) { - appendable.append(joiner.separator); - Entry e = parts.next(); - appendable.append(joiner.toString(e.getKey())); - appendable.append(keyValueSeparator); - appendable.append(joiner.toString(e.getValue())); - } - } - return appendable; - } - - /** - * Appends the string representation of each entry in {@code entries}, using the previously - * configured separator and key-value separator, to {@code builder}. Identical to {@link - * #appendTo(Appendable, Iterable)}, except that it does not throw {@link IOException}. - * - * @since 10.0 - */ - @Beta - public StringBuilder appendTo(StringBuilder builder, Iterable> entries) { - return appendTo(builder, entries.iterator()); - } - - /** - * Appends the string representation of each entry in {@code entries}, using the previously - * configured separator and key-value separator, to {@code builder}. Identical to {@link - * #appendTo(Appendable, Iterable)}, except that it does not throw {@link IOException}. - * - * @since 11.0 - */ - @Beta - public StringBuilder appendTo(StringBuilder builder, Iterator> entries) { - try { - appendTo((Appendable) builder, entries); - } catch (IOException impossible) { - throw new AssertionError(impossible); - } - return builder; - } - - /** - * Returns a string containing the string representation of each entry in {@code entries}, using - * the previously configured separator and key-value separator. - * - * @since 10.0 - */ - @Beta - @CheckReturnValue - public String join(Iterable> entries) { - return join(entries.iterator()); - } - - /** - * Returns a string containing the string representation of each entry in {@code entries}, using - * the previously configured separator and key-value separator. - * - * @since 11.0 - */ - @Beta - @CheckReturnValue - public String join(Iterator> entries) { - return appendTo(new StringBuilder(), entries).toString(); - } - - /** - * Returns a map joiner with the same behavior as this one, except automatically substituting - * {@code nullText} for any provided null keys or values. - */ - @CheckReturnValue - public MapJoiner useForNull(String nullText) { - return new MapJoiner(joiner.useForNull(nullText), keyValueSeparator); - } - } - - CharSequence toString(Object part) { - checkNotNull(part); // checkNotNull for GWT (do not optimize). - return (part instanceof CharSequence) ? (CharSequence) part : part.toString(); - } - - private static Iterable iterable( - final Object first, final Object second, final Object[] rest) { - checkNotNull(rest); - return new AbstractList() { - @Override - public int size() { - return rest.length + 2; - } - - @Override - public Object get(int index) { - switch (index) { - case 0: - return first; - case 1: - return second; - default: - return rest[index - 2]; - } - } - }; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/MoreObjects.java b/thirdparty/google-guava/src/main/java/com/google/common/base/MoreObjects.java deleted file mode 100644 index f87a89222380..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/MoreObjects.java +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright (C) 2014 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Arrays; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * Helper functions that operate on any {@code Object}, and are not already provided in - * {@link java.util.Objects}. - * - *

See the Guava User Guide on writing - * {@code Object} methods with {@code MoreObjects}. - * - * @author Laurence Gonsalves - * @since 18.0 (since 2.0 as {@code Objects}) - */ -@GwtCompatible -public final class MoreObjects { - /** - * Returns the first of two given parameters that is not {@code null}, if either is, or otherwise - * throws a {@link NullPointerException}. - * - *

Note: if {@code first} is represented as an {@link Optional}, this can be - * accomplished with {@link Optional#or(Object) first.or(second)}. That approach also allows for - * lazy evaluation of the fallback instance, using {@link Optional#or(Supplier) - * first.or(supplier)}. - * - * @return {@code first} if it is non-null; otherwise {@code second} if it is non-null - * @throws NullPointerException if both {@code first} and {@code second} are null - * @since 18.0 (since 3.0 as {@code Objects.firstNonNull()}). - */ - @CheckReturnValue - public static T firstNonNull(@Nullable T first, @Nullable T second) { - return first != null ? first : checkNotNull(second); - } - - /** - * Creates an instance of {@link ToStringHelper}. - * - *

This is helpful for implementing {@link Object#toString()}. - * Specification by example:

   {@code
-   *   // Returns "ClassName{}"
-   *   MoreObjects.toStringHelper(this)
-   *       .toString();
-   *
-   *   // Returns "ClassName{x=1}"
-   *   MoreObjects.toStringHelper(this)
-   *       .add("x", 1)
-   *       .toString();
-   *
-   *   // Returns "MyObject{x=1}"
-   *   MoreObjects.toStringHelper("MyObject")
-   *       .add("x", 1)
-   *       .toString();
-   *
-   *   // Returns "ClassName{x=1, y=foo}"
-   *   MoreObjects.toStringHelper(this)
-   *       .add("x", 1)
-   *       .add("y", "foo")
-   *       .toString();
-   *
-   *   // Returns "ClassName{x=1}"
-   *   MoreObjects.toStringHelper(this)
-   *       .omitNullValues()
-   *       .add("x", 1)
-   *       .add("y", null)
-   *       .toString();
-   *   }}
- * - *

Note that in GWT, class names are often obfuscated. - * - * @param self the object to generate the string for (typically {@code this}), used only for its - * class name - * @since 18.0 (since 2.0 as {@code Objects.toStringHelper()}). - */ - @CheckReturnValue - public static ToStringHelper toStringHelper(Object self) { - return new ToStringHelper(self.getClass().getSimpleName()); - } - - /** - * Creates an instance of {@link ToStringHelper} in the same manner as {@link - * #toStringHelper(Object)}, but using the simple name of {@code clazz} instead of using an - * instance's {@link Object#getClass()}. - * - *

Note that in GWT, class names are often obfuscated. - * - * @param clazz the {@link Class} of the instance - * @since 18.0 (since 7.0 as {@code Objects.toStringHelper()}). - */ - @CheckReturnValue - public static ToStringHelper toStringHelper(Class clazz) { - return new ToStringHelper(clazz.getSimpleName()); - } - - /** - * Creates an instance of {@link ToStringHelper} in the same manner as {@link - * #toStringHelper(Object)}, but using {@code className} instead of using an instance's {@link - * Object#getClass()}. - * - * @param className the name of the instance type - * @since 18.0 (since 7.0 as {@code Objects.toStringHelper()}). - */ - @CheckReturnValue - public static ToStringHelper toStringHelper(String className) { - return new ToStringHelper(className); - } - - /** - * Support class for {@link MoreObjects#toStringHelper}. - * - * @author Jason Lee - * @since 18.0 (since 2.0 as {@code Objects.ToStringHelper}). - */ - public static final class ToStringHelper { - private final String className; - private ValueHolder holderHead = new ValueHolder(); - private ValueHolder holderTail = holderHead; - private boolean omitNullValues = false; - - /** - * Use {@link MoreObjects#toStringHelper(Object)} to create an instance. - */ - private ToStringHelper(String className) { - this.className = checkNotNull(className); - } - - /** - * Configures the {@link ToStringHelper} so {@link #toString()} will ignore - * properties with null value. The order of calling this method, relative - * to the {@code add()}/{@code addValue()} methods, is not significant. - * - * @since 18.0 (since 12.0 as {@code Objects.ToStringHelper.omitNullValues()}). - */ - public ToStringHelper omitNullValues() { - omitNullValues = true; - return this; - } - - /** - * Adds a name/value pair to the formatted output in {@code name=value} - * format. If {@code value} is {@code null}, the string {@code "null"} - * is used, unless {@link #omitNullValues()} is called, in which case this - * name/value pair will not be added. - */ - public ToStringHelper add(String name, @Nullable Object value) { - return addHolder(name, value); - } - - /** - * Adds a name/value pair to the formatted output in {@code name=value} - * format. - * - * @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.add()}). - */ - public ToStringHelper add(String name, boolean value) { - return addHolder(name, String.valueOf(value)); - } - - /** - * Adds a name/value pair to the formatted output in {@code name=value} - * format. - * - * @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.add()}). - */ - public ToStringHelper add(String name, char value) { - return addHolder(name, String.valueOf(value)); - } - - /** - * Adds a name/value pair to the formatted output in {@code name=value} - * format. - * - * @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.add()}). - */ - public ToStringHelper add(String name, double value) { - return addHolder(name, String.valueOf(value)); - } - - /** - * Adds a name/value pair to the formatted output in {@code name=value} - * format. - * - * @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.add()}). - */ - public ToStringHelper add(String name, float value) { - return addHolder(name, String.valueOf(value)); - } - - /** - * Adds a name/value pair to the formatted output in {@code name=value} - * format. - * - * @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.add()}). - */ - public ToStringHelper add(String name, int value) { - return addHolder(name, String.valueOf(value)); - } - - /** - * Adds a name/value pair to the formatted output in {@code name=value} - * format. - * - * @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.add()}). - */ - public ToStringHelper add(String name, long value) { - return addHolder(name, String.valueOf(value)); - } - - /** - * Adds an unnamed value to the formatted output. - * - *

It is strongly encouraged to use {@link #add(String, Object)} instead - * and give value a readable name. - */ - public ToStringHelper addValue(@Nullable Object value) { - return addHolder(value); - } - - /** - * Adds an unnamed value to the formatted output. - * - *

It is strongly encouraged to use {@link #add(String, boolean)} instead - * and give value a readable name. - * - * @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.addValue()}). - */ - public ToStringHelper addValue(boolean value) { - return addHolder(String.valueOf(value)); - } - - /** - * Adds an unnamed value to the formatted output. - * - *

It is strongly encouraged to use {@link #add(String, char)} instead - * and give value a readable name. - * - * @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.addValue()}). - */ - public ToStringHelper addValue(char value) { - return addHolder(String.valueOf(value)); - } - - /** - * Adds an unnamed value to the formatted output. - * - *

It is strongly encouraged to use {@link #add(String, double)} instead - * and give value a readable name. - * - * @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.addValue()}). - */ - public ToStringHelper addValue(double value) { - return addHolder(String.valueOf(value)); - } - - /** - * Adds an unnamed value to the formatted output. - * - *

It is strongly encouraged to use {@link #add(String, float)} instead - * and give value a readable name. - * - * @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.addValue()}). - */ - public ToStringHelper addValue(float value) { - return addHolder(String.valueOf(value)); - } - - /** - * Adds an unnamed value to the formatted output. - * - *

It is strongly encouraged to use {@link #add(String, int)} instead - * and give value a readable name. - * - * @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.addValue()}). - */ - public ToStringHelper addValue(int value) { - return addHolder(String.valueOf(value)); - } - - /** - * Adds an unnamed value to the formatted output. - * - *

It is strongly encouraged to use {@link #add(String, long)} instead - * and give value a readable name. - * - * @since 18.0 (since 11.0 as {@code Objects.ToStringHelper.addValue()}). - */ - public ToStringHelper addValue(long value) { - return addHolder(String.valueOf(value)); - } - - /** - * Returns a string in the format specified by - * {@link MoreObjects#toStringHelper(Object)}. - * - *

After calling this method, you can keep adding more properties to later - * call toString() again and get a more complete representation of the - * same object; but properties cannot be removed, so this only allows - * limited reuse of the helper instance. The helper allows duplication of - * properties (multiple name/value pairs with the same name can be added). - */ - @CheckReturnValue - @Override - public String toString() { - // create a copy to keep it consistent in case value changes - boolean omitNullValuesSnapshot = omitNullValues; - String nextSeparator = ""; - StringBuilder builder = new StringBuilder(32).append(className).append('{'); - for (ValueHolder valueHolder = holderHead.next; - valueHolder != null; - valueHolder = valueHolder.next) { - Object value = valueHolder.value; - if (!omitNullValuesSnapshot || value != null) { - builder.append(nextSeparator); - nextSeparator = ", "; - - if (valueHolder.name != null) { - builder.append(valueHolder.name).append('='); - } - if (value != null && value.getClass().isArray()) { - Object[] objectArray = {value}; - String arrayString = Arrays.deepToString(objectArray); - builder.append(arrayString.substring(1, arrayString.length() - 1)); - } else { - builder.append(value); - } - } - } - return builder.append('}').toString(); - } - - private ValueHolder addHolder() { - ValueHolder valueHolder = new ValueHolder(); - holderTail = holderTail.next = valueHolder; - return valueHolder; - } - - private ToStringHelper addHolder(@Nullable Object value) { - ValueHolder valueHolder = addHolder(); - valueHolder.value = value; - return this; - } - - private ToStringHelper addHolder(String name, @Nullable Object value) { - ValueHolder valueHolder = addHolder(); - valueHolder.value = value; - valueHolder.name = checkNotNull(name); - return this; - } - - private static final class ValueHolder { - String name; - Object value; - ValueHolder next; - } - } - - private MoreObjects() {} -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Objects.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Objects.java deleted file mode 100644 index 62817dacdffa..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Objects.java +++ /dev/null @@ -1,437 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Arrays; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * Helper functions that can operate on any {@code Object}. - * - *

See the Guava User Guide on writing - * {@code Object} methods with {@code Objects}. - * - * @author Laurence Gonsalves - * @since 2.0 - */ -@GwtCompatible -public final class Objects { - private Objects() {} - - /** - * Determines whether two possibly-null objects are equal. Returns: - * - *

    - *
  • {@code true} if {@code a} and {@code b} are both null. - *
  • {@code true} if {@code a} and {@code b} are both non-null and they are - * equal according to {@link Object#equals(Object)}. - *
  • {@code false} in all other situations. - *
- * - *

This assumes that any non-null objects passed to this function conform - * to the {@code equals()} contract. - * - *

Note for Java 7 and later: This method should be treated as - * deprecated; use {@link java.util.Objects#equals} instead. - */ - @CheckReturnValue - public static boolean equal(@Nullable Object a, @Nullable Object b) { - return a == b || (a != null && a.equals(b)); - } - - /** - * Generates a hash code for multiple values. The hash code is generated by - * calling {@link Arrays#hashCode(Object[])}. Note that array arguments to - * this method, with the exception of a single Object array, do not get any - * special handling; their hash codes are based on identity and not contents. - * - *

This is useful for implementing {@link Object#hashCode()}. For example, - * in an object that has three properties, {@code x}, {@code y}, and - * {@code z}, one could write: - *

   {@code
-   *   public int hashCode() {
-   *     return Objects.hashCode(getX(), getY(), getZ());
-   *   }}
- * - *

Warning: When a single object is supplied, the returned hash code - * does not equal the hash code of that object. - * - *

Note for Java 7 and later: This method should be treated as - * deprecated; use {@link java.util.Objects#hash} instead. - */ - @CheckReturnValue - public static int hashCode(@Nullable Object... objects) { - return Arrays.hashCode(objects); - } - - /** - * Creates an instance of {@link ToStringHelper}. - * - *

This is helpful for implementing {@link Object#toString()}. - * Specification by example:

   {@code
-   *   // Returns "ClassName{}"
-   *   Objects.toStringHelper(this)
-   *       .toString();
-   *
-   *   // Returns "ClassName{x=1}"
-   *   Objects.toStringHelper(this)
-   *       .add("x", 1)
-   *       .toString();
-   *
-   *   // Returns "MyObject{x=1}"
-   *   Objects.toStringHelper("MyObject")
-   *       .add("x", 1)
-   *       .toString();
-   *
-   *   // Returns "ClassName{x=1, y=foo}"
-   *   Objects.toStringHelper(this)
-   *       .add("x", 1)
-   *       .add("y", "foo")
-   *       .toString();
-   *
-   *   // Returns "ClassName{x=1}"
-   *   Objects.toStringHelper(this)
-   *       .omitNullValues()
-   *       .add("x", 1)
-   *       .add("y", null)
-   *       .toString();
-   *   }}
- * - *

Note that in GWT, class names are often obfuscated. - * - * @param self the object to generate the string for (typically {@code this}), - * used only for its class name - * @since 2.0 - * @deprecated Use {@link MoreObjects#toStringHelper(Object)} instead. This - * method is scheduled for removal in June 2016. - */ - @CheckReturnValue - @Deprecated - public static ToStringHelper toStringHelper(Object self) { - return new ToStringHelper(self.getClass().getSimpleName()); - } - - /** - * Creates an instance of {@link ToStringHelper} in the same manner as - * {@link Objects#toStringHelper(Object)}, but using the name of {@code clazz} - * instead of using an instance's {@link Object#getClass()}. - * - *

Note that in GWT, class names are often obfuscated. - * - * @param clazz the {@link Class} of the instance - * @since 7.0 (source-compatible since 2.0) - * @deprecated Use {@link MoreObjects#toStringHelper(Class)} instead. This - * method is scheduled for removal in June 2016. - */ - @CheckReturnValue - @Deprecated - public static ToStringHelper toStringHelper(Class clazz) { - return new ToStringHelper(clazz.getSimpleName()); - } - - /** - * Creates an instance of {@link ToStringHelper} in the same manner as - * {@link Objects#toStringHelper(Object)}, but using {@code className} instead - * of using an instance's {@link Object#getClass()}. - * - * @param className the name of the instance type - * @since 7.0 (source-compatible since 2.0) - * @deprecated Use {@link MoreObjects#toStringHelper(String)} instead. This - * method is scheduled for removal in June 2016. - */ - @CheckReturnValue - @Deprecated - public static ToStringHelper toStringHelper(String className) { - return new ToStringHelper(className); - } - - /** - * Returns the first of two given parameters that is not {@code null}, if - * either is, or otherwise throws a {@link NullPointerException}. - * - *

Note: if {@code first} is represented as an {@link Optional}, - * this can be accomplished with - * {@linkplain Optional#or(Object) first.or(second)}. - * That approach also allows for lazy evaluation of the fallback instance, - * using {@linkplain Optional#or(Supplier) first.or(Supplier)}. - * - * @return {@code first} if {@code first} is not {@code null}, or - * {@code second} if {@code first} is {@code null} and {@code second} is - * not {@code null} - * @throws NullPointerException if both {@code first} and {@code second} were - * {@code null} - * @since 3.0 - * @deprecated Use {@link MoreObjects#firstNonNull} instead. This method is - * scheduled for removal in June 2016. - */ - @CheckReturnValue - @Deprecated - public static T firstNonNull(@Nullable T first, @Nullable T second) { - return MoreObjects.firstNonNull(first, second); - } - - /** - * Support class for {@link Objects#toStringHelper}. - * - * @author Jason Lee - * @since 2.0 - * @deprecated Use {@link MoreObjects.ToStringHelper} instead. This class is - * scheduled for removal in June 2016. - */ - @Deprecated - public static final class ToStringHelper { - private final String className; - private ValueHolder holderHead = new ValueHolder(); - private ValueHolder holderTail = holderHead; - private boolean omitNullValues = false; - - /** - * Use {@link Objects#toStringHelper(Object)} to create an instance. - */ - private ToStringHelper(String className) { - this.className = checkNotNull(className); - } - - /** - * Configures the {@link ToStringHelper} so {@link #toString()} will ignore - * properties with null value. The order of calling this method, relative - * to the {@code add()}/{@code addValue()} methods, is not significant. - * - * @since 12.0 - */ - public ToStringHelper omitNullValues() { - omitNullValues = true; - return this; - } - - /** - * Adds a name/value pair to the formatted output in {@code name=value} - * format. If {@code value} is {@code null}, the string {@code "null"} - * is used, unless {@link #omitNullValues()} is called, in which case this - * name/value pair will not be added. - */ - public ToStringHelper add(String name, @Nullable Object value) { - return addHolder(name, value); - } - - /** - * Adds a name/value pair to the formatted output in {@code name=value} - * format. - * - * @since 11.0 (source-compatible since 2.0) - */ - public ToStringHelper add(String name, boolean value) { - return addHolder(name, String.valueOf(value)); - } - - /** - * Adds a name/value pair to the formatted output in {@code name=value} - * format. - * - * @since 11.0 (source-compatible since 2.0) - */ - public ToStringHelper add(String name, char value) { - return addHolder(name, String.valueOf(value)); - } - - /** - * Adds a name/value pair to the formatted output in {@code name=value} - * format. - * - * @since 11.0 (source-compatible since 2.0) - */ - public ToStringHelper add(String name, double value) { - return addHolder(name, String.valueOf(value)); - } - - /** - * Adds a name/value pair to the formatted output in {@code name=value} - * format. - * - * @since 11.0 (source-compatible since 2.0) - */ - public ToStringHelper add(String name, float value) { - return addHolder(name, String.valueOf(value)); - } - - /** - * Adds a name/value pair to the formatted output in {@code name=value} - * format. - * - * @since 11.0 (source-compatible since 2.0) - */ - public ToStringHelper add(String name, int value) { - return addHolder(name, String.valueOf(value)); - } - - /** - * Adds a name/value pair to the formatted output in {@code name=value} - * format. - * - * @since 11.0 (source-compatible since 2.0) - */ - public ToStringHelper add(String name, long value) { - return addHolder(name, String.valueOf(value)); - } - - /** - * Adds an unnamed value to the formatted output. - * - *

It is strongly encouraged to use {@link #add(String, Object)} instead - * and give value a readable name. - */ - public ToStringHelper addValue(@Nullable Object value) { - return addHolder(value); - } - - /** - * Adds an unnamed value to the formatted output. - * - *

It is strongly encouraged to use {@link #add(String, boolean)} instead - * and give value a readable name. - * - * @since 11.0 (source-compatible since 2.0) - */ - public ToStringHelper addValue(boolean value) { - return addHolder(String.valueOf(value)); - } - - /** - * Adds an unnamed value to the formatted output. - * - *

It is strongly encouraged to use {@link #add(String, char)} instead - * and give value a readable name. - * - * @since 11.0 (source-compatible since 2.0) - */ - public ToStringHelper addValue(char value) { - return addHolder(String.valueOf(value)); - } - - /** - * Adds an unnamed value to the formatted output. - * - *

It is strongly encouraged to use {@link #add(String, double)} instead - * and give value a readable name. - * - * @since 11.0 (source-compatible since 2.0) - */ - public ToStringHelper addValue(double value) { - return addHolder(String.valueOf(value)); - } - - /** - * Adds an unnamed value to the formatted output. - * - *

It is strongly encouraged to use {@link #add(String, float)} instead - * and give value a readable name. - * - * @since 11.0 (source-compatible since 2.0) - */ - public ToStringHelper addValue(float value) { - return addHolder(String.valueOf(value)); - } - - /** - * Adds an unnamed value to the formatted output. - * - *

It is strongly encouraged to use {@link #add(String, int)} instead - * and give value a readable name. - * - * @since 11.0 (source-compatible since 2.0) - */ - public ToStringHelper addValue(int value) { - return addHolder(String.valueOf(value)); - } - - /** - * Adds an unnamed value to the formatted output. - * - *

It is strongly encouraged to use {@link #add(String, long)} instead - * and give value a readable name. - * - * @since 11.0 (source-compatible since 2.0) - */ - public ToStringHelper addValue(long value) { - return addHolder(String.valueOf(value)); - } - - /** - * Returns a string in the format specified by {@link - * Objects#toStringHelper(Object)}. - * - *

After calling this method, you can keep adding more properties to later - * call toString() again and get a more complete representation of the - * same object; but properties cannot be removed, so this only allows - * limited reuse of the helper instance. The helper allows duplication of - * properties (multiple name/value pairs with the same name can be added). - */ - @Override - public String toString() { - // create a copy to keep it consistent in case value changes - boolean omitNullValuesSnapshot = omitNullValues; - String nextSeparator = ""; - StringBuilder builder = new StringBuilder(32).append(className).append('{'); - for (ValueHolder valueHolder = holderHead.next; - valueHolder != null; - valueHolder = valueHolder.next) { - if (!omitNullValuesSnapshot || valueHolder.value != null) { - builder.append(nextSeparator); - nextSeparator = ", "; - - if (valueHolder.name != null) { - builder.append(valueHolder.name).append('='); - } - builder.append(valueHolder.value); - } - } - return builder.append('}').toString(); - } - - private ValueHolder addHolder() { - ValueHolder valueHolder = new ValueHolder(); - holderTail = holderTail.next = valueHolder; - return valueHolder; - } - - private ToStringHelper addHolder(@Nullable Object value) { - ValueHolder valueHolder = addHolder(); - valueHolder.value = value; - return this; - } - - private ToStringHelper addHolder(String name, @Nullable Object value) { - ValueHolder valueHolder = addHolder(); - valueHolder.value = value; - valueHolder.name = checkNotNull(name); - return this; - } - - private static final class ValueHolder { - String name; - Object value; - ValueHolder next; - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Optional.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Optional.java deleted file mode 100644 index 6c4724b75d03..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Optional.java +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; -import java.util.Iterator; -import java.util.Set; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * An immutable object that may contain a non-null reference to another object. Each - * instance of this type either contains a non-null reference, or contains nothing (in - * which case we say that the reference is "absent"); it is never said to "contain {@code - * null}". - * - *

A non-null {@code Optional} reference can be used as a replacement for a nullable - * {@code T} reference. It allows you to represent "a {@code T} that must be present" and - * a "a {@code T} that might be absent" as two distinct types in your program, which can - * aid clarity. - * - *

Some uses of this class include - * - *

    - *
  • As a method return type, as an alternative to returning {@code null} to indicate - * that no value was available - *
  • To distinguish between "unknown" (for example, not present in a map) and "known to - * have no value" (present in the map, with value {@code Optional.absent()}) - *
  • To wrap nullable references for storage in a collection that does not support - * {@code null} (though there are - * - * several other approaches to this that should be considered first) - *
- * - *

A common alternative to using this class is to find or create a suitable - * null object for the - * type in question. - * - *

This class is not intended as a direct analogue of any existing "option" or "maybe" - * construct from other programming environments, though it may bear some similarities. - * - *

Comparison to {@code java.util.Optional} (JDK 8 and higher): A new {@code Optional} - * class was added for Java 8. The two classes are extremely similar, but incompatible (they cannot - * share a common supertype). All known differences are listed either here or with the - * relevant methods below. - * - *

    - *
  • This class is serializable; {@code java.util.Optional} is not. - *
  • {@code java.util.Optional} has the additional methods {@code ifPresent}, {@code filter}, - * {@code flatMap}, and {@code orElseThrow}. - *
  • {@code java.util} offers the primitive-specialized versions {@code OptionalInt}, {@code - * OptionalLong} and {@code OptionalDouble}, the use of which is recommended; Guava does not - * have these. - *
- * - *

There are no plans to deprecate this class in the foreseeable future. However, we do - * gently recommend that you prefer the new, standard Java class whenever possible. - * - *

See the Guava User Guide article on - * using {@code Optional}. - * - * @param the type of instance that can be contained. {@code Optional} is naturally - * covariant on this type, so it is safe to cast an {@code Optional} to {@code - * Optional} for any supertype {@code S} of {@code T}. - * @author Kurt Alfred Kluever - * @author Kevin Bourrillion - * @since 10.0 - */ -@CheckReturnValue -@GwtCompatible(serializable = true) -public abstract class Optional implements Serializable { - /** - * Returns an {@code Optional} instance with no contained reference. - * - *

Comparison to {@code java.util.Optional}: this method is equivalent to Java 8's - * {@code Optional.empty}. - */ - public static Optional absent() { - return Absent.withType(); - } - - /** - * Returns an {@code Optional} instance containing the given non-null reference. To have {@code - * null} treated as {@link #absent}, use {@link #fromNullable} instead. - * - *

Comparison to {@code java.util.Optional}: no differences. - * - * @throws NullPointerException if {@code reference} is null - */ - public static Optional of(T reference) { - return new Present(checkNotNull(reference)); - } - - /** - * If {@code nullableReference} is non-null, returns an {@code Optional} instance containing that - * reference; otherwise returns {@link Optional#absent}. - * - *

Comparison to {@code java.util.Optional}: this method is equivalent to Java 8's - * {@code Optional.ofNullable}. - */ - public static Optional fromNullable(@Nullable T nullableReference) { - return (nullableReference == null) - ? Optional.absent() - : new Present(nullableReference); - } - - Optional() {} - - /** - * Returns {@code true} if this holder contains a (non-null) instance. - * - *

Comparison to {@code java.util.Optional}: no differences. - */ - public abstract boolean isPresent(); - - /** - * Returns the contained instance, which must be present. If the instance might be - * absent, use {@link #or(Object)} or {@link #orNull} instead. - * - *

Comparison to {@code java.util.Optional}: when the value is absent, this method - * throws {@link IllegalStateException}, whereas the Java 8 counterpart throws {@link - * NoSuchElementException}. - * - * @throws IllegalStateException if the instance is absent ({@link #isPresent} returns - * {@code false}); depending on this specific exception type (over the more general - * {@link RuntimeException}) is discouraged - */ - public abstract T get(); - - /** - * Returns the contained instance if it is present; {@code defaultValue} otherwise. If - * no default value should be required because the instance is known to be present, use - * {@link #get()} instead. For a default value of {@code null}, use {@link #orNull}. - * - *

Note about generics: The signature {@code public T or(T defaultValue)} is overly - * restrictive. However, the ideal signature, {@code public S or(S)}, is not legal - * Java. As a result, some sensible operations involving subtypes are compile errors: - *

   {@code
-   *
-   *   Optional optionalInt = getSomeOptionalInt();
-   *   Number value = optionalInt.or(0.5); // error
-   *
-   *   FluentIterable numbers = getSomeNumbers();
-   *   Optional first = numbers.first();
-   *   Number value = first.or(0.5); // error}
- * - *

As a workaround, it is always safe to cast an {@code Optional} to {@code - * Optional}. Casting either of the above example {@code Optional} instances to {@code - * Optional} (where {@code Number} is the desired output type) solves the problem: - *

   {@code
-   *
-   *   Optional optionalInt = (Optional) getSomeOptionalInt();
-   *   Number value = optionalInt.or(0.5); // fine
-   *
-   *   FluentIterable numbers = getSomeNumbers();
-   *   Optional first = (Optional) numbers.first();
-   *   Number value = first.or(0.5); // fine}
- * - *

Comparison to {@code java.util.Optional}: this method is similar to Java 8's - * {@code Optional.orElse}, but will not accept {@code null} as a {@code defaultValue} ({@link - * #orNull} must be used instead). As a result, the value returned by this method is guaranteed - * non-null, which is not the case for the {@code java.util} equivalent. - */ - public abstract T or(T defaultValue); - - /** - * Returns this {@code Optional} if it has a value present; {@code secondChoice} - * otherwise. - * - *

Comparison to {@code java.util.Optional}: this method has no equivalent in Java 8's - * {@code Optional} class; write {@code thisOptional.isPresent() ? thisOptional : secondChoice} - * instead. - */ - public abstract Optional or(Optional secondChoice); - - /** - * Returns the contained instance if it is present; {@code supplier.get()} otherwise. - * - *

Comparison to {@code java.util.Optional}: this method is similar to Java 8's - * {@code Optional.orElseGet}, except when {@code supplier} returns {@code null}. In this case - * this method throws an exception, whereas the Java 8 method returns the {@code null} to the - * caller. - * - * @throws NullPointerException if this optional's value is absent and the supplier returns - * {@code null} - */ - @Beta - public abstract T or(Supplier supplier); - - /** - * Returns the contained instance if it is present; {@code null} otherwise. If the - * instance is known to be present, use {@link #get()} instead. - * - *

Comparison to {@code java.util.Optional}: this method is equivalent to Java 8's - * {@code Optional.orElse(null)}. - */ - @Nullable - public abstract T orNull(); - - /** - * Returns an immutable singleton {@link Set} whose only element is the contained instance - * if it is present; an empty immutable {@link Set} otherwise. - * - *

Comparison to {@code java.util.Optional}: this method has no equivalent in Java 8's - * {@code Optional} class. However, this common usage:

   {@code
-   *
-   *   for (Foo foo : possibleFoo.asSet()) {
-   *     doSomethingWith(foo);
-   *   }}
- * - * ... can be replaced with:
   {@code
-   *
-   *   possibleFoo.ifPresent(foo -> doSomethingWith(foo));}
- * - * @since 11.0 - */ - public abstract Set asSet(); - - /** - * If the instance is present, it is transformed with the given {@link Function}; otherwise, - * {@link Optional#absent} is returned. - * - *

Comparison to {@code java.util.Optional}: this method is similar to Java 8's - * {@code Optional.map}, except when {@code function} returns {@code null}. In this case this - * method throws an exception, whereas the Java 8 method returns {@code Optional.absent()}. - * - * @throws NullPointerException if the function returns {@code null} - * @since 12.0 - */ - public abstract Optional transform(Function function); - - /** - * Returns {@code true} if {@code object} is an {@code Optional} instance, and either - * the contained references are {@linkplain Object#equals equal} to each other or both - * are absent. Note that {@code Optional} instances of differing parameterized types can - * be equal. - * - *

Comparison to {@code java.util.Optional}: no differences. - */ - @Override - public abstract boolean equals(@Nullable Object object); - - /** - * Returns a hash code for this instance. - * - *

Comparison to {@code java.util.Optional}: this class leaves the specific choice of - * hash code unspecified, unlike the Java 8 equivalent. - */ - @Override - public abstract int hashCode(); - - /** - * Returns a string representation for this instance. - * - *

Comparison to {@code java.util.Optional}: this class leaves the specific string - * representation unspecified, unlike the Java 8 equivalent. - */ - @Override - public abstract String toString(); - - /** - * Returns the value of each present instance from the supplied {@code optionals}, in order, - * skipping over occurrences of {@link Optional#absent}. Iterators are unmodifiable and are - * evaluated lazily. - * - *

Comparison to {@code java.util.Optional}: this method has no equivalent in Java 8's - * {@code Optional} class; use - * {@code optionals.stream().filter(Optional::isPresent).map(Optional::get)} instead. - * - * @since 11.0 (generics widened in 13.0) - */ - @Beta - public static Iterable presentInstances( - final Iterable> optionals) { - checkNotNull(optionals); - return new Iterable() { - @Override - public Iterator iterator() { - return new AbstractIterator() { - private final Iterator> iterator = - checkNotNull(optionals.iterator()); - - @Override - protected T computeNext() { - while (iterator.hasNext()) { - Optional optional = iterator.next(); - if (optional.isPresent()) { - return optional.get(); - } - } - return endOfData(); - } - }; - } - }; - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/PairwiseEquivalence.java b/thirdparty/google-guava/src/main/java/com/google/common/base/PairwiseEquivalence.java deleted file mode 100644 index d409d2451b72..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/PairwiseEquivalence.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; -import java.util.Iterator; - -import javax.annotation.Nullable; - -@GwtCompatible(serializable = true) -final class PairwiseEquivalence extends Equivalence> implements Serializable { - - final Equivalence elementEquivalence; - - PairwiseEquivalence(Equivalence elementEquivalence) { - this.elementEquivalence = Preconditions.checkNotNull(elementEquivalence); - } - - @Override - protected boolean doEquivalent(Iterable iterableA, Iterable iterableB) { - Iterator iteratorA = iterableA.iterator(); - Iterator iteratorB = iterableB.iterator(); - - while (iteratorA.hasNext() && iteratorB.hasNext()) { - if (!elementEquivalence.equivalent(iteratorA.next(), iteratorB.next())) { - return false; - } - } - - return !iteratorA.hasNext() && !iteratorB.hasNext(); - } - - @Override - protected int doHash(Iterable iterable) { - int hash = 78721; - for (T element : iterable) { - hash = hash * 24943 + elementEquivalence.hash(element); - } - return hash; - } - - @Override - public boolean equals(@Nullable Object object) { - if (object instanceof PairwiseEquivalence) { - PairwiseEquivalence that = (PairwiseEquivalence) object; - return this.elementEquivalence.equals(that.elementEquivalence); - } - - return false; - } - - @Override - public int hashCode() { - return elementEquivalence.hashCode() ^ 0x46a3eb07; - } - - @Override - public String toString() { - return elementEquivalence + ".pairwise()"; - } - - private static final long serialVersionUID = 1; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Platform.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Platform.java deleted file mode 100644 index 8debd9199b04..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Platform.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import com.google.common.annotations.GwtCompatible; - -import java.lang.ref.WeakReference; - -/** - * Methods factored out so that they can be emulated differently in GWT. - * - * @author Jesse Wilson - */ -@GwtCompatible(emulated = true) -final class Platform { - private Platform() {} - - /** Calls {@link System#nanoTime()}. */ - static long systemNanoTime() { - return System.nanoTime(); - } - - static CharMatcher precomputeCharMatcher(CharMatcher matcher) { - return matcher.precomputedInternal(); - } - - static > Optional getEnumIfPresent(Class enumClass, String value) { - WeakReference> ref = Enums.getEnumConstants(enumClass).get(value); - return ref == null - ? Optional.absent() - : Optional.of(enumClass.cast(ref.get())); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Preconditions.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Preconditions.java deleted file mode 100644 index a27205fc43c6..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Preconditions.java +++ /dev/null @@ -1,440 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.base; - -import com.google.common.annotations.GwtCompatible; - -import javax.annotation.Nullable; - -/** - * Static convenience methods that help a method or constructor check whether it was invoked - * correctly (whether its preconditions have been met). These methods generally accept a - * {@code boolean} expression which is expected to be {@code true} (or in the case of {@code - * checkNotNull}, an object reference which is expected to be non-null). When {@code false} (or - * {@code null}) is passed instead, the {@code Preconditions} method throws an unchecked exception, - * which helps the calling method communicate to its caller that that caller has made - * a mistake. Example:

   {@code
- *
- *   /**
- *    * Returns the positive square root of the given value.
- *    *
- *    * @throws IllegalArgumentException if the value is negative
- *    *}{@code /
- *   public static double sqrt(double value) {
- *     Preconditions.checkArgument(value >= 0.0, "negative value: %s", value);
- *     // calculate the square root
- *   }
- *
- *   void exampleBadCaller() {
- *     double d = sqrt(-1.0);
- *   }}
- * - * In this example, {@code checkArgument} throws an {@code IllegalArgumentException} to indicate - * that {@code exampleBadCaller} made an error in its call to {@code sqrt}. - * - *

Warning about performance

- * - *

The goal of this class is to improve readability of code, but in some circumstances this may - * come at a significant performance cost. Remember that parameter values for message construction - * must all be computed eagerly, and autoboxing and varargs array creation may happen as well, even - * when the precondition check then succeeds (as it should almost always do in production). In some - * circumstances these wasted CPU cycles and allocations can add up to a real problem. - * Performance-sensitive precondition checks can always be converted to the customary form: - *

   {@code
- *
- *   if (value < 0.0) {
- *     throw new IllegalArgumentException("negative value: " + value);
- *   }}
- * - *

Other types of preconditions

- * - *

Not every type of precondition failure is supported by these methods. Continue to throw - * standard JDK exceptions such as {@link java.util.NoSuchElementException} or {@link - * UnsupportedOperationException} in the situations they are intended for. - * - *

Non-preconditions

- * - *

It is of course possible to use the methods of this class to check for invalid conditions - * which are not the caller's fault. Doing so is not recommended because it is - * misleading to future readers of the code and of stack traces. See - * Conditional - * failures explained in the Guava User Guide for more advice. - * - *

{@code java.util.Objects.requireNonNull()}

- * - *

Projects which use {@code com.google.common} should generally avoid the use of {@link - * java.util.Objects#requireNonNull(Object)}. Instead, use whichever of {@link - * #checkNotNull(Object)} or {@link Verify#verifyNotNull(Object)} is appropriate to the situation. - * (The same goes for the message-accepting overloads.) - * - *

Only {@code %s} is supported

- * - *

In {@code Preconditions} error message template strings, only the {@code "%s"} specifier is - * supported, not the full range of {@link java.util.Formatter} specifiers. - * - *

More information

- * - *

See the Guava User Guide on - * using {@code - * Preconditions}. - * - * @author Kevin Bourrillion - * @since 2.0 - */ -@GwtCompatible -public final class Preconditions { - private Preconditions() {} - - /** - * Ensures the truth of an expression involving one or more parameters to the calling method. - * - * @param expression a boolean expression - * @throws IllegalArgumentException if {@code expression} is false - */ - public static void checkArgument(boolean expression) { - if (!expression) { - throw new IllegalArgumentException(); - } - } - - /** - * Ensures the truth of an expression involving one or more parameters to the calling method. - * - * @param expression a boolean expression - * @param errorMessage the exception message to use if the check fails; will be converted to a - * string using {@link String#valueOf(Object)} - * @throws IllegalArgumentException if {@code expression} is false - */ - public static void checkArgument(boolean expression, @Nullable Object errorMessage) { - if (!expression) { - throw new IllegalArgumentException(String.valueOf(errorMessage)); - } - } - - /** - * Ensures the truth of an expression involving one or more parameters to the calling method. - * - * @param expression a boolean expression - * @param errorMessageTemplate a template for the exception message should the check fail. The - * message is formed by replacing each {@code %s} placeholder in the template with an - * argument. These are matched by position - the first {@code %s} gets {@code - * errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message - * in square braces. Unmatched placeholders will be left as-is. - * @param errorMessageArgs the arguments to be substituted into the message template. Arguments - * are converted to strings using {@link String#valueOf(Object)}. - * @throws IllegalArgumentException if {@code expression} is false - * @throws NullPointerException if the check fails and either {@code errorMessageTemplate} or - * {@code errorMessageArgs} is null (don't let this happen) - */ - public static void checkArgument( - boolean expression, - @Nullable String errorMessageTemplate, - @Nullable Object... errorMessageArgs) { - if (!expression) { - throw new IllegalArgumentException(format(errorMessageTemplate, errorMessageArgs)); - } - } - - /** - * Ensures the truth of an expression involving the state of the calling instance, but not - * involving any parameters to the calling method. - * - * @param expression a boolean expression - * @throws IllegalStateException if {@code expression} is false - */ - public static void checkState(boolean expression) { - if (!expression) { - throw new IllegalStateException(); - } - } - - /** - * Ensures the truth of an expression involving the state of the calling instance, but not - * involving any parameters to the calling method. - * - * @param expression a boolean expression - * @param errorMessage the exception message to use if the check fails; will be converted to a - * string using {@link String#valueOf(Object)} - * @throws IllegalStateException if {@code expression} is false - */ - public static void checkState(boolean expression, @Nullable Object errorMessage) { - if (!expression) { - throw new IllegalStateException(String.valueOf(errorMessage)); - } - } - - /** - * Ensures the truth of an expression involving the state of the calling instance, but not - * involving any parameters to the calling method. - * - * @param expression a boolean expression - * @param errorMessageTemplate a template for the exception message should the check fail. The - * message is formed by replacing each {@code %s} placeholder in the template with an - * argument. These are matched by position - the first {@code %s} gets {@code - * errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message - * in square braces. Unmatched placeholders will be left as-is. - * @param errorMessageArgs the arguments to be substituted into the message template. Arguments - * are converted to strings using {@link String#valueOf(Object)}. - * @throws IllegalStateException if {@code expression} is false - * @throws NullPointerException if the check fails and either {@code errorMessageTemplate} or - * {@code errorMessageArgs} is null (don't let this happen) - */ - public static void checkState( - boolean expression, - @Nullable String errorMessageTemplate, - @Nullable Object... errorMessageArgs) { - if (!expression) { - throw new IllegalStateException(format(errorMessageTemplate, errorMessageArgs)); - } - } - - /** - * Ensures that an object reference passed as a parameter to the calling method is not null. - * - * @param reference an object reference - * @return the non-null reference that was validated - * @throws NullPointerException if {@code reference} is null - */ - public static T checkNotNull(T reference) { - if (reference == null) { - throw new NullPointerException(); - } - return reference; - } - - /** - * Ensures that an object reference passed as a parameter to the calling method is not null. - * - * @param reference an object reference - * @param errorMessage the exception message to use if the check fails; will be converted to a - * string using {@link String#valueOf(Object)} - * @return the non-null reference that was validated - * @throws NullPointerException if {@code reference} is null - */ - public static T checkNotNull(T reference, @Nullable Object errorMessage) { - if (reference == null) { - throw new NullPointerException(String.valueOf(errorMessage)); - } - return reference; - } - - /** - * Ensures that an object reference passed as a parameter to the calling method is not null. - * - * @param reference an object reference - * @param errorMessageTemplate a template for the exception message should the check fail. The - * message is formed by replacing each {@code %s} placeholder in the template with an - * argument. These are matched by position - the first {@code %s} gets {@code - * errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message - * in square braces. Unmatched placeholders will be left as-is. - * @param errorMessageArgs the arguments to be substituted into the message template. Arguments - * are converted to strings using {@link String#valueOf(Object)}. - * @return the non-null reference that was validated - * @throws NullPointerException if {@code reference} is null - */ - public static T checkNotNull( - T reference, @Nullable String errorMessageTemplate, @Nullable Object... errorMessageArgs) { - if (reference == null) { - // If either of these parameters is null, the right thing happens anyway - throw new NullPointerException(format(errorMessageTemplate, errorMessageArgs)); - } - return reference; - } - - /* - * All recent hotspots (as of 2009) *really* like to have the natural code - * - * if (guardExpression) { - * throw new BadException(messageExpression); - * } - * - * refactored so that messageExpression is moved to a separate String-returning method. - * - * if (guardExpression) { - * throw new BadException(badMsg(...)); - * } - * - * The alternative natural refactorings into void or Exception-returning methods are much slower. - * This is a big deal - we're talking factors of 2-8 in microbenchmarks, not just 10-20%. (This - * is a hotspot optimizer bug, which should be fixed, but that's a separate, big project). - * - * The coding pattern above is heavily used in java.util, e.g. in ArrayList. There is a - * RangeCheckMicroBenchmark in the JDK that was used to test this. - * - * But the methods in this class want to throw different exceptions, depending on the args, so it - * appears that this pattern is not directly applicable. But we can use the ridiculous, devious - * trick of throwing an exception in the middle of the construction of another exception. Hotspot - * is fine with that. - */ - - /** - * Ensures that {@code index} specifies a valid element in an array, list or string of size - * {@code size}. An element index may range from zero, inclusive, to {@code size}, exclusive. - * - * @param index a user-supplied index identifying an element of an array, list or string - * @param size the size of that array, list or string - * @return the value of {@code index} - * @throws IndexOutOfBoundsException if {@code index} is negative or is not less than {@code size} - * @throws IllegalArgumentException if {@code size} is negative - */ - public static int checkElementIndex(int index, int size) { - return checkElementIndex(index, size, "index"); - } - - /** - * Ensures that {@code index} specifies a valid element in an array, list or string of size - * {@code size}. An element index may range from zero, inclusive, to {@code size}, exclusive. - * - * @param index a user-supplied index identifying an element of an array, list or string - * @param size the size of that array, list or string - * @param desc the text to use to describe this index in an error message - * @return the value of {@code index} - * @throws IndexOutOfBoundsException if {@code index} is negative or is not less than {@code size} - * @throws IllegalArgumentException if {@code size} is negative - */ - public static int checkElementIndex(int index, int size, @Nullable String desc) { - // Carefully optimized for execution by hotspot (explanatory comment above) - if (index < 0 || index >= size) { - throw new IndexOutOfBoundsException(badElementIndex(index, size, desc)); - } - return index; - } - - private static String badElementIndex(int index, int size, String desc) { - if (index < 0) { - return format("%s (%s) must not be negative", desc, index); - } else if (size < 0) { - throw new IllegalArgumentException("negative size: " + size); - } else { // index >= size - return format("%s (%s) must be less than size (%s)", desc, index, size); - } - } - - /** - * Ensures that {@code index} specifies a valid position in an array, list or string of - * size {@code size}. A position index may range from zero to {@code size}, inclusive. - * - * @param index a user-supplied index identifying a position in an array, list or string - * @param size the size of that array, list or string - * @return the value of {@code index} - * @throws IndexOutOfBoundsException if {@code index} is negative or is greater than {@code size} - * @throws IllegalArgumentException if {@code size} is negative - */ - public static int checkPositionIndex(int index, int size) { - return checkPositionIndex(index, size, "index"); - } - - /** - * Ensures that {@code index} specifies a valid position in an array, list or string of - * size {@code size}. A position index may range from zero to {@code size}, inclusive. - * - * @param index a user-supplied index identifying a position in an array, list or string - * @param size the size of that array, list or string - * @param desc the text to use to describe this index in an error message - * @return the value of {@code index} - * @throws IndexOutOfBoundsException if {@code index} is negative or is greater than {@code size} - * @throws IllegalArgumentException if {@code size} is negative - */ - public static int checkPositionIndex(int index, int size, @Nullable String desc) { - // Carefully optimized for execution by hotspot (explanatory comment above) - if (index < 0 || index > size) { - throw new IndexOutOfBoundsException(badPositionIndex(index, size, desc)); - } - return index; - } - - private static String badPositionIndex(int index, int size, String desc) { - if (index < 0) { - return format("%s (%s) must not be negative", desc, index); - } else if (size < 0) { - throw new IllegalArgumentException("negative size: " + size); - } else { // index > size - return format("%s (%s) must not be greater than size (%s)", desc, index, size); - } - } - - /** - * Ensures that {@code start} and {@code end} specify a valid positions in an array, list - * or string of size {@code size}, and are in order. A position index may range from zero to - * {@code size}, inclusive. - * - * @param start a user-supplied index identifying a starting position in an array, list or string - * @param end a user-supplied index identifying a ending position in an array, list or string - * @param size the size of that array, list or string - * @throws IndexOutOfBoundsException if either index is negative or is greater than {@code size}, - * or if {@code end} is less than {@code start} - * @throws IllegalArgumentException if {@code size} is negative - */ - public static void checkPositionIndexes(int start, int end, int size) { - // Carefully optimized for execution by hotspot (explanatory comment above) - if (start < 0 || end < start || end > size) { - throw new IndexOutOfBoundsException(badPositionIndexes(start, end, size)); - } - } - - private static String badPositionIndexes(int start, int end, int size) { - if (start < 0 || start > size) { - return badPositionIndex(start, size, "start index"); - } - if (end < 0 || end > size) { - return badPositionIndex(end, size, "end index"); - } - // end < start - return format("end index (%s) must not be less than start index (%s)", end, start); - } - - /** - * Substitutes each {@code %s} in {@code template} with an argument. These are matched by - * position: the first {@code %s} gets {@code args[0]}, etc. If there are more arguments than - * placeholders, the unmatched arguments will be appended to the end of the formatted message in - * square braces. - * - * @param template a non-null string containing 0 or more {@code %s} placeholders. - * @param args the arguments to be substituted into the message template. Arguments are converted - * to strings using {@link String#valueOf(Object)}. Arguments can be null. - */ - // Note that this is somewhat-improperly used from Verify.java as well. - static String format(String template, @Nullable Object... args) { - template = String.valueOf(template); // null -> "null" - - // start substituting the arguments into the '%s' placeholders - StringBuilder builder = new StringBuilder(template.length() + 16 * args.length); - int templateStart = 0; - int i = 0; - while (i < args.length) { - int placeholderStart = template.indexOf("%s", templateStart); - if (placeholderStart == -1) { - break; - } - builder.append(template.substring(templateStart, placeholderStart)); - builder.append(args[i++]); - templateStart = placeholderStart + 2; - } - builder.append(template.substring(templateStart)); - - // if we run out of placeholders, append the extra args in square braces - if (i < args.length) { - builder.append(" ["); - builder.append(args[i++]); - while (i < args.length) { - builder.append(", "); - builder.append(args[i++]); - } - builder.append(']'); - } - - return builder.toString(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Predicate.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Predicate.java deleted file mode 100644 index 43defb85342d..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Predicate.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import com.google.common.annotations.GwtCompatible; - -import javax.annotation.Nullable; - -/** - * Determines a true or false value for a given input. - * - *

The {@link Predicates} class provides common predicates and related utilities. - * - *

See the Guava User Guide article on the use of {@code - * Predicate}. - * - * @author Kevin Bourrillion - * @since 2.0 - */ -@GwtCompatible -public interface Predicate { - /** - * Returns the result of applying this predicate to {@code input}. This method is generally - * expected, but not absolutely required, to have the following properties: - * - *

    - *
  • Its execution does not cause any observable side effects. - *
  • The computation is consistent with equals; that is, {@link Objects#equal - * Objects.equal}{@code (a, b)} implies that {@code predicate.apply(a) == - * predicate.apply(b))}. - *
- * - * @throws NullPointerException if {@code input} is null and this predicate does not accept null - * arguments - */ - boolean apply(@Nullable T input); - - /** - * Indicates whether another object is equal to this predicate. - * - *

Most implementations will have no reason to override the behavior of {@link Object#equals}. - * However, an implementation may also choose to return {@code true} whenever {@code object} is a - * {@link Predicate} that it considers interchangeable with this one. "Interchangeable" - * typically means that {@code this.apply(t) == that.apply(t)} for all {@code t} of type - * {@code T}). Note that a {@code false} result from this method does not imply that the - * predicates are known not to be interchangeable. - */ - @Override - boolean equals(@Nullable Object object); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Predicates.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Predicates.java deleted file mode 100644 index 67c04cf97c9e..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Predicates.java +++ /dev/null @@ -1,712 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.regex.Pattern; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * Static utility methods pertaining to {@code Predicate} instances. - * - *

All methods returns serializable predicates as long as they're given - * serializable parameters. - * - *

See the Guava User Guide article on the - * use of {@code Predicate}. - * - * @author Kevin Bourrillion - * @since 2.0 - */ -@CheckReturnValue -@GwtCompatible(emulated = true) -public final class Predicates { - private Predicates() {} - - // TODO(kevinb): considering having these implement a VisitablePredicate - // interface which specifies an accept(PredicateVisitor) method. - - /** - * Returns a predicate that always evaluates to {@code true}. - */ - @GwtCompatible(serializable = true) - public static Predicate alwaysTrue() { - return ObjectPredicate.ALWAYS_TRUE.withNarrowedType(); - } - - /** - * Returns a predicate that always evaluates to {@code false}. - */ - @GwtCompatible(serializable = true) - public static Predicate alwaysFalse() { - return ObjectPredicate.ALWAYS_FALSE.withNarrowedType(); - } - - /** - * Returns a predicate that evaluates to {@code true} if the object reference - * being tested is null. - */ - @GwtCompatible(serializable = true) - public static Predicate isNull() { - return ObjectPredicate.IS_NULL.withNarrowedType(); - } - - /** - * Returns a predicate that evaluates to {@code true} if the object reference - * being tested is not null. - */ - @GwtCompatible(serializable = true) - public static Predicate notNull() { - return ObjectPredicate.NOT_NULL.withNarrowedType(); - } - - /** - * Returns a predicate that evaluates to {@code true} if the given predicate - * evaluates to {@code false}. - */ - public static Predicate not(Predicate predicate) { - return new NotPredicate(predicate); - } - - /** - * Returns a predicate that evaluates to {@code true} if each of its - * components evaluates to {@code true}. The components are evaluated in - * order, and evaluation will be "short-circuited" as soon as a false - * predicate is found. It defensively copies the iterable passed in, so future - * changes to it won't alter the behavior of this predicate. If {@code - * components} is empty, the returned predicate will always evaluate to {@code - * true}. - */ - public static Predicate and(Iterable> components) { - return new AndPredicate(defensiveCopy(components)); - } - - /** - * Returns a predicate that evaluates to {@code true} if each of its - * components evaluates to {@code true}. The components are evaluated in - * order, and evaluation will be "short-circuited" as soon as a false - * predicate is found. It defensively copies the array passed in, so future - * changes to it won't alter the behavior of this predicate. If {@code - * components} is empty, the returned predicate will always evaluate to {@code - * true}. - */ - public static Predicate and(Predicate... components) { - return new AndPredicate(defensiveCopy(components)); - } - - /** - * Returns a predicate that evaluates to {@code true} if both of its - * components evaluate to {@code true}. The components are evaluated in - * order, and evaluation will be "short-circuited" as soon as a false - * predicate is found. - */ - public static Predicate and(Predicate first, Predicate second) { - return new AndPredicate(Predicates.asList(checkNotNull(first), checkNotNull(second))); - } - - /** - * Returns a predicate that evaluates to {@code true} if any one of its - * components evaluates to {@code true}. The components are evaluated in - * order, and evaluation will be "short-circuited" as soon as a - * true predicate is found. It defensively copies the iterable passed in, so - * future changes to it won't alter the behavior of this predicate. If {@code - * components} is empty, the returned predicate will always evaluate to {@code - * false}. - */ - public static Predicate or(Iterable> components) { - return new OrPredicate(defensiveCopy(components)); - } - - /** - * Returns a predicate that evaluates to {@code true} if any one of its - * components evaluates to {@code true}. The components are evaluated in - * order, and evaluation will be "short-circuited" as soon as a - * true predicate is found. It defensively copies the array passed in, so - * future changes to it won't alter the behavior of this predicate. If {@code - * components} is empty, the returned predicate will always evaluate to {@code - * false}. - */ - public static Predicate or(Predicate... components) { - return new OrPredicate(defensiveCopy(components)); - } - - /** - * Returns a predicate that evaluates to {@code true} if either of its - * components evaluates to {@code true}. The components are evaluated in - * order, and evaluation will be "short-circuited" as soon as a - * true predicate is found. - */ - public static Predicate or(Predicate first, Predicate second) { - return new OrPredicate(Predicates.asList(checkNotNull(first), checkNotNull(second))); - } - - /** - * Returns a predicate that evaluates to {@code true} if the object being - * tested {@code equals()} the given target or both are null. - */ - public static Predicate equalTo(@Nullable T target) { - return (target == null) ? Predicates.isNull() : new IsEqualToPredicate(target); - } - - /** - * Returns a predicate that evaluates to {@code true} if the object being - * tested is an instance of the given class. If the object being tested - * is {@code null} this predicate evaluates to {@code false}. - * - *

If you want to filter an {@code Iterable} to narrow its type, consider - * using {@link com.google.common.collect.Iterables#filter(Iterable, Class)} - * in preference. - * - *

Warning: contrary to the typical assumptions about predicates (as - * documented at {@link Predicate#apply}), the returned predicate may not be - * consistent with equals. For example, {@code - * instanceOf(ArrayList.class)} will yield different results for the two equal - * instances {@code Lists.newArrayList(1)} and {@code Arrays.asList(1)}. - */ - @GwtIncompatible("Class.isInstance") - public static Predicate instanceOf(Class clazz) { - return new InstanceOfPredicate(clazz); - } - - /** - * Returns a predicate that evaluates to {@code true} if the class being - * tested is assignable from the given class. The returned predicate - * does not allow null inputs. - * - * @since 10.0 - */ - @GwtIncompatible("Class.isAssignableFrom") - @Beta - public static Predicate> assignableFrom(Class clazz) { - return new AssignableFromPredicate(clazz); - } - - /** - * Returns a predicate that evaluates to {@code true} if the object reference - * being tested is a member of the given collection. It does not defensively - * copy the collection passed in, so future changes to it will alter the - * behavior of the predicate. - * - *

This method can technically accept any {@code Collection}, but using - * a typed collection helps prevent bugs. This approach doesn't block any - * potential users since it is always possible to use {@code - * Predicates.in()}. - * - * @param target the collection that may contain the function input - */ - public static Predicate in(Collection target) { - return new InPredicate(target); - } - - /** - * Returns the composition of a function and a predicate. For every {@code x}, - * the generated predicate returns {@code predicate(function(x))}. - * - * @return the composition of the provided function and predicate - */ - public static Predicate compose( - Predicate predicate, Function function) { - return new CompositionPredicate(predicate, function); - } - - /** - * Returns a predicate that evaluates to {@code true} if the - * {@code CharSequence} being tested contains any match for the given - * regular expression pattern. The test used is equivalent to - * {@code Pattern.compile(pattern).matcher(arg).find()} - * - * @throws java.util.regex.PatternSyntaxException if the pattern is invalid - * @since 3.0 - */ - @GwtIncompatible(value = "java.util.regex.Pattern") - public static Predicate containsPattern(String pattern) { - return new ContainsPatternFromStringPredicate(pattern); - } - - /** - * Returns a predicate that evaluates to {@code true} if the - * {@code CharSequence} being tested contains any match for the given - * regular expression pattern. The test used is equivalent to - * {@code pattern.matcher(arg).find()} - * - * @since 3.0 - */ - @GwtIncompatible(value = "java.util.regex.Pattern") - public static Predicate contains(Pattern pattern) { - return new ContainsPatternPredicate(pattern); - } - - // End public API, begin private implementation classes. - - // Package private for GWT serialization. - enum ObjectPredicate implements Predicate { - /** @see Predicates#alwaysTrue() */ - ALWAYS_TRUE { - @Override - public boolean apply(@Nullable Object o) { - return true; - } - - @Override - public String toString() { - return "Predicates.alwaysTrue()"; - } - }, - /** @see Predicates#alwaysFalse() */ - ALWAYS_FALSE { - @Override - public boolean apply(@Nullable Object o) { - return false; - } - - @Override - public String toString() { - return "Predicates.alwaysFalse()"; - } - }, - /** @see Predicates#isNull() */ - IS_NULL { - @Override - public boolean apply(@Nullable Object o) { - return o == null; - } - - @Override - public String toString() { - return "Predicates.isNull()"; - } - }, - /** @see Predicates#notNull() */ - NOT_NULL { - @Override - public boolean apply(@Nullable Object o) { - return o != null; - } - - @Override - public String toString() { - return "Predicates.notNull()"; - } - }; - - @SuppressWarnings("unchecked") // safe contravariant cast - Predicate withNarrowedType() { - return (Predicate) this; - } - } - - /** @see Predicates#not(Predicate) */ - private static class NotPredicate implements Predicate, Serializable { - final Predicate predicate; - - NotPredicate(Predicate predicate) { - this.predicate = checkNotNull(predicate); - } - - @Override - public boolean apply(@Nullable T t) { - return !predicate.apply(t); - } - - @Override - public int hashCode() { - return ~predicate.hashCode(); - } - - @Override - public boolean equals(@Nullable Object obj) { - if (obj instanceof NotPredicate) { - NotPredicate that = (NotPredicate) obj; - return predicate.equals(that.predicate); - } - return false; - } - - @Override - public String toString() { - return "Predicates.not(" + predicate + ")"; - } - - private static final long serialVersionUID = 0; - } - - private static final Joiner COMMA_JOINER = Joiner.on(','); - - /** @see Predicates#and(Iterable) */ - private static class AndPredicate implements Predicate, Serializable { - private final List> components; - - private AndPredicate(List> components) { - this.components = components; - } - - @Override - public boolean apply(@Nullable T t) { - // Avoid using the Iterator to avoid generating garbage (issue 820). - for (int i = 0; i < components.size(); i++) { - if (!components.get(i).apply(t)) { - return false; - } - } - return true; - } - - @Override - public int hashCode() { - // add a random number to avoid collisions with OrPredicate - return components.hashCode() + 0x12472c2c; - } - - @Override - public boolean equals(@Nullable Object obj) { - if (obj instanceof AndPredicate) { - AndPredicate that = (AndPredicate) obj; - return components.equals(that.components); - } - return false; - } - - @Override - public String toString() { - return "Predicates.and(" + COMMA_JOINER.join(components) + ")"; - } - - private static final long serialVersionUID = 0; - } - - /** @see Predicates#or(Iterable) */ - private static class OrPredicate implements Predicate, Serializable { - private final List> components; - - private OrPredicate(List> components) { - this.components = components; - } - - @Override - public boolean apply(@Nullable T t) { - // Avoid using the Iterator to avoid generating garbage (issue 820). - for (int i = 0; i < components.size(); i++) { - if (components.get(i).apply(t)) { - return true; - } - } - return false; - } - - @Override - public int hashCode() { - // add a random number to avoid collisions with AndPredicate - return components.hashCode() + 0x053c91cf; - } - - @Override - public boolean equals(@Nullable Object obj) { - if (obj instanceof OrPredicate) { - OrPredicate that = (OrPredicate) obj; - return components.equals(that.components); - } - return false; - } - - @Override - public String toString() { - return "Predicates.or(" + COMMA_JOINER.join(components) + ")"; - } - - private static final long serialVersionUID = 0; - } - - /** @see Predicates#equalTo(Object) */ - private static class IsEqualToPredicate implements Predicate, Serializable { - private final T target; - - private IsEqualToPredicate(T target) { - this.target = target; - } - - @Override - public boolean apply(T t) { - return target.equals(t); - } - - @Override - public int hashCode() { - return target.hashCode(); - } - - @Override - public boolean equals(@Nullable Object obj) { - if (obj instanceof IsEqualToPredicate) { - IsEqualToPredicate that = (IsEqualToPredicate) obj; - return target.equals(that.target); - } - return false; - } - - @Override - public String toString() { - return "Predicates.equalTo(" + target + ")"; - } - - private static final long serialVersionUID = 0; - } - - /** @see Predicates#instanceOf(Class) */ - @GwtIncompatible("Class.isInstance") - private static class InstanceOfPredicate implements Predicate, Serializable { - private final Class clazz; - - private InstanceOfPredicate(Class clazz) { - this.clazz = checkNotNull(clazz); - } - - @Override - public boolean apply(@Nullable Object o) { - return clazz.isInstance(o); - } - - @Override - public int hashCode() { - return clazz.hashCode(); - } - - @Override - public boolean equals(@Nullable Object obj) { - if (obj instanceof InstanceOfPredicate) { - InstanceOfPredicate that = (InstanceOfPredicate) obj; - return clazz == that.clazz; - } - return false; - } - - @Override - public String toString() { - return "Predicates.instanceOf(" + clazz.getName() + ")"; - } - - private static final long serialVersionUID = 0; - } - - /** @see Predicates#assignableFrom(Class) */ - @GwtIncompatible("Class.isAssignableFrom") - private static class AssignableFromPredicate implements Predicate>, Serializable { - private final Class clazz; - - private AssignableFromPredicate(Class clazz) { - this.clazz = checkNotNull(clazz); - } - - @Override - public boolean apply(Class input) { - return clazz.isAssignableFrom(input); - } - - @Override - public int hashCode() { - return clazz.hashCode(); - } - - @Override - public boolean equals(@Nullable Object obj) { - if (obj instanceof AssignableFromPredicate) { - AssignableFromPredicate that = (AssignableFromPredicate) obj; - return clazz == that.clazz; - } - return false; - } - - @Override - public String toString() { - return "Predicates.assignableFrom(" + clazz.getName() + ")"; - } - - private static final long serialVersionUID = 0; - } - - /** @see Predicates#in(Collection) */ - private static class InPredicate implements Predicate, Serializable { - private final Collection target; - - private InPredicate(Collection target) { - this.target = checkNotNull(target); - } - - @Override - public boolean apply(@Nullable T t) { - try { - return target.contains(t); - } catch (NullPointerException e) { - return false; - } catch (ClassCastException e) { - return false; - } - } - - @Override - public boolean equals(@Nullable Object obj) { - if (obj instanceof InPredicate) { - InPredicate that = (InPredicate) obj; - return target.equals(that.target); - } - return false; - } - - @Override - public int hashCode() { - return target.hashCode(); - } - - @Override - public String toString() { - return "Predicates.in(" + target + ")"; - } - - private static final long serialVersionUID = 0; - } - - /** @see Predicates#compose(Predicate, Function) */ - private static class CompositionPredicate implements Predicate, Serializable { - final Predicate p; - final Function f; - - private CompositionPredicate(Predicate p, Function f) { - this.p = checkNotNull(p); - this.f = checkNotNull(f); - } - - @Override - public boolean apply(@Nullable A a) { - return p.apply(f.apply(a)); - } - - @Override - public boolean equals(@Nullable Object obj) { - if (obj instanceof CompositionPredicate) { - CompositionPredicate that = (CompositionPredicate) obj; - return f.equals(that.f) && p.equals(that.p); - } - return false; - } - - @Override - public int hashCode() { - return f.hashCode() ^ p.hashCode(); - } - - @Override - public String toString() { - // TODO(cpovirk): maybe make this look like the method call does ("Predicates.compose(...)") - return p + "(" + f + ")"; - } - - private static final long serialVersionUID = 0; - } - - /** @see Predicates#contains(Pattern) */ - @GwtIncompatible("Only used by other GWT-incompatible code.") - private static class ContainsPatternPredicate implements Predicate, Serializable { - final Pattern pattern; - - ContainsPatternPredicate(Pattern pattern) { - this.pattern = checkNotNull(pattern); - } - - @Override - public boolean apply(CharSequence t) { - return pattern.matcher(t).find(); - } - - @Override - public int hashCode() { - // Pattern uses Object.hashCode, so we have to reach - // inside to build a hashCode consistent with equals. - - return Objects.hashCode(pattern.pattern(), pattern.flags()); - } - - @Override - public boolean equals(@Nullable Object obj) { - if (obj instanceof ContainsPatternPredicate) { - ContainsPatternPredicate that = (ContainsPatternPredicate) obj; - - // Pattern uses Object (identity) equality, so we have to reach - // inside to compare individual fields. - return Objects.equal(pattern.pattern(), that.pattern.pattern()) - && Objects.equal(pattern.flags(), that.pattern.flags()); - } - return false; - } - - @Override - public String toString() { - String patternString = Objects.toStringHelper(pattern) - .add("pattern", pattern.pattern()) - .add("pattern.flags", pattern.flags()) - .toString(); - return "Predicates.contains(" + patternString + ")"; - } - - private static final long serialVersionUID = 0; - } - - /** @see Predicates#containsPattern(String) */ - @GwtIncompatible("Only used by other GWT-incompatible code.") - private static class ContainsPatternFromStringPredicate extends ContainsPatternPredicate { - - ContainsPatternFromStringPredicate(String string) { - super(Pattern.compile(string)); - } - - @Override - public String toString() { - return "Predicates.containsPattern(" + pattern.pattern() + ")"; - } - - private static final long serialVersionUID = 0; - } - - private static List> asList( - Predicate first, Predicate second) { - // TODO(kevinb): understand why we still get a warning despite @SafeVarargs! - return Arrays.>asList(first, second); - } - - private static List defensiveCopy(T... array) { - return defensiveCopy(Arrays.asList(array)); - } - - static List defensiveCopy(Iterable iterable) { - ArrayList list = new ArrayList(); - for (T element : iterable) { - list.add(checkNotNull(element)); - } - return list; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Present.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Present.java deleted file mode 100644 index b5103b716944..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Present.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Collections; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * Implementation of an {@link Optional} containing a reference. - */ -@GwtCompatible -final class Present extends Optional { - private final T reference; - - Present(T reference) { - this.reference = reference; - } - - @Override - public boolean isPresent() { - return true; - } - - @Override - public T get() { - return reference; - } - - @Override - public T or(T defaultValue) { - checkNotNull(defaultValue, "use Optional.orNull() instead of Optional.or(null)"); - return reference; - } - - @Override - public Optional or(Optional secondChoice) { - checkNotNull(secondChoice); - return this; - } - - @Override - public T or(Supplier supplier) { - checkNotNull(supplier); - return reference; - } - - @Override - public T orNull() { - return reference; - } - - @Override - public Set asSet() { - return Collections.singleton(reference); - } - - @Override - public Optional transform(Function function) { - return new Present( - checkNotNull( - function.apply(reference), - "the Function passed to Optional.transform() must not return null.")); - } - - @Override - public boolean equals(@Nullable Object object) { - if (object instanceof Present) { - Present other = (Present) object; - return reference.equals(other.reference); - } - return false; - } - - @Override - public int hashCode() { - return 0x598df91c + reference.hashCode(); - } - - @Override - public String toString() { - return "Optional.of(" + reference + ")"; - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/SmallCharMatcher.java b/thirdparty/google-guava/src/main/java/com/google/common/base/SmallCharMatcher.java deleted file mode 100644 index 2bea0eb47bb1..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/SmallCharMatcher.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import com.google.common.annotations.GwtIncompatible; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.CharMatcher.NamedFastMatcher; - -import java.util.BitSet; - -/** - * An immutable version of CharMatcher for smallish sets of characters that uses a hash table - * with linear probing to check for matches. - * - * @author Christopher Swenson - */ -@GwtIncompatible("no precomputation is done in GWT") -final class SmallCharMatcher extends NamedFastMatcher { - static final int MAX_SIZE = 1023; - private final char[] table; - private final boolean containsZero; - private final long filter; - - private SmallCharMatcher(char[] table, long filter, boolean containsZero, String description) { - super(description); - this.table = table; - this.filter = filter; - this.containsZero = containsZero; - } - - private static final int C1 = 0xcc9e2d51; - private static final int C2 = 0x1b873593; - - /* - * This method was rewritten in Java from an intermediate step of the Murmur hash function in - * http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp, which contained the - * following header: - * - * MurmurHash3 was written by Austin Appleby, and is placed in the public domain. The author - * hereby disclaims copyright to this source code. - */ - static int smear(int hashCode) { - return C2 * Integer.rotateLeft(hashCode * C1, 15); - } - - private boolean checkFilter(int c) { - return 1 == (1 & (filter >> c)); - } - - // This is all essentially copied from ImmutableSet, but we have to duplicate because - // of dependencies. - - // Represents how tightly we can pack things, as a maximum. - private static final double DESIRED_LOAD_FACTOR = 0.5; - - /** - * Returns an array size suitable for the backing array of a hash table that - * uses open addressing with linear probing in its implementation. The - * returned size is the smallest power of two that can hold setSize elements - * with the desired load factor. - */ - @VisibleForTesting - static int chooseTableSize(int setSize) { - if (setSize == 1) { - return 2; - } - // Correct the size for open addressing to match desired load factor. - // Round up to the next highest power of 2. - int tableSize = Integer.highestOneBit(setSize - 1) << 1; - while (tableSize * DESIRED_LOAD_FACTOR < setSize) { - tableSize <<= 1; - } - return tableSize; - } - - static CharMatcher from(BitSet chars, String description) { - // Compute the filter. - long filter = 0; - int size = chars.cardinality(); - boolean containsZero = chars.get(0); - // Compute the hash table. - char[] table = new char[chooseTableSize(size)]; - int mask = table.length - 1; - for (int c = chars.nextSetBit(0); c != -1; c = chars.nextSetBit(c + 1)) { - // Compute the filter at the same time. - filter |= 1L << c; - int index = smear(c) & mask; - while (true) { - // Check for empty. - if (table[index] == 0) { - table[index] = (char) c; - break; - } - // Linear probing. - index = (index + 1) & mask; - } - } - return new SmallCharMatcher(table, filter, containsZero, description); - } - - @Override - public boolean matches(char c) { - if (c == 0) { - return containsZero; - } - if (!checkFilter(c)) { - return false; - } - int mask = table.length - 1; - int startingIndex = smear(c) & mask; - int index = startingIndex; - do { - // Check for empty. - if (table[index] == 0) { - return false; - // Check for match. - } else if (table[index] == c) { - return true; - } else { - // Linear probing. - index = (index + 1) & mask; - } - // Check to see if we wrapped around the whole table. - } while (index != startingIndex); - return false; - } - - @Override - void setBits(BitSet table) { - if (containsZero) { - table.set(0); - } - for (char c : this.table) { - if (c != 0) { - table.set(c); - } - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Splitter.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Splitter.java deleted file mode 100644 index 6c45952befa5..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Splitter.java +++ /dev/null @@ -1,643 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.annotation.CheckReturnValue; - -/** - * Extracts non-overlapping substrings from an input string, typically by - * recognizing appearances of a separator sequence. This separator can be - * specified as a single {@linkplain #on(char) character}, fixed {@linkplain - * #on(String) string}, {@linkplain #onPattern regular expression} or {@link - * #on(CharMatcher) CharMatcher} instance. Or, instead of using a separator at - * all, a splitter can extract adjacent substrings of a given {@linkplain - * #fixedLength fixed length}. - * - *

For example, this expression:

   {@code
- *
- *   Splitter.on(',').split("foo,bar,qux")}
- * - * ... produces an {@code Iterable} containing {@code "foo"}, {@code "bar"} and - * {@code "qux"}, in that order. - * - *

By default, {@code Splitter}'s behavior is simplistic and unassuming. The - * following expression:

   {@code
- *
- *   Splitter.on(',').split(" foo,,,  bar ,")}
- * - * ... yields the substrings {@code [" foo", "", "", " bar ", ""]}. If this - * is not the desired behavior, use configuration methods to obtain a new - * splitter instance with modified behavior:
   {@code
- *
- *   private static final Splitter MY_SPLITTER = Splitter.on(',')
- *       .trimResults()
- *       .omitEmptyStrings();}
- * - *

Now {@code MY_SPLITTER.split("foo,,, bar ,")} returns just {@code ["foo", - * "bar"]}. Note that the order in which these configuration methods are called - * is never significant. - * - *

Warning: Splitter instances are immutable. Invoking a configuration - * method has no effect on the receiving instance; you must store and use the - * new splitter instance it returns instead.

   {@code
- *
- *   // Do NOT do this
- *   Splitter splitter = Splitter.on('/');
- *   splitter.trimResults(); // does nothing!
- *   return splitter.split("wrong / wrong / wrong");}
- * - *

For separator-based splitters that do not use {@code omitEmptyStrings}, an - * input string containing {@code n} occurrences of the separator naturally - * yields an iterable of size {@code n + 1}. So if the separator does not occur - * anywhere in the input, a single substring is returned containing the entire - * input. Consequently, all splitters split the empty string to {@code [""]} - * (note: even fixed-length splitters). - * - *

Splitter instances are thread-safe immutable, and are therefore safe to - * store as {@code static final} constants. - * - *

The {@link Joiner} class provides the inverse operation to splitting, but - * note that a round-trip between the two should be assumed to be lossy. - * - *

Exception: for consistency with separator-based splitters, {@code - * split("")} does not yield an empty iterable, but an iterable containing - * {@code ""}. This is the only case in which {@code - * Iterables.size(split(input))} does not equal {@code - * IntMath.divide(input.length(), length, CEILING)}. To avoid this behavior, - * use {@code omitEmptyStrings}. - * - * @param length the desired length of pieces after splitting, a positive - * integer - * @return a splitter, with default settings, that can split into fixed sized - * pieces - * @throws IllegalArgumentException if {@code length} is zero or negative - */ - @CheckReturnValue - public static Splitter fixedLength(final int length) { - checkArgument(length > 0, "The length may not be less than 1"); - - return new Splitter( - new Strategy() { - @Override - public SplittingIterator iterator(final Splitter splitter, CharSequence toSplit) { - return new SplittingIterator(splitter, toSplit) { - @Override - public int separatorStart(int start) { - int nextChunkStart = start + length; - return (nextChunkStart < toSplit.length() ? nextChunkStart : -1); - } - - @Override - public int separatorEnd(int separatorPosition) { - return separatorPosition; - } - }; - } - }); - } - - /** - * Returns a splitter that behaves equivalently to {@code this} splitter, but - * automatically omits empty strings from the results. For example, {@code - * Splitter.on(',').omitEmptyStrings().split(",a,,,b,c,,")} returns an - * iterable containing only {@code ["a", "b", "c"]}. - * - *

If either {@code trimResults} option is also specified when creating a - * splitter, that splitter always trims results first before checking for - * emptiness. So, for example, {@code - * Splitter.on(':').omitEmptyStrings().trimResults().split(": : : ")} returns - * an empty iterable. - * - *

Note that it is ordinarily not possible for {@link #split(CharSequence)} - * to return an empty iterable, but when using this option, it can (if the - * input sequence consists of nothing but separators). - * - * @return a splitter with the desired configuration - */ - @CheckReturnValue - public Splitter omitEmptyStrings() { - return new Splitter(strategy, true, trimmer, limit); - } - - /** - * Returns a splitter that behaves equivalently to {@code this} splitter but - * stops splitting after it reaches the limit. - * The limit defines the maximum number of items returned by the iterator, or - * the maximum size of the list returned by {@link #splitToList}. - * - *

For example, - * {@code Splitter.on(',').limit(3).split("a,b,c,d")} returns an iterable - * containing {@code ["a", "b", "c,d"]}. When omitting empty strings, the - * omitted strings do no count. Hence, - * {@code Splitter.on(',').limit(3).omitEmptyStrings().split("a,,,b,,,c,d")} - * returns an iterable containing {@code ["a", "b", "c,d"}. - * When trim is requested, all entries, including the last are trimmed. Hence - * {@code Splitter.on(',').limit(3).trimResults().split(" a , b , c , d ")} - * results in {@code ["a", "b", "c , d"]}. - * - * @param limit the maximum number of items returned - * @return a splitter with the desired configuration - * @since 9.0 - */ - @CheckReturnValue - public Splitter limit(int limit) { - checkArgument(limit > 0, "must be greater than zero: %s", limit); - return new Splitter(strategy, omitEmptyStrings, trimmer, limit); - } - - /** - * Returns a splitter that behaves equivalently to {@code this} splitter, but - * automatically removes leading and trailing {@linkplain - * CharMatcher#WHITESPACE whitespace} from each returned substring; equivalent - * to {@code trimResults(CharMatcher.WHITESPACE)}. For example, {@code - * Splitter.on(',').trimResults().split(" a, b ,c ")} returns an iterable - * containing {@code ["a", "b", "c"]}. - * - * @return a splitter with the desired configuration - */ - @CheckReturnValue - public Splitter trimResults() { - return trimResults(CharMatcher.WHITESPACE); - } - - /** - * Returns a splitter that behaves equivalently to {@code this} splitter, but - * removes all leading or trailing characters matching the given {@code - * CharMatcher} from each returned substring. For example, {@code - * Splitter.on(',').trimResults(CharMatcher.is('_')).split("_a ,_b_ ,c__")} - * returns an iterable containing {@code ["a ", "b_ ", "c"]}. - * - * @param trimmer a {@link CharMatcher} that determines whether a character - * should be removed from the beginning/end of a subsequence - * @return a splitter with the desired configuration - */ - // TODO(kevinb): throw if a trimmer was already specified! - @CheckReturnValue - public Splitter trimResults(CharMatcher trimmer) { - checkNotNull(trimmer); - return new Splitter(strategy, omitEmptyStrings, trimmer, limit); - } - - /** - * Splits {@code sequence} into string components and makes them available - * through an {@link Iterator}, which may be lazily evaluated. If you want - * an eagerly computed {@link List}, use {@link #splitToList(CharSequence)}. - * - * @param sequence the sequence of characters to split - * @return an iteration over the segments split from the parameter. - */ - @CheckReturnValue - public Iterable split(final CharSequence sequence) { - checkNotNull(sequence); - - return new Iterable() { - @Override - public Iterator iterator() { - return splittingIterator(sequence); - } - - @Override - public String toString() { - return Joiner.on(", ") - .appendTo(new StringBuilder().append('['), this) - .append(']') - .toString(); - } - }; - } - - private Iterator splittingIterator(CharSequence sequence) { - return strategy.iterator(this, sequence); - } - - /** - * Splits {@code sequence} into string components and returns them as - * an immutable list. If you want an {@link Iterable} which may be lazily - * evaluated, use {@link #split(CharSequence)}. - * - * @param sequence the sequence of characters to split - * @return an immutable list of the segments split from the parameter - * @since 15.0 - */ - @CheckReturnValue - @Beta - public List splitToList(CharSequence sequence) { - checkNotNull(sequence); - - Iterator iterator = splittingIterator(sequence); - List result = new ArrayList(); - - while (iterator.hasNext()) { - result.add(iterator.next()); - } - - return Collections.unmodifiableList(result); - } - - /** - * Returns a {@code MapSplitter} which splits entries based on this splitter, - * and splits entries into keys and values using the specified separator. - * - * @since 10.0 - */ - @CheckReturnValue - @Beta - public MapSplitter withKeyValueSeparator(String separator) { - return withKeyValueSeparator(on(separator)); - } - - /** - * Returns a {@code MapSplitter} which splits entries based on this splitter, - * and splits entries into keys and values using the specified separator. - * - * @since 14.0 - */ - @CheckReturnValue - @Beta - public MapSplitter withKeyValueSeparator(char separator) { - return withKeyValueSeparator(on(separator)); - } - - /** - * Returns a {@code MapSplitter} which splits entries based on this splitter, - * and splits entries into keys and values using the specified key-value - * splitter. - * - * @since 10.0 - */ - @CheckReturnValue - @Beta - public MapSplitter withKeyValueSeparator(Splitter keyValueSplitter) { - return new MapSplitter(this, keyValueSplitter); - } - - /** - * An object that splits strings into maps as {@code Splitter} splits - * iterables and lists. Like {@code Splitter}, it is thread-safe and - * immutable. - * - * @since 10.0 - */ - @Beta - public static final class MapSplitter { - private static final String INVALID_ENTRY_MESSAGE = "Chunk [%s] is not a valid entry"; - private final Splitter outerSplitter; - private final Splitter entrySplitter; - - private MapSplitter(Splitter outerSplitter, Splitter entrySplitter) { - this.outerSplitter = outerSplitter; // only "this" is passed - this.entrySplitter = checkNotNull(entrySplitter); - } - - /** - * Splits {@code sequence} into substrings, splits each substring into - * an entry, and returns an unmodifiable map with each of the entries. For - * example, - * Splitter.on(';').trimResults().withKeyValueSeparator("=>") - * .split("a=>b ; c=>b") - * will return a mapping from {@code "a"} to {@code "b"} and - * {@code "c"} to {@code b}. - * - *

The returned map preserves the order of the entries from - * {@code sequence}. - * - * @throws IllegalArgumentException if the specified sequence does not split - * into valid map entries, or if there are duplicate keys - */ - @CheckReturnValue - public Map split(CharSequence sequence) { - Map map = new LinkedHashMap(); - for (String entry : outerSplitter.split(sequence)) { - Iterator entryFields = entrySplitter.splittingIterator(entry); - - checkArgument(entryFields.hasNext(), INVALID_ENTRY_MESSAGE, entry); - String key = entryFields.next(); - checkArgument(!map.containsKey(key), "Duplicate key [%s] found.", key); - - checkArgument(entryFields.hasNext(), INVALID_ENTRY_MESSAGE, entry); - String value = entryFields.next(); - map.put(key, value); - - checkArgument(!entryFields.hasNext(), INVALID_ENTRY_MESSAGE, entry); - } - return Collections.unmodifiableMap(map); - } - } - - private interface Strategy { - Iterator iterator(Splitter splitter, CharSequence toSplit); - } - - private abstract static class SplittingIterator extends AbstractIterator { - final CharSequence toSplit; - final CharMatcher trimmer; - final boolean omitEmptyStrings; - - /** - * Returns the first index in {@code toSplit} at or after {@code start} - * that contains the separator. - */ - abstract int separatorStart(int start); - - /** - * Returns the first index in {@code toSplit} after {@code - * separatorPosition} that does not contain a separator. This method is only - * invoked after a call to {@code separatorStart}. - */ - abstract int separatorEnd(int separatorPosition); - - int offset = 0; - int limit; - - protected SplittingIterator(Splitter splitter, CharSequence toSplit) { - this.trimmer = splitter.trimmer; - this.omitEmptyStrings = splitter.omitEmptyStrings; - this.limit = splitter.limit; - this.toSplit = toSplit; - } - - @Override - protected String computeNext() { - /* - * The returned string will be from the end of the last match to the - * beginning of the next one. nextStart is the start position of the - * returned substring, while offset is the place to start looking for a - * separator. - */ - int nextStart = offset; - while (offset != -1) { - int start = nextStart; - int end; - - int separatorPosition = separatorStart(offset); - if (separatorPosition == -1) { - end = toSplit.length(); - offset = -1; - } else { - end = separatorPosition; - offset = separatorEnd(separatorPosition); - } - if (offset == nextStart) { - /* - * This occurs when some pattern has an empty match, even if it - * doesn't match the empty string -- for example, if it requires - * lookahead or the like. The offset must be increased to look for - * separators beyond this point, without changing the start position - * of the next returned substring -- so nextStart stays the same. - */ - offset++; - if (offset >= toSplit.length()) { - offset = -1; - } - continue; - } - - while (start < end && trimmer.matches(toSplit.charAt(start))) { - start++; - } - while (end > start && trimmer.matches(toSplit.charAt(end - 1))) { - end--; - } - - if (omitEmptyStrings && start == end) { - // Don't include the (unused) separator in next split string. - nextStart = offset; - continue; - } - - if (limit == 1) { - // The limit has been reached, return the rest of the string as the - // final item. This is tested after empty string removal so that - // empty strings do not count towards the limit. - end = toSplit.length(); - offset = -1; - // Since we may have changed the end, we need to trim it again. - while (end > start && trimmer.matches(toSplit.charAt(end - 1))) { - end--; - } - } else { - limit--; - } - - return toSplit.subSequence(start, end).toString(); - } - return endOfData(); - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/StandardSystemProperty.java b/thirdparty/google-guava/src/main/java/com/google/common/base/StandardSystemProperty.java deleted file mode 100644 index 21734587d55d..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/StandardSystemProperty.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtIncompatible; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * Represents a {@linkplain System#getProperties() standard system property}. - * - * @author Kurt Alfred Kluever - * @since 15.0 - */ -@Beta -@GwtIncompatible("java.lang.System#getProperty") -@CheckReturnValue -public enum StandardSystemProperty { - - /** Java Runtime Environment version. */ - JAVA_VERSION("java.version"), - - /** Java Runtime Environment vendor. */ - JAVA_VENDOR("java.vendor"), - - /** Java vendor URL. */ - JAVA_VENDOR_URL("java.vendor.url"), - - /** Java installation directory. */ - JAVA_HOME("java.home"), - - /** Java Virtual Machine specification version. */ - JAVA_VM_SPECIFICATION_VERSION("java.vm.specification.version"), - - /** Java Virtual Machine specification vendor. */ - JAVA_VM_SPECIFICATION_VENDOR("java.vm.specification.vendor"), - - /** Java Virtual Machine specification name. */ - JAVA_VM_SPECIFICATION_NAME("java.vm.specification.name"), - - /** Java Virtual Machine implementation version. */ - JAVA_VM_VERSION("java.vm.version"), - - /** Java Virtual Machine implementation vendor. */ - JAVA_VM_VENDOR("java.vm.vendor"), - - /** Java Virtual Machine implementation name. */ - JAVA_VM_NAME("java.vm.name"), - - /** Java Runtime Environment specification version. */ - JAVA_SPECIFICATION_VERSION("java.specification.version"), - - /** Java Runtime Environment specification vendor. */ - JAVA_SPECIFICATION_VENDOR("java.specification.vendor"), - - /** Java Runtime Environment specification name. */ - JAVA_SPECIFICATION_NAME("java.specification.name"), - - /** Java class format version number. */ - JAVA_CLASS_VERSION("java.class.version"), - - /** Java class path. */ - JAVA_CLASS_PATH("java.class.path"), - - /** List of paths to search when loading libraries. */ - JAVA_LIBRARY_PATH("java.library.path"), - - /** Default temp file path. */ - JAVA_IO_TMPDIR("java.io.tmpdir"), - - /** Name of JIT compiler to use. */ - JAVA_COMPILER("java.compiler"), - - /** Path of extension directory or directories. */ - JAVA_EXT_DIRS("java.ext.dirs"), - - /** Operating system name. */ - OS_NAME("os.name"), - - /** Operating system architecture. */ - OS_ARCH("os.arch"), - - /** Operating system version. */ - OS_VERSION("os.version"), - - /** File separator ("/" on UNIX). */ - FILE_SEPARATOR("file.separator"), - - /** Path separator (":" on UNIX). */ - PATH_SEPARATOR("path.separator"), - - /** Line separator ("\n" on UNIX). */ - LINE_SEPARATOR("line.separator"), - - /** User's account name. */ - USER_NAME("user.name"), - - /** User's home directory. */ - USER_HOME("user.home"), - - /** User's current working directory. */ - USER_DIR("user.dir"); - - private final String key; - - private StandardSystemProperty(String key) { - this.key = key; - } - - /** - * Returns the key used to lookup this system property. - */ - public String key() { - return key; - } - - /** - * Returns the current value for this system property by delegating to - * {@link System#getProperty(String)}. - */ - @Nullable - public String value() { - return System.getProperty(key); - } - - /** - * Returns a string representation of this system property. - */ - @Override - public String toString() { - return key() + "=" + value(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Stopwatch.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Stopwatch.java deleted file mode 100644 index 51be949da0f0..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Stopwatch.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; -import static java.util.concurrent.TimeUnit.DAYS; -import static java.util.concurrent.TimeUnit.HOURS; -import static java.util.concurrent.TimeUnit.MICROSECONDS; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static java.util.concurrent.TimeUnit.MINUTES; -import static java.util.concurrent.TimeUnit.NANOSECONDS; -import static java.util.concurrent.TimeUnit.SECONDS; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; - -import java.util.Locale; -import java.util.concurrent.TimeUnit; - -import javax.annotation.CheckReturnValue; - -/** - * An object that measures elapsed time in nanoseconds. It is useful to measure - * elapsed time using this class instead of direct calls to {@link - * System#nanoTime} for a few reasons: - * - *

    - *
  • An alternate time source can be substituted, for testing or performance - * reasons. - *
  • As documented by {@code nanoTime}, the value returned has no absolute - * meaning, and can only be interpreted as relative to another timestamp - * returned by {@code nanoTime} at a different time. {@code Stopwatch} is a - * more effective abstraction because it exposes only these relative values, - * not the absolute ones. - *
- * - *

Basic usage: - *

- *   Stopwatch stopwatch = Stopwatch.{@link #createStarted createStarted}();
- *   doSomething();
- *   stopwatch.{@link #stop stop}(); // optional
- *
- *   long millis = stopwatch.elapsed(MILLISECONDS);
- *
- *   log.info("time: " + stopwatch); // formatted string like "12.3 ms"
- * - *

Stopwatch methods are not idempotent; it is an error to start or stop a - * stopwatch that is already in the desired state. - * - *

When testing code that uses this class, use - * {@link #createUnstarted(Ticker)} or {@link #createStarted(Ticker)} to - * supply a fake or mock ticker. - * This allows you to - * simulate any valid behavior of the stopwatch. - * - *

Note: This class is not thread-safe. - * - * @author Kevin Bourrillion - * @since 10.0 - */ -@GwtCompatible(emulated = true) -public final class Stopwatch { - private final Ticker ticker; - private boolean isRunning; - private long elapsedNanos; - private long startTick; - - /** - * Creates (but does not start) a new stopwatch using {@link System#nanoTime} - * as its time source. - * - * @since 15.0 - */ - @CheckReturnValue - public static Stopwatch createUnstarted() { - return new Stopwatch(); - } - - /** - * Creates (but does not start) a new stopwatch, using the specified time - * source. - * - * @since 15.0 - */ - @CheckReturnValue - public static Stopwatch createUnstarted(Ticker ticker) { - return new Stopwatch(ticker); - } - - /** - * Creates (and starts) a new stopwatch using {@link System#nanoTime} - * as its time source. - * - * @since 15.0 - */ - @CheckReturnValue - public static Stopwatch createStarted() { - return new Stopwatch().start(); - } - - /** - * Creates (and starts) a new stopwatch, using the specified time - * source. - * - * @since 15.0 - */ - @CheckReturnValue - public static Stopwatch createStarted(Ticker ticker) { - return new Stopwatch(ticker).start(); - } - - Stopwatch() { - this.ticker = Ticker.systemTicker(); - } - - Stopwatch(Ticker ticker) { - this.ticker = checkNotNull(ticker, "ticker"); - } - - /** - * Returns {@code true} if {@link #start()} has been called on this stopwatch, - * and {@link #stop()} has not been called since the last call to {@code - * start()}. - */ - @CheckReturnValue - public boolean isRunning() { - return isRunning; - } - - /** - * Starts the stopwatch. - * - * @return this {@code Stopwatch} instance - * @throws IllegalStateException if the stopwatch is already running. - */ - public Stopwatch start() { - checkState(!isRunning, "This stopwatch is already running."); - isRunning = true; - startTick = ticker.read(); - return this; - } - - /** - * Stops the stopwatch. Future reads will return the fixed duration that had - * elapsed up to this point. - * - * @return this {@code Stopwatch} instance - * @throws IllegalStateException if the stopwatch is already stopped. - */ - public Stopwatch stop() { - long tick = ticker.read(); - checkState(isRunning, "This stopwatch is already stopped."); - isRunning = false; - elapsedNanos += tick - startTick; - return this; - } - - /** - * Sets the elapsed time for this stopwatch to zero, - * and places it in a stopped state. - * - * @return this {@code Stopwatch} instance - */ - public Stopwatch reset() { - elapsedNanos = 0; - isRunning = false; - return this; - } - - private long elapsedNanos() { - return isRunning ? ticker.read() - startTick + elapsedNanos : elapsedNanos; - } - - /** - * Returns the current elapsed time shown on this stopwatch, expressed - * in the desired time unit, with any fraction rounded down. - * - *

Note that the overhead of measurement can be more than a microsecond, so - * it is generally not useful to specify {@link TimeUnit#NANOSECONDS} - * precision here. - * - * @since 14.0 (since 10.0 as {@code elapsedTime()}) - */ - @CheckReturnValue - public long elapsed(TimeUnit desiredUnit) { - return desiredUnit.convert(elapsedNanos(), NANOSECONDS); - } - - /** - * Returns a string representation of the current elapsed time. - */ - @GwtIncompatible("String.format()") - @Override - public String toString() { - long nanos = elapsedNanos(); - - TimeUnit unit = chooseUnit(nanos); - double value = (double) nanos / NANOSECONDS.convert(1, unit); - - // Too bad this functionality is not exposed as a regular method call - return String.format(Locale.ROOT, "%.4g %s", value, abbreviate(unit)); - } - - private static TimeUnit chooseUnit(long nanos) { - if (DAYS.convert(nanos, NANOSECONDS) > 0) { - return DAYS; - } - if (HOURS.convert(nanos, NANOSECONDS) > 0) { - return HOURS; - } - if (MINUTES.convert(nanos, NANOSECONDS) > 0) { - return MINUTES; - } - if (SECONDS.convert(nanos, NANOSECONDS) > 0) { - return SECONDS; - } - if (MILLISECONDS.convert(nanos, NANOSECONDS) > 0) { - return MILLISECONDS; - } - if (MICROSECONDS.convert(nanos, NANOSECONDS) > 0) { - return MICROSECONDS; - } - return NANOSECONDS; - } - - private static String abbreviate(TimeUnit unit) { - switch (unit) { - case NANOSECONDS: - return "ns"; - case MICROSECONDS: - return "\u03bcs"; // μs - case MILLISECONDS: - return "ms"; - case SECONDS: - return "s"; - case MINUTES: - return "min"; - case HOURS: - return "h"; - case DAYS: - return "d"; - default: - throw new AssertionError(); - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Strings.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Strings.java deleted file mode 100644 index 4e4c2f6ac215..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Strings.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (C) 2010 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.VisibleForTesting; - -import java.util.Formatter; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * Static utility methods pertaining to {@code String} or {@code CharSequence} - * instances. - * - * @author Kevin Bourrillion - * @since 3.0 - */ -@CheckReturnValue -@GwtCompatible -public final class Strings { - private Strings() {} - - /** - * Returns the given string if it is non-null; the empty string otherwise. - * - * @param string the string to test and possibly return - * @return {@code string} itself if it is non-null; {@code ""} if it is null - */ - public static String nullToEmpty(@Nullable String string) { - return (string == null) ? "" : string; - } - - /** - * Returns the given string if it is nonempty; {@code null} otherwise. - * - * @param string the string to test and possibly return - * @return {@code string} itself if it is nonempty; {@code null} if it is - * empty or null - */ - @Nullable - public static String emptyToNull(@Nullable String string) { - return isNullOrEmpty(string) ? null : string; - } - - /** - * Returns {@code true} if the given string is null or is the empty string. - * - *

Consider normalizing your string references with {@link #nullToEmpty}. - * If you do, you can use {@link String#isEmpty()} instead of this - * method, and you won't need special null-safe forms of methods like {@link - * String#toUpperCase} either. Or, if you'd like to normalize "in the other - * direction," converting empty strings to {@code null}, you can use {@link - * #emptyToNull}. - * - * @param string a string reference to check - * @return {@code true} if the string is null or is the empty string - */ - public static boolean isNullOrEmpty(@Nullable String string) { - return string == null || string.length() == 0; // string.isEmpty() in Java 6 - } - - /** - * Returns a string, of length at least {@code minLength}, consisting of - * {@code string} prepended with as many copies of {@code padChar} as are - * necessary to reach that length. For example, - * - *

    - *
  • {@code padStart("7", 3, '0')} returns {@code "007"} - *
  • {@code padStart("2010", 3, '0')} returns {@code "2010"} - *
- * - *

See {@link Formatter} for a richer set of formatting capabilities. - * - * @param string the string which should appear at the end of the result - * @param minLength the minimum length the resulting string must have. Can be - * zero or negative, in which case the input string is always returned. - * @param padChar the character to insert at the beginning of the result until - * the minimum length is reached - * @return the padded string - */ - public static String padStart(String string, int minLength, char padChar) { - checkNotNull(string); // eager for GWT. - if (string.length() >= minLength) { - return string; - } - StringBuilder sb = new StringBuilder(minLength); - for (int i = string.length(); i < minLength; i++) { - sb.append(padChar); - } - sb.append(string); - return sb.toString(); - } - - /** - * Returns a string, of length at least {@code minLength}, consisting of - * {@code string} appended with as many copies of {@code padChar} as are - * necessary to reach that length. For example, - * - *

    - *
  • {@code padEnd("4.", 5, '0')} returns {@code "4.000"} - *
  • {@code padEnd("2010", 3, '!')} returns {@code "2010"} - *
- * - *

See {@link Formatter} for a richer set of formatting capabilities. - * - * @param string the string which should appear at the beginning of the result - * @param minLength the minimum length the resulting string must have. Can be - * zero or negative, in which case the input string is always returned. - * @param padChar the character to append to the end of the result until the - * minimum length is reached - * @return the padded string - */ - public static String padEnd(String string, int minLength, char padChar) { - checkNotNull(string); // eager for GWT. - if (string.length() >= minLength) { - return string; - } - StringBuilder sb = new StringBuilder(minLength); - sb.append(string); - for (int i = string.length(); i < minLength; i++) { - sb.append(padChar); - } - return sb.toString(); - } - - /** - * Returns a string consisting of a specific number of concatenated copies of - * an input string. For example, {@code repeat("hey", 3)} returns the string - * {@code "heyheyhey"}. - * - * @param string any non-null string - * @param count the number of times to repeat it; a nonnegative integer - * @return a string containing {@code string} repeated {@code count} times - * (the empty string if {@code count} is zero) - * @throws IllegalArgumentException if {@code count} is negative - */ - public static String repeat(String string, int count) { - checkNotNull(string); // eager for GWT. - - if (count <= 1) { - checkArgument(count >= 0, "invalid count: %s", count); - return (count == 0) ? "" : string; - } - - // IF YOU MODIFY THE CODE HERE, you must update StringsRepeatBenchmark - final int len = string.length(); - final long longSize = (long) len * (long) count; - final int size = (int) longSize; - if (size != longSize) { - throw new ArrayIndexOutOfBoundsException("Required array size too large: " + longSize); - } - - final char[] array = new char[size]; - string.getChars(0, len, array, 0); - int n; - for (n = len; n < size - n; n <<= 1) { - System.arraycopy(array, 0, array, n, n); - } - System.arraycopy(array, 0, array, n, size - n); - return new String(array); - } - - /** - * Returns the longest string {@code prefix} such that - * {@code a.toString().startsWith(prefix) && b.toString().startsWith(prefix)}, - * taking care not to split surrogate pairs. If {@code a} and {@code b} have - * no common prefix, returns the empty string. - * - * @since 11.0 - */ - public static String commonPrefix(CharSequence a, CharSequence b) { - checkNotNull(a); - checkNotNull(b); - - int maxPrefixLength = Math.min(a.length(), b.length()); - int p = 0; - while (p < maxPrefixLength && a.charAt(p) == b.charAt(p)) { - p++; - } - if (validSurrogatePairAt(a, p - 1) || validSurrogatePairAt(b, p - 1)) { - p--; - } - return a.subSequence(0, p).toString(); - } - - /** - * Returns the longest string {@code suffix} such that - * {@code a.toString().endsWith(suffix) && b.toString().endsWith(suffix)}, - * taking care not to split surrogate pairs. If {@code a} and {@code b} have - * no common suffix, returns the empty string. - * - * @since 11.0 - */ - public static String commonSuffix(CharSequence a, CharSequence b) { - checkNotNull(a); - checkNotNull(b); - - int maxSuffixLength = Math.min(a.length(), b.length()); - int s = 0; - while (s < maxSuffixLength && a.charAt(a.length() - s - 1) == b.charAt(b.length() - s - 1)) { - s++; - } - if (validSurrogatePairAt(a, a.length() - s - 1) - || validSurrogatePairAt(b, b.length() - s - 1)) { - s--; - } - return a.subSequence(a.length() - s, a.length()).toString(); - } - - /** - * True when a valid surrogate pair starts at the given {@code index} in the - * given {@code string}. Out-of-range indexes return false. - */ - @VisibleForTesting - static boolean validSurrogatePairAt(CharSequence string, int index) { - return index >= 0 - && index <= (string.length() - 2) - && Character.isHighSurrogate(string.charAt(index)) - && Character.isLowSurrogate(string.charAt(index + 1)); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Supplier.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Supplier.java deleted file mode 100644 index aca0b32a6c3a..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Supplier.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import com.google.common.annotations.GwtCompatible; - -/** - * A class that can supply objects of a single type. Semantically, this could - * be a factory, generator, builder, closure, or something else entirely. No - * guarantees are implied by this interface. - * - * @author Harry Heymann - * @since 2.0 - */ -@GwtCompatible -public interface Supplier { - /** - * Retrieves an instance of the appropriate type. The returned object may or - * may not be a new instance, depending on the implementation. - * - * @return an instance of the appropriate type - */ - T get(); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Suppliers.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Suppliers.java deleted file mode 100644 index 838e64ff58fa..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Suppliers.java +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.VisibleForTesting; - -import java.io.Serializable; -import java.util.concurrent.TimeUnit; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * Useful suppliers. - * - *

All methods return serializable suppliers as long as they're given - * serializable parameters. - * - * @author Laurence Gonsalves - * @author Harry Heymann - * @since 2.0 - */ -@CheckReturnValue -@GwtCompatible -public final class Suppliers { - private Suppliers() {} - - /** - * Returns a new supplier which is the composition of the provided function - * and supplier. In other words, the new supplier's value will be computed by - * retrieving the value from {@code supplier}, and then applying - * {@code function} to that value. Note that the resulting supplier will not - * call {@code supplier} or invoke {@code function} until it is called. - */ - public static Supplier compose(Function function, Supplier supplier) { - Preconditions.checkNotNull(function); - Preconditions.checkNotNull(supplier); - return new SupplierComposition(function, supplier); - } - - private static class SupplierComposition implements Supplier, Serializable { - final Function function; - final Supplier supplier; - - SupplierComposition(Function function, Supplier supplier) { - this.function = function; - this.supplier = supplier; - } - - @Override - public T get() { - return function.apply(supplier.get()); - } - - @Override - public boolean equals(@Nullable Object obj) { - if (obj instanceof SupplierComposition) { - SupplierComposition that = (SupplierComposition) obj; - return function.equals(that.function) && supplier.equals(that.supplier); - } - return false; - } - - @Override - public int hashCode() { - return Objects.hashCode(function, supplier); - } - - @Override - public String toString() { - return "Suppliers.compose(" + function + ", " + supplier + ")"; - } - - private static final long serialVersionUID = 0; - } - - /** - * Returns a supplier which caches the instance retrieved during the first - * call to {@code get()} and returns that value on subsequent calls to - * {@code get()}. See: - * memoization - * - *

The returned supplier is thread-safe. The delegate's {@code get()} - * method will be invoked at most once. The supplier's serialized form does - * not contain the cached value, which will be recalculated when {@code get()} - * is called on the reserialized instance. - * - *

If {@code delegate} is an instance created by an earlier call to {@code - * memoize}, it is returned directly. - */ - public static Supplier memoize(Supplier delegate) { - return (delegate instanceof MemoizingSupplier) - ? delegate - : new MemoizingSupplier(Preconditions.checkNotNull(delegate)); - } - - @VisibleForTesting - static class MemoizingSupplier implements Supplier, Serializable { - final Supplier delegate; - transient volatile boolean initialized; - // "value" does not need to be volatile; visibility piggy-backs - // on volatile read of "initialized". - transient T value; - - MemoizingSupplier(Supplier delegate) { - this.delegate = delegate; - } - - @Override - public T get() { - // A 2-field variant of Double Checked Locking. - if (!initialized) { - synchronized (this) { - if (!initialized) { - T t = delegate.get(); - value = t; - initialized = true; - return t; - } - } - } - return value; - } - - @Override - public String toString() { - return "Suppliers.memoize(" + delegate + ")"; - } - - private static final long serialVersionUID = 0; - } - - /** - * Returns a supplier that caches the instance supplied by the delegate and - * removes the cached value after the specified time has passed. Subsequent - * calls to {@code get()} return the cached value if the expiration time has - * not passed. After the expiration time, a new value is retrieved, cached, - * and returned. See: - * memoization - * - *

The returned supplier is thread-safe. The supplier's serialized form - * does not contain the cached value, which will be recalculated when {@code - * get()} is called on the reserialized instance. - * - * @param duration the length of time after a value is created that it - * should stop being returned by subsequent {@code get()} calls - * @param unit the unit that {@code duration} is expressed in - * @throws IllegalArgumentException if {@code duration} is not positive - * @since 2.0 - */ - public static Supplier memoizeWithExpiration( - Supplier delegate, long duration, TimeUnit unit) { - return new ExpiringMemoizingSupplier(delegate, duration, unit); - } - - @VisibleForTesting - static class ExpiringMemoizingSupplier implements Supplier, Serializable { - final Supplier delegate; - final long durationNanos; - transient volatile T value; - // The special value 0 means "not yet initialized". - transient volatile long expirationNanos; - - ExpiringMemoizingSupplier(Supplier delegate, long duration, TimeUnit unit) { - this.delegate = Preconditions.checkNotNull(delegate); - this.durationNanos = unit.toNanos(duration); - Preconditions.checkArgument(duration > 0); - } - - @Override - public T get() { - // Another variant of Double Checked Locking. - // - // We use two volatile reads. We could reduce this to one by - // putting our fields into a holder class, but (at least on x86) - // the extra memory consumption and indirection are more - // expensive than the extra volatile reads. - long nanos = expirationNanos; - long now = Platform.systemNanoTime(); - if (nanos == 0 || now - nanos >= 0) { - synchronized (this) { - if (nanos == expirationNanos) { // recheck for lost race - T t = delegate.get(); - value = t; - nanos = now + durationNanos; - // In the very unlikely event that nanos is 0, set it to 1; - // no one will notice 1 ns of tardiness. - expirationNanos = (nanos == 0) ? 1 : nanos; - return t; - } - } - } - return value; - } - - @Override - public String toString() { - // This is a little strange if the unit the user provided was not NANOS, - // but we don't want to store the unit just for toString - return "Suppliers.memoizeWithExpiration(" + delegate + ", " + durationNanos + ", NANOS)"; - } - - private static final long serialVersionUID = 0; - } - - /** - * Returns a supplier that always supplies {@code instance}. - */ - public static Supplier ofInstance(@Nullable T instance) { - return new SupplierOfInstance(instance); - } - - private static class SupplierOfInstance implements Supplier, Serializable { - final T instance; - - SupplierOfInstance(@Nullable T instance) { - this.instance = instance; - } - - @Override - public T get() { - return instance; - } - - @Override - public boolean equals(@Nullable Object obj) { - if (obj instanceof SupplierOfInstance) { - SupplierOfInstance that = (SupplierOfInstance) obj; - return Objects.equal(instance, that.instance); - } - return false; - } - - @Override - public int hashCode() { - return Objects.hashCode(instance); - } - - @Override - public String toString() { - return "Suppliers.ofInstance(" + instance + ")"; - } - - private static final long serialVersionUID = 0; - } - - /** - * Returns a supplier whose {@code get()} method synchronizes on - * {@code delegate} before calling it, making it thread-safe. - */ - public static Supplier synchronizedSupplier(Supplier delegate) { - return new ThreadSafeSupplier(Preconditions.checkNotNull(delegate)); - } - - private static class ThreadSafeSupplier implements Supplier, Serializable { - final Supplier delegate; - - ThreadSafeSupplier(Supplier delegate) { - this.delegate = delegate; - } - - @Override - public T get() { - synchronized (delegate) { - return delegate.get(); - } - } - - @Override - public String toString() { - return "Suppliers.synchronizedSupplier(" + delegate + ")"; - } - - private static final long serialVersionUID = 0; - } - - /** - * Returns a function that accepts a supplier and returns the result of - * invoking {@link Supplier#get} on that supplier. - * - * @since 8.0 - */ - @Beta - public static Function, T> supplierFunction() { - @SuppressWarnings("unchecked") // implementation is "fully variant" - SupplierFunction sf = (SupplierFunction) SupplierFunctionImpl.INSTANCE; - return sf; - } - - private interface SupplierFunction extends Function, T> {} - - private enum SupplierFunctionImpl implements SupplierFunction { - INSTANCE; - - // Note: This makes T a "pass-through type" - @Override - public Object apply(Supplier input) { - return input.get(); - } - - @Override - public String toString() { - return "Suppliers.supplierFunction()"; - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Throwables.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Throwables.java deleted file mode 100644 index 04b64bbeb2ba..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Throwables.java +++ /dev/null @@ -1,380 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import static com.google.common.base.Preconditions.checkNotNull; -import static java.util.Arrays.asList; -import static java.util.Collections.unmodifiableList; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.VisibleForTesting; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.AbstractList; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * Static utility methods pertaining to instances of {@link Throwable}. - * - *

See the Guava User Guide entry on Throwables. - * - * @author Kevin Bourrillion - * @author Ben Yu - * @since 1.0 - */ -public final class Throwables { - private Throwables() {} - - /** - * Propagates {@code throwable} exactly as-is, if and only if it is an instance of {@code - * declaredType}. Example usage: - *

-   *   try {
-   *     someMethodThatCouldThrowAnything();
-   *   } catch (IKnowWhatToDoWithThisException e) {
-   *     handle(e);
-   *   } catch (Throwable t) {
-   *     Throwables.propagateIfInstanceOf(t, IOException.class);
-   *     Throwables.propagateIfInstanceOf(t, SQLException.class);
-   *     throw Throwables.propagate(t);
-   *   }
-   * 
- */ - public static void propagateIfInstanceOf( - @Nullable Throwable throwable, Class declaredType) throws X { - // Check for null is needed to avoid frequent JNI calls to isInstance(). - if (throwable != null && declaredType.isInstance(throwable)) { - throw declaredType.cast(throwable); - } - } - - /** - * Propagates {@code throwable} exactly as-is, if and only if it is an instance of {@link - * RuntimeException} or {@link Error}. Example usage: - *
-   *   try {
-   *     someMethodThatCouldThrowAnything();
-   *   } catch (IKnowWhatToDoWithThisException e) {
-   *     handle(e);
-   *   } catch (Throwable t) {
-   *     Throwables.propagateIfPossible(t);
-   *     throw new RuntimeException("unexpected", t);
-   *   }
-   * 
- */ - public static void propagateIfPossible(@Nullable Throwable throwable) { - propagateIfInstanceOf(throwable, Error.class); - propagateIfInstanceOf(throwable, RuntimeException.class); - } - - /** - * Propagates {@code throwable} exactly as-is, if and only if it is an instance of {@link - * RuntimeException}, {@link Error}, or {@code declaredType}. Example usage: - *
-   *   try {
-   *     someMethodThatCouldThrowAnything();
-   *   } catch (IKnowWhatToDoWithThisException e) {
-   *     handle(e);
-   *   } catch (Throwable t) {
-   *     Throwables.propagateIfPossible(t, OtherException.class);
-   *     throw new RuntimeException("unexpected", t);
-   *   }
-   * 
- * - * @param throwable the Throwable to possibly propagate - * @param declaredType the single checked exception type declared by the calling method - */ - public static void propagateIfPossible( - @Nullable Throwable throwable, Class declaredType) throws X { - propagateIfInstanceOf(throwable, declaredType); - propagateIfPossible(throwable); - } - - /** - * Propagates {@code throwable} exactly as-is, if and only if it is an instance of {@link - * RuntimeException}, {@link Error}, {@code declaredType1}, or {@code declaredType2}. In the - * unlikely case that you have three or more declared checked exception types, you can handle them - * all by invoking these methods repeatedly. See usage example in {@link - * #propagateIfPossible(Throwable, Class)}. - * - * @param throwable the Throwable to possibly propagate - * @param declaredType1 any checked exception type declared by the calling method - * @param declaredType2 any other checked exception type declared by the calling method - */ - public static void propagateIfPossible( - @Nullable Throwable throwable, Class declaredType1, Class declaredType2) - throws X1, X2 { - checkNotNull(declaredType2); - propagateIfInstanceOf(throwable, declaredType1); - propagateIfPossible(throwable, declaredType2); - } - - /** - * Propagates {@code throwable} as-is if it is an instance of {@link RuntimeException} or {@link - * Error}, or else as a last resort, wraps it in a {@code RuntimeException} and then propagates. - *

- * This method always throws an exception. The {@code RuntimeException} return type is only for - * client code to make Java type system happy in case a return value is required by the enclosing - * method. Example usage: - *

-   *   T doSomething() {
-   *     try {
-   *       return someMethodThatCouldThrowAnything();
-   *     } catch (IKnowWhatToDoWithThisException e) {
-   *       return handle(e);
-   *     } catch (Throwable t) {
-   *       throw Throwables.propagate(t);
-   *     }
-   *   }
-   * 
- * - * @param throwable the Throwable to propagate - * @return nothing will ever be returned; this return type is only for your convenience, as - * illustrated in the example above - */ - public static RuntimeException propagate(Throwable throwable) { - propagateIfPossible(checkNotNull(throwable)); - throw new RuntimeException(throwable); - } - - /** - * Returns the innermost cause of {@code throwable}. The first throwable in a - * chain provides context from when the error or exception was initially - * detected. Example usage: - *
-   *   assertEquals("Unable to assign a customer id", Throwables.getRootCause(e).getMessage());
-   * 
- */ - @CheckReturnValue - public static Throwable getRootCause(Throwable throwable) { - Throwable cause; - while ((cause = throwable.getCause()) != null) { - throwable = cause; - } - return throwable; - } - - /** - * Gets a {@code Throwable} cause chain as a list. The first entry in the list will be {@code - * throwable} followed by its cause hierarchy. Note that this is a snapshot of the cause chain - * and will not reflect any subsequent changes to the cause chain. - * - *

Here's an example of how it can be used to find specific types of exceptions in the cause - * chain: - * - *

-   * Iterables.filter(Throwables.getCausalChain(e), IOException.class));
-   * 
- * - * @param throwable the non-null {@code Throwable} to extract causes from - * @return an unmodifiable list containing the cause chain starting with {@code throwable} - */ - @Beta // TODO(kevinb): decide best return type - @CheckReturnValue - public static List getCausalChain(Throwable throwable) { - checkNotNull(throwable); - List causes = new ArrayList(4); - while (throwable != null) { - causes.add(throwable); - throwable = throwable.getCause(); - } - return Collections.unmodifiableList(causes); - } - - /** - * Returns a string containing the result of {@link Throwable#toString() toString()}, followed by - * the full, recursive stack trace of {@code throwable}. Note that you probably should not be - * parsing the resulting string; if you need programmatic access to the stack frames, you can call - * {@link Throwable#getStackTrace()}. - */ - @CheckReturnValue - public static String getStackTraceAsString(Throwable throwable) { - StringWriter stringWriter = new StringWriter(); - throwable.printStackTrace(new PrintWriter(stringWriter)); - return stringWriter.toString(); - } - - /** - * Returns the stack trace of {@code throwable}, possibly providing slower iteration over the full - * trace but faster iteration over parts of the trace. Here, "slower" and "faster" are defined in - * comparison to the normal way to access the stack trace, {@link Throwable#getStackTrace() - * throwable.getStackTrace()}. Note, however, that this method's special implementation is not - * available for all platforms and configurations. If that implementation is unavailable, this - * method falls back to {@code getStackTrace}. Callers that require the special implementation can - * check its availability with {@link #lazyStackTraceIsLazy()}. - * - *

The expected (but not guaranteed) performance of the special implementation differs from - * {@code getStackTrace} in one main way: The {@code lazyStackTrace} call itself returns quickly - * by delaying the per-stack-frame work until each element is accessed. Roughly speaking: - * - *

    - *
  • {@code getStackTrace} takes {@code stackSize} time to return but then negligible time to - * retrieve each element of the returned list. - *
  • {@code lazyStackTrace} takes negligible time to return but then {@code 1/stackSize} time to - * retrieve each element of the returned list (probably slightly more than {@code 1/stackSize}). - *
- * - *

Note: The special implementation does not respect calls to {@link Throwable#setStackTrace - * throwable.setStackTrace}. Instead, it always reflects the original stack trace from the - * exception's creation. - * - * @since 19.0 - */ - // TODO(cpovirk): Say something about the possibility that List access could fail at runtime? - @Beta - @CheckReturnValue - public static List lazyStackTrace(Throwable throwable) { - return lazyStackTraceIsLazy() - ? jlaStackTrace(throwable) - : unmodifiableList(asList(throwable.getStackTrace())); - } - - /** - * Returns whether {@link #lazyStackTrace} will use the special implementation described in its - * documentation. - * - * @since 19.0 - */ - @Beta - @CheckReturnValue - public static boolean lazyStackTraceIsLazy() { - return getStackTraceElementMethod != null & getStackTraceDepthMethod != null; - } - - private static List jlaStackTrace(final Throwable t) { - checkNotNull(t); - /* - * TODO(cpovirk): Consider optimizing iterator() to catch IOOBE instead of doing bounds checks. - * - * TODO(cpovirk): Consider the UnsignedBytes pattern if it performs faster and doesn't cause - * AOSP grief. - */ - return new AbstractList() { - @Override - public StackTraceElement get(int n) { - return (StackTraceElement) - invokeAccessibleNonThrowingMethod(getStackTraceElementMethod, jla, t, n); - } - - @Override - public int size() { - return (Integer) invokeAccessibleNonThrowingMethod(getStackTraceDepthMethod, jla, t); - } - }; - } - - private static Object invokeAccessibleNonThrowingMethod( - Method method, Object receiver, Object... params) { - try { - return method.invoke(receiver, params); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - throw propagate(e.getCause()); - } - } - - /** JavaLangAccess class name to load using reflection */ - private static final String JAVA_LANG_ACCESS_CLASSNAME = "sun.misc.JavaLangAccess"; - - /** SharedSecrets class name to load using reflection */ - @VisibleForTesting static final String SHARED_SECRETS_CLASSNAME = "sun.misc.SharedSecrets"; - - /** Access to some fancy internal JVM internals. */ - @Nullable private static final Object jla = getJLA(); - - /** - * The "getStackTraceElementMethod" method, only available on some JDKs so we use reflection to - * find it when available. When this is null, use the slow way. - */ - @Nullable - private static final Method getStackTraceElementMethod = (jla == null) ? null : getGetMethod(); - - /** - * The "getStackTraceDepth" method, only available on some JDKs so we use reflection to find it - * when available. When this is null, use the slow way. - */ - @Nullable - private static final Method getStackTraceDepthMethod = (jla == null) ? null : getSizeMethod(); - - /** - * Returns the JavaLangAccess class that is present in all Sun JDKs. It is not whitelisted for - * AppEngine, and not present in non-Sun JDKs. - */ - @Nullable - private static Object getJLA() { - try { - /* - * We load sun.misc.* classes using reflection since Android doesn't support these classes and - * would result in compilation failure if we directly refer to these classes. - */ - Class sharedSecrets = Class.forName(SHARED_SECRETS_CLASSNAME, false, null); - Method langAccess = sharedSecrets.getMethod("getJavaLangAccess"); - return langAccess.invoke(null); - } catch (ThreadDeath death) { - throw death; - } catch (Throwable t) { - /* - * This is not one of AppEngine's whitelisted classes, so even in Sun JDKs, this can fail with - * a NoClassDefFoundError. Other apps might deny access to sun.misc packages. - */ - return null; - } - } - - /** - * Returns the Method that can be used to resolve an individual StackTraceElement, or null if that - * method cannot be found (it is only to be found in fairly recent JDKs). - */ - @Nullable - private static Method getGetMethod() { - return getJlaMethod("getStackTraceElement", Throwable.class, int.class); - } - - /** - * Returns the Method that can be used to return the size of a stack, or null if that method - * cannot be found (it is only to be found in fairly recent JDKs). - */ - @Nullable - private static Method getSizeMethod() { - return getJlaMethod("getStackTraceDepth", Throwable.class); - } - - @Nullable - private static Method getJlaMethod(String name, Class... parameterTypes) throws ThreadDeath { - try { - return Class.forName(JAVA_LANG_ACCESS_CLASSNAME, false, null).getMethod(name, parameterTypes); - } catch (ThreadDeath death) { - throw death; - } catch (Throwable t) { - /* - * Either the JavaLangAccess class itself is not found, or the method is not supported on the - * JVM. - */ - return null; - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Ticker.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Ticker.java deleted file mode 100644 index 670163b04bd3..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Ticker.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import javax.annotation.CheckReturnValue; - -/** - * A time source; returns a time value representing the number of nanoseconds elapsed since some - * fixed but arbitrary point in time. Note that most users should use {@link Stopwatch} instead of - * interacting with this class directly. - * - *

Warning: this interface can only be used to measure elapsed time, not wall time. - * - * @author Kevin Bourrillion - * @since 10.0 - * (mostly source-compatible since 9.0) - */ -@Beta -@GwtCompatible -public abstract class Ticker { - /** - * Constructor for use by subclasses. - */ - protected Ticker() {} - - /** - * Returns the number of nanoseconds elapsed since this ticker's fixed - * point of reference. - */ - public abstract long read(); - - /** - * A ticker that reads the current time using {@link System#nanoTime}. - * - * @since 10.0 - */ - @CheckReturnValue - public static Ticker systemTicker() { - return SYSTEM_TICKER; - } - - private static final Ticker SYSTEM_TICKER = - new Ticker() { - @Override - public long read() { - return Platform.systemNanoTime(); - } - }; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Utf8.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Utf8.java deleted file mode 100644 index 106491e0aeee..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Utf8.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (C) 2013 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.base; - -import static com.google.common.base.Preconditions.checkPositionIndexes; -import static java.lang.Character.MAX_SURROGATE; -import static java.lang.Character.MIN_SURROGATE; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import javax.annotation.CheckReturnValue; - -/** - * Low-level, high-performance utility methods related to the {@linkplain Charsets#UTF_8 UTF-8} - * character encoding. UTF-8 is defined in section D92 of - * The Unicode Standard Core - * Specification, Chapter 3. - * - *

The variant of UTF-8 implemented by this class is the restricted definition of UTF-8 - * introduced in Unicode 3.1. One implication of this is that it rejects - * "non-shortest form" byte - * sequences, even though the JDK decoder may accept them. - * - * @author Martin Buchholz - * @author Clément Roux - * @since 16.0 - */ -@Beta -@GwtCompatible -public final class Utf8 { - /** - * Returns the number of bytes in the UTF-8-encoded form of {@code sequence}. For a string, - * this method is equivalent to {@code string.getBytes(UTF_8).length}, but is more efficient in - * both time and space. - * - * @throws IllegalArgumentException if {@code sequence} contains ill-formed UTF-16 (unpaired - * surrogates) - */ - @CheckReturnValue - public static int encodedLength(CharSequence sequence) { - // Warning to maintainers: this implementation is highly optimized. - int utf16Length = sequence.length(); - int utf8Length = utf16Length; - int i = 0; - - // This loop optimizes for pure ASCII. - while (i < utf16Length && sequence.charAt(i) < 0x80) { - i++; - } - - // This loop optimizes for chars less than 0x800. - for (; i < utf16Length; i++) { - char c = sequence.charAt(i); - if (c < 0x800) { - utf8Length += ((0x7f - c) >>> 31); // branch free! - } else { - utf8Length += encodedLengthGeneral(sequence, i); - break; - } - } - - if (utf8Length < utf16Length) { - // Necessary and sufficient condition for overflow because of maximum 3x expansion - throw new IllegalArgumentException( - "UTF-8 length does not fit in int: " + (utf8Length + (1L << 32))); - } - return utf8Length; - } - - private static int encodedLengthGeneral(CharSequence sequence, int start) { - int utf16Length = sequence.length(); - int utf8Length = 0; - for (int i = start; i < utf16Length; i++) { - char c = sequence.charAt(i); - if (c < 0x800) { - utf8Length += (0x7f - c) >>> 31; // branch free! - } else { - utf8Length += 2; - // jdk7+: if (Character.isSurrogate(c)) { - if (MIN_SURROGATE <= c && c <= MAX_SURROGATE) { - // Check that we have a well-formed surrogate pair. - if (Character.codePointAt(sequence, i) == c) { - throw new IllegalArgumentException(unpairedSurrogateMsg(i)); - } - i++; - } - } - } - return utf8Length; - } - - /** - * Returns {@code true} if {@code bytes} is a well-formed UTF-8 byte sequence according to - * Unicode 6.0. Note that this is a stronger criterion than simply whether the bytes can be - * decoded. For example, some versions of the JDK decoder will accept "non-shortest form" byte - * sequences, but encoding never reproduces these. Such byte sequences are not considered - * well-formed. - * - *

This method returns {@code true} if and only if {@code Arrays.equals(bytes, new - * String(bytes, UTF_8).getBytes(UTF_8))} does, but is more efficient in both time and space. - */ - @CheckReturnValue - public static boolean isWellFormed(byte[] bytes) { - return isWellFormed(bytes, 0, bytes.length); - } - - /** - * Returns whether the given byte array slice is a well-formed UTF-8 byte sequence, as defined by - * {@link #isWellFormed(byte[])}. Note that this can be false even when {@code - * isWellFormed(bytes)} is true. - * - * @param bytes the input buffer - * @param off the offset in the buffer of the first byte to read - * @param len the number of bytes to read from the buffer - */ - @CheckReturnValue - public static boolean isWellFormed(byte[] bytes, int off, int len) { - int end = off + len; - checkPositionIndexes(off, end, bytes.length); - // Look for the first non-ASCII character. - for (int i = off; i < end; i++) { - if (bytes[i] < 0) { - return isWellFormedSlowPath(bytes, i, end); - } - } - return true; - } - - private static boolean isWellFormedSlowPath(byte[] bytes, int off, int end) { - int index = off; - while (true) { - int byte1; - - // Optimize for interior runs of ASCII bytes. - do { - if (index >= end) { - return true; - } - } while ((byte1 = bytes[index++]) >= 0); - - if (byte1 < (byte) 0xE0) { - // Two-byte form. - if (index == end) { - return false; - } - // Simultaneously check for illegal trailing-byte in leading position - // and overlong 2-byte form. - if (byte1 < (byte) 0xC2 || bytes[index++] > (byte) 0xBF) { - return false; - } - } else if (byte1 < (byte) 0xF0) { - // Three-byte form. - if (index + 1 >= end) { - return false; - } - int byte2 = bytes[index++]; - if (byte2 > (byte) 0xBF - // Overlong? 5 most significant bits must not all be zero. - || (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0) - // Check for illegal surrogate codepoints. - || (byte1 == (byte) 0xED && (byte) 0xA0 <= byte2) - // Third byte trailing-byte test. - || bytes[index++] > (byte) 0xBF) { - return false; - } - } else { - // Four-byte form. - if (index + 2 >= end) { - return false; - } - int byte2 = bytes[index++]; - if (byte2 > (byte) 0xBF - // Check that 1 <= plane <= 16. Tricky optimized form of: - // if (byte1 > (byte) 0xF4 - // || byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 - // || byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F) - || (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0 - // Third byte trailing-byte test - || bytes[index++] > (byte) 0xBF - // Fourth byte trailing-byte test - || bytes[index++] > (byte) 0xBF) { - return false; - } - } - } - } - - private static String unpairedSurrogateMsg(int i) { - return "Unpaired surrogate at index " + i; - } - - private Utf8() {} -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/Verify.java b/thirdparty/google-guava/src/main/java/com/google/common/base/Verify.java deleted file mode 100644 index f6d77b4a79ec..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/Verify.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2013 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.base; - -import static com.google.common.base.Preconditions.format; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import javax.annotation.Nullable; - -/** - * Static convenience methods that serve the same purpose as Java language - * - * assertions, except that they are always enabled. These methods should be used instead of Java - * assertions whenever there is a chance the check may fail "in real life". Example:

   {@code
- *
- *   Bill bill = remoteService.getLastUnpaidBill();
- *
- *   // In case bug 12345 happens again we'd rather just die
- *   Verify.verify(bill.status() == Status.UNPAID,
- *       "Unexpected bill status: %s", bill.status());}
- * - *

Comparison to alternatives

- * - *

Note: In some cases the differences explained below can be subtle. When it's unclear - * which approach to use, don't worry too much about it; just pick something that seems - * reasonable and it will be fine. - * - *

    - *
  • If checking whether the caller has violated your method or constructor's contract - * (such as by passing an invalid argument), use the utilities of the {@link Preconditions} - * class instead. - * - *
  • If checking an impossible condition (which cannot happen unless your own class - * or its trusted dependencies is badly broken), this is what ordinary Java assertions - * are for. Note that assertions are not enabled by default; they are essentially considered - * "compiled comments." - * - *
  • An explicit {@code if/throw} (as illustrated below) is always acceptable; we still recommend - * using our {@link VerifyException} exception type. Throwing a plain {@link RuntimeException} - * is frowned upon. - * - *
  • Use of {@link java.util.Objects#requireNonNull(Object)} is generally discouraged, since - * {@link #verifyNotNull(Object)} and {@link Preconditions#checkNotNull(Object)} perform the - * same function with more clarity. - *
- * - *

Warning about performance

- * - *

Remember that parameter values for message construction must all be computed eagerly, and - * autoboxing and varargs array creation may happen as well, even when the verification succeeds and - * the message ends up unneeded. Performance-sensitive verification checks should continue to use - * usual form:

   {@code
- *
- *   Bill bill = remoteService.getLastUnpaidBill();
- *   if (bill.status() != Status.UNPAID) {
- *     throw new VerifyException("Unexpected bill status: " + bill.status());
- *   }}
- * - *

Only {@code %s} is supported

- * - *

As with {@link Preconditions} error message template strings, only the {@code "%s"} specifier - * is supported, not the full range of {@link java.util.Formatter} specifiers. However, note that - * if the number of arguments does not match the number of occurrences of {@code "%s"} in the - * format string, {@code Verify} will still behave as expected, and will still include all argument - * values in the error message; the message will simply not be formatted exactly as intended. - * - *

More information

- * - * See - * Conditional - * failures explained in the Guava User Guide for advice on when this class should be used. - * - * @since 17.0 - */ -@Beta -@GwtCompatible -public final class Verify { - /** - * Ensures that {@code expression} is {@code true}, throwing a {@code VerifyException} with no - * message otherwise. - * - * @throws VerifyException if {@code expression} is {@code false} - */ - public static void verify(boolean expression) { - if (!expression) { - throw new VerifyException(); - } - } - - /** - * Ensures that {@code expression} is {@code true}, throwing a {@code VerifyException} with a - * custom message otherwise. - * - * @param expression a boolean expression - * @param errorMessageTemplate a template for the exception message should the - * check fail. The message is formed by replacing each {@code %s} - * placeholder in the template with an argument. These are matched by - * position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc. - * Unmatched arguments will be appended to the formatted message in square - * braces. Unmatched placeholders will be left as-is. - * @param errorMessageArgs the arguments to be substituted into the message - * template. Arguments are converted to strings using - * {@link String#valueOf(Object)}. - * @throws VerifyException if {@code expression} is {@code false} - */ - public static void verify( - boolean expression, - @Nullable String errorMessageTemplate, - @Nullable Object... errorMessageArgs) { - if (!expression) { - throw new VerifyException(format(errorMessageTemplate, errorMessageArgs)); - } - } - - /** - * Ensures that {@code reference} is non-null, throwing a {@code VerifyException} with a default - * message otherwise. - * - * @return {@code reference}, guaranteed to be non-null, for convenience - * @throws VerifyException if {@code reference} is {@code null} - */ - public static T verifyNotNull(@Nullable T reference) { - return verifyNotNull(reference, "expected a non-null reference"); - } - - /** - * Ensures that {@code reference} is non-null, throwing a {@code VerifyException} with a custom - * message otherwise. - * - * @param errorMessageTemplate a template for the exception message should the - * check fail. The message is formed by replacing each {@code %s} - * placeholder in the template with an argument. These are matched by - * position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc. - * Unmatched arguments will be appended to the formatted message in square - * braces. Unmatched placeholders will be left as-is. - * @param errorMessageArgs the arguments to be substituted into the message - * template. Arguments are converted to strings using - * {@link String#valueOf(Object)}. - * @return {@code reference}, guaranteed to be non-null, for convenience - * @throws VerifyException if {@code reference} is {@code null} - */ - public static T verifyNotNull( - @Nullable T reference, - @Nullable String errorMessageTemplate, - @Nullable Object... errorMessageArgs) { - verify(reference != null, errorMessageTemplate, errorMessageArgs); - return reference; - } - - // TODO(kevinb): consider T verifySingleton(Iterable) to take over for - // Iterables.getOnlyElement() - - private Verify() {} -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/VerifyException.java b/thirdparty/google-guava/src/main/java/com/google/common/base/VerifyException.java deleted file mode 100644 index bbcacd7fda3f..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/VerifyException.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2013 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.base; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import javax.annotation.Nullable; - -/** - * Exception thrown upon the failure of a - * verification - * check, including those performed by the convenience methods of the {@link Verify} class. - * - * @since 17.0 - */ -@Beta -@GwtCompatible -public class VerifyException extends RuntimeException { - /** Constructs a {@code VerifyException} with no message. */ - public VerifyException() {} - - /** Constructs a {@code VerifyException} with the message {@code message}. */ - public VerifyException(@Nullable String message) { - super(message); - } - - /** - * Constructs a {@code VerifyException} with the cause {@code cause} and a message that is - * {@code null} if {@code cause} is null, and {@code cause.toString()} otherwise. - * - * @since 19.0 - */ - public VerifyException(@Nullable Throwable cause) { - super(cause); - } - - /** - * Constructs a {@code VerifyException} with the message {@code message} and the cause - * {@code cause}. - * - * @since 19.0 - */ - public VerifyException(@Nullable String message, @Nullable Throwable cause) { - super(message, cause); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/internal/Finalizer.java b/thirdparty/google-guava/src/main/java/com/google/common/base/internal/Finalizer.java deleted file mode 100644 index 4b0b7d7d71a6..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/internal/Finalizer.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base.internal; - -import java.lang.ref.PhantomReference; -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import com.google.common.logging.Level; -import com.google.common.logging.Logger; - -/** - * Thread that finalizes referents. All references should implement - * {@code com.google.common.base.FinalizableReference}. - * - *

While this class is public, we consider it to be *internal* and not part - * of our published API. It is public so we can access it reflectively across - * class loaders in secure environments. - * - *

This class can't depend on other Guava code. If we were - * to load this class in the same class loader as the rest of - * Guava, this thread would keep an indirect strong reference - * to the class loader and prevent it from being garbage collected. This - * poses a problem for environments where you want to throw away the class - * loader. For example, dynamically reloading a web application or unloading - * an OSGi bundle. - * - *

{@code com.google.common.base.FinalizableReferenceQueue} loads this class - * in its own class loader. That way, this class doesn't prevent the main - * class loader from getting garbage collected, and this class can detect when - * the main class loader has been garbage collected and stop itself. - */ -public class Finalizer implements Runnable { - - private static final Logger logger = Logger.getLogger(Finalizer.class.getName()); - - /** Name of FinalizableReference.class. */ - private static final String FINALIZABLE_REFERENCE = "com.google.common.base.FinalizableReference"; - - /** - * Starts the Finalizer thread. FinalizableReferenceQueue calls this method - * reflectively. - * - * @param finalizableReferenceClass FinalizableReference.class. - * @param queue a reference queue that the thread will poll. - * @param frqReference a phantom reference to the FinalizableReferenceQueue, which will be - * queued either when the FinalizableReferenceQueue is no longer referenced anywhere, or when - * its close() method is called. - */ - public static void startFinalizer( - Class finalizableReferenceClass, - ReferenceQueue queue, - PhantomReference frqReference) { - /* - * We use FinalizableReference.class for two things: - * - * 1) To invoke FinalizableReference.finalizeReferent() - * - * 2) To detect when FinalizableReference's class loader has to be garbage - * collected, at which point, Finalizer can stop running - */ - if (!finalizableReferenceClass.getName().equals(FINALIZABLE_REFERENCE)) { - throw new IllegalArgumentException("Expected " + FINALIZABLE_REFERENCE + "."); - } - - Finalizer finalizer = new Finalizer(finalizableReferenceClass, queue, frqReference); - Thread thread = new Thread(finalizer); - thread.setName(Finalizer.class.getName()); - thread.setDaemon(true); - - try { - if (inheritableThreadLocals != null) { - inheritableThreadLocals.set(thread, null); - } - } catch (Throwable t) { - logger.log( - Level.INFO, - "Failed to clear thread local values inherited by reference finalizer thread.", - t); - } - - thread.start(); - } - - private final WeakReference> finalizableReferenceClassReference; - private final PhantomReference frqReference; - private final ReferenceQueue queue; - - private static final Field inheritableThreadLocals = getInheritableThreadLocalsField(); - - /** Constructs a new finalizer thread. */ - private Finalizer( - Class finalizableReferenceClass, - ReferenceQueue queue, - PhantomReference frqReference) { - this.queue = queue; - - this.finalizableReferenceClassReference = - new WeakReference>(finalizableReferenceClass); - - // Keep track of the FRQ that started us so we know when to stop. - this.frqReference = frqReference; - } - - /** - * Loops continuously, pulling references off the queue and cleaning them up. - */ - @SuppressWarnings("InfiniteLoopStatement") - @Override - public void run() { - while (true) { - try { - if (!cleanUp(queue.remove())) { - break; - } - } catch (InterruptedException e) { - // ignore - } - } - } - - /** - * Cleans up a single reference. Catches and logs all throwables. - * @return true if the caller should continue, false if the associated FinalizableReferenceQueue - * is no longer referenced. - */ - private boolean cleanUp(Reference reference) { - Method finalizeReferentMethod = getFinalizeReferentMethod(); - if (finalizeReferentMethod == null) { - return false; - } - do { - /* - * This is for the benefit of phantom references. Weak and soft - * references will have already been cleared by this point. - */ - reference.clear(); - - if (reference == frqReference) { - /* - * The client no longer has a reference to the - * FinalizableReferenceQueue. We can stop. - */ - return false; - } - - try { - finalizeReferentMethod.invoke(reference); - } catch (Throwable t) { - logger.log(Level.SEVERE, "Error cleaning up after reference.", t); - } - - /* - * Loop as long as we have references available so as not to waste - * CPU looking up the Method over and over again. - */ - } while ((reference = queue.poll()) != null); - return true; - } - - /** - * Looks up FinalizableReference.finalizeReferent() method. - */ - private Method getFinalizeReferentMethod() { - Class finalizableReferenceClass = finalizableReferenceClassReference.get(); - if (finalizableReferenceClass == null) { - /* - * FinalizableReference's class loader was reclaimed. While there's a - * chance that other finalizable references could be enqueued - * subsequently (at which point the class loader would be resurrected - * by virtue of us having a strong reference to it), we should pretty - * much just shut down and make sure we don't keep it alive any longer - * than necessary. - */ - return null; - } - try { - return finalizableReferenceClass.getMethod("finalizeReferent"); - } catch (NoSuchMethodException e) { - throw new AssertionError(e); - } - } - - public static Field getInheritableThreadLocalsField() { - try { - Field inheritableThreadLocals = Thread.class.getDeclaredField("inheritableThreadLocals"); - inheritableThreadLocals.setAccessible(true); - return inheritableThreadLocals; - } catch (Throwable t) { - logger.log( - Level.INFO, - "Couldn't access Thread.inheritableThreadLocals. Reference finalizer threads will " - + "inherit thread local values."); - return null; - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/base/package-info.java b/thirdparty/google-guava/src/main/java/com/google/common/base/package-info.java deleted file mode 100644 index 38f8f7ad2741..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/base/package-info.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Basic utility libraries and interfaces. - * - *

This package is a part of the open-source - * Guava libraries. - * - *

Contents

- * - *

String-related utilities

- * - *
    - *
  • {@link com.google.common.base.Ascii} - *
  • {@link com.google.common.base.CaseFormat} - *
  • {@link com.google.common.base.CharMatcher} - *
  • {@link com.google.common.base.Charsets} - *
  • {@link com.google.common.base.Joiner} - *
  • {@link com.google.common.base.Splitter} - *
  • {@link com.google.common.base.Strings} - *
- * - *

Function types

- * - *
    - *
  • {@link com.google.common.base.Function}, - * {@link com.google.common.base.Functions} - *
  • {@link com.google.common.base.Predicate}, - * {@link com.google.common.base.Predicates} - *
  • {@link com.google.common.base.Equivalence} - *
  • {@link com.google.common.base.Converter} - *
  • {@link com.google.common.base.Supplier}, - * {@link com.google.common.base.Suppliers} - *
- * - *

Other

- * - *
    - *
  • {@link com.google.common.base.Defaults} - *
  • {@link com.google.common.base.Enums} - *
  • {@link com.google.common.base.Objects} - *
  • {@link com.google.common.base.Optional} - *
  • {@link com.google.common.base.Preconditions} - *
  • {@link com.google.common.base.Stopwatch} - *
  • {@link com.google.common.base.Throwables} - *
- * - */ -@ParametersAreNonnullByDefault -package com.google.common.base; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/thirdparty/google-guava/src/main/java/com/google/common/cache/AbstractCache.java b/thirdparty/google-guava/src/main/java/com/google/common/cache/AbstractCache.java deleted file mode 100644 index 7506cdbed4d1..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/cache/AbstractCache.java +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.cache; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; - -import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ExecutionException; - -/** - * This class provides a skeletal implementation of the {@code Cache} interface to minimize the - * effort required to implement this interface. - * - *

To implement a cache, the programmer needs only to extend this class and provide an - * implementation for the {@link #put} and {@link #getIfPresent} methods. {@link #getAllPresent} is - * implemented in terms of {@link #getIfPresent}; {@link #putAll} is implemented in terms of - * {@link #put}, {@link #invalidateAll(Iterable)} is implemented in terms of {@link #invalidate}. - * The method {@link #cleanUp} is a no-op. All other methods throw an - * {@link UnsupportedOperationException}. - * - * @author Charles Fry - * @since 10.0 - */ -@GwtCompatible -public abstract class AbstractCache implements Cache { - - /** Constructor for use by subclasses. */ - protected AbstractCache() {} - - /** - * @since 11.0 - */ - @Override - public V get(K key, Callable valueLoader) throws ExecutionException { - throw new UnsupportedOperationException(); - } - - /** - * This implementation of {@code getAllPresent} lacks any insight into the internal cache data - * structure, and is thus forced to return the query keys instead of the cached keys. This is only - * possible with an unsafe cast which requires {@code keys} to actually be of type {@code K}. - * - * {@inheritDoc} - * - * @since 11.0 - */ - @Override - public ImmutableMap getAllPresent(Iterable keys) { - Map result = Maps.newLinkedHashMap(); - for (Object key : keys) { - if (!result.containsKey(key)) { - @SuppressWarnings("unchecked") - K castKey = (K) key; - V value = getIfPresent(key); - if (value != null) { - result.put(castKey, value); - } - } - } - return ImmutableMap.copyOf(result); - } - - /** - * @since 11.0 - */ - @Override - public void put(K key, V value) { - throw new UnsupportedOperationException(); - } - - /** - * @since 12.0 - */ - @Override - public void putAll(Map m) { - for (Map.Entry entry : m.entrySet()) { - put(entry.getKey(), entry.getValue()); - } - } - - @Override - public void cleanUp() {} - - @Override - public long size() { - throw new UnsupportedOperationException(); - } - - @Override - public void invalidate(Object key) { - throw new UnsupportedOperationException(); - } - - /** - * @since 11.0 - */ - @Override - public void invalidateAll(Iterable keys) { - for (Object key : keys) { - invalidate(key); - } - } - - @Override - public void invalidateAll() { - throw new UnsupportedOperationException(); - } - - @Override - public CacheStats stats() { - throw new UnsupportedOperationException(); - } - - @Override - public ConcurrentMap asMap() { - throw new UnsupportedOperationException(); - } - - /** - * Accumulates statistics during the operation of a {@link Cache} for presentation by {@link - * Cache#stats}. This is solely intended for consumption by {@code Cache} implementors. - * - * @since 10.0 - */ - public interface StatsCounter { - /** - * Records cache hits. This should be called when a cache request returns a cached value. - * - * @param count the number of hits to record - * @since 11.0 - */ - void recordHits(int count); - - /** - * Records cache misses. This should be called when a cache request returns a value that was - * not found in the cache. This method should be called by the loading thread, as well as by - * threads blocking on the load. Multiple concurrent calls to {@link Cache} lookup methods with - * the same key on an absent value should result in a single call to either - * {@code recordLoadSuccess} or {@code recordLoadException} and multiple calls to this method, - * despite all being served by the results of a single load operation. - * - * @param count the number of misses to record - * @since 11.0 - */ - void recordMisses(int count); - - /** - * Records the successful load of a new entry. This should be called when a cache request - * causes an entry to be loaded, and the loading completes successfully. In contrast to - * {@link #recordMisses}, this method should only be called by the loading thread. - * - * @param loadTime the number of nanoseconds the cache spent computing or retrieving the new - * value - */ - void recordLoadSuccess(long loadTime); - - /** - * Records the failed load of a new entry. This should be called when a cache request causes - * an entry to be loaded, but an exception is thrown while loading the entry. In contrast to - * {@link #recordMisses}, this method should only be called by the loading thread. - * - * @param loadTime the number of nanoseconds the cache spent computing or retrieving the new - * value prior to an exception being thrown - */ - void recordLoadException(long loadTime); - - /** - * Records the eviction of an entry from the cache. This should only been called when an entry - * is evicted due to the cache's eviction strategy, and not as a result of manual {@linkplain - * Cache#invalidate invalidations}. - */ - void recordEviction(); - - /** - * Returns a snapshot of this counter's values. Note that this may be an inconsistent view, as - * it may be interleaved with update operations. - */ - CacheStats snapshot(); - } - - /** - * A thread-safe {@link StatsCounter} implementation for use by {@link Cache} implementors. - * - * @since 10.0 - */ - public static final class SimpleStatsCounter implements StatsCounter { - private final LongAddable hitCount = LongAddables.create(); - private final LongAddable missCount = LongAddables.create(); - private final LongAddable loadSuccessCount = LongAddables.create(); - private final LongAddable loadExceptionCount = LongAddables.create(); - private final LongAddable totalLoadTime = LongAddables.create(); - private final LongAddable evictionCount = LongAddables.create(); - - /** - * Constructs an instance with all counts initialized to zero. - */ - public SimpleStatsCounter() {} - - /** - * @since 11.0 - */ - @Override - public void recordHits(int count) { - hitCount.add(count); - } - - /** - * @since 11.0 - */ - @Override - public void recordMisses(int count) { - missCount.add(count); - } - - @Override - public void recordLoadSuccess(long loadTime) { - loadSuccessCount.increment(); - totalLoadTime.add(loadTime); - } - - @Override - public void recordLoadException(long loadTime) { - loadExceptionCount.increment(); - totalLoadTime.add(loadTime); - } - - @Override - public void recordEviction() { - evictionCount.increment(); - } - - @Override - public CacheStats snapshot() { - return new CacheStats( - hitCount.sum(), - missCount.sum(), - loadSuccessCount.sum(), - loadExceptionCount.sum(), - totalLoadTime.sum(), - evictionCount.sum()); - } - - /** - * Increments all counters by the values in {@code other}. - */ - public void incrementBy(StatsCounter other) { - CacheStats otherStats = other.snapshot(); - hitCount.add(otherStats.hitCount()); - missCount.add(otherStats.missCount()); - loadSuccessCount.add(otherStats.loadSuccessCount()); - loadExceptionCount.add(otherStats.loadExceptionCount()); - totalLoadTime.add(otherStats.totalLoadTime()); - evictionCount.add(otherStats.evictionCount()); - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/cache/AbstractLoadingCache.java b/thirdparty/google-guava/src/main/java/com/google/common/cache/AbstractLoadingCache.java deleted file mode 100644 index ded9f7b985c8..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/cache/AbstractLoadingCache.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.cache; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; -import com.google.common.util.concurrent.UncheckedExecutionException; - -import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; - -/** - * This class provides a skeletal implementation of the {@code Cache} interface to minimize the - * effort required to implement this interface. - * - *

To implement a cache, the programmer needs only to extend this class and provide an - * implementation for the {@link #get(Object)} and {@link #getIfPresent} methods. - * {@link #getUnchecked}, {@link #get(Object, Callable)}, and {@link #getAll} are implemented in - * terms of {@code get}; {@link #getAllPresent} is implemented in terms of {@code getIfPresent}; - * {@link #putAll} is implemented in terms of {@link #put}, {@link #invalidateAll(Iterable)} is - * implemented in terms of {@link #invalidate}. The method {@link #cleanUp} is a no-op. All other - * methods throw an {@link UnsupportedOperationException}. - * - * @author Charles Fry - * @since 11.0 - */ -public abstract class AbstractLoadingCache - extends AbstractCache implements LoadingCache { - - /** Constructor for use by subclasses. */ - protected AbstractLoadingCache() {} - - @Override - public V getUnchecked(K key) { - try { - return get(key); - } catch (ExecutionException e) { - throw new UncheckedExecutionException(e.getCause()); - } - } - - @Override - public ImmutableMap getAll(Iterable keys) throws ExecutionException { - Map result = Maps.newLinkedHashMap(); - for (K key : keys) { - if (!result.containsKey(key)) { - result.put(key, get(key)); - } - } - return ImmutableMap.copyOf(result); - } - - @Override - public final V apply(K key) { - return getUnchecked(key); - } - - @Override - public void refresh(K key) { - throw new UnsupportedOperationException(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/cache/Cache.java b/thirdparty/google-guava/src/main/java/com/google/common/cache/Cache.java deleted file mode 100644 index 344821cfbff9..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/cache/Cache.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.cache; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.collect.ImmutableMap; -import com.google.common.util.concurrent.ExecutionError; -import com.google.common.util.concurrent.UncheckedExecutionException; - -import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ExecutionException; - -import javax.annotation.Nullable; - -/** - * A semi-persistent mapping from keys to values. Cache entries are manually added using - * {@link #get(Object, Callable)} or {@link #put(Object, Object)}, and are stored in the cache until - * either evicted or manually invalidated. - * - *

Implementations of this interface are expected to be thread-safe, and can be safely accessed - * by multiple concurrent threads. - * - * @author Charles Fry - * @since 10.0 - */ -@GwtCompatible -public interface Cache { - - /** - * Returns the value associated with {@code key} in this cache, or {@code null} if there is no - * cached value for {@code key}. - * - * @since 11.0 - */ - @Nullable - V getIfPresent(Object key); - - /** - * Returns the value associated with {@code key} in this cache, obtaining that value from - * {@code valueLoader} if necessary. No observable state associated with this cache is modified - * until loading completes. This method provides a simple substitute for the conventional - * "if cached, return; otherwise create, cache and return" pattern. - * - *

Warning: as with {@link CacheLoader#load}, {@code valueLoader} must not return - * {@code null}; it may either return a non-null value or throw an exception. - * - * @throws ExecutionException if a checked exception was thrown while loading the value - * @throws UncheckedExecutionException if an unchecked exception was thrown while loading the - * value - * @throws ExecutionError if an error was thrown while loading the value - * - * @since 11.0 - */ - V get(K key, Callable valueLoader) throws ExecutionException; - - /** - * Returns a map of the values associated with {@code keys} in this cache. The returned map will - * only contain entries which are already present in the cache. - * - * @since 11.0 - */ - ImmutableMap getAllPresent(Iterable keys); - - /** - * Associates {@code value} with {@code key} in this cache. If the cache previously contained a - * value associated with {@code key}, the old value is replaced by {@code value}. - * - *

Prefer {@link #get(Object, Callable)} when using the conventional "if cached, return; - * otherwise create, cache and return" pattern. - * - * @since 11.0 - */ - void put(K key, V value); - - /** - * Copies all of the mappings from the specified map to the cache. The effect of this call is - * equivalent to that of calling {@code put(k, v)} on this map once for each mapping from key - * {@code k} to value {@code v} in the specified map. The behavior of this operation is undefined - * if the specified map is modified while the operation is in progress. - * - * @since 12.0 - */ - void putAll(Map m); - - /** - * Discards any cached value for key {@code key}. - */ - void invalidate(Object key); - - /** - * Discards any cached values for keys {@code keys}. - * - * @since 11.0 - */ - void invalidateAll(Iterable keys); - - /** - * Discards all entries in the cache. - */ - void invalidateAll(); - - /** - * Returns the approximate number of entries in this cache. - */ - long size(); - - /** - * Returns a current snapshot of this cache's cumulative statistics. All stats are initialized - * to zero, and are monotonically increasing over the lifetime of the cache. - * - */ - CacheStats stats(); - - /** - * Returns a view of the entries stored in this cache as a thread-safe map. Modifications made to - * the map directly affect the cache. - * - *

Iterators from the returned map are at least weakly consistent: they are safe for - * concurrent use, but if the cache is modified (including by eviction) after the iterator is - * created, it is undefined which of the changes (if any) will be reflected in that iterator. - */ - ConcurrentMap asMap(); - - /** - * Performs any pending maintenance operations needed by the cache. Exactly which activities are - * performed -- if any -- is implementation-dependent. - */ - void cleanUp(); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/cache/CacheBuilder.java b/thirdparty/google-guava/src/main/java/com/google/common/cache/CacheBuilder.java deleted file mode 100644 index 04fc46b5ea73..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/cache/CacheBuilder.java +++ /dev/null @@ -1,867 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.cache; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.base.Ascii; -import com.google.common.base.Equivalence; -import com.google.common.base.MoreObjects; -import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; -import com.google.common.base.Ticker; -import com.google.common.cache.AbstractCache.SimpleStatsCounter; -import com.google.common.cache.AbstractCache.StatsCounter; -import com.google.common.cache.LocalCache.Strength; - -import java.lang.ref.SoftReference; -import java.lang.ref.WeakReference; -import java.util.ConcurrentModificationException; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; -import com.google.common.logging.Level; -import com.google.common.logging.Logger; - -import javax.annotation.CheckReturnValue; - -/** - *

A builder of {@link LoadingCache} and {@link Cache} instances having any combination of the - * following features: - * - *

    - *
  • automatic loading of entries into the cache - *
  • least-recently-used eviction when a maximum size is exceeded - *
  • time-based expiration of entries, measured since last access or last write - *
  • keys automatically wrapped in {@linkplain WeakReference weak} references - *
  • values automatically wrapped in {@linkplain WeakReference weak} or - * {@linkplain SoftReference soft} references - *
  • notification of evicted (or otherwise removed) entries - *
  • accumulation of cache access statistics - *
- * - * - *

These features are all optional; caches can be created using all or none of them. By default - * cache instances created by {@code CacheBuilder} will not perform any type of eviction. - * - *

Usage example:

   {@code
- *
- *   LoadingCache graphs = CacheBuilder.newBuilder()
- *       .maximumSize(10000)
- *       .expireAfterWrite(10, TimeUnit.MINUTES)
- *       .removalListener(MY_LISTENER)
- *       .build(
- *           new CacheLoader() {
- *             public Graph load(Key key) throws AnyException {
- *               return createExpensiveGraph(key);
- *             }
- *           });}
- * - *

Or equivalently,

   {@code
- *
- *   // In real life this would come from a command-line flag or config file
- *   String spec = "maximumSize=10000,expireAfterWrite=10m";
- *
- *   LoadingCache graphs = CacheBuilder.from(spec)
- *       .removalListener(MY_LISTENER)
- *       .build(
- *           new CacheLoader() {
- *             public Graph load(Key key) throws AnyException {
- *               return createExpensiveGraph(key);
- *             }
- *           });}
- * - *

The returned cache is implemented as a hash table with similar performance characteristics to - * {@link ConcurrentHashMap}. It implements all optional operations of the {@link LoadingCache} and - * {@link Cache} interfaces. The {@code asMap} view (and its collection views) have weakly - * consistent iterators. This means that they are safe for concurrent use, but if other threads - * modify the cache after the iterator is created, it is undefined which of these changes, if any, - * are reflected in that iterator. These iterators never throw {@link - * ConcurrentModificationException}. - * - *

Note: by default, the returned cache uses equality comparisons (the - * {@link Object#equals equals} method) to determine equality for keys or values. However, if - * {@link #weakKeys} was specified, the cache uses identity ({@code ==}) - * comparisons instead for keys. Likewise, if {@link #weakValues} or {@link #softValues} was - * specified, the cache uses identity comparisons for values. - * - *

Entries are automatically evicted from the cache when any of - * {@linkplain #maximumSize(long) maximumSize}, {@linkplain #maximumWeight(long) maximumWeight}, - * {@linkplain #expireAfterWrite expireAfterWrite}, - * {@linkplain #expireAfterAccess expireAfterAccess}, {@linkplain #weakKeys weakKeys}, - * {@linkplain #weakValues weakValues}, or {@linkplain #softValues softValues} are requested. - * - *

If {@linkplain #maximumSize(long) maximumSize} or - * {@linkplain #maximumWeight(long) maximumWeight} is requested entries may be evicted on each cache - * modification. - * - *

If {@linkplain #expireAfterWrite expireAfterWrite} or - * {@linkplain #expireAfterAccess expireAfterAccess} is requested entries may be evicted on each - * cache modification, on occasional cache accesses, or on calls to {@link Cache#cleanUp}. Expired - * entries may be counted by {@link Cache#size}, but will never be visible to read or write - * operations. - * - *

If {@linkplain #weakKeys weakKeys}, {@linkplain #weakValues weakValues}, or - * {@linkplain #softValues softValues} are requested, it is possible for a key or value present in - * the cache to be reclaimed by the garbage collector. Entries with reclaimed keys or values may be - * removed from the cache on each cache modification, on occasional cache accesses, or on calls to - * {@link Cache#cleanUp}; such entries may be counted in {@link Cache#size}, but will never be - * visible to read or write operations. - * - *

Certain cache configurations will result in the accrual of periodic maintenance tasks which - * will be performed during write operations, or during occasional read operations in the absence of - * writes. The {@link Cache#cleanUp} method of the returned cache will also perform maintenance, but - * calling it should not be necessary with a high throughput cache. Only caches built with - * {@linkplain #removalListener removalListener}, {@linkplain #expireAfterWrite expireAfterWrite}, - * {@linkplain #expireAfterAccess expireAfterAccess}, {@linkplain #weakKeys weakKeys}, - * {@linkplain #weakValues weakValues}, or {@linkplain #softValues softValues} perform periodic - * maintenance. - * - *

The caches produced by {@code CacheBuilder} are serializable, and the deserialized caches - * retain all the configuration properties of the original cache. Note that the serialized form does - * not include cache contents, but only configuration. - * - *

See the Guava User Guide article on caching for a higher-level - * explanation. - * - * @param the base key type for all caches created by this builder - * @param the base value type for all caches created by this builder - * @author Charles Fry - * @author Kevin Bourrillion - * @since 10.0 - */ -@GwtCompatible(emulated = true) -public final class CacheBuilder { - private static final int DEFAULT_INITIAL_CAPACITY = 16; - private static final int DEFAULT_CONCURRENCY_LEVEL = 4; - private static final int DEFAULT_EXPIRATION_NANOS = 0; - private static final int DEFAULT_REFRESH_NANOS = 0; - - static final Supplier NULL_STATS_COUNTER = Suppliers.ofInstance( - new StatsCounter() { - @Override - public void recordHits(int count) {} - - @Override - public void recordMisses(int count) {} - - @Override - public void recordLoadSuccess(long loadTime) {} - - @Override - public void recordLoadException(long loadTime) {} - - @Override - public void recordEviction() {} - - @Override - public CacheStats snapshot() { - return EMPTY_STATS; - } - }); - static final CacheStats EMPTY_STATS = new CacheStats(0, 0, 0, 0, 0, 0); - - static final Supplier CACHE_STATS_COUNTER = - new Supplier() { - @Override - public StatsCounter get() { - return new SimpleStatsCounter(); - } - }; - - enum NullListener implements RemovalListener { - INSTANCE; - - @Override - public void onRemoval(RemovalNotification notification) {} - } - - enum OneWeigher implements Weigher { - INSTANCE; - - @Override - public int weigh(Object key, Object value) { - return 1; - } - } - - static final Ticker NULL_TICKER = new Ticker() { - @Override - public long read() { - return 0; - } - }; - - private static final Logger logger = Logger.getLogger(CacheBuilder.class.getName()); - - static final int UNSET_INT = -1; - - boolean strictParsing = true; - - int initialCapacity = UNSET_INT; - int concurrencyLevel = UNSET_INT; - long maximumSize = UNSET_INT; - long maximumWeight = UNSET_INT; - Weigher weigher; - - Strength keyStrength; - Strength valueStrength; - - long expireAfterWriteNanos = UNSET_INT; - long expireAfterAccessNanos = UNSET_INT; - long refreshNanos = UNSET_INT; - - Equivalence keyEquivalence; - Equivalence valueEquivalence; - - RemovalListener removalListener; - Ticker ticker; - - Supplier statsCounterSupplier = NULL_STATS_COUNTER; - - // TODO(fry): make constructor private and update tests to use newBuilder - CacheBuilder() {} - - /** - * Constructs a new {@code CacheBuilder} instance with default settings, including strong keys, - * strong values, and no automatic eviction of any kind. - */ - public static CacheBuilder newBuilder() { - return new CacheBuilder(); - } - - /** - * Constructs a new {@code CacheBuilder} instance with the settings specified in {@code spec}. - * - * @since 12.0 - */ - @GwtIncompatible("To be supported") - public static CacheBuilder from(CacheBuilderSpec spec) { - return spec.toCacheBuilder() - .lenientParsing(); - } - - /** - * Constructs a new {@code CacheBuilder} instance with the settings specified in {@code spec}. - * This is especially useful for command-line configuration of a {@code CacheBuilder}. - * - * @param spec a String in the format specified by {@link CacheBuilderSpec} - * @since 12.0 - */ - @GwtIncompatible("To be supported") - public static CacheBuilder from(String spec) { - return from(CacheBuilderSpec.parse(spec)); - } - - /** - * Enables lenient parsing. Useful for tests and spec parsing. - */ - @GwtIncompatible("To be supported") - CacheBuilder lenientParsing() { - strictParsing = false; - return this; - } - - /** - * Sets a custom {@code Equivalence} strategy for comparing keys. - * - *

By default, the cache uses {@link Equivalence#identity} to determine key equality when - * {@link #weakKeys} is specified, and {@link Equivalence#equals()} otherwise. - */ - @GwtIncompatible("To be supported") - CacheBuilder keyEquivalence(Equivalence equivalence) { - checkState(keyEquivalence == null, "key equivalence was already set to %s", keyEquivalence); - keyEquivalence = checkNotNull(equivalence); - return this; - } - - Equivalence getKeyEquivalence() { - return MoreObjects.firstNonNull(keyEquivalence, getKeyStrength().defaultEquivalence()); - } - - /** - * Sets a custom {@code Equivalence} strategy for comparing values. - * - *

By default, the cache uses {@link Equivalence#identity} to determine value equality when - * {@link #weakValues} or {@link #softValues} is specified, and {@link Equivalence#equals()} - * otherwise. - */ - @GwtIncompatible("To be supported") - CacheBuilder valueEquivalence(Equivalence equivalence) { - checkState(valueEquivalence == null, - "value equivalence was already set to %s", valueEquivalence); - this.valueEquivalence = checkNotNull(equivalence); - return this; - } - - Equivalence getValueEquivalence() { - return MoreObjects.firstNonNull(valueEquivalence, getValueStrength().defaultEquivalence()); - } - - /** - * Sets the minimum total size for the internal hash tables. For example, if the initial capacity - * is {@code 60}, and the concurrency level is {@code 8}, then eight segments are created, each - * having a hash table of size eight. Providing a large enough estimate at construction time - * avoids the need for expensive resizing operations later, but setting this value unnecessarily - * high wastes memory. - * - * @throws IllegalArgumentException if {@code initialCapacity} is negative - * @throws IllegalStateException if an initial capacity was already set - */ - public CacheBuilder initialCapacity(int initialCapacity) { - checkState(this.initialCapacity == UNSET_INT, "initial capacity was already set to %s", - this.initialCapacity); - checkArgument(initialCapacity >= 0); - this.initialCapacity = initialCapacity; - return this; - } - - int getInitialCapacity() { - return (initialCapacity == UNSET_INT) ? DEFAULT_INITIAL_CAPACITY : initialCapacity; - } - - /** - * Guides the allowed concurrency among update operations. Used as a hint for internal sizing. The - * table is internally partitioned to try to permit the indicated number of concurrent updates - * without contention. Because assignment of entries to these partitions is not necessarily - * uniform, the actual concurrency observed may vary. Ideally, you should choose a value to - * accommodate as many threads as will ever concurrently modify the table. Using a significantly - * higher value than you need can waste space and time, and a significantly lower value can lead - * to thread contention. But overestimates and underestimates within an order of magnitude do not - * usually have much noticeable impact. A value of one permits only one thread to modify the cache - * at a time, but since read operations and cache loading computations can proceed concurrently, - * this still yields higher concurrency than full synchronization. - * - *

Defaults to 4. Note:The default may change in the future. If you care about this - * value, you should always choose it explicitly. - * - *

The current implementation uses the concurrency level to create a fixed number of hashtable - * segments, each governed by its own write lock. The segment lock is taken once for each explicit - * write, and twice for each cache loading computation (once prior to loading the new value, - * and once after loading completes). Much internal cache management is performed at the segment - * granularity. For example, access queues and write queues are kept per segment when they are - * required by the selected eviction algorithm. As such, when writing unit tests it is not - * uncommon to specify {@code concurrencyLevel(1)} in order to achieve more deterministic eviction - * behavior. - * - *

Note that future implementations may abandon segment locking in favor of more advanced - * concurrency controls. - * - * @throws IllegalArgumentException if {@code concurrencyLevel} is nonpositive - * @throws IllegalStateException if a concurrency level was already set - */ - public CacheBuilder concurrencyLevel(int concurrencyLevel) { - checkState(this.concurrencyLevel == UNSET_INT, "concurrency level was already set to %s", - this.concurrencyLevel); - checkArgument(concurrencyLevel > 0); - this.concurrencyLevel = concurrencyLevel; - return this; - } - - int getConcurrencyLevel() { - return (concurrencyLevel == UNSET_INT) ? DEFAULT_CONCURRENCY_LEVEL : concurrencyLevel; - } - - /** - * Specifies the maximum number of entries the cache may contain. Note that the cache may evict - * an entry before this limit is exceeded. As the cache size grows close to the maximum, the - * cache evicts entries that are less likely to be used again. For example, the cache may evict an - * entry because it hasn't been used recently or very often. - * - *

When {@code size} is zero, elements will be evicted immediately after being loaded into the - * cache. This can be useful in testing, or to disable caching temporarily without a code change. - * - *

This feature cannot be used in conjunction with {@link #maximumWeight}. - * - * @param size the maximum size of the cache - * @throws IllegalArgumentException if {@code size} is negative - * @throws IllegalStateException if a maximum size or weight was already set - */ - public CacheBuilder maximumSize(long size) { - checkState(this.maximumSize == UNSET_INT, "maximum size was already set to %s", - this.maximumSize); - checkState(this.maximumWeight == UNSET_INT, "maximum weight was already set to %s", - this.maximumWeight); - checkState(this.weigher == null, "maximum size can not be combined with weigher"); - checkArgument(size >= 0, "maximum size must not be negative"); - this.maximumSize = size; - return this; - } - - /** - * Specifies the maximum weight of entries the cache may contain. Weight is determined using the - * {@link Weigher} specified with {@link #weigher}, and use of this method requires a - * corresponding call to {@link #weigher} prior to calling {@link #build}. - * - *

Note that the cache may evict an entry before this limit is exceeded. As the cache - * size grows close to the maximum, the cache evicts entries that are less likely to be used - * again. For example, the cache may evict an entry because it hasn't been used recently or very - * often. - * - *

When {@code weight} is zero, elements will be evicted immediately after being loaded into - * cache. This can be useful in testing, or to disable caching temporarily without a code - * change. - * - *

Note that weight is only used to determine whether the cache is over capacity; it has no - * effect on selecting which entry should be evicted next. - * - *

This feature cannot be used in conjunction with {@link #maximumSize}. - * - * @param weight the maximum total weight of entries the cache may contain - * @throws IllegalArgumentException if {@code weight} is negative - * @throws IllegalStateException if a maximum weight or size was already set - * @since 11.0 - */ - @GwtIncompatible("To be supported") - public CacheBuilder maximumWeight(long weight) { - checkState(this.maximumWeight == UNSET_INT, "maximum weight was already set to %s", - this.maximumWeight); - checkState(this.maximumSize == UNSET_INT, "maximum size was already set to %s", - this.maximumSize); - this.maximumWeight = weight; - checkArgument(weight >= 0, "maximum weight must not be negative"); - return this; - } - - /** - * Specifies the weigher to use in determining the weight of entries. Entry weight is taken - * into consideration by {@link #maximumWeight(long)} when determining which entries to evict, and - * use of this method requires a corresponding call to {@link #maximumWeight(long)} prior to - * calling {@link #build}. Weights are measured and recorded when entries are inserted into the - * cache, and are thus effectively static during the lifetime of a cache entry. - * - *

When the weight of an entry is zero it will not be considered for size-based eviction - * (though it still may be evicted by other means). - * - *

Important note: Instead of returning this as a {@code CacheBuilder} - * instance, this method returns {@code CacheBuilder}. From this point on, either the - * original reference or the returned reference may be used to complete configuration and build - * the cache, but only the "generic" one is type-safe. That is, it will properly prevent you from - * building caches whose key or value types are incompatible with the types accepted by the - * weigher already provided; the {@code CacheBuilder} type cannot do this. For best results, - * simply use the standard method-chaining idiom, as illustrated in the documentation at top, - * configuring a {@code CacheBuilder} and building your {@link Cache} all in a single statement. - * - *

Warning: if you ignore the above advice, and use this {@code CacheBuilder} to build - * a cache whose key or value type is incompatible with the weigher, you will likely experience - * a {@link ClassCastException} at some undefined point in the future. - * - * @param weigher the weigher to use in calculating the weight of cache entries - * @throws IllegalArgumentException if {@code size} is negative - * @throws IllegalStateException if a maximum size was already set - * @since 11.0 - */ - @GwtIncompatible("To be supported") - public CacheBuilder weigher( - Weigher weigher) { - checkState(this.weigher == null); - if (strictParsing) { - checkState(this.maximumSize == UNSET_INT, "weigher can not be combined with maximum size", - this.maximumSize); - } - - // safely limiting the kinds of caches this can produce - @SuppressWarnings("unchecked") - CacheBuilder me = (CacheBuilder) this; - me.weigher = checkNotNull(weigher); - return me; - } - - long getMaximumWeight() { - if (expireAfterWriteNanos == 0 || expireAfterAccessNanos == 0) { - return 0; - } - return (weigher == null) ? maximumSize : maximumWeight; - } - - // Make a safe contravariant cast now so we don't have to do it over and over. - @SuppressWarnings("unchecked") - Weigher getWeigher() { - return (Weigher) MoreObjects.firstNonNull(weigher, OneWeigher.INSTANCE); - } - - /** - * Specifies that each key (not value) stored in the cache should be wrapped in a {@link - * WeakReference} (by default, strong references are used). - * - *

Warning: when this method is used, the resulting cache will use identity ({@code ==}) - * comparison to determine equality of keys. - * - *

Entries with keys that have been garbage collected may be counted in {@link Cache#size}, - * but will never be visible to read or write operations; such entries are cleaned up as part of - * the routine maintenance described in the class javadoc. - * - * @throws IllegalStateException if the key strength was already set - */ - @GwtIncompatible("java.lang.ref.WeakReference") - public CacheBuilder weakKeys() { - return setKeyStrength(Strength.WEAK); - } - - CacheBuilder setKeyStrength(Strength strength) { - checkState(keyStrength == null, "Key strength was already set to %s", keyStrength); - keyStrength = checkNotNull(strength); - return this; - } - - Strength getKeyStrength() { - return MoreObjects.firstNonNull(keyStrength, Strength.STRONG); - } - - /** - * Specifies that each value (not key) stored in the cache should be wrapped in a - * {@link WeakReference} (by default, strong references are used). - * - *

Weak values will be garbage collected once they are weakly reachable. This makes them a poor - * candidate for caching; consider {@link #softValues} instead. - * - *

Note: when this method is used, the resulting cache will use identity ({@code ==}) - * comparison to determine equality of values. - * - *

Entries with values that have been garbage collected may be counted in {@link Cache#size}, - * but will never be visible to read or write operations; such entries are cleaned up as part of - * the routine maintenance described in the class javadoc. - * - * @throws IllegalStateException if the value strength was already set - */ - @GwtIncompatible("java.lang.ref.WeakReference") - public CacheBuilder weakValues() { - return setValueStrength(Strength.WEAK); - } - - /** - * Specifies that each value (not key) stored in the cache should be wrapped in a - * {@link SoftReference} (by default, strong references are used). Softly-referenced objects will - * be garbage-collected in a globally least-recently-used manner, in response to memory - * demand. - * - *

Warning: in most circumstances it is better to set a per-cache {@linkplain - * #maximumSize(long) maximum size} instead of using soft references. You should only use this - * method if you are well familiar with the practical consequences of soft references. - * - *

Note: when this method is used, the resulting cache will use identity ({@code ==}) - * comparison to determine equality of values. - * - *

Entries with values that have been garbage collected may be counted in {@link Cache#size}, - * but will never be visible to read or write operations; such entries are cleaned up as part of - * the routine maintenance described in the class javadoc. - * - * @throws IllegalStateException if the value strength was already set - */ - @GwtIncompatible("java.lang.ref.SoftReference") - public CacheBuilder softValues() { - return setValueStrength(Strength.SOFT); - } - - CacheBuilder setValueStrength(Strength strength) { - checkState(valueStrength == null, "Value strength was already set to %s", valueStrength); - valueStrength = checkNotNull(strength); - return this; - } - - Strength getValueStrength() { - return MoreObjects.firstNonNull(valueStrength, Strength.STRONG); - } - - /** - * Specifies that each entry should be automatically removed from the cache once a fixed duration - * has elapsed after the entry's creation, or the most recent replacement of its value. - * - *

When {@code duration} is zero, this method hands off to - * {@link #maximumSize(long) maximumSize}{@code (0)}, ignoring any otherwise-specificed maximum - * size or weight. This can be useful in testing, or to disable caching temporarily without a code - * change. - * - *

Expired entries may be counted in {@link Cache#size}, but will never be visible to read or - * write operations. Expired entries are cleaned up as part of the routine maintenance described - * in the class javadoc. - * - * @param duration the length of time after an entry is created that it should be automatically - * removed - * @param unit the unit that {@code duration} is expressed in - * @throws IllegalArgumentException if {@code duration} is negative - * @throws IllegalStateException if the time to live or time to idle was already set - */ - public CacheBuilder expireAfterWrite(long duration, TimeUnit unit) { - checkState(expireAfterWriteNanos == UNSET_INT, "expireAfterWrite was already set to %s ns", - expireAfterWriteNanos); - checkArgument(duration >= 0, "duration cannot be negative: %s %s", duration, unit); - this.expireAfterWriteNanos = unit.toNanos(duration); - return this; - } - - long getExpireAfterWriteNanos() { - return (expireAfterWriteNanos == UNSET_INT) ? DEFAULT_EXPIRATION_NANOS : expireAfterWriteNanos; - } - - /** - * Specifies that each entry should be automatically removed from the cache once a fixed duration - * has elapsed after the entry's creation, the most recent replacement of its value, or its last - * access. Access time is reset by all cache read and write operations (including - * {@code Cache.asMap().get(Object)} and {@code Cache.asMap().put(K, V)}), but not by operations - * on the collection-views of {@link Cache#asMap}. - * - *

When {@code duration} is zero, this method hands off to - * {@link #maximumSize(long) maximumSize}{@code (0)}, ignoring any otherwise-specificed maximum - * size or weight. This can be useful in testing, or to disable caching temporarily without a code - * change. - * - *

Expired entries may be counted in {@link Cache#size}, but will never be visible to read or - * write operations. Expired entries are cleaned up as part of the routine maintenance described - * in the class javadoc. - * - * @param duration the length of time after an entry is last accessed that it should be - * automatically removed - * @param unit the unit that {@code duration} is expressed in - * @throws IllegalArgumentException if {@code duration} is negative - * @throws IllegalStateException if the time to idle or time to live was already set - */ - public CacheBuilder expireAfterAccess(long duration, TimeUnit unit) { - checkState(expireAfterAccessNanos == UNSET_INT, "expireAfterAccess was already set to %s ns", - expireAfterAccessNanos); - checkArgument(duration >= 0, "duration cannot be negative: %s %s", duration, unit); - this.expireAfterAccessNanos = unit.toNanos(duration); - return this; - } - - long getExpireAfterAccessNanos() { - return (expireAfterAccessNanos == UNSET_INT) - ? DEFAULT_EXPIRATION_NANOS : expireAfterAccessNanos; - } - - /** - * Specifies that active entries are eligible for automatic refresh once a fixed duration has - * elapsed after the entry's creation, or the most recent replacement of its value. The semantics - * of refreshes are specified in {@link LoadingCache#refresh}, and are performed by calling - * {@link CacheLoader#reload}. - * - *

As the default implementation of {@link CacheLoader#reload} is synchronous, it is - * recommended that users of this method override {@link CacheLoader#reload} with an asynchronous - * implementation; otherwise refreshes will be performed during unrelated cache read and write - * operations. - * - *

Currently automatic refreshes are performed when the first stale request for an entry - * occurs. The request triggering refresh will make a blocking call to {@link CacheLoader#reload} - * and immediately return the new value if the returned future is complete, and the old value - * otherwise. - * - *

Note: all exceptions thrown during refresh will be logged and then swallowed. - * - * @param duration the length of time after an entry is created that it should be considered - * stale, and thus eligible for refresh - * @param unit the unit that {@code duration} is expressed in - * @throws IllegalArgumentException if {@code duration} is negative - * @throws IllegalStateException if the refresh interval was already set - * @since 11.0 - */ - @GwtIncompatible("To be supported (synchronously).") - public CacheBuilder refreshAfterWrite(long duration, TimeUnit unit) { - checkNotNull(unit); - checkState(refreshNanos == UNSET_INT, "refresh was already set to %s ns", refreshNanos); - checkArgument(duration > 0, "duration must be positive: %s %s", duration, unit); - this.refreshNanos = unit.toNanos(duration); - return this; - } - - long getRefreshNanos() { - return (refreshNanos == UNSET_INT) ? DEFAULT_REFRESH_NANOS : refreshNanos; - } - - /** - * Specifies a nanosecond-precision time source for this cache. By default, - * {@link System#nanoTime} is used. - * - *

The primary intent of this method is to facilitate testing of caches with a fake or mock - * time source. - * - * @throws IllegalStateException if a ticker was already set - */ - public CacheBuilder ticker(Ticker ticker) { - checkState(this.ticker == null); - this.ticker = checkNotNull(ticker); - return this; - } - - Ticker getTicker(boolean recordsTime) { - if (ticker != null) { - return ticker; - } - return recordsTime ? Ticker.systemTicker() : NULL_TICKER; - } - - /** - * Specifies a listener instance that caches should notify each time an entry is removed for any - * {@linkplain RemovalCause reason}. Each cache created by this builder will invoke this listener - * as part of the routine maintenance described in the class documentation above. - * - *

Warning: after invoking this method, do not continue to use this cache - * builder reference; instead use the reference this method returns. At runtime, these - * point to the same instance, but only the returned reference has the correct generic type - * information so as to ensure type safety. For best results, use the standard method-chaining - * idiom illustrated in the class documentation above, configuring a builder and building your - * cache in a single statement. Failure to heed this advice can result in a {@link - * ClassCastException} being thrown by a cache operation at some undefined point in the - * future. - * - *

Warning: any exception thrown by {@code listener} will not be propagated to - * the {@code Cache} user, only logged via a {@link Logger}. - * - * @return the cache builder reference that should be used instead of {@code this} for any - * remaining configuration and cache building - * @throws IllegalStateException if a removal listener was already set - */ - @CheckReturnValue - public CacheBuilder removalListener( - RemovalListener listener) { - checkState(this.removalListener == null); - - // safely limiting the kinds of caches this can produce - @SuppressWarnings("unchecked") - CacheBuilder me = (CacheBuilder) this; - me.removalListener = checkNotNull(listener); - return me; - } - - // Make a safe contravariant cast now so we don't have to do it over and over. - @SuppressWarnings("unchecked") - RemovalListener getRemovalListener() { - return (RemovalListener) - MoreObjects.firstNonNull(removalListener, NullListener.INSTANCE); - } - - /** - * Enable the accumulation of {@link CacheStats} during the operation of the cache. Without this - * {@link Cache#stats} will return zero for all statistics. Note that recording stats requires - * bookkeeping to be performed with each operation, and thus imposes a performance penalty on - * cache operation. - * - * @since 12.0 (previously, stats collection was automatic) - */ - public CacheBuilder recordStats() { - statsCounterSupplier = CACHE_STATS_COUNTER; - return this; - } - - boolean isRecordingStats() { - return statsCounterSupplier == CACHE_STATS_COUNTER; - } - - Supplier getStatsCounterSupplier() { - return statsCounterSupplier; - } - - /** - * Builds a cache, which either returns an already-loaded value for a given key or atomically - * computes or retrieves it using the supplied {@code CacheLoader}. If another thread is currently - * loading the value for this key, simply waits for that thread to finish and returns its - * loaded value. Note that multiple threads can concurrently load values for distinct keys. - * - *

This method does not alter the state of this {@code CacheBuilder} instance, so it can be - * invoked again to create multiple independent caches. - * - * @param loader the cache loader used to obtain new values - * @return a cache having the requested features - */ - public LoadingCache build( - CacheLoader loader) { - checkWeightWithWeigher(); - return new LocalCache.LocalLoadingCache(this, loader); - } - - /** - * Builds a cache which does not automatically load values when keys are requested. - * - *

Consider {@link #build(CacheLoader)} instead, if it is feasible to implement a - * {@code CacheLoader}. - * - *

This method does not alter the state of this {@code CacheBuilder} instance, so it can be - * invoked again to create multiple independent caches. - * - * @return a cache having the requested features - * @since 11.0 - */ - public Cache build() { - checkWeightWithWeigher(); - checkNonLoadingCache(); - return new LocalCache.LocalManualCache(this); - } - - private void checkNonLoadingCache() { - checkState(refreshNanos == UNSET_INT, "refreshAfterWrite requires a LoadingCache"); - } - - private void checkWeightWithWeigher() { - if (weigher == null) { - checkState(maximumWeight == UNSET_INT, "maximumWeight requires weigher"); - } else { - if (strictParsing) { - checkState(maximumWeight != UNSET_INT, "weigher requires maximumWeight"); - } else { - if (maximumWeight == UNSET_INT) { - logger.log(Level.WARNING, "ignoring weigher specified without maximumWeight"); - } - } - } - } - - /** - * Returns a string representation for this CacheBuilder instance. The exact form of the returned - * string is not specified. - */ - @Override - public String toString() { - MoreObjects.ToStringHelper s = MoreObjects.toStringHelper(this); - if (initialCapacity != UNSET_INT) { - s.add("initialCapacity", initialCapacity); - } - if (concurrencyLevel != UNSET_INT) { - s.add("concurrencyLevel", concurrencyLevel); - } - if (maximumSize != UNSET_INT) { - s.add("maximumSize", maximumSize); - } - if (maximumWeight != UNSET_INT) { - s.add("maximumWeight", maximumWeight); - } - if (expireAfterWriteNanos != UNSET_INT) { - s.add("expireAfterWrite", expireAfterWriteNanos + "ns"); - } - if (expireAfterAccessNanos != UNSET_INT) { - s.add("expireAfterAccess", expireAfterAccessNanos + "ns"); - } - if (keyStrength != null) { - s.add("keyStrength", Ascii.toLowerCase(keyStrength.toString())); - } - if (valueStrength != null) { - s.add("valueStrength", Ascii.toLowerCase(valueStrength.toString())); - } - if (keyEquivalence != null) { - s.addValue("keyEquivalence"); - } - if (valueEquivalence != null) { - s.addValue("valueEquivalence"); - } - if (removalListener != null) { - s.addValue("removalListener"); - } - return s.toString(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/cache/CacheBuilderSpec.java b/thirdparty/google-guava/src/main/java/com/google/common/cache/CacheBuilderSpec.java deleted file mode 100644 index 979b70b19844..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/cache/CacheBuilderSpec.java +++ /dev/null @@ -1,478 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.cache; - -import static com.google.common.base.Preconditions.checkArgument; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.MoreObjects; -import com.google.common.base.Objects; -import com.google.common.base.Splitter; -import com.google.common.cache.LocalCache.Strength; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; - -import java.util.List; -import java.util.Locale; -import java.util.concurrent.TimeUnit; - -import javax.annotation.Nullable; - -/** - * A specification of a {@link CacheBuilder} configuration. - * - *

{@code CacheBuilderSpec} supports parsing configuration off of a string, which - * makes it especially useful for command-line configuration of a {@code CacheBuilder}. - * - *

The string syntax is a series of comma-separated keys or key-value pairs, - * each corresponding to a {@code CacheBuilder} method. - *

    - *
  • {@code concurrencyLevel=[integer]}: sets {@link CacheBuilder#concurrencyLevel}. - *
  • {@code initialCapacity=[integer]}: sets {@link CacheBuilder#initialCapacity}. - *
  • {@code maximumSize=[long]}: sets {@link CacheBuilder#maximumSize}. - *
  • {@code maximumWeight=[long]}: sets {@link CacheBuilder#maximumWeight}. - *
  • {@code expireAfterAccess=[duration]}: sets {@link CacheBuilder#expireAfterAccess}. - *
  • {@code expireAfterWrite=[duration]}: sets {@link CacheBuilder#expireAfterWrite}. - *
  • {@code refreshAfterWrite=[duration]}: sets {@link CacheBuilder#refreshAfterWrite}. - *
  • {@code weakKeys}: sets {@link CacheBuilder#weakKeys}. - *
  • {@code softValues}: sets {@link CacheBuilder#softValues}. - *
  • {@code weakValues}: sets {@link CacheBuilder#weakValues}. - *
  • {@code recordStats}: sets {@link CacheBuilder#recordStats}. - *
- * - *

The set of supported keys will grow as {@code CacheBuilder} evolves, but existing keys - * will never be removed. - * - *

Durations are represented by an integer, followed by one of "d", "h", "m", - * or "s", representing days, hours, minutes, or seconds respectively. (There - * is currently no syntax to request expiration in milliseconds, microseconds, - * or nanoseconds.) - * - *

Whitespace before and after commas and equal signs is ignored. Keys may - * not be repeated; it is also illegal to use the following pairs of keys in - * a single value: - *

    - *
  • {@code maximumSize} and {@code maximumWeight} - *
  • {@code softValues} and {@code weakValues} - *
- * - *

{@code CacheBuilderSpec} does not support configuring {@code CacheBuilder} methods - * with non-value parameters. These must be configured in code. - * - *

A new {@code CacheBuilder} can be instantiated from a {@code CacheBuilderSpec} using - * {@link CacheBuilder#from(CacheBuilderSpec)} or {@link CacheBuilder#from(String)}. - * - * @author Adam Winer - * @since 12.0 - */ -public final class CacheBuilderSpec { - /** Parses a single value. */ - private interface ValueParser { - void parse(CacheBuilderSpec spec, String key, @Nullable String value); - } - - /** Splits each key-value pair. */ - private static final Splitter KEYS_SPLITTER = Splitter.on(',').trimResults(); - - /** Splits the key from the value. */ - private static final Splitter KEY_VALUE_SPLITTER = Splitter.on('=').trimResults(); - - /** Map of names to ValueParser. */ - private static final ImmutableMap VALUE_PARSERS = - ImmutableMap.builder() - .put("initialCapacity", new InitialCapacityParser()) - .put("maximumSize", new MaximumSizeParser()) - .put("maximumWeight", new MaximumWeightParser()) - .put("concurrencyLevel", new ConcurrencyLevelParser()) - .put("weakKeys", new KeyStrengthParser(Strength.WEAK)) - .put("softValues", new ValueStrengthParser(Strength.SOFT)) - .put("weakValues", new ValueStrengthParser(Strength.WEAK)) - .put("recordStats", new RecordStatsParser()) - .put("expireAfterAccess", new AccessDurationParser()) - .put("expireAfterWrite", new WriteDurationParser()) - .put("refreshAfterWrite", new RefreshDurationParser()) - .put("refreshInterval", new RefreshDurationParser()) - .build(); - - @VisibleForTesting Integer initialCapacity; - @VisibleForTesting Long maximumSize; - @VisibleForTesting Long maximumWeight; - @VisibleForTesting Integer concurrencyLevel; - @VisibleForTesting Strength keyStrength; - @VisibleForTesting Strength valueStrength; - @VisibleForTesting Boolean recordStats; - @VisibleForTesting long writeExpirationDuration; - @VisibleForTesting TimeUnit writeExpirationTimeUnit; - @VisibleForTesting long accessExpirationDuration; - @VisibleForTesting TimeUnit accessExpirationTimeUnit; - @VisibleForTesting long refreshDuration; - @VisibleForTesting TimeUnit refreshTimeUnit; - /** Specification; used for toParseableString(). */ - private final String specification; - - private CacheBuilderSpec(String specification) { - this.specification = specification; - } - - /** - * Creates a CacheBuilderSpec from a string. - * - * @param cacheBuilderSpecification the string form - */ - public static CacheBuilderSpec parse(String cacheBuilderSpecification) { - CacheBuilderSpec spec = new CacheBuilderSpec(cacheBuilderSpecification); - if (!cacheBuilderSpecification.isEmpty()) { - for (String keyValuePair : KEYS_SPLITTER.split(cacheBuilderSpecification)) { - List keyAndValue = ImmutableList.copyOf(KEY_VALUE_SPLITTER.split(keyValuePair)); - checkArgument(!keyAndValue.isEmpty(), "blank key-value pair"); - checkArgument(keyAndValue.size() <= 2, - "key-value pair %s with more than one equals sign", keyValuePair); - - // Find the ValueParser for the current key. - String key = keyAndValue.get(0); - ValueParser valueParser = VALUE_PARSERS.get(key); - checkArgument(valueParser != null, "unknown key %s", key); - - String value = keyAndValue.size() == 1 ? null : keyAndValue.get(1); - valueParser.parse(spec, key, value); - } - } - - return spec; - } - - /** - * Returns a CacheBuilderSpec that will prevent caching. - */ - public static CacheBuilderSpec disableCaching() { - // Maximum size of zero is one way to block caching - return CacheBuilderSpec.parse("maximumSize=0"); - } - - /** - * Returns a CacheBuilder configured according to this instance's specification. - */ - CacheBuilder toCacheBuilder() { - CacheBuilder builder = CacheBuilder.newBuilder(); - if (initialCapacity != null) { - builder.initialCapacity(initialCapacity); - } - if (maximumSize != null) { - builder.maximumSize(maximumSize); - } - if (maximumWeight != null) { - builder.maximumWeight(maximumWeight); - } - if (concurrencyLevel != null) { - builder.concurrencyLevel(concurrencyLevel); - } - if (keyStrength != null) { - switch (keyStrength) { - case WEAK: - builder.weakKeys(); - break; - default: - throw new AssertionError(); - } - } - if (valueStrength != null) { - switch (valueStrength) { - case SOFT: - builder.softValues(); - break; - case WEAK: - builder.weakValues(); - break; - default: - throw new AssertionError(); - } - } - if (recordStats != null && recordStats) { - builder.recordStats(); - } - if (writeExpirationTimeUnit != null) { - builder.expireAfterWrite(writeExpirationDuration, writeExpirationTimeUnit); - } - if (accessExpirationTimeUnit != null) { - builder.expireAfterAccess(accessExpirationDuration, accessExpirationTimeUnit); - } - if (refreshTimeUnit != null) { - builder.refreshAfterWrite(refreshDuration, refreshTimeUnit); - } - - return builder; - } - - /** - * Returns a string that can be used to parse an equivalent - * {@code CacheBuilderSpec}. The order and form of this representation is - * not guaranteed, except that reparsing its output will produce - * a {@code CacheBuilderSpec} equal to this instance. - */ - public String toParsableString() { - return specification; - } - - /** - * Returns a string representation for this CacheBuilderSpec instance. - * The form of this representation is not guaranteed. - */ - @Override - public String toString() { - return MoreObjects.toStringHelper(this).addValue(toParsableString()).toString(); - } - - @Override - public int hashCode() { - return Objects.hashCode( - initialCapacity, - maximumSize, - maximumWeight, - concurrencyLevel, - keyStrength, - valueStrength, - recordStats, - durationInNanos(writeExpirationDuration, writeExpirationTimeUnit), - durationInNanos(accessExpirationDuration, accessExpirationTimeUnit), - durationInNanos(refreshDuration, refreshTimeUnit)); - } - - @Override - public boolean equals(@Nullable Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof CacheBuilderSpec)) { - return false; - } - CacheBuilderSpec that = (CacheBuilderSpec) obj; - return Objects.equal(initialCapacity, that.initialCapacity) - && Objects.equal(maximumSize, that.maximumSize) - && Objects.equal(maximumWeight, that.maximumWeight) - && Objects.equal(concurrencyLevel, that.concurrencyLevel) - && Objects.equal(keyStrength, that.keyStrength) - && Objects.equal(valueStrength, that.valueStrength) - && Objects.equal(recordStats, that.recordStats) - && Objects.equal(durationInNanos(writeExpirationDuration, writeExpirationTimeUnit), - durationInNanos(that.writeExpirationDuration, that.writeExpirationTimeUnit)) - && Objects.equal(durationInNanos(accessExpirationDuration, accessExpirationTimeUnit), - durationInNanos(that.accessExpirationDuration, that.accessExpirationTimeUnit)) - && Objects.equal(durationInNanos(refreshDuration, refreshTimeUnit), - durationInNanos(that.refreshDuration, that.refreshTimeUnit)); - } - - /** - * Converts an expiration duration/unit pair into a single Long for hashing and equality. - * Uses nanos to match CacheBuilder implementation. - */ - @Nullable private static Long durationInNanos(long duration, @Nullable TimeUnit unit) { - return (unit == null) ? null : unit.toNanos(duration); - } - - /** Base class for parsing integers. */ - abstract static class IntegerParser implements ValueParser { - protected abstract void parseInteger(CacheBuilderSpec spec, int value); - - @Override - public void parse(CacheBuilderSpec spec, String key, String value) { - checkArgument(value != null && !value.isEmpty(), "value of key %s omitted", key); - try { - parseInteger(spec, Integer.parseInt(value)); - } catch (NumberFormatException e) { - throw new IllegalArgumentException( - format("key %s value set to %s, must be integer", key, value), e); - } - } - } - - /** Base class for parsing integers. */ - abstract static class LongParser implements ValueParser { - protected abstract void parseLong(CacheBuilderSpec spec, long value); - - @Override - public void parse(CacheBuilderSpec spec, String key, String value) { - checkArgument(value != null && !value.isEmpty(), "value of key %s omitted", key); - try { - parseLong(spec, Long.parseLong(value)); - } catch (NumberFormatException e) { - throw new IllegalArgumentException( - format("key %s value set to %s, must be integer", key, value), e); - } - } - } - - /** Parse initialCapacity */ - static class InitialCapacityParser extends IntegerParser { - @Override - protected void parseInteger(CacheBuilderSpec spec, int value) { - checkArgument(spec.initialCapacity == null, - "initial capacity was already set to ", spec.initialCapacity); - spec.initialCapacity = value; - } - } - - /** Parse maximumSize */ - static class MaximumSizeParser extends LongParser { - @Override - protected void parseLong(CacheBuilderSpec spec, long value) { - checkArgument(spec.maximumSize == null, - "maximum size was already set to ", spec.maximumSize); - checkArgument(spec.maximumWeight == null, - "maximum weight was already set to ", spec.maximumWeight); - spec.maximumSize = value; - } - } - - /** Parse maximumWeight */ - static class MaximumWeightParser extends LongParser { - @Override - protected void parseLong(CacheBuilderSpec spec, long value) { - checkArgument(spec.maximumWeight == null, - "maximum weight was already set to ", spec.maximumWeight); - checkArgument(spec.maximumSize == null, - "maximum size was already set to ", spec.maximumSize); - spec.maximumWeight = value; - } - } - - /** Parse concurrencyLevel */ - static class ConcurrencyLevelParser extends IntegerParser { - @Override - protected void parseInteger(CacheBuilderSpec spec, int value) { - checkArgument(spec.concurrencyLevel == null, - "concurrency level was already set to ", spec.concurrencyLevel); - spec.concurrencyLevel = value; - } - } - - /** Parse weakKeys */ - static class KeyStrengthParser implements ValueParser { - private final Strength strength; - - public KeyStrengthParser(Strength strength) { - this.strength = strength; - } - - @Override - public void parse(CacheBuilderSpec spec, String key, @Nullable String value) { - checkArgument(value == null, "key %s does not take values", key); - checkArgument(spec.keyStrength == null, "%s was already set to %s", key, spec.keyStrength); - spec.keyStrength = strength; - } - } - - /** Parse weakValues and softValues */ - static class ValueStrengthParser implements ValueParser { - private final Strength strength; - - public ValueStrengthParser(Strength strength) { - this.strength = strength; - } - - @Override - public void parse(CacheBuilderSpec spec, String key, @Nullable String value) { - checkArgument(value == null, "key %s does not take values", key); - checkArgument(spec.valueStrength == null, - "%s was already set to %s", key, spec.valueStrength); - - spec.valueStrength = strength; - } - } - - /** Parse recordStats */ - static class RecordStatsParser implements ValueParser { - - @Override - public void parse(CacheBuilderSpec spec, String key, @Nullable String value) { - checkArgument(value == null, "recordStats does not take values"); - checkArgument(spec.recordStats == null, "recordStats already set"); - spec.recordStats = true; - } - } - - /** Base class for parsing times with durations */ - abstract static class DurationParser implements ValueParser { - protected abstract void parseDuration( - CacheBuilderSpec spec, - long duration, - TimeUnit unit); - - @Override - public void parse(CacheBuilderSpec spec, String key, String value) { - checkArgument(value != null && !value.isEmpty(), "value of key %s omitted", key); - try { - char lastChar = value.charAt(value.length() - 1); - TimeUnit timeUnit; - switch (lastChar) { - case 'd': - timeUnit = TimeUnit.DAYS; - break; - case 'h': - timeUnit = TimeUnit.HOURS; - break; - case 'm': - timeUnit = TimeUnit.MINUTES; - break; - case 's': - timeUnit = TimeUnit.SECONDS; - break; - default: - throw new IllegalArgumentException( - format("key %s invalid format. was %s, must end with one of [dDhHmMsS]", - key, value)); - } - - long duration = Long.parseLong(value.substring(0, value.length() - 1)); - parseDuration(spec, duration, timeUnit); - } catch (NumberFormatException e) { - throw new IllegalArgumentException( - format("key %s value set to %s, must be integer", key, value)); - } - } - } - - /** Parse expireAfterAccess */ - static class AccessDurationParser extends DurationParser { - @Override protected void parseDuration(CacheBuilderSpec spec, long duration, TimeUnit unit) { - checkArgument(spec.accessExpirationTimeUnit == null, "expireAfterAccess already set"); - spec.accessExpirationDuration = duration; - spec.accessExpirationTimeUnit = unit; - } - } - - /** Parse expireAfterWrite */ - static class WriteDurationParser extends DurationParser { - @Override protected void parseDuration(CacheBuilderSpec spec, long duration, TimeUnit unit) { - checkArgument(spec.writeExpirationTimeUnit == null, "expireAfterWrite already set"); - spec.writeExpirationDuration = duration; - spec.writeExpirationTimeUnit = unit; - } - } - - /** Parse refreshAfterWrite */ - static class RefreshDurationParser extends DurationParser { - @Override protected void parseDuration(CacheBuilderSpec spec, long duration, TimeUnit unit) { - checkArgument(spec.refreshTimeUnit == null, "refreshAfterWrite already set"); - spec.refreshDuration = duration; - spec.refreshTimeUnit = unit; - } - } - - private static String format(String format, Object... args) { - return String.format(Locale.ROOT, format, args); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/cache/CacheLoader.java b/thirdparty/google-guava/src/main/java/com/google/common/cache/CacheLoader.java deleted file mode 100644 index bbdb66d8cbda..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/cache/CacheLoader.java +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.cache; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.base.Function; -import com.google.common.base.Supplier; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.ListenableFutureTask; - -import java.io.Serializable; -import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.Executor; - -/** - * Computes or retrieves values, based on a key, for use in populating a {@link LoadingCache}. - * - *

Most implementations will only need to implement {@link #load}. Other methods may be - * overridden as desired. - * - *

Usage example:

   {@code
- *
- *   CacheLoader loader = new CacheLoader() {
- *     public Graph load(Key key) throws AnyException {
- *       return createExpensiveGraph(key);
- *     }
- *   };
- *   LoadingCache cache = CacheBuilder.newBuilder().build(loader);}
- * - * @author Charles Fry - * @since 10.0 - */ -@GwtCompatible(emulated = true) -public abstract class CacheLoader { - /** - * Constructor for use by subclasses. - */ - protected CacheLoader() {} - - /** - * Computes or retrieves the value corresponding to {@code key}. - * - * @param key the non-null key whose value should be loaded - * @return the value associated with {@code key}; must not be null - * @throws Exception if unable to load the result - * @throws InterruptedException if this method is interrupted. {@code InterruptedException} is - * treated like any other {@code Exception} in all respects except that, when it is caught, - * the thread's interrupt status is set - */ - public abstract V load(K key) throws Exception; - - /** - * Computes or retrieves a replacement value corresponding to an already-cached {@code key}. This - * method is called when an existing cache entry is refreshed by - * {@link CacheBuilder#refreshAfterWrite}, or through a call to {@link LoadingCache#refresh}. - * - *

This implementation synchronously delegates to {@link #load}. It is recommended that it be - * overridden with an asynchronous implementation when using - * {@link CacheBuilder#refreshAfterWrite}. - * - *

Note: all exceptions thrown by this method will be logged and then swallowed. - * - * @param key the non-null key whose value should be loaded - * @param oldValue the non-null old value corresponding to {@code key} - * @return the future new value associated with {@code key}; - * must not be null, must not return null - * @throws Exception if unable to reload the result - * @throws InterruptedException if this method is interrupted. {@code InterruptedException} is - * treated like any other {@code Exception} in all respects except that, when it is caught, - * the thread's interrupt status is set - * @since 11.0 - */ - @GwtIncompatible("Futures") - public ListenableFuture reload(K key, V oldValue) throws Exception { - checkNotNull(key); - checkNotNull(oldValue); - return Futures.immediateFuture(load(key)); - } - - /** - * Computes or retrieves the values corresponding to {@code keys}. This method is called by - * {@link LoadingCache#getAll}. - * - *

If the returned map doesn't contain all requested {@code keys} then the entries it does - * contain will be cached, but {@code getAll} will throw an exception. If the returned map - * contains extra keys not present in {@code keys} then all returned entries will be cached, - * but only the entries for {@code keys} will be returned from {@code getAll}. - * - *

This method should be overriden when bulk retrieval is significantly more efficient than - * many individual lookups. Note that {@link LoadingCache#getAll} will defer to individual calls - * to {@link LoadingCache#get} if this method is not overriden. - * - * @param keys the unique, non-null keys whose values should be loaded - * @return a map from each key in {@code keys} to the value associated with that key; - * may not contain null values - * @throws Exception if unable to load the result - * @throws InterruptedException if this method is interrupted. {@code InterruptedException} is - * treated like any other {@code Exception} in all respects except that, when it is caught, - * the thread's interrupt status is set - * @since 11.0 - */ - public Map loadAll(Iterable keys) throws Exception { - // This will be caught by getAll(), causing it to fall back to multiple calls to - // LoadingCache.get - throw new UnsupportedLoadingOperationException(); - } - - /** - * Returns a cache loader based on an existing function instance. Note that there's no need - * to create a new function just to pass it in here; just subclass {@code CacheLoader} and - * implement {@link #load load} instead. - * - * @param function the function to be used for loading values; must never return {@code null} - * @return a cache loader that loads values by passing each key to {@code function} - */ - public static CacheLoader from(Function function) { - return new FunctionToCacheLoader(function); - } - - private static final class FunctionToCacheLoader - extends CacheLoader implements Serializable { - private final Function computingFunction; - - public FunctionToCacheLoader(Function computingFunction) { - this.computingFunction = checkNotNull(computingFunction); - } - - @Override - public V load(K key) { - return computingFunction.apply(checkNotNull(key)); - } - - private static final long serialVersionUID = 0; - } - - /** - * Returns a cache loader based on an existing supplier instance. Note that there's no need - * to create a new supplier just to pass it in here; just subclass {@code CacheLoader} and - * implement {@link #load load} instead. - * - * @param supplier the supplier to be used for loading values; must never return {@code null} - * @return a cache loader that loads values by calling {@link Supplier#get}, irrespective of the - * key - */ - public static CacheLoader from(Supplier supplier) { - return new SupplierToCacheLoader(supplier); - } - - /** - * Returns a {@code CacheLoader} which wraps {@code loader}, executing calls to - * {@link CacheLoader#reload} using {@code executor}. - * - *

This method is useful only when {@code loader.reload} has a synchronous implementation, - * such as {@linkplain #reload the default implementation}. - * - * @since 17.0 - */ - @GwtIncompatible("Executor + Futures") - public static CacheLoader asyncReloading(final CacheLoader loader, - final Executor executor) { - checkNotNull(loader); - checkNotNull(executor); - return new CacheLoader() { - @Override - public V load(K key) throws Exception { - return loader.load(key); - } - - @Override - public ListenableFuture reload(final K key, final V oldValue) throws Exception { - ListenableFutureTask task = ListenableFutureTask.create(new Callable() { - @Override - public V call() throws Exception { - return loader.reload(key, oldValue).get(); - } - }); - executor.execute(task); - return task; - } - - @Override - public Map loadAll(Iterable keys) throws Exception { - return loader.loadAll(keys); - } - }; - } - - private static final class SupplierToCacheLoader - extends CacheLoader implements Serializable { - private final Supplier computingSupplier; - - public SupplierToCacheLoader(Supplier computingSupplier) { - this.computingSupplier = checkNotNull(computingSupplier); - } - - @Override - public V load(Object key) { - checkNotNull(key); - return computingSupplier.get(); - } - - private static final long serialVersionUID = 0; - } - - /** - * Exception thrown by {@code loadAll()} to indicate that it is not supported. - * - * @since 19.0 - */ - public static final class UnsupportedLoadingOperationException - extends UnsupportedOperationException { - // Package-private because this should only be thrown by loadAll() when it is not overridden. - // Cache implementors may want to catch it but should not need to be able to throw it. - UnsupportedLoadingOperationException() {} - } - - /** - * Thrown to indicate that an invalid response was returned from a call to {@link CacheLoader}. - * - * @since 11.0 - */ - public static final class InvalidCacheLoadException extends RuntimeException { - public InvalidCacheLoadException(String message) { - super(message); - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/cache/CacheStats.java b/thirdparty/google-guava/src/main/java/com/google/common/cache/CacheStats.java deleted file mode 100644 index cfee32ea56eb..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/cache/CacheStats.java +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.cache; - -import static com.google.common.base.Preconditions.checkArgument; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.MoreObjects; -import com.google.common.base.Objects; - -import java.util.concurrent.Callable; - -import javax.annotation.Nullable; - -/** - * Statistics about the performance of a {@link Cache}. Instances of this class are immutable. - * - *

Cache statistics are incremented according to the following rules: - * - *

    - *
  • When a cache lookup encounters an existing cache entry {@code hitCount} is incremented. - *
  • When a cache lookup first encounters a missing cache entry, a new entry is loaded. - *
      - *
    • After successfully loading an entry {@code missCount} and {@code loadSuccessCount} are - * incremented, and the total loading time, in nanoseconds, is added to - * {@code totalLoadTime}. - *
    • When an exception is thrown while loading an entry, {@code missCount} and {@code - * loadExceptionCount} are incremented, and the total loading time, in nanoseconds, is - * added to {@code totalLoadTime}. - *
    • Cache lookups that encounter a missing cache entry that is still loading will wait - * for loading to complete (whether successful or not) and then increment {@code missCount}. - *
    - *
  • When an entry is evicted from the cache, {@code evictionCount} is incremented. - *
  • No stats are modified when a cache entry is invalidated or manually removed. - *
  • No stats are modified by operations invoked on the {@linkplain Cache#asMap asMap} view of - * the cache. - *
- * - *

A lookup is specifically defined as an invocation of one of the methods - * {@link LoadingCache#get(Object)}, {@link LoadingCache#getUnchecked(Object)}, - * {@link Cache#get(Object, Callable)}, or {@link LoadingCache#getAll(Iterable)}. - * - * @author Charles Fry - * @since 10.0 - */ -@GwtCompatible -public final class CacheStats { - private final long hitCount; - private final long missCount; - private final long loadSuccessCount; - private final long loadExceptionCount; - private final long totalLoadTime; - private final long evictionCount; - - /** - * Constructs a new {@code CacheStats} instance. - * - *

Five parameters of the same type in a row is a bad thing, but this class is not constructed - * by end users and is too fine-grained for a builder. - */ - public CacheStats(long hitCount, long missCount, long loadSuccessCount, - long loadExceptionCount, long totalLoadTime, long evictionCount) { - checkArgument(hitCount >= 0); - checkArgument(missCount >= 0); - checkArgument(loadSuccessCount >= 0); - checkArgument(loadExceptionCount >= 0); - checkArgument(totalLoadTime >= 0); - checkArgument(evictionCount >= 0); - - this.hitCount = hitCount; - this.missCount = missCount; - this.loadSuccessCount = loadSuccessCount; - this.loadExceptionCount = loadExceptionCount; - this.totalLoadTime = totalLoadTime; - this.evictionCount = evictionCount; - } - - /** - * Returns the number of times {@link Cache} lookup methods have returned either a cached or - * uncached value. This is defined as {@code hitCount + missCount}. - */ - public long requestCount() { - return hitCount + missCount; - } - - /** - * Returns the number of times {@link Cache} lookup methods have returned a cached value. - */ - public long hitCount() { - return hitCount; - } - - /** - * Returns the ratio of cache requests which were hits. This is defined as - * {@code hitCount / requestCount}, or {@code 1.0} when {@code requestCount == 0}. - * Note that {@code hitRate + missRate =~ 1.0}. - */ - public double hitRate() { - long requestCount = requestCount(); - return (requestCount == 0) ? 1.0 : (double) hitCount / requestCount; - } - - /** - * Returns the number of times {@link Cache} lookup methods have returned an uncached (newly - * loaded) value, or null. Multiple concurrent calls to {@link Cache} lookup methods on an absent - * value can result in multiple misses, all returning the results of a single cache load - * operation. - */ - public long missCount() { - return missCount; - } - - /** - * Returns the ratio of cache requests which were misses. This is defined as - * {@code missCount / requestCount}, or {@code 0.0} when {@code requestCount == 0}. - * Note that {@code hitRate + missRate =~ 1.0}. Cache misses include all requests which - * weren't cache hits, including requests which resulted in either successful or failed loading - * attempts, and requests which waited for other threads to finish loading. It is thus the case - * that {@code missCount >= loadSuccessCount + loadExceptionCount}. Multiple - * concurrent misses for the same key will result in a single load operation. - */ - public double missRate() { - long requestCount = requestCount(); - return (requestCount == 0) ? 0.0 : (double) missCount / requestCount; - } - - /** - * Returns the total number of times that {@link Cache} lookup methods attempted to load new - * values. This includes both successful load operations, as well as those that threw - * exceptions. This is defined as {@code loadSuccessCount + loadExceptionCount}. - */ - public long loadCount() { - return loadSuccessCount + loadExceptionCount; - } - - /** - * Returns the number of times {@link Cache} lookup methods have successfully loaded a new value. - * This is always incremented in conjunction with {@link #missCount}, though {@code missCount} - * is also incremented when an exception is encountered during cache loading (see - * {@link #loadExceptionCount}). Multiple concurrent misses for the same key will result in a - * single load operation. - */ - public long loadSuccessCount() { - return loadSuccessCount; - } - - /** - * Returns the number of times {@link Cache} lookup methods threw an exception while loading a - * new value. This is always incremented in conjunction with {@code missCount}, though - * {@code missCount} is also incremented when cache loading completes successfully (see - * {@link #loadSuccessCount}). Multiple concurrent misses for the same key will result in a - * single load operation. - */ - public long loadExceptionCount() { - return loadExceptionCount; - } - - /** - * Returns the ratio of cache loading attempts which threw exceptions. This is defined as - * {@code loadExceptionCount / (loadSuccessCount + loadExceptionCount)}, or - * {@code 0.0} when {@code loadSuccessCount + loadExceptionCount == 0}. - */ - public double loadExceptionRate() { - long totalLoadCount = loadSuccessCount + loadExceptionCount; - return (totalLoadCount == 0) - ? 0.0 - : (double) loadExceptionCount / totalLoadCount; - } - - /** - * Returns the total number of nanoseconds the cache has spent loading new values. This can be - * used to calculate the miss penalty. This value is increased every time - * {@code loadSuccessCount} or {@code loadExceptionCount} is incremented. - */ - public long totalLoadTime() { - return totalLoadTime; - } - - /** - * Returns the average time spent loading new values. This is defined as - * {@code totalLoadTime / (loadSuccessCount + loadExceptionCount)}. - */ - public double averageLoadPenalty() { - long totalLoadCount = loadSuccessCount + loadExceptionCount; - return (totalLoadCount == 0) - ? 0.0 - : (double) totalLoadTime / totalLoadCount; - } - - /** - * Returns the number of times an entry has been evicted. This count does not include manual - * {@linkplain Cache#invalidate invalidations}. - */ - public long evictionCount() { - return evictionCount; - } - - /** - * Returns a new {@code CacheStats} representing the difference between this {@code CacheStats} - * and {@code other}. Negative values, which aren't supported by {@code CacheStats} will be - * rounded up to zero. - */ - public CacheStats minus(CacheStats other) { - return new CacheStats( - Math.max(0, hitCount - other.hitCount), - Math.max(0, missCount - other.missCount), - Math.max(0, loadSuccessCount - other.loadSuccessCount), - Math.max(0, loadExceptionCount - other.loadExceptionCount), - Math.max(0, totalLoadTime - other.totalLoadTime), - Math.max(0, evictionCount - other.evictionCount)); - } - - /** - * Returns a new {@code CacheStats} representing the sum of this {@code CacheStats} - * and {@code other}. - * - * @since 11.0 - */ - public CacheStats plus(CacheStats other) { - return new CacheStats( - hitCount + other.hitCount, - missCount + other.missCount, - loadSuccessCount + other.loadSuccessCount, - loadExceptionCount + other.loadExceptionCount, - totalLoadTime + other.totalLoadTime, - evictionCount + other.evictionCount); - } - - @Override - public int hashCode() { - return Objects.hashCode(hitCount, missCount, loadSuccessCount, loadExceptionCount, - totalLoadTime, evictionCount); - } - - @Override - public boolean equals(@Nullable Object object) { - if (object instanceof CacheStats) { - CacheStats other = (CacheStats) object; - return hitCount == other.hitCount - && missCount == other.missCount - && loadSuccessCount == other.loadSuccessCount - && loadExceptionCount == other.loadExceptionCount - && totalLoadTime == other.totalLoadTime - && evictionCount == other.evictionCount; - } - return false; - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("hitCount", hitCount) - .add("missCount", missCount) - .add("loadSuccessCount", loadSuccessCount) - .add("loadExceptionCount", loadExceptionCount) - .add("totalLoadTime", totalLoadTime) - .add("evictionCount", evictionCount) - .toString(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/cache/ForwardingCache.java b/thirdparty/google-guava/src/main/java/com/google/common/cache/ForwardingCache.java deleted file mode 100644 index 8cbe30799c80..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/cache/ForwardingCache.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.cache; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ForwardingObject; -import com.google.common.collect.ImmutableMap; - -import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ExecutionException; - -import javax.annotation.Nullable; - -/** - * A cache which forwards all its method calls to another cache. Subclasses should override one or - * more methods to modify the behavior of the backing cache as desired per the - * decorator pattern. - * - * @author Charles Fry - * @since 10.0 - */ -public abstract class ForwardingCache extends ForwardingObject implements Cache { - - /** Constructor for use by subclasses. */ - protected ForwardingCache() {} - - @Override - protected abstract Cache delegate(); - - /** - * @since 11.0 - */ - @Override - @Nullable - public V getIfPresent(Object key) { - return delegate().getIfPresent(key); - } - - /** - * @since 11.0 - */ - @Override - public V get(K key, Callable valueLoader) throws ExecutionException { - return delegate().get(key, valueLoader); - } - - /** - * @since 11.0 - */ - @Override - public ImmutableMap getAllPresent(Iterable keys) { - return delegate().getAllPresent(keys); - } - - /** - * @since 11.0 - */ - @Override - public void put(K key, V value) { - delegate().put(key, value); - } - - /** - * @since 12.0 - */ - @Override - public void putAll(Map m) { - delegate().putAll(m); - } - - @Override - public void invalidate(Object key) { - delegate().invalidate(key); - } - - /** - * @since 11.0 - */ - @Override - public void invalidateAll(Iterable keys) { - delegate().invalidateAll(keys); - } - - @Override - public void invalidateAll() { - delegate().invalidateAll(); - } - - @Override - public long size() { - return delegate().size(); - } - - @Override - public CacheStats stats() { - return delegate().stats(); - } - - @Override - public ConcurrentMap asMap() { - return delegate().asMap(); - } - - @Override - public void cleanUp() { - delegate().cleanUp(); - } - - /** - * A simplified version of {@link ForwardingCache} where subclasses can pass in an already - * constructed {@link Cache} as the delegate. - * - * @since 10.0 - */ - public abstract static class SimpleForwardingCache extends ForwardingCache { - private final Cache delegate; - - protected SimpleForwardingCache(Cache delegate) { - this.delegate = Preconditions.checkNotNull(delegate); - } - - @Override - protected final Cache delegate() { - return delegate; - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/cache/ForwardingLoadingCache.java b/thirdparty/google-guava/src/main/java/com/google/common/cache/ForwardingLoadingCache.java deleted file mode 100644 index bac682302e20..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/cache/ForwardingLoadingCache.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.cache; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableMap; - -import java.util.concurrent.ExecutionException; - -/** - * A cache which forwards all its method calls to another cache. Subclasses should override one or - * more methods to modify the behavior of the backing cache as desired per the - * decorator pattern. - * - *

Note that {@link #get}, {@link #getUnchecked}, and {@link #apply} all expose the same - * underlying functionality, so should probably be overridden as a group. - * - * @author Charles Fry - * @since 11.0 - */ -public abstract class ForwardingLoadingCache - extends ForwardingCache implements LoadingCache { - - /** Constructor for use by subclasses. */ - protected ForwardingLoadingCache() {} - - @Override - protected abstract LoadingCache delegate(); - - @Override - public V get(K key) throws ExecutionException { - return delegate().get(key); - } - - @Override - public V getUnchecked(K key) { - return delegate().getUnchecked(key); - } - - @Override - public ImmutableMap getAll(Iterable keys) throws ExecutionException { - return delegate().getAll(keys); - } - - @Override - public V apply(K key) { - return delegate().apply(key); - } - - @Override - public void refresh(K key) { - delegate().refresh(key); - } - - /** - * A simplified version of {@link ForwardingLoadingCache} where subclasses can pass in an already - * constructed {@link LoadingCache} as the delegate. - * - * @since 10.0 - */ - public abstract static class SimpleForwardingLoadingCache - extends ForwardingLoadingCache { - private final LoadingCache delegate; - - protected SimpleForwardingLoadingCache(LoadingCache delegate) { - this.delegate = Preconditions.checkNotNull(delegate); - } - - @Override - protected final LoadingCache delegate() { - return delegate; - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/cache/LoadingCache.java b/thirdparty/google-guava/src/main/java/com/google/common/cache/LoadingCache.java deleted file mode 100644 index 4f7fb99e2bac..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/cache/LoadingCache.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.cache; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Function; -import com.google.common.collect.ImmutableMap; -import com.google.common.util.concurrent.ExecutionError; -import com.google.common.util.concurrent.UncheckedExecutionException; - -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ExecutionException; - -/** - * A semi-persistent mapping from keys to values. Values are automatically loaded by the cache, - * and are stored in the cache until either evicted or manually invalidated. - * - *

Implementations of this interface are expected to be thread-safe, and can be safely accessed - * by multiple concurrent threads. - * - *

When evaluated as a {@link Function}, a cache yields the same result as invoking - * {@link #getUnchecked}. - * - * @author Charles Fry - * @since 11.0 - */ -@GwtCompatible -public interface LoadingCache extends Cache, Function { - - /** - * Returns the value associated with {@code key} in this cache, first loading that value if - * necessary. No observable state associated with this cache is modified until loading completes. - * - *

If another call to {@link #get} or {@link #getUnchecked} is currently loading the value for - * {@code key}, simply waits for that thread to finish and returns its loaded value. Note that - * multiple threads can concurrently load values for distinct keys. - * - *

Caches loaded by a {@link CacheLoader} will call {@link CacheLoader#load} to load new values - * into the cache. Newly loaded values are added to the cache using - * {@code Cache.asMap().putIfAbsent} after loading has completed; if another value was associated - * with {@code key} while the new value was loading then a removal notification will be sent for - * the new value. - * - *

If the cache loader associated with this cache is known not to throw checked - * exceptions, then prefer {@link #getUnchecked} over this method. - * - * @throws ExecutionException if a checked exception was thrown while loading the value. ({@code - * ExecutionException} is thrown even if - * computation was interrupted by an {@code InterruptedException}.) - * @throws UncheckedExecutionException if an unchecked exception was thrown while loading the - * value - * @throws ExecutionError if an error was thrown while loading the value - */ - V get(K key) throws ExecutionException; - - /** - * Returns the value associated with {@code key} in this cache, first loading that value if - * necessary. No observable state associated with this cache is modified until loading - * completes. Unlike {@link #get}, this method does not throw a checked exception, and thus should - * only be used in situations where checked exceptions are not thrown by the cache loader. - * - *

If another call to {@link #get} or {@link #getUnchecked} is currently loading the value for - * {@code key}, simply waits for that thread to finish and returns its loaded value. Note that - * multiple threads can concurrently load values for distinct keys. - * - *

Caches loaded by a {@link CacheLoader} will call {@link CacheLoader#load} to load new values - * into the cache. Newly loaded values are added to the cache using - * {@code Cache.asMap().putIfAbsent} after loading has completed; if another value was associated - * with {@code key} while the new value was loading then a removal notification will be sent for - * the new value. - * - *

Warning: this method silently converts checked exceptions to unchecked exceptions, - * and should not be used with cache loaders which throw checked exceptions. In such cases use - * {@link #get} instead. - * - * @throws UncheckedExecutionException if an exception was thrown while loading the value. (As - * explained in the last paragraph above, this should be an unchecked exception only.) - * @throws ExecutionError if an error was thrown while loading the value - */ - V getUnchecked(K key); - - /** - * Returns a map of the values associated with {@code keys}, creating or retrieving those values - * if necessary. The returned map contains entries that were already cached, combined with newly - * loaded entries; it will never contain null keys or values. - * - *

Caches loaded by a {@link CacheLoader} will issue a single request to - * {@link CacheLoader#loadAll} for all keys which are not already present in the cache. All - * entries returned by {@link CacheLoader#loadAll} will be stored in the cache, over-writing - * any previously cached values. This method will throw an exception if - * {@link CacheLoader#loadAll} returns {@code null}, returns a map containing null keys or values, - * or fails to return an entry for each requested key. - * - *

Note that duplicate elements in {@code keys}, as determined by {@link Object#equals}, will - * be ignored. - * - * @throws ExecutionException if a checked exception was thrown while loading the value. ({@code - * ExecutionException} is thrown even if - * computation was interrupted by an {@code InterruptedException}.) - * @throws UncheckedExecutionException if an unchecked exception was thrown while loading the - * values - * @throws ExecutionError if an error was thrown while loading the values - * @since 11.0 - */ - ImmutableMap getAll(Iterable keys) throws ExecutionException; - - /** - * @deprecated Provided to satisfy the {@code Function} interface; use {@link #get} or - * {@link #getUnchecked} instead. - * @throws UncheckedExecutionException if an exception was thrown while loading the value. (As - * described in the documentation for {@link #getUnchecked}, {@code LoadingCache} should be - * used as a {@code Function} only with cache loaders that throw only unchecked exceptions.) - */ - @Deprecated - @Override - V apply(K key); - - /** - * Loads a new value for key {@code key}, possibly asynchronously. While the new value is loading - * the previous value (if any) will continue to be returned by {@code get(key)} unless it is - * evicted. If the new value is loaded successfully it will replace the previous value in the - * cache; if an exception is thrown while refreshing the previous value will remain, and the - * exception will be logged (using {@link com.google.common.logging.Logger}) and swallowed. - * - *

Caches loaded by a {@link CacheLoader} will call {@link CacheLoader#reload} if the - * cache currently contains a value for {@code key}, and {@link CacheLoader#load} otherwise. - * Loading is asynchronous only if {@link CacheLoader#reload} was overridden with an - * asynchronous implementation. - * - *

Returns without doing anything if another thread is currently loading the value for - * {@code key}. If the cache loader associated with this cache performs refresh asynchronously - * then this method may return before refresh completes. - * - * @since 11.0 - */ - void refresh(K key); - - /** - * {@inheritDoc} - * - *

Note that although the view is modifiable, no method on the returned map will ever - * cause entries to be automatically loaded. - */ - @Override - ConcurrentMap asMap(); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/cache/LocalCache.java b/thirdparty/google-guava/src/main/java/com/google/common/cache/LocalCache.java deleted file mode 100644 index 9e74277750ee..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/cache/LocalCache.java +++ /dev/null @@ -1,4911 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.cache; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; -import static com.google.common.cache.CacheBuilder.NULL_TICKER; -import static com.google.common.cache.CacheBuilder.UNSET_INT; -import static com.google.common.util.concurrent.MoreExecutors.directExecutor; -import static com.google.common.util.concurrent.Uninterruptibles.getUninterruptibly; -import static java.util.concurrent.TimeUnit.NANOSECONDS; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Equivalence; -import com.google.common.base.Function; -import com.google.common.base.Stopwatch; -import com.google.common.base.Ticker; -import com.google.common.cache.AbstractCache.SimpleStatsCounter; -import com.google.common.cache.AbstractCache.StatsCounter; -import com.google.common.cache.CacheBuilder.NullListener; -import com.google.common.cache.CacheBuilder.OneWeigher; -import com.google.common.cache.CacheLoader.InvalidCacheLoadException; -import com.google.common.cache.CacheLoader.UnsupportedLoadingOperationException; -import com.google.common.collect.AbstractSequentialIterator; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterators; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.google.common.primitives.Ints; -import com.google.common.util.concurrent.ExecutionError; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.SettableFuture; -import com.google.common.util.concurrent.UncheckedExecutionException; -import com.google.common.util.concurrent.Uninterruptibles; -import com.google.j2objc.annotations.Weak; -import com.google.j2objc.annotations.WeakOuter; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.Serializable; -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.SoftReference; -import java.lang.ref.WeakReference; -import java.util.AbstractCollection; -import java.util.AbstractMap; -import java.util.AbstractQueue; -import java.util.AbstractSet; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.NoSuchElementException; -import java.util.Queue; -import java.util.Set; -import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReferenceArray; -import java.util.concurrent.locks.ReentrantLock; -import com.google.common.logging.Level; -import com.google.common.logging.Logger; - -import javax.annotation.Nullable; -import javax.annotation.concurrent.GuardedBy; - -/** - * The concurrent hash map implementation built by {@link CacheBuilder}. - * - *

This implementation is heavily derived from revision 1.96 of ConcurrentHashMap.java. - * - * @author Charles Fry - * @author Bob Lee ({@code com.google.common.collect.MapMaker}) - * @author Doug Lea ({@code ConcurrentHashMap}) - */ -@GwtCompatible(emulated = true) -class LocalCache extends AbstractMap implements ConcurrentMap { - - /* - * The basic strategy is to subdivide the table among Segments, each of which itself is a - * concurrently readable hash table. The map supports non-blocking reads and concurrent writes - * across different segments. - * - * If a maximum size is specified, a best-effort bounding is performed per segment, using a - * page-replacement algorithm to determine which entries to evict when the capacity has been - * exceeded. - * - * The page replacement algorithm's data structures are kept casually consistent with the map. The - * ordering of writes to a segment is sequentially consistent. An update to the map and recording - * of reads may not be immediately reflected on the algorithm's data structures. These structures - * are guarded by a lock and operations are applied in batches to avoid lock contention. The - * penalty of applying the batches is spread across threads so that the amortized cost is slightly - * higher than performing just the operation without enforcing the capacity constraint. - * - * This implementation uses a per-segment queue to record a memento of the additions, removals, - * and accesses that were performed on the map. The queue is drained on writes and when it exceeds - * its capacity threshold. - * - * The Least Recently Used page replacement algorithm was chosen due to its simplicity, high hit - * rate, and ability to be implemented with O(1) time complexity. The initial LRU implementation - * operates per-segment rather than globally for increased implementation simplicity. We expect - * the cache hit rate to be similar to that of a global LRU algorithm. - */ - - // Constants - - /** - * The maximum capacity, used if a higher value is implicitly specified by either of the - * constructors with arguments. MUST be a power of two <= 1<<30 to ensure that entries are - * indexable using ints. - */ - static final int MAXIMUM_CAPACITY = 1 << 30; - - /** The maximum number of segments to allow; used to bound constructor arguments. */ - static final int MAX_SEGMENTS = 1 << 16; // slightly conservative - - /** Number of (unsynchronized) retries in the containsValue method. */ - static final int CONTAINS_VALUE_RETRIES = 3; - - /** - * Number of cache access operations that can be buffered per segment before the cache's recency - * ordering information is updated. This is used to avoid lock contention by recording a memento - * of reads and delaying a lock acquisition until the threshold is crossed or a mutation occurs. - * - *

This must be a (2^n)-1 as it is used as a mask. - */ - static final int DRAIN_THRESHOLD = 0x3F; - - /** - * Maximum number of entries to be drained in a single cleanup run. This applies independently to - * the cleanup queue and both reference queues. - */ - // TODO(fry): empirically optimize this - static final int DRAIN_MAX = 16; - - // Fields - - static final Logger logger = Logger.getLogger(LocalCache.class.getName()); - - /** - * Mask value for indexing into segments. The upper bits of a key's hash code are used to choose - * the segment. - */ - final int segmentMask; - - /** - * Shift value for indexing within segments. Helps prevent entries that end up in the same segment - * from also ending up in the same bucket. - */ - final int segmentShift; - - /** The segments, each of which is a specialized hash table. */ - final Segment[] segments; - - /** The concurrency level. */ - final int concurrencyLevel; - - /** Strategy for comparing keys. */ - final Equivalence keyEquivalence; - - /** Strategy for comparing values. */ - final Equivalence valueEquivalence; - - /** Strategy for referencing keys. */ - final Strength keyStrength; - - /** Strategy for referencing values. */ - final Strength valueStrength; - - /** The maximum weight of this map. UNSET_INT if there is no maximum. */ - final long maxWeight; - - /** Weigher to weigh cache entries. */ - final Weigher weigher; - - /** How long after the last access to an entry the map will retain that entry. */ - final long expireAfterAccessNanos; - - /** How long after the last write to an entry the map will retain that entry. */ - final long expireAfterWriteNanos; - - /** How long after the last write an entry becomes a candidate for refresh. */ - final long refreshNanos; - - /** Entries waiting to be consumed by the removal listener. */ - // TODO(fry): define a new type which creates event objects and automates the clear logic - final Queue> removalNotificationQueue; - - /** - * A listener that is invoked when an entry is removed due to expiration or garbage collection of - * soft/weak entries. - */ - final RemovalListener removalListener; - - /** Measures time in a testable way. */ - final Ticker ticker; - - /** Factory used to create new entries. */ - final EntryFactory entryFactory; - - /** - * Accumulates global cache statistics. Note that there are also per-segments stats counters - * which must be aggregated to obtain a global stats view. - */ - final StatsCounter globalStatsCounter; - - /** - * The default cache loader to use on loading operations. - */ - @Nullable - final CacheLoader defaultLoader; - - /** - * Creates a new, empty map with the specified strategy, initial capacity and concurrency level. - */ - LocalCache( - CacheBuilder builder, @Nullable CacheLoader loader) { - concurrencyLevel = Math.min(builder.getConcurrencyLevel(), MAX_SEGMENTS); - - keyStrength = builder.getKeyStrength(); - valueStrength = builder.getValueStrength(); - - keyEquivalence = builder.getKeyEquivalence(); - valueEquivalence = builder.getValueEquivalence(); - - maxWeight = builder.getMaximumWeight(); - weigher = builder.getWeigher(); - expireAfterAccessNanos = builder.getExpireAfterAccessNanos(); - expireAfterWriteNanos = builder.getExpireAfterWriteNanos(); - refreshNanos = builder.getRefreshNanos(); - - removalListener = builder.getRemovalListener(); - removalNotificationQueue = (removalListener == NullListener.INSTANCE) - ? LocalCache.>discardingQueue() - : new ConcurrentLinkedQueue>(); - - ticker = builder.getTicker(recordsTime()); - entryFactory = EntryFactory.getFactory(keyStrength, usesAccessEntries(), usesWriteEntries()); - globalStatsCounter = builder.getStatsCounterSupplier().get(); - defaultLoader = loader; - - int initialCapacity = Math.min(builder.getInitialCapacity(), MAXIMUM_CAPACITY); - if (evictsBySize() && !customWeigher()) { - initialCapacity = Math.min(initialCapacity, (int) maxWeight); - } - - // Find the lowest power-of-two segmentCount that exceeds concurrencyLevel, unless - // maximumSize/Weight is specified in which case ensure that each segment gets at least 10 - // entries. The special casing for size-based eviction is only necessary because that eviction - // happens per segment instead of globally, so too many segments compared to the maximum size - // will result in random eviction behavior. - int segmentShift = 0; - int segmentCount = 1; - while (segmentCount < concurrencyLevel - && (!evictsBySize() || segmentCount * 20 <= maxWeight)) { - ++segmentShift; - segmentCount <<= 1; - } - this.segmentShift = 32 - segmentShift; - segmentMask = segmentCount - 1; - - this.segments = newSegmentArray(segmentCount); - - int segmentCapacity = initialCapacity / segmentCount; - if (segmentCapacity * segmentCount < initialCapacity) { - ++segmentCapacity; - } - - int segmentSize = 1; - while (segmentSize < segmentCapacity) { - segmentSize <<= 1; - } - - if (evictsBySize()) { - // Ensure sum of segment max weights = overall max weights - long maxSegmentWeight = maxWeight / segmentCount + 1; - long remainder = maxWeight % segmentCount; - for (int i = 0; i < this.segments.length; ++i) { - if (i == remainder) { - maxSegmentWeight--; - } - this.segments[i] = - createSegment(segmentSize, maxSegmentWeight, builder.getStatsCounterSupplier().get()); - } - } else { - for (int i = 0; i < this.segments.length; ++i) { - this.segments[i] = - createSegment(segmentSize, UNSET_INT, builder.getStatsCounterSupplier().get()); - } - } - } - - boolean evictsBySize() { - return maxWeight >= 0; - } - - boolean customWeigher() { - return weigher != OneWeigher.INSTANCE; - } - - boolean expires() { - return expiresAfterWrite() || expiresAfterAccess(); - } - - boolean expiresAfterWrite() { - return expireAfterWriteNanos > 0; - } - - boolean expiresAfterAccess() { - return expireAfterAccessNanos > 0; - } - - boolean refreshes() { - return refreshNanos > 0; - } - - boolean usesAccessQueue() { - return expiresAfterAccess() || evictsBySize(); - } - - boolean usesWriteQueue() { - return expiresAfterWrite(); - } - - boolean recordsWrite() { - return expiresAfterWrite() || refreshes(); - } - - boolean recordsAccess() { - return expiresAfterAccess(); - } - - boolean recordsTime() { - return recordsWrite() || recordsAccess(); - } - - boolean usesWriteEntries() { - return usesWriteQueue() || recordsWrite(); - } - - boolean usesAccessEntries() { - return usesAccessQueue() || recordsAccess(); - } - - boolean usesKeyReferences() { - return keyStrength != Strength.STRONG; - } - - boolean usesValueReferences() { - return valueStrength != Strength.STRONG; - } - - enum Strength { - /* - * TODO(kevinb): If we strongly reference the value and aren't loading, we needn't wrap the - * value. This could save ~8 bytes per entry. - */ - - STRONG { - @Override - ValueReference referenceValue( - Segment segment, ReferenceEntry entry, V value, int weight) { - return (weight == 1) - ? new StrongValueReference(value) - : new WeightedStrongValueReference(value, weight); - } - - @Override - Equivalence defaultEquivalence() { - return Equivalence.equals(); - } - }, - - SOFT { - @Override - ValueReference referenceValue( - Segment segment, ReferenceEntry entry, V value, int weight) { - return (weight == 1) - ? new SoftValueReference(segment.valueReferenceQueue, value, entry) - : new WeightedSoftValueReference( - segment.valueReferenceQueue, value, entry, weight); - } - - @Override - Equivalence defaultEquivalence() { - return Equivalence.identity(); - } - }, - - WEAK { - @Override - ValueReference referenceValue( - Segment segment, ReferenceEntry entry, V value, int weight) { - return (weight == 1) - ? new WeakValueReference(segment.valueReferenceQueue, value, entry) - : new WeightedWeakValueReference( - segment.valueReferenceQueue, value, entry, weight); - } - - @Override - Equivalence defaultEquivalence() { - return Equivalence.identity(); - } - }; - - /** - * Creates a reference for the given value according to this value strength. - */ - abstract ValueReference referenceValue( - Segment segment, ReferenceEntry entry, V value, int weight); - - /** - * Returns the default equivalence strategy used to compare and hash keys or values referenced - * at this strength. This strategy will be used unless the user explicitly specifies an - * alternate strategy. - */ - abstract Equivalence defaultEquivalence(); - } - - /** - * Creates new entries. - */ - enum EntryFactory { - STRONG { - @Override - ReferenceEntry newEntry( - Segment segment, K key, int hash, @Nullable ReferenceEntry next) { - return new StrongEntry(key, hash, next); - } - }, - STRONG_ACCESS { - @Override - ReferenceEntry newEntry( - Segment segment, K key, int hash, @Nullable ReferenceEntry next) { - return new StrongAccessEntry(key, hash, next); - } - - @Override - ReferenceEntry copyEntry( - Segment segment, ReferenceEntry original, ReferenceEntry newNext) { - ReferenceEntry newEntry = super.copyEntry(segment, original, newNext); - copyAccessEntry(original, newEntry); - return newEntry; - } - }, - STRONG_WRITE { - @Override - ReferenceEntry newEntry( - Segment segment, K key, int hash, @Nullable ReferenceEntry next) { - return new StrongWriteEntry(key, hash, next); - } - - @Override - ReferenceEntry copyEntry( - Segment segment, ReferenceEntry original, ReferenceEntry newNext) { - ReferenceEntry newEntry = super.copyEntry(segment, original, newNext); - copyWriteEntry(original, newEntry); - return newEntry; - } - }, - STRONG_ACCESS_WRITE { - @Override - ReferenceEntry newEntry( - Segment segment, K key, int hash, @Nullable ReferenceEntry next) { - return new StrongAccessWriteEntry(key, hash, next); - } - - @Override - ReferenceEntry copyEntry( - Segment segment, ReferenceEntry original, ReferenceEntry newNext) { - ReferenceEntry newEntry = super.copyEntry(segment, original, newNext); - copyAccessEntry(original, newEntry); - copyWriteEntry(original, newEntry); - return newEntry; - } - }, - - WEAK { - @Override - ReferenceEntry newEntry( - Segment segment, K key, int hash, @Nullable ReferenceEntry next) { - return new WeakEntry(segment.keyReferenceQueue, key, hash, next); - } - }, - WEAK_ACCESS { - @Override - ReferenceEntry newEntry( - Segment segment, K key, int hash, @Nullable ReferenceEntry next) { - return new WeakAccessEntry(segment.keyReferenceQueue, key, hash, next); - } - - @Override - ReferenceEntry copyEntry( - Segment segment, ReferenceEntry original, ReferenceEntry newNext) { - ReferenceEntry newEntry = super.copyEntry(segment, original, newNext); - copyAccessEntry(original, newEntry); - return newEntry; - } - }, - WEAK_WRITE { - @Override - ReferenceEntry newEntry( - Segment segment, K key, int hash, @Nullable ReferenceEntry next) { - return new WeakWriteEntry(segment.keyReferenceQueue, key, hash, next); - } - - @Override - ReferenceEntry copyEntry( - Segment segment, ReferenceEntry original, ReferenceEntry newNext) { - ReferenceEntry newEntry = super.copyEntry(segment, original, newNext); - copyWriteEntry(original, newEntry); - return newEntry; - } - }, - WEAK_ACCESS_WRITE { - @Override - ReferenceEntry newEntry( - Segment segment, K key, int hash, @Nullable ReferenceEntry next) { - return new WeakAccessWriteEntry(segment.keyReferenceQueue, key, hash, next); - } - - @Override - ReferenceEntry copyEntry( - Segment segment, ReferenceEntry original, ReferenceEntry newNext) { - ReferenceEntry newEntry = super.copyEntry(segment, original, newNext); - copyAccessEntry(original, newEntry); - copyWriteEntry(original, newEntry); - return newEntry; - } - }; - - /** - * Masks used to compute indices in the following table. - */ - static final int ACCESS_MASK = 1; - static final int WRITE_MASK = 2; - static final int WEAK_MASK = 4; - - /** - * Look-up table for factories. - */ - static final EntryFactory[] factories = { - STRONG, STRONG_ACCESS, STRONG_WRITE, STRONG_ACCESS_WRITE, - WEAK, WEAK_ACCESS, WEAK_WRITE, WEAK_ACCESS_WRITE, - }; - - static EntryFactory getFactory(Strength keyStrength, boolean usesAccessQueue, - boolean usesWriteQueue) { - int flags = ((keyStrength == Strength.WEAK) ? WEAK_MASK : 0) - | (usesAccessQueue ? ACCESS_MASK : 0) - | (usesWriteQueue ? WRITE_MASK : 0); - return factories[flags]; - } - - /** - * Creates a new entry. - * - * @param segment to create the entry for - * @param key of the entry - * @param hash of the key - * @param next entry in the same bucket - */ - abstract ReferenceEntry newEntry( - Segment segment, K key, int hash, @Nullable ReferenceEntry next); - - /** - * Copies an entry, assigning it a new {@code next} entry. - * - * @param original the entry to copy - * @param newNext entry in the same bucket - */ - // Guarded By Segment.this - ReferenceEntry copyEntry( - Segment segment, ReferenceEntry original, ReferenceEntry newNext) { - return newEntry(segment, original.getKey(), original.getHash(), newNext); - } - - // Guarded By Segment.this - void copyAccessEntry(ReferenceEntry original, ReferenceEntry newEntry) { - // TODO(fry): when we link values instead of entries this method can go - // away, as can connectAccessOrder, nullifyAccessOrder. - newEntry.setAccessTime(original.getAccessTime()); - - connectAccessOrder(original.getPreviousInAccessQueue(), newEntry); - connectAccessOrder(newEntry, original.getNextInAccessQueue()); - - nullifyAccessOrder(original); - } - - // Guarded By Segment.this - void copyWriteEntry(ReferenceEntry original, ReferenceEntry newEntry) { - // TODO(fry): when we link values instead of entries this method can go - // away, as can connectWriteOrder, nullifyWriteOrder. - newEntry.setWriteTime(original.getWriteTime()); - - connectWriteOrder(original.getPreviousInWriteQueue(), newEntry); - connectWriteOrder(newEntry, original.getNextInWriteQueue()); - - nullifyWriteOrder(original); - } - } - - /** - * A reference to a value. - */ - interface ValueReference { - /** - * Returns the value. Does not block or throw exceptions. - */ - @Nullable - V get(); - - /** - * Waits for a value that may still be loading. Unlike get(), this method can block (in the - * case of FutureValueReference). - * - * @throws ExecutionException if the loading thread throws an exception - * @throws ExecutionError if the loading thread throws an error - */ - V waitForValue() throws ExecutionException; - - /** - * Returns the weight of this entry. This is assumed to be static between calls to setValue. - */ - int getWeight(); - - /** - * Returns the entry associated with this value reference, or {@code null} if this value - * reference is independent of any entry. - */ - @Nullable - ReferenceEntry getEntry(); - - /** - * Creates a copy of this reference for the given entry. - * - *

{@code value} may be null only for a loading reference. - */ - ValueReference copyFor( - ReferenceQueue queue, @Nullable V value, ReferenceEntry entry); - - /** - * Notifify pending loads that a new value was set. This is only relevant to loading - * value references. - */ - void notifyNewValue(@Nullable V newValue); - - /** - * Returns true if a new value is currently loading, regardless of whether or not there is an - * existing value. It is assumed that the return value of this method is constant for any given - * ValueReference instance. - */ - boolean isLoading(); - - /** - * Returns true if this reference contains an active value, meaning one that is still considered - * present in the cache. Active values consist of live values, which are returned by cache - * lookups, and dead values, which have been evicted but awaiting removal. Non-active values - * consist strictly of loading values, though during refresh a value may be both active and - * loading. - */ - boolean isActive(); - } - - /** - * Placeholder. Indicates that the value hasn't been set yet. - */ - static final ValueReference UNSET = new ValueReference() { - @Override - public Object get() { - return null; - } - - @Override - public int getWeight() { - return 0; - } - - @Override - public ReferenceEntry getEntry() { - return null; - } - - @Override - public ValueReference copyFor(ReferenceQueue queue, - @Nullable Object value, ReferenceEntry entry) { - return this; - } - - @Override - public boolean isLoading() { - return false; - } - - @Override - public boolean isActive() { - return false; - } - - @Override - public Object waitForValue() { - return null; - } - - @Override - public void notifyNewValue(Object newValue) {} - }; - - /** - * Singleton placeholder that indicates a value is being loaded. - */ - @SuppressWarnings("unchecked") // impl never uses a parameter or returns any non-null value - static ValueReference unset() { - return (ValueReference) UNSET; - } - - /** - * An entry in a reference map. - * - * Entries in the map can be in the following states: - * - * Valid: - * - Live: valid key/value are set - * - Loading: loading is pending - * - * Invalid: - * - Expired: time expired (key/value may still be set) - * - Collected: key/value was partially collected, but not yet cleaned up - * - Unset: marked as unset, awaiting cleanup or reuse - */ - interface ReferenceEntry { - /** - * Returns the value reference from this entry. - */ - ValueReference getValueReference(); - - /** - * Sets the value reference for this entry. - */ - void setValueReference(ValueReference valueReference); - - /** - * Returns the next entry in the chain. - */ - @Nullable - ReferenceEntry getNext(); - - /** - * Returns the entry's hash. - */ - int getHash(); - - /** - * Returns the key for this entry. - */ - @Nullable - K getKey(); - - /* - * Used by entries that use access order. Access entries are maintained in a doubly-linked list. - * New entries are added at the tail of the list at write time; stale entries are expired from - * the head of the list. - */ - - /** - * Returns the time that this entry was last accessed, in ns. - */ - long getAccessTime(); - - /** - * Sets the entry access time in ns. - */ - void setAccessTime(long time); - - /** - * Returns the next entry in the access queue. - */ - ReferenceEntry getNextInAccessQueue(); - - /** - * Sets the next entry in the access queue. - */ - void setNextInAccessQueue(ReferenceEntry next); - - /** - * Returns the previous entry in the access queue. - */ - ReferenceEntry getPreviousInAccessQueue(); - - /** - * Sets the previous entry in the access queue. - */ - void setPreviousInAccessQueue(ReferenceEntry previous); - - /* - * Implemented by entries that use write order. Write entries are maintained in a - * doubly-linked list. New entries are added at the tail of the list at write time and stale - * entries are expired from the head of the list. - */ - - /** - * Returns the time that this entry was last written, in ns. - */ - long getWriteTime(); - - /** - * Sets the entry write time in ns. - */ - void setWriteTime(long time); - - /** - * Returns the next entry in the write queue. - */ - ReferenceEntry getNextInWriteQueue(); - - /** - * Sets the next entry in the write queue. - */ - void setNextInWriteQueue(ReferenceEntry next); - - /** - * Returns the previous entry in the write queue. - */ - ReferenceEntry getPreviousInWriteQueue(); - - /** - * Sets the previous entry in the write queue. - */ - void setPreviousInWriteQueue(ReferenceEntry previous); - } - - private enum NullEntry implements ReferenceEntry { - INSTANCE; - - @Override - public ValueReference getValueReference() { - return null; - } - - @Override - public void setValueReference(ValueReference valueReference) {} - - @Override - public ReferenceEntry getNext() { - return null; - } - - @Override - public int getHash() { - return 0; - } - - @Override - public Object getKey() { - return null; - } - - @Override - public long getAccessTime() { - return 0; - } - - @Override - public void setAccessTime(long time) {} - - @Override - public ReferenceEntry getNextInAccessQueue() { - return this; - } - - @Override - public void setNextInAccessQueue(ReferenceEntry next) {} - - @Override - public ReferenceEntry getPreviousInAccessQueue() { - return this; - } - - @Override - public void setPreviousInAccessQueue(ReferenceEntry previous) {} - - @Override - public long getWriteTime() { - return 0; - } - - @Override - public void setWriteTime(long time) {} - - @Override - public ReferenceEntry getNextInWriteQueue() { - return this; - } - - @Override - public void setNextInWriteQueue(ReferenceEntry next) {} - - @Override - public ReferenceEntry getPreviousInWriteQueue() { - return this; - } - - @Override - public void setPreviousInWriteQueue(ReferenceEntry previous) {} - } - - abstract static class AbstractReferenceEntry implements ReferenceEntry { - @Override - public ValueReference getValueReference() { - throw new UnsupportedOperationException(); - } - - @Override - public void setValueReference(ValueReference valueReference) { - throw new UnsupportedOperationException(); - } - - @Override - public ReferenceEntry getNext() { - throw new UnsupportedOperationException(); - } - - @Override - public int getHash() { - throw new UnsupportedOperationException(); - } - - @Override - public K getKey() { - throw new UnsupportedOperationException(); - } - - @Override - public long getAccessTime() { - throw new UnsupportedOperationException(); - } - - @Override - public void setAccessTime(long time) { - throw new UnsupportedOperationException(); - } - - @Override - public ReferenceEntry getNextInAccessQueue() { - throw new UnsupportedOperationException(); - } - - @Override - public void setNextInAccessQueue(ReferenceEntry next) { - throw new UnsupportedOperationException(); - } - - @Override - public ReferenceEntry getPreviousInAccessQueue() { - throw new UnsupportedOperationException(); - } - - @Override - public void setPreviousInAccessQueue(ReferenceEntry previous) { - throw new UnsupportedOperationException(); - } - - @Override - public long getWriteTime() { - throw new UnsupportedOperationException(); - } - - @Override - public void setWriteTime(long time) { - throw new UnsupportedOperationException(); - } - - @Override - public ReferenceEntry getNextInWriteQueue() { - throw new UnsupportedOperationException(); - } - - @Override - public void setNextInWriteQueue(ReferenceEntry next) { - throw new UnsupportedOperationException(); - } - - @Override - public ReferenceEntry getPreviousInWriteQueue() { - throw new UnsupportedOperationException(); - } - - @Override - public void setPreviousInWriteQueue(ReferenceEntry previous) { - throw new UnsupportedOperationException(); - } - } - - @SuppressWarnings("unchecked") // impl never uses a parameter or returns any non-null value - static ReferenceEntry nullEntry() { - return (ReferenceEntry) NullEntry.INSTANCE; - } - - static final Queue DISCARDING_QUEUE = new AbstractQueue() { - @Override - public boolean offer(Object o) { - return true; - } - - @Override - public Object peek() { - return null; - } - - @Override - public Object poll() { - return null; - } - - @Override - public int size() { - return 0; - } - - @Override - public Iterator iterator() { - return ImmutableSet.of().iterator(); - } - }; - - /** - * Queue that discards all elements. - */ - @SuppressWarnings("unchecked") // impl never uses a parameter or returns any non-null value - static Queue discardingQueue() { - return (Queue) DISCARDING_QUEUE; - } - - /* - * Note: All of this duplicate code sucks, but it saves a lot of memory. If only Java had mixins! - * To maintain this code, make a change for the strong reference type. Then, cut and paste, and - * replace "Strong" with "Soft" or "Weak" within the pasted text. The primary difference is that - * strong entries store the key reference directly while soft and weak entries delegate to their - * respective superclasses. - */ - - /** - * Used for strongly-referenced keys. - */ - static class StrongEntry extends AbstractReferenceEntry { - final K key; - - StrongEntry(K key, int hash, @Nullable ReferenceEntry next) { - this.key = key; - this.hash = hash; - this.next = next; - } - - @Override - public K getKey() { - return this.key; - } - - // The code below is exactly the same for each entry type. - - final int hash; - final ReferenceEntry next; - volatile ValueReference valueReference = unset(); - - @Override - public ValueReference getValueReference() { - return valueReference; - } - - @Override - public void setValueReference(ValueReference valueReference) { - this.valueReference = valueReference; - } - - @Override - public int getHash() { - return hash; - } - - @Override - public ReferenceEntry getNext() { - return next; - } - } - - static final class StrongAccessEntry extends StrongEntry { - StrongAccessEntry(K key, int hash, @Nullable ReferenceEntry next) { - super(key, hash, next); - } - - // The code below is exactly the same for each access entry type. - - volatile long accessTime = Long.MAX_VALUE; - - @Override - public long getAccessTime() { - return accessTime; - } - - @Override - public void setAccessTime(long time) { - this.accessTime = time; - } - - // Guarded By Segment.this - ReferenceEntry nextAccess = nullEntry(); - - @Override - public ReferenceEntry getNextInAccessQueue() { - return nextAccess; - } - - @Override - public void setNextInAccessQueue(ReferenceEntry next) { - this.nextAccess = next; - } - - // Guarded By Segment.this - ReferenceEntry previousAccess = nullEntry(); - - @Override - public ReferenceEntry getPreviousInAccessQueue() { - return previousAccess; - } - - @Override - public void setPreviousInAccessQueue(ReferenceEntry previous) { - this.previousAccess = previous; - } - } - - static final class StrongWriteEntry extends StrongEntry { - StrongWriteEntry(K key, int hash, @Nullable ReferenceEntry next) { - super(key, hash, next); - } - - // The code below is exactly the same for each write entry type. - - volatile long writeTime = Long.MAX_VALUE; - - @Override - public long getWriteTime() { - return writeTime; - } - - @Override - public void setWriteTime(long time) { - this.writeTime = time; - } - - // Guarded By Segment.this - ReferenceEntry nextWrite = nullEntry(); - - @Override - public ReferenceEntry getNextInWriteQueue() { - return nextWrite; - } - - @Override - public void setNextInWriteQueue(ReferenceEntry next) { - this.nextWrite = next; - } - - // Guarded By Segment.this - ReferenceEntry previousWrite = nullEntry(); - - @Override - public ReferenceEntry getPreviousInWriteQueue() { - return previousWrite; - } - - @Override - public void setPreviousInWriteQueue(ReferenceEntry previous) { - this.previousWrite = previous; - } - } - - static final class StrongAccessWriteEntry extends StrongEntry { - StrongAccessWriteEntry(K key, int hash, @Nullable ReferenceEntry next) { - super(key, hash, next); - } - - // The code below is exactly the same for each access entry type. - - volatile long accessTime = Long.MAX_VALUE; - - @Override - public long getAccessTime() { - return accessTime; - } - - @Override - public void setAccessTime(long time) { - this.accessTime = time; - } - - // Guarded By Segment.this - ReferenceEntry nextAccess = nullEntry(); - - @Override - public ReferenceEntry getNextInAccessQueue() { - return nextAccess; - } - - @Override - public void setNextInAccessQueue(ReferenceEntry next) { - this.nextAccess = next; - } - - // Guarded By Segment.this - ReferenceEntry previousAccess = nullEntry(); - - @Override - public ReferenceEntry getPreviousInAccessQueue() { - return previousAccess; - } - - @Override - public void setPreviousInAccessQueue(ReferenceEntry previous) { - this.previousAccess = previous; - } - - // The code below is exactly the same for each write entry type. - - volatile long writeTime = Long.MAX_VALUE; - - @Override - public long getWriteTime() { - return writeTime; - } - - @Override - public void setWriteTime(long time) { - this.writeTime = time; - } - - // Guarded By Segment.this - ReferenceEntry nextWrite = nullEntry(); - - @Override - public ReferenceEntry getNextInWriteQueue() { - return nextWrite; - } - - @Override - public void setNextInWriteQueue(ReferenceEntry next) { - this.nextWrite = next; - } - - // Guarded By Segment.this - ReferenceEntry previousWrite = nullEntry(); - - @Override - public ReferenceEntry getPreviousInWriteQueue() { - return previousWrite; - } - - @Override - public void setPreviousInWriteQueue(ReferenceEntry previous) { - this.previousWrite = previous; - } - } - - /** - * Used for weakly-referenced keys. - */ - static class WeakEntry extends WeakReference implements ReferenceEntry { - WeakEntry(ReferenceQueue queue, K key, int hash, @Nullable ReferenceEntry next) { - super(key, queue); - this.hash = hash; - this.next = next; - } - - @Override - public K getKey() { - return get(); - } - - /* - * It'd be nice to get these for free from AbstractReferenceEntry, but we're already extending - * WeakReference. - */ - - // null access - - @Override - public long getAccessTime() { - throw new UnsupportedOperationException(); - } - - @Override - public void setAccessTime(long time) { - throw new UnsupportedOperationException(); - } - - @Override - public ReferenceEntry getNextInAccessQueue() { - throw new UnsupportedOperationException(); - } - - @Override - public void setNextInAccessQueue(ReferenceEntry next) { - throw new UnsupportedOperationException(); - } - - @Override - public ReferenceEntry getPreviousInAccessQueue() { - throw new UnsupportedOperationException(); - } - - @Override - public void setPreviousInAccessQueue(ReferenceEntry previous) { - throw new UnsupportedOperationException(); - } - - // null write - - @Override - public long getWriteTime() { - throw new UnsupportedOperationException(); - } - - @Override - public void setWriteTime(long time) { - throw new UnsupportedOperationException(); - } - - @Override - public ReferenceEntry getNextInWriteQueue() { - throw new UnsupportedOperationException(); - } - - @Override - public void setNextInWriteQueue(ReferenceEntry next) { - throw new UnsupportedOperationException(); - } - - @Override - public ReferenceEntry getPreviousInWriteQueue() { - throw new UnsupportedOperationException(); - } - - @Override - public void setPreviousInWriteQueue(ReferenceEntry previous) { - throw new UnsupportedOperationException(); - } - - // The code below is exactly the same for each entry type. - - final int hash; - final ReferenceEntry next; - volatile ValueReference valueReference = unset(); - - @Override - public ValueReference getValueReference() { - return valueReference; - } - - @Override - public void setValueReference(ValueReference valueReference) { - this.valueReference = valueReference; - } - - @Override - public int getHash() { - return hash; - } - - @Override - public ReferenceEntry getNext() { - return next; - } - } - - static final class WeakAccessEntry extends WeakEntry { - WeakAccessEntry( - ReferenceQueue queue, K key, int hash, @Nullable ReferenceEntry next) { - super(queue, key, hash, next); - } - - // The code below is exactly the same for each access entry type. - - volatile long accessTime = Long.MAX_VALUE; - - @Override - public long getAccessTime() { - return accessTime; - } - - @Override - public void setAccessTime(long time) { - this.accessTime = time; - } - - // Guarded By Segment.this - ReferenceEntry nextAccess = nullEntry(); - - @Override - public ReferenceEntry getNextInAccessQueue() { - return nextAccess; - } - - @Override - public void setNextInAccessQueue(ReferenceEntry next) { - this.nextAccess = next; - } - - // Guarded By Segment.this - ReferenceEntry previousAccess = nullEntry(); - - @Override - public ReferenceEntry getPreviousInAccessQueue() { - return previousAccess; - } - - @Override - public void setPreviousInAccessQueue(ReferenceEntry previous) { - this.previousAccess = previous; - } - } - - static final class WeakWriteEntry extends WeakEntry { - WeakWriteEntry( - ReferenceQueue queue, K key, int hash, @Nullable ReferenceEntry next) { - super(queue, key, hash, next); - } - - // The code below is exactly the same for each write entry type. - - volatile long writeTime = Long.MAX_VALUE; - - @Override - public long getWriteTime() { - return writeTime; - } - - @Override - public void setWriteTime(long time) { - this.writeTime = time; - } - - // Guarded By Segment.this - ReferenceEntry nextWrite = nullEntry(); - - @Override - public ReferenceEntry getNextInWriteQueue() { - return nextWrite; - } - - @Override - public void setNextInWriteQueue(ReferenceEntry next) { - this.nextWrite = next; - } - - // Guarded By Segment.this - ReferenceEntry previousWrite = nullEntry(); - - @Override - public ReferenceEntry getPreviousInWriteQueue() { - return previousWrite; - } - - @Override - public void setPreviousInWriteQueue(ReferenceEntry previous) { - this.previousWrite = previous; - } - } - - static final class WeakAccessWriteEntry extends WeakEntry { - WeakAccessWriteEntry( - ReferenceQueue queue, K key, int hash, @Nullable ReferenceEntry next) { - super(queue, key, hash, next); - } - - // The code below is exactly the same for each access entry type. - - volatile long accessTime = Long.MAX_VALUE; - - @Override - public long getAccessTime() { - return accessTime; - } - - @Override - public void setAccessTime(long time) { - this.accessTime = time; - } - - // Guarded By Segment.this - ReferenceEntry nextAccess = nullEntry(); - - @Override - public ReferenceEntry getNextInAccessQueue() { - return nextAccess; - } - - @Override - public void setNextInAccessQueue(ReferenceEntry next) { - this.nextAccess = next; - } - - // Guarded By Segment.this - ReferenceEntry previousAccess = nullEntry(); - - @Override - public ReferenceEntry getPreviousInAccessQueue() { - return previousAccess; - } - - @Override - public void setPreviousInAccessQueue(ReferenceEntry previous) { - this.previousAccess = previous; - } - - // The code below is exactly the same for each write entry type. - - volatile long writeTime = Long.MAX_VALUE; - - @Override - public long getWriteTime() { - return writeTime; - } - - @Override - public void setWriteTime(long time) { - this.writeTime = time; - } - - // Guarded By Segment.this - ReferenceEntry nextWrite = nullEntry(); - - @Override - public ReferenceEntry getNextInWriteQueue() { - return nextWrite; - } - - @Override - public void setNextInWriteQueue(ReferenceEntry next) { - this.nextWrite = next; - } - - // Guarded By Segment.this - ReferenceEntry previousWrite = nullEntry(); - - @Override - public ReferenceEntry getPreviousInWriteQueue() { - return previousWrite; - } - - @Override - public void setPreviousInWriteQueue(ReferenceEntry previous) { - this.previousWrite = previous; - } - } - - /** - * References a weak value. - */ - static class WeakValueReference - extends WeakReference implements ValueReference { - final ReferenceEntry entry; - - WeakValueReference(ReferenceQueue queue, V referent, ReferenceEntry entry) { - super(referent, queue); - this.entry = entry; - } - - @Override - public int getWeight() { - return 1; - } - - @Override - public ReferenceEntry getEntry() { - return entry; - } - - @Override - public void notifyNewValue(V newValue) {} - - @Override - public ValueReference copyFor( - ReferenceQueue queue, V value, ReferenceEntry entry) { - return new WeakValueReference(queue, value, entry); - } - - @Override - public boolean isLoading() { - return false; - } - - @Override - public boolean isActive() { - return true; - } - - @Override - public V waitForValue() { - return get(); - } - } - - /** - * References a soft value. - */ - static class SoftValueReference - extends SoftReference implements ValueReference { - final ReferenceEntry entry; - - SoftValueReference(ReferenceQueue queue, V referent, ReferenceEntry entry) { - super(referent, queue); - this.entry = entry; - } - - @Override - public int getWeight() { - return 1; - } - - @Override - public ReferenceEntry getEntry() { - return entry; - } - - @Override - public void notifyNewValue(V newValue) {} - - @Override - public ValueReference copyFor( - ReferenceQueue queue, V value, ReferenceEntry entry) { - return new SoftValueReference(queue, value, entry); - } - - @Override - public boolean isLoading() { - return false; - } - - @Override - public boolean isActive() { - return true; - } - - @Override - public V waitForValue() { - return get(); - } - } - - /** - * References a strong value. - */ - static class StrongValueReference implements ValueReference { - final V referent; - - StrongValueReference(V referent) { - this.referent = referent; - } - - @Override - public V get() { - return referent; - } - - @Override - public int getWeight() { - return 1; - } - - @Override - public ReferenceEntry getEntry() { - return null; - } - - @Override - public ValueReference copyFor( - ReferenceQueue queue, V value, ReferenceEntry entry) { - return this; - } - - @Override - public boolean isLoading() { - return false; - } - - @Override - public boolean isActive() { - return true; - } - - @Override - public V waitForValue() { - return get(); - } - - @Override - public void notifyNewValue(V newValue) {} - } - - /** - * References a weak value. - */ - static final class WeightedWeakValueReference extends WeakValueReference { - final int weight; - - WeightedWeakValueReference(ReferenceQueue queue, V referent, ReferenceEntry entry, - int weight) { - super(queue, referent, entry); - this.weight = weight; - } - - @Override - public int getWeight() { - return weight; - } - - @Override - public ValueReference copyFor( - ReferenceQueue queue, V value, ReferenceEntry entry) { - return new WeightedWeakValueReference(queue, value, entry, weight); - } - } - - /** - * References a soft value. - */ - static final class WeightedSoftValueReference extends SoftValueReference { - final int weight; - - WeightedSoftValueReference(ReferenceQueue queue, V referent, ReferenceEntry entry, - int weight) { - super(queue, referent, entry); - this.weight = weight; - } - - @Override - public int getWeight() { - return weight; - } - @Override - public ValueReference copyFor( - ReferenceQueue queue, V value, ReferenceEntry entry) { - return new WeightedSoftValueReference(queue, value, entry, weight); - } - - } - - /** - * References a strong value. - */ - static final class WeightedStrongValueReference extends StrongValueReference { - final int weight; - - WeightedStrongValueReference(V referent, int weight) { - super(referent); - this.weight = weight; - } - - @Override - public int getWeight() { - return weight; - } - } - - /** - * Applies a supplemental hash function to a given hash code, which defends against poor quality - * hash functions. This is critical when the concurrent hash map uses power-of-two length hash - * tables, that otherwise encounter collisions for hash codes that do not differ in lower or - * upper bits. - * - * @param h hash code - */ - static int rehash(int h) { - // Spread bits to regularize both segment and index locations, - // using variant of single-word Wang/Jenkins hash. - // TODO(kevinb): use Hashing/move this to Hashing? - h += (h << 15) ^ 0xffffcd7d; - h ^= (h >>> 10); - h += (h << 3); - h ^= (h >>> 6); - h += (h << 2) + (h << 14); - return h ^ (h >>> 16); - } - - /** - * This method is a convenience for testing. Code should call {@link Segment#newEntry} directly. - */ - @VisibleForTesting - ReferenceEntry newEntry(K key, int hash, @Nullable ReferenceEntry next) { - Segment segment = segmentFor(hash); - segment.lock(); - try { - return segment.newEntry(key, hash, next); - } finally { - segment.unlock(); - } - } - - /** - * This method is a convenience for testing. Code should call {@link Segment#copyEntry} directly. - */ - // Guarded By Segment.this - @VisibleForTesting - ReferenceEntry copyEntry(ReferenceEntry original, ReferenceEntry newNext) { - int hash = original.getHash(); - return segmentFor(hash).copyEntry(original, newNext); - } - - /** - * This method is a convenience for testing. Code should call {@link Segment#setValue} instead. - */ - // Guarded By Segment.this - @VisibleForTesting - ValueReference newValueReference(ReferenceEntry entry, V value, int weight) { - int hash = entry.getHash(); - return valueStrength.referenceValue(segmentFor(hash), entry, checkNotNull(value), weight); - } - - int hash(@Nullable Object key) { - int h = keyEquivalence.hash(key); - return rehash(h); - } - - void reclaimValue(ValueReference valueReference) { - ReferenceEntry entry = valueReference.getEntry(); - int hash = entry.getHash(); - segmentFor(hash).reclaimValue(entry.getKey(), hash, valueReference); - } - - void reclaimKey(ReferenceEntry entry) { - int hash = entry.getHash(); - segmentFor(hash).reclaimKey(entry, hash); - } - - /** - * This method is a convenience for testing. Code should call {@link Segment#getLiveValue} - * instead. - */ - @VisibleForTesting - boolean isLive(ReferenceEntry entry, long now) { - return segmentFor(entry.getHash()).getLiveValue(entry, now) != null; - } - - /** - * Returns the segment that should be used for a key with the given hash. - * - * @param hash the hash code for the key - * @return the segment - */ - Segment segmentFor(int hash) { - // TODO(fry): Lazily create segments? - return segments[(hash >>> segmentShift) & segmentMask]; - } - - Segment createSegment( - int initialCapacity, long maxSegmentWeight, StatsCounter statsCounter) { - return new Segment(this, initialCapacity, maxSegmentWeight, statsCounter); - } - - /** - * Gets the value from an entry. Returns null if the entry is invalid, partially-collected, - * loading, or expired. Unlike {@link Segment#getLiveValue} this method does not attempt to - * cleanup stale entries. As such it should only be called outside of a segment context, such as - * during iteration. - */ - @Nullable - V getLiveValue(ReferenceEntry entry, long now) { - if (entry.getKey() == null) { - return null; - } - V value = entry.getValueReference().get(); - if (value == null) { - return null; - } - - if (isExpired(entry, now)) { - return null; - } - return value; - } - - // expiration - - /** - * Returns true if the entry has expired. - */ - boolean isExpired(ReferenceEntry entry, long now) { - checkNotNull(entry); - if (expiresAfterAccess() - && (now - entry.getAccessTime() >= expireAfterAccessNanos)) { - return true; - } - if (expiresAfterWrite() - && (now - entry.getWriteTime() >= expireAfterWriteNanos)) { - return true; - } - return false; - } - - // queues - - // Guarded By Segment.this - static void connectAccessOrder(ReferenceEntry previous, ReferenceEntry next) { - previous.setNextInAccessQueue(next); - next.setPreviousInAccessQueue(previous); - } - - // Guarded By Segment.this - static void nullifyAccessOrder(ReferenceEntry nulled) { - ReferenceEntry nullEntry = nullEntry(); - nulled.setNextInAccessQueue(nullEntry); - nulled.setPreviousInAccessQueue(nullEntry); - } - - // Guarded By Segment.this - static void connectWriteOrder(ReferenceEntry previous, ReferenceEntry next) { - previous.setNextInWriteQueue(next); - next.setPreviousInWriteQueue(previous); - } - - // Guarded By Segment.this - static void nullifyWriteOrder(ReferenceEntry nulled) { - ReferenceEntry nullEntry = nullEntry(); - nulled.setNextInWriteQueue(nullEntry); - nulled.setPreviousInWriteQueue(nullEntry); - } - - /** - * Notifies listeners that an entry has been automatically removed due to expiration, eviction, - * or eligibility for garbage collection. This should be called every time expireEntries or - * evictEntry is called (once the lock is released). - */ - void processPendingNotifications() { - RemovalNotification notification; - while ((notification = removalNotificationQueue.poll()) != null) { - try { - removalListener.onRemoval(notification); - } catch (Throwable e) { - logger.log(Level.WARNING, "Exception thrown by removal listener", e); - } - } - } - - @SuppressWarnings("unchecked") - final Segment[] newSegmentArray(int ssize) { - return new Segment[ssize]; - } - - // Inner Classes - - /** - * Segments are specialized versions of hash tables. This subclass inherits from ReentrantLock - * opportunistically, just to simplify some locking and avoid separate construction. - */ - @SuppressWarnings("serial") // This class is never serialized. - static class Segment extends ReentrantLock { - - /* - * TODO(fry): Consider copying variables (like evictsBySize) from outer class into this class. - * It will require more memory but will reduce indirection. - */ - - /* - * Segments maintain a table of entry lists that are ALWAYS kept in a consistent state, so can - * be read without locking. Next fields of nodes are immutable (final). All list additions are - * performed at the front of each bin. This makes it easy to check changes, and also fast to - * traverse. When nodes would otherwise be changed, new nodes are created to replace them. This - * works well for hash tables since the bin lists tend to be short. (The average length is less - * than two.) - * - * Read operations can thus proceed without locking, but rely on selected uses of volatiles to - * ensure that completed write operations performed by other threads are noticed. For most - * purposes, the "count" field, tracking the number of elements, serves as that volatile - * variable ensuring visibility. This is convenient because this field needs to be read in many - * read operations anyway: - * - * - All (unsynchronized) read operations must first read the "count" field, and should not - * look at table entries if it is 0. - * - * - All (synchronized) write operations should write to the "count" field after structurally - * changing any bin. The operations must not take any action that could even momentarily - * cause a concurrent read operation to see inconsistent data. This is made easier by the - * nature of the read operations in Map. For example, no operation can reveal that the table - * has grown but the threshold has not yet been updated, so there are no atomicity requirements - * for this with respect to reads. - * - * As a guide, all critical volatile reads and writes to the count field are marked in code - * comments. - */ - - @Weak final LocalCache map; - - /** - * The number of live elements in this segment's region. - */ - volatile int count; - - /** - * The weight of the live elements in this segment's region. - */ - @GuardedBy("this") - long totalWeight; - - /** - * Number of updates that alter the size of the table. This is used during bulk-read methods to - * make sure they see a consistent snapshot: If modCounts change during a traversal of segments - * loading size or checking containsValue, then we might have an inconsistent view of state - * so (usually) must retry. - */ - int modCount; - - /** - * The table is expanded when its size exceeds this threshold. (The value of this field is - * always {@code (int) (capacity * 0.75)}.) - */ - int threshold; - - /** - * The per-segment table. - */ - volatile AtomicReferenceArray> table; - - /** - * The maximum weight of this segment. UNSET_INT if there is no maximum. - */ - final long maxSegmentWeight; - - /** - * The key reference queue contains entries whose keys have been garbage collected, and which - * need to be cleaned up internally. - */ - final ReferenceQueue keyReferenceQueue; - - /** - * The value reference queue contains value references whose values have been garbage collected, - * and which need to be cleaned up internally. - */ - final ReferenceQueue valueReferenceQueue; - - /** - * The recency queue is used to record which entries were accessed for updating the access - * list's ordering. It is drained as a batch operation when either the DRAIN_THRESHOLD is - * crossed or a write occurs on the segment. - */ - final Queue> recencyQueue; - - /** - * A counter of the number of reads since the last write, used to drain queues on a small - * fraction of read operations. - */ - final AtomicInteger readCount = new AtomicInteger(); - - /** - * A queue of elements currently in the map, ordered by write time. Elements are added to the - * tail of the queue on write. - */ - @GuardedBy("this") - final Queue> writeQueue; - - /** - * A queue of elements currently in the map, ordered by access time. Elements are added to the - * tail of the queue on access (note that writes count as accesses). - */ - @GuardedBy("this") - final Queue> accessQueue; - - /** Accumulates cache statistics. */ - final StatsCounter statsCounter; - - Segment(LocalCache map, int initialCapacity, long maxSegmentWeight, - StatsCounter statsCounter) { - this.map = map; - this.maxSegmentWeight = maxSegmentWeight; - this.statsCounter = checkNotNull(statsCounter); - initTable(newEntryArray(initialCapacity)); - - keyReferenceQueue = map.usesKeyReferences() - ? new ReferenceQueue() : null; - - valueReferenceQueue = map.usesValueReferences() - ? new ReferenceQueue() : null; - - recencyQueue = map.usesAccessQueue() - ? new ConcurrentLinkedQueue>() - : LocalCache.>discardingQueue(); - - writeQueue = map.usesWriteQueue() - ? new WriteQueue() - : LocalCache.>discardingQueue(); - - accessQueue = map.usesAccessQueue() - ? new AccessQueue() - : LocalCache.>discardingQueue(); - } - - AtomicReferenceArray> newEntryArray(int size) { - return new AtomicReferenceArray>(size); - } - - void initTable(AtomicReferenceArray> newTable) { - this.threshold = newTable.length() * 3 / 4; // 0.75 - if (!map.customWeigher() && this.threshold == maxSegmentWeight) { - // prevent spurious expansion before eviction - this.threshold++; - } - this.table = newTable; - } - - @GuardedBy("this") - ReferenceEntry newEntry(K key, int hash, @Nullable ReferenceEntry next) { - return map.entryFactory.newEntry(this, checkNotNull(key), hash, next); - } - - /** - * Copies {@code original} into a new entry chained to {@code newNext}. Returns the new entry, - * or {@code null} if {@code original} was already garbage collected. - */ - @GuardedBy("this") - ReferenceEntry copyEntry(ReferenceEntry original, ReferenceEntry newNext) { - if (original.getKey() == null) { - // key collected - return null; - } - - ValueReference valueReference = original.getValueReference(); - V value = valueReference.get(); - if ((value == null) && valueReference.isActive()) { - // value collected - return null; - } - - ReferenceEntry newEntry = map.entryFactory.copyEntry(this, original, newNext); - newEntry.setValueReference(valueReference.copyFor(this.valueReferenceQueue, value, newEntry)); - return newEntry; - } - - /** - * Sets a new value of an entry. Adds newly created entries at the end of the access queue. - */ - @GuardedBy("this") - void setValue(ReferenceEntry entry, K key, V value, long now) { - ValueReference previous = entry.getValueReference(); - int weight = map.weigher.weigh(key, value); - checkState(weight >= 0, "Weights must be non-negative"); - - ValueReference valueReference = - map.valueStrength.referenceValue(this, entry, value, weight); - entry.setValueReference(valueReference); - recordWrite(entry, weight, now); - previous.notifyNewValue(value); - } - - // loading - - V get(K key, int hash, CacheLoader loader) throws ExecutionException { - checkNotNull(key); - checkNotNull(loader); - try { - if (count != 0) { // read-volatile - // don't call getLiveEntry, which would ignore loading values - ReferenceEntry e = getEntry(key, hash); - if (e != null) { - long now = map.ticker.read(); - V value = getLiveValue(e, now); - if (value != null) { - recordRead(e, now); - statsCounter.recordHits(1); - return scheduleRefresh(e, key, hash, value, now, loader); - } - ValueReference valueReference = e.getValueReference(); - if (valueReference.isLoading()) { - return waitForLoadingValue(e, key, valueReference); - } - } - } - - // at this point e is either null or expired; - return lockedGetOrLoad(key, hash, loader); - } catch (ExecutionException ee) { - Throwable cause = ee.getCause(); - if (cause instanceof Error) { - throw new ExecutionError((Error) cause); - } else if (cause instanceof RuntimeException) { - throw new UncheckedExecutionException(cause); - } - throw ee; - } finally { - postReadCleanup(); - } - } - - V lockedGetOrLoad(K key, int hash, CacheLoader loader) - throws ExecutionException { - ReferenceEntry e; - ValueReference valueReference = null; - LoadingValueReference loadingValueReference = null; - boolean createNewEntry = true; - - lock(); - try { - // re-read ticker once inside the lock - long now = map.ticker.read(); - preWriteCleanup(now); - - int newCount = this.count - 1; - AtomicReferenceArray> table = this.table; - int index = hash & (table.length() - 1); - ReferenceEntry first = table.get(index); - - for (e = first; e != null; e = e.getNext()) { - K entryKey = e.getKey(); - if (e.getHash() == hash && entryKey != null - && map.keyEquivalence.equivalent(key, entryKey)) { - valueReference = e.getValueReference(); - if (valueReference.isLoading()) { - createNewEntry = false; - } else { - V value = valueReference.get(); - if (value == null) { - enqueueNotification(entryKey, hash, valueReference, RemovalCause.COLLECTED); - } else if (map.isExpired(e, now)) { - // This is a duplicate check, as preWriteCleanup already purged expired - // entries, but let's accomodate an incorrect expiration queue. - enqueueNotification(entryKey, hash, valueReference, RemovalCause.EXPIRED); - } else { - recordLockedRead(e, now); - statsCounter.recordHits(1); - // we were concurrent with loading; don't consider refresh - return value; - } - - // immediately reuse invalid entries - writeQueue.remove(e); - accessQueue.remove(e); - this.count = newCount; // write-volatile - } - break; - } - } - - if (createNewEntry) { - loadingValueReference = new LoadingValueReference(); - - if (e == null) { - e = newEntry(key, hash, first); - e.setValueReference(loadingValueReference); - table.set(index, e); - } else { - e.setValueReference(loadingValueReference); - } - } - } finally { - unlock(); - postWriteCleanup(); - } - - if (createNewEntry) { - try { - // Synchronizes on the entry to allow failing fast when a recursive load is - // detected. This may be circumvented when an entry is copied, but will fail fast most - // of the time. - synchronized (e) { - return loadSync(key, hash, loadingValueReference, loader); - } - } finally { - statsCounter.recordMisses(1); - } - } else { - // The entry already exists. Wait for loading. - return waitForLoadingValue(e, key, valueReference); - } - } - - V waitForLoadingValue(ReferenceEntry e, K key, ValueReference valueReference) - throws ExecutionException { - if (!valueReference.isLoading()) { - throw new AssertionError(); - } - - checkState(!Thread.holdsLock(e), "Recursive load of: %s", key); - // don't consider expiration as we're concurrent with loading - try { - V value = valueReference.waitForValue(); - if (value == null) { - throw new InvalidCacheLoadException("CacheLoader returned null for key " + key + "."); - } - // re-read ticker now that loading has completed - long now = map.ticker.read(); - recordRead(e, now); - return value; - } finally { - statsCounter.recordMisses(1); - } - } - - // at most one of loadSync/loadAsync may be called for any given LoadingValueReference - - V loadSync(K key, int hash, LoadingValueReference loadingValueReference, - CacheLoader loader) throws ExecutionException { - ListenableFuture loadingFuture = loadingValueReference.loadFuture(key, loader); - return getAndRecordStats(key, hash, loadingValueReference, loadingFuture); - } - - ListenableFuture loadAsync(final K key, final int hash, - final LoadingValueReference loadingValueReference, CacheLoader loader) { - final ListenableFuture loadingFuture = loadingValueReference.loadFuture(key, loader); - loadingFuture.addListener( - new Runnable() { - @Override - public void run() { - try { - V newValue = getAndRecordStats(key, hash, loadingValueReference, loadingFuture); - } catch (Throwable t) { - logger.log(Level.WARNING, "Exception thrown during refresh", t); - loadingValueReference.setException(t); - } - } - }, directExecutor()); - return loadingFuture; - } - - /** - * Waits uninterruptibly for {@code newValue} to be loaded, and then records loading stats. - */ - V getAndRecordStats(K key, int hash, LoadingValueReference loadingValueReference, - ListenableFuture newValue) throws ExecutionException { - V value = null; - try { - value = getUninterruptibly(newValue); - if (value == null) { - throw new InvalidCacheLoadException("CacheLoader returned null for key " + key + "."); - } - statsCounter.recordLoadSuccess(loadingValueReference.elapsedNanos()); - storeLoadedValue(key, hash, loadingValueReference, value); - return value; - } finally { - if (value == null) { - statsCounter.recordLoadException(loadingValueReference.elapsedNanos()); - removeLoadingValue(key, hash, loadingValueReference); - } - } - } - - V scheduleRefresh(ReferenceEntry entry, K key, int hash, V oldValue, long now, - CacheLoader loader) { - if (map.refreshes() && (now - entry.getWriteTime() > map.refreshNanos) - && !entry.getValueReference().isLoading()) { - V newValue = refresh(key, hash, loader, true); - if (newValue != null) { - return newValue; - } - } - return oldValue; - } - - /** - * Refreshes the value associated with {@code key}, unless another thread is already doing so. - * Returns the newly refreshed value associated with {@code key} if it was refreshed inline, or - * {@code null} if another thread is performing the refresh or if an error occurs during - * refresh. - */ - @Nullable - V refresh(K key, int hash, CacheLoader loader, boolean checkTime) { - final LoadingValueReference loadingValueReference = - insertLoadingValueReference(key, hash, checkTime); - if (loadingValueReference == null) { - return null; - } - - ListenableFuture result = loadAsync(key, hash, loadingValueReference, loader); - if (result.isDone()) { - try { - return Uninterruptibles.getUninterruptibly(result); - } catch (Throwable t) { - // don't let refresh exceptions propagate; error was already logged - } - } - return null; - } - - /** - * Returns a newly inserted {@code LoadingValueReference}, or null if the live value reference - * is already loading. - */ - @Nullable - LoadingValueReference insertLoadingValueReference(final K key, final int hash, - boolean checkTime) { - ReferenceEntry e = null; - lock(); - try { - long now = map.ticker.read(); - preWriteCleanup(now); - - AtomicReferenceArray> table = this.table; - int index = hash & (table.length() - 1); - ReferenceEntry first = table.get(index); - - // Look for an existing entry. - for (e = first; e != null; e = e.getNext()) { - K entryKey = e.getKey(); - if (e.getHash() == hash && entryKey != null - && map.keyEquivalence.equivalent(key, entryKey)) { - // We found an existing entry. - - ValueReference valueReference = e.getValueReference(); - if (valueReference.isLoading() - || (checkTime && (now - e.getWriteTime() < map.refreshNanos))) { - // refresh is a no-op if loading is pending - // if checkTime, we want to check *after* acquiring the lock if refresh still needs - // to be scheduled - return null; - } - - // continue returning old value while loading - ++modCount; - LoadingValueReference loadingValueReference = - new LoadingValueReference(valueReference); - e.setValueReference(loadingValueReference); - return loadingValueReference; - } - } - - ++modCount; - LoadingValueReference loadingValueReference = new LoadingValueReference(); - e = newEntry(key, hash, first); - e.setValueReference(loadingValueReference); - table.set(index, e); - return loadingValueReference; - } finally { - unlock(); - postWriteCleanup(); - } - } - - // reference queues, for garbage collection cleanup - - /** - * Cleanup collected entries when the lock is available. - */ - void tryDrainReferenceQueues() { - if (tryLock()) { - try { - drainReferenceQueues(); - } finally { - unlock(); - } - } - } - - /** - * Drain the key and value reference queues, cleaning up internal entries containing garbage - * collected keys or values. - */ - @GuardedBy("this") - void drainReferenceQueues() { - if (map.usesKeyReferences()) { - drainKeyReferenceQueue(); - } - if (map.usesValueReferences()) { - drainValueReferenceQueue(); - } - } - - @GuardedBy("this") - void drainKeyReferenceQueue() { - Reference ref; - int i = 0; - while ((ref = keyReferenceQueue.poll()) != null) { - @SuppressWarnings("unchecked") - ReferenceEntry entry = (ReferenceEntry) ref; - map.reclaimKey(entry); - if (++i == DRAIN_MAX) { - break; - } - } - } - - @GuardedBy("this") - void drainValueReferenceQueue() { - Reference ref; - int i = 0; - while ((ref = valueReferenceQueue.poll()) != null) { - @SuppressWarnings("unchecked") - ValueReference valueReference = (ValueReference) ref; - map.reclaimValue(valueReference); - if (++i == DRAIN_MAX) { - break; - } - } - } - - /** - * Clears all entries from the key and value reference queues. - */ - void clearReferenceQueues() { - if (map.usesKeyReferences()) { - clearKeyReferenceQueue(); - } - if (map.usesValueReferences()) { - clearValueReferenceQueue(); - } - } - - void clearKeyReferenceQueue() { - while (keyReferenceQueue.poll() != null) {} - } - - void clearValueReferenceQueue() { - while (valueReferenceQueue.poll() != null) {} - } - - // recency queue, shared by expiration and eviction - - /** - * Records the relative order in which this read was performed by adding {@code entry} to the - * recency queue. At write-time, or when the queue is full past the threshold, the queue will - * be drained and the entries therein processed. - * - *

Note: locked reads should use {@link #recordLockedRead}. - */ - void recordRead(ReferenceEntry entry, long now) { - if (map.recordsAccess()) { - entry.setAccessTime(now); - } - recencyQueue.add(entry); - } - - /** - * Updates the eviction metadata that {@code entry} was just read. This currently amounts to - * adding {@code entry} to relevant eviction lists. - * - *

Note: this method should only be called under lock, as it directly manipulates the - * eviction queues. Unlocked reads should use {@link #recordRead}. - */ - @GuardedBy("this") - void recordLockedRead(ReferenceEntry entry, long now) { - if (map.recordsAccess()) { - entry.setAccessTime(now); - } - accessQueue.add(entry); - } - - /** - * Updates eviction metadata that {@code entry} was just written. This currently amounts to - * adding {@code entry} to relevant eviction lists. - */ - @GuardedBy("this") - void recordWrite(ReferenceEntry entry, int weight, long now) { - // we are already under lock, so drain the recency queue immediately - drainRecencyQueue(); - totalWeight += weight; - - if (map.recordsAccess()) { - entry.setAccessTime(now); - } - if (map.recordsWrite()) { - entry.setWriteTime(now); - } - accessQueue.add(entry); - writeQueue.add(entry); - } - - /** - * Drains the recency queue, updating eviction metadata that the entries therein were read in - * the specified relative order. This currently amounts to adding them to relevant eviction - * lists (accounting for the fact that they could have been removed from the map since being - * added to the recency queue). - */ - @GuardedBy("this") - void drainRecencyQueue() { - ReferenceEntry e; - while ((e = recencyQueue.poll()) != null) { - // An entry may be in the recency queue despite it being removed from - // the map . This can occur when the entry was concurrently read while a - // writer is removing it from the segment or after a clear has removed - // all of the segment's entries. - if (accessQueue.contains(e)) { - accessQueue.add(e); - } - } - } - - // expiration - - /** - * Cleanup expired entries when the lock is available. - */ - void tryExpireEntries(long now) { - if (tryLock()) { - try { - expireEntries(now); - } finally { - unlock(); - // don't call postWriteCleanup as we're in a read - } - } - } - - @GuardedBy("this") - void expireEntries(long now) { - drainRecencyQueue(); - - ReferenceEntry e; - while ((e = writeQueue.peek()) != null && map.isExpired(e, now)) { - if (!removeEntry(e, e.getHash(), RemovalCause.EXPIRED)) { - throw new AssertionError(); - } - } - while ((e = accessQueue.peek()) != null && map.isExpired(e, now)) { - if (!removeEntry(e, e.getHash(), RemovalCause.EXPIRED)) { - throw new AssertionError(); - } - } - } - - // eviction - - @GuardedBy("this") - void enqueueNotification(ReferenceEntry entry, RemovalCause cause) { - enqueueNotification(entry.getKey(), entry.getHash(), entry.getValueReference(), cause); - } - - @GuardedBy("this") - void enqueueNotification(@Nullable K key, int hash, ValueReference valueReference, - RemovalCause cause) { - totalWeight -= valueReference.getWeight(); - if (cause.wasEvicted()) { - statsCounter.recordEviction(); - } - if (map.removalNotificationQueue != DISCARDING_QUEUE) { - V value = valueReference.get(); - RemovalNotification notification = RemovalNotification.create(key, value, cause); - map.removalNotificationQueue.offer(notification); - } - } - - /** - * Performs eviction if the segment is over capacity. Avoids flushing the entire cache if the - * newest entry exceeds the maximum weight all on its own. - * - * @param newest the most recently added entry - */ - @GuardedBy("this") - void evictEntries(ReferenceEntry newest) { - if (!map.evictsBySize()) { - return; - } - - drainRecencyQueue(); - - // If the newest entry by itself is too heavy for the segment, don't bother evicting - // anything else, just that - if (newest.getValueReference().getWeight() > maxSegmentWeight) { - if (!removeEntry(newest, newest.getHash(), RemovalCause.SIZE)) { - throw new AssertionError(); - } - } - - while (totalWeight > maxSegmentWeight) { - ReferenceEntry e = getNextEvictable(); - if (!removeEntry(e, e.getHash(), RemovalCause.SIZE)) { - throw new AssertionError(); - } - } - } - - // TODO(fry): instead implement this with an eviction head - @GuardedBy("this") - ReferenceEntry getNextEvictable() { - for (ReferenceEntry e : accessQueue) { - int weight = e.getValueReference().getWeight(); - if (weight > 0) { - return e; - } - } - throw new AssertionError(); - } - - /** - * Returns first entry of bin for given hash. - */ - ReferenceEntry getFirst(int hash) { - // read this volatile field only once - AtomicReferenceArray> table = this.table; - return table.get(hash & (table.length() - 1)); - } - - // Specialized implementations of map methods - - @Nullable - ReferenceEntry getEntry(Object key, int hash) { - for (ReferenceEntry e = getFirst(hash); e != null; e = e.getNext()) { - if (e.getHash() != hash) { - continue; - } - - K entryKey = e.getKey(); - if (entryKey == null) { - tryDrainReferenceQueues(); - continue; - } - - if (map.keyEquivalence.equivalent(key, entryKey)) { - return e; - } - } - - return null; - } - - @Nullable - ReferenceEntry getLiveEntry(Object key, int hash, long now) { - ReferenceEntry e = getEntry(key, hash); - if (e == null) { - return null; - } else if (map.isExpired(e, now)) { - tryExpireEntries(now); - return null; - } - return e; - } - - /** - * Gets the value from an entry. Returns null if the entry is invalid, partially-collected, - * loading, or expired. - */ - V getLiveValue(ReferenceEntry entry, long now) { - if (entry.getKey() == null) { - tryDrainReferenceQueues(); - return null; - } - V value = entry.getValueReference().get(); - if (value == null) { - tryDrainReferenceQueues(); - return null; - } - - if (map.isExpired(entry, now)) { - tryExpireEntries(now); - return null; - } - return value; - } - - @Nullable - V get(Object key, int hash) { - try { - if (count != 0) { // read-volatile - long now = map.ticker.read(); - ReferenceEntry e = getLiveEntry(key, hash, now); - if (e == null) { - return null; - } - - V value = e.getValueReference().get(); - if (value != null) { - recordRead(e, now); - return scheduleRefresh(e, e.getKey(), hash, value, now, map.defaultLoader); - } - tryDrainReferenceQueues(); - } - return null; - } finally { - postReadCleanup(); - } - } - - boolean containsKey(Object key, int hash) { - try { - if (count != 0) { // read-volatile - long now = map.ticker.read(); - ReferenceEntry e = getLiveEntry(key, hash, now); - if (e == null) { - return false; - } - return e.getValueReference().get() != null; - } - - return false; - } finally { - postReadCleanup(); - } - } - - /** - * This method is a convenience for testing. Code should call {@link - * LocalCache#containsValue} directly. - */ - @VisibleForTesting - boolean containsValue(Object value) { - try { - if (count != 0) { // read-volatile - long now = map.ticker.read(); - AtomicReferenceArray> table = this.table; - int length = table.length(); - for (int i = 0; i < length; ++i) { - for (ReferenceEntry e = table.get(i); e != null; e = e.getNext()) { - V entryValue = getLiveValue(e, now); - if (entryValue == null) { - continue; - } - if (map.valueEquivalence.equivalent(value, entryValue)) { - return true; - } - } - } - } - - return false; - } finally { - postReadCleanup(); - } - } - - @Nullable - V put(K key, int hash, V value, boolean onlyIfAbsent) { - lock(); - try { - long now = map.ticker.read(); - preWriteCleanup(now); - - int newCount = this.count + 1; - if (newCount > this.threshold) { // ensure capacity - expand(); - newCount = this.count + 1; - } - - AtomicReferenceArray> table = this.table; - int index = hash & (table.length() - 1); - ReferenceEntry first = table.get(index); - - // Look for an existing entry. - for (ReferenceEntry e = first; e != null; e = e.getNext()) { - K entryKey = e.getKey(); - if (e.getHash() == hash && entryKey != null - && map.keyEquivalence.equivalent(key, entryKey)) { - // We found an existing entry. - - ValueReference valueReference = e.getValueReference(); - V entryValue = valueReference.get(); - - if (entryValue == null) { - ++modCount; - if (valueReference.isActive()) { - enqueueNotification(key, hash, valueReference, RemovalCause.COLLECTED); - setValue(e, key, value, now); - newCount = this.count; // count remains unchanged - } else { - setValue(e, key, value, now); - newCount = this.count + 1; - } - this.count = newCount; // write-volatile - evictEntries(e); - return null; - } else if (onlyIfAbsent) { - // Mimic - // "if (!map.containsKey(key)) ... - // else return map.get(key); - recordLockedRead(e, now); - return entryValue; - } else { - // clobber existing entry, count remains unchanged - ++modCount; - enqueueNotification(key, hash, valueReference, RemovalCause.REPLACED); - setValue(e, key, value, now); - evictEntries(e); - return entryValue; - } - } - } - - // Create a new entry. - ++modCount; - ReferenceEntry newEntry = newEntry(key, hash, first); - setValue(newEntry, key, value, now); - table.set(index, newEntry); - newCount = this.count + 1; - this.count = newCount; // write-volatile - evictEntries(newEntry); - return null; - } finally { - unlock(); - postWriteCleanup(); - } - } - - /** - * Expands the table if possible. - */ - @GuardedBy("this") - void expand() { - AtomicReferenceArray> oldTable = table; - int oldCapacity = oldTable.length(); - if (oldCapacity >= MAXIMUM_CAPACITY) { - return; - } - - /* - * Reclassify nodes in each list to new Map. Because we are using power-of-two expansion, the - * elements from each bin must either stay at same index, or move with a power of two offset. - * We eliminate unnecessary node creation by catching cases where old nodes can be reused - * because their next fields won't change. Statistically, at the default threshold, only - * about one-sixth of them need cloning when a table doubles. The nodes they replace will be - * garbage collectable as soon as they are no longer referenced by any reader thread that may - * be in the midst of traversing table right now. - */ - - int newCount = count; - AtomicReferenceArray> newTable = newEntryArray(oldCapacity << 1); - threshold = newTable.length() * 3 / 4; - int newMask = newTable.length() - 1; - for (int oldIndex = 0; oldIndex < oldCapacity; ++oldIndex) { - // We need to guarantee that any existing reads of old Map can - // proceed. So we cannot yet null out each bin. - ReferenceEntry head = oldTable.get(oldIndex); - - if (head != null) { - ReferenceEntry next = head.getNext(); - int headIndex = head.getHash() & newMask; - - // Single node on list - if (next == null) { - newTable.set(headIndex, head); - } else { - // Reuse the consecutive sequence of nodes with the same target - // index from the end of the list. tail points to the first - // entry in the reusable list. - ReferenceEntry tail = head; - int tailIndex = headIndex; - for (ReferenceEntry e = next; e != null; e = e.getNext()) { - int newIndex = e.getHash() & newMask; - if (newIndex != tailIndex) { - // The index changed. We'll need to copy the previous entry. - tailIndex = newIndex; - tail = e; - } - } - newTable.set(tailIndex, tail); - - // Clone nodes leading up to the tail. - for (ReferenceEntry e = head; e != tail; e = e.getNext()) { - int newIndex = e.getHash() & newMask; - ReferenceEntry newNext = newTable.get(newIndex); - ReferenceEntry newFirst = copyEntry(e, newNext); - if (newFirst != null) { - newTable.set(newIndex, newFirst); - } else { - removeCollectedEntry(e); - newCount--; - } - } - } - } - } - table = newTable; - this.count = newCount; - } - - boolean replace(K key, int hash, V oldValue, V newValue) { - lock(); - try { - long now = map.ticker.read(); - preWriteCleanup(now); - - AtomicReferenceArray> table = this.table; - int index = hash & (table.length() - 1); - ReferenceEntry first = table.get(index); - - for (ReferenceEntry e = first; e != null; e = e.getNext()) { - K entryKey = e.getKey(); - if (e.getHash() == hash && entryKey != null - && map.keyEquivalence.equivalent(key, entryKey)) { - ValueReference valueReference = e.getValueReference(); - V entryValue = valueReference.get(); - if (entryValue == null) { - if (valueReference.isActive()) { - // If the value disappeared, this entry is partially collected. - int newCount = this.count - 1; - ++modCount; - ReferenceEntry newFirst = removeValueFromChain( - first, e, entryKey, hash, valueReference, RemovalCause.COLLECTED); - newCount = this.count - 1; - table.set(index, newFirst); - this.count = newCount; // write-volatile - } - return false; - } - - if (map.valueEquivalence.equivalent(oldValue, entryValue)) { - ++modCount; - enqueueNotification(key, hash, valueReference, RemovalCause.REPLACED); - setValue(e, key, newValue, now); - evictEntries(e); - return true; - } else { - // Mimic - // "if (map.containsKey(key) && map.get(key).equals(oldValue))..." - recordLockedRead(e, now); - return false; - } - } - } - - return false; - } finally { - unlock(); - postWriteCleanup(); - } - } - - @Nullable - V replace(K key, int hash, V newValue) { - lock(); - try { - long now = map.ticker.read(); - preWriteCleanup(now); - - AtomicReferenceArray> table = this.table; - int index = hash & (table.length() - 1); - ReferenceEntry first = table.get(index); - - for (ReferenceEntry e = first; e != null; e = e.getNext()) { - K entryKey = e.getKey(); - if (e.getHash() == hash && entryKey != null - && map.keyEquivalence.equivalent(key, entryKey)) { - ValueReference valueReference = e.getValueReference(); - V entryValue = valueReference.get(); - if (entryValue == null) { - if (valueReference.isActive()) { - // If the value disappeared, this entry is partially collected. - int newCount = this.count - 1; - ++modCount; - ReferenceEntry newFirst = removeValueFromChain( - first, e, entryKey, hash, valueReference, RemovalCause.COLLECTED); - newCount = this.count - 1; - table.set(index, newFirst); - this.count = newCount; // write-volatile - } - return null; - } - - ++modCount; - enqueueNotification(key, hash, valueReference, RemovalCause.REPLACED); - setValue(e, key, newValue, now); - evictEntries(e); - return entryValue; - } - } - - return null; - } finally { - unlock(); - postWriteCleanup(); - } - } - - @Nullable - V remove(Object key, int hash) { - lock(); - try { - long now = map.ticker.read(); - preWriteCleanup(now); - - int newCount = this.count - 1; - AtomicReferenceArray> table = this.table; - int index = hash & (table.length() - 1); - ReferenceEntry first = table.get(index); - - for (ReferenceEntry e = first; e != null; e = e.getNext()) { - K entryKey = e.getKey(); - if (e.getHash() == hash && entryKey != null - && map.keyEquivalence.equivalent(key, entryKey)) { - ValueReference valueReference = e.getValueReference(); - V entryValue = valueReference.get(); - - RemovalCause cause; - if (entryValue != null) { - cause = RemovalCause.EXPLICIT; - } else if (valueReference.isActive()) { - cause = RemovalCause.COLLECTED; - } else { - // currently loading - return null; - } - - ++modCount; - ReferenceEntry newFirst = removeValueFromChain( - first, e, entryKey, hash, valueReference, cause); - newCount = this.count - 1; - table.set(index, newFirst); - this.count = newCount; // write-volatile - return entryValue; - } - } - - return null; - } finally { - unlock(); - postWriteCleanup(); - } - } - - boolean storeLoadedValue(K key, int hash, LoadingValueReference oldValueReference, - V newValue) { - lock(); - try { - long now = map.ticker.read(); - preWriteCleanup(now); - - int newCount = this.count + 1; - if (newCount > this.threshold) { // ensure capacity - expand(); - newCount = this.count + 1; - } - - AtomicReferenceArray> table = this.table; - int index = hash & (table.length() - 1); - ReferenceEntry first = table.get(index); - - for (ReferenceEntry e = first; e != null; e = e.getNext()) { - K entryKey = e.getKey(); - if (e.getHash() == hash && entryKey != null - && map.keyEquivalence.equivalent(key, entryKey)) { - ValueReference valueReference = e.getValueReference(); - V entryValue = valueReference.get(); - // replace the old LoadingValueReference if it's live, otherwise - // perform a putIfAbsent - if (oldValueReference == valueReference - || (entryValue == null && valueReference != UNSET)) { - ++modCount; - if (oldValueReference.isActive()) { - RemovalCause cause = - (entryValue == null) ? RemovalCause.COLLECTED : RemovalCause.REPLACED; - enqueueNotification(key, hash, oldValueReference, cause); - newCount--; - } - setValue(e, key, newValue, now); - this.count = newCount; // write-volatile - evictEntries(e); - return true; - } - - // the loaded value was already clobbered - valueReference = new WeightedStrongValueReference(newValue, 0); - enqueueNotification(key, hash, valueReference, RemovalCause.REPLACED); - return false; - } - } - - ++modCount; - ReferenceEntry newEntry = newEntry(key, hash, first); - setValue(newEntry, key, newValue, now); - table.set(index, newEntry); - this.count = newCount; // write-volatile - evictEntries(newEntry); - return true; - } finally { - unlock(); - postWriteCleanup(); - } - } - - boolean remove(Object key, int hash, Object value) { - lock(); - try { - long now = map.ticker.read(); - preWriteCleanup(now); - - int newCount = this.count - 1; - AtomicReferenceArray> table = this.table; - int index = hash & (table.length() - 1); - ReferenceEntry first = table.get(index); - - for (ReferenceEntry e = first; e != null; e = e.getNext()) { - K entryKey = e.getKey(); - if (e.getHash() == hash && entryKey != null - && map.keyEquivalence.equivalent(key, entryKey)) { - ValueReference valueReference = e.getValueReference(); - V entryValue = valueReference.get(); - - RemovalCause cause; - if (map.valueEquivalence.equivalent(value, entryValue)) { - cause = RemovalCause.EXPLICIT; - } else if (entryValue == null && valueReference.isActive()) { - cause = RemovalCause.COLLECTED; - } else { - // currently loading - return false; - } - - ++modCount; - ReferenceEntry newFirst = removeValueFromChain( - first, e, entryKey, hash, valueReference, cause); - newCount = this.count - 1; - table.set(index, newFirst); - this.count = newCount; // write-volatile - return (cause == RemovalCause.EXPLICIT); - } - } - - return false; - } finally { - unlock(); - postWriteCleanup(); - } - } - - void clear() { - if (count != 0) { // read-volatile - lock(); - try { - AtomicReferenceArray> table = this.table; - for (int i = 0; i < table.length(); ++i) { - for (ReferenceEntry e = table.get(i); e != null; e = e.getNext()) { - // Loading references aren't actually in the map yet. - if (e.getValueReference().isActive()) { - enqueueNotification(e, RemovalCause.EXPLICIT); - } - } - } - for (int i = 0; i < table.length(); ++i) { - table.set(i, null); - } - clearReferenceQueues(); - writeQueue.clear(); - accessQueue.clear(); - readCount.set(0); - - ++modCount; - count = 0; // write-volatile - } finally { - unlock(); - postWriteCleanup(); - } - } - } - - @GuardedBy("this") - @Nullable - ReferenceEntry removeValueFromChain(ReferenceEntry first, - ReferenceEntry entry, @Nullable K key, int hash, ValueReference valueReference, - RemovalCause cause) { - enqueueNotification(key, hash, valueReference, cause); - writeQueue.remove(entry); - accessQueue.remove(entry); - - if (valueReference.isLoading()) { - valueReference.notifyNewValue(null); - return first; - } else { - return removeEntryFromChain(first, entry); - } - } - - @GuardedBy("this") - @Nullable - ReferenceEntry removeEntryFromChain(ReferenceEntry first, - ReferenceEntry entry) { - int newCount = count; - ReferenceEntry newFirst = entry.getNext(); - for (ReferenceEntry e = first; e != entry; e = e.getNext()) { - ReferenceEntry next = copyEntry(e, newFirst); - if (next != null) { - newFirst = next; - } else { - removeCollectedEntry(e); - newCount--; - } - } - this.count = newCount; - return newFirst; - } - - @GuardedBy("this") - void removeCollectedEntry(ReferenceEntry entry) { - enqueueNotification(entry, RemovalCause.COLLECTED); - writeQueue.remove(entry); - accessQueue.remove(entry); - } - - /** - * Removes an entry whose key has been garbage collected. - */ - boolean reclaimKey(ReferenceEntry entry, int hash) { - lock(); - try { - int newCount = count - 1; - AtomicReferenceArray> table = this.table; - int index = hash & (table.length() - 1); - ReferenceEntry first = table.get(index); - - for (ReferenceEntry e = first; e != null; e = e.getNext()) { - if (e == entry) { - ++modCount; - ReferenceEntry newFirst = removeValueFromChain( - first, e, e.getKey(), hash, e.getValueReference(), RemovalCause.COLLECTED); - newCount = this.count - 1; - table.set(index, newFirst); - this.count = newCount; // write-volatile - return true; - } - } - - return false; - } finally { - unlock(); - postWriteCleanup(); - } - } - - /** - * Removes an entry whose value has been garbage collected. - */ - boolean reclaimValue(K key, int hash, ValueReference valueReference) { - lock(); - try { - int newCount = this.count - 1; - AtomicReferenceArray> table = this.table; - int index = hash & (table.length() - 1); - ReferenceEntry first = table.get(index); - - for (ReferenceEntry e = first; e != null; e = e.getNext()) { - K entryKey = e.getKey(); - if (e.getHash() == hash && entryKey != null - && map.keyEquivalence.equivalent(key, entryKey)) { - ValueReference v = e.getValueReference(); - if (v == valueReference) { - ++modCount; - ReferenceEntry newFirst = removeValueFromChain( - first, e, entryKey, hash, valueReference, RemovalCause.COLLECTED); - newCount = this.count - 1; - table.set(index, newFirst); - this.count = newCount; // write-volatile - return true; - } - return false; - } - } - - return false; - } finally { - unlock(); - if (!isHeldByCurrentThread()) { // don't cleanup inside of put - postWriteCleanup(); - } - } - } - - boolean removeLoadingValue(K key, int hash, LoadingValueReference valueReference) { - lock(); - try { - AtomicReferenceArray> table = this.table; - int index = hash & (table.length() - 1); - ReferenceEntry first = table.get(index); - - for (ReferenceEntry e = first; e != null; e = e.getNext()) { - K entryKey = e.getKey(); - if (e.getHash() == hash && entryKey != null - && map.keyEquivalence.equivalent(key, entryKey)) { - ValueReference v = e.getValueReference(); - if (v == valueReference) { - if (valueReference.isActive()) { - e.setValueReference(valueReference.getOldValue()); - } else { - ReferenceEntry newFirst = removeEntryFromChain(first, e); - table.set(index, newFirst); - } - return true; - } - return false; - } - } - - return false; - } finally { - unlock(); - postWriteCleanup(); - } - } - - @GuardedBy("this") - boolean removeEntry(ReferenceEntry entry, int hash, RemovalCause cause) { - int newCount = this.count - 1; - AtomicReferenceArray> table = this.table; - int index = hash & (table.length() - 1); - ReferenceEntry first = table.get(index); - - for (ReferenceEntry e = first; e != null; e = e.getNext()) { - if (e == entry) { - ++modCount; - ReferenceEntry newFirst = removeValueFromChain( - first, e, e.getKey(), hash, e.getValueReference(), cause); - newCount = this.count - 1; - table.set(index, newFirst); - this.count = newCount; // write-volatile - return true; - } - } - - return false; - } - - /** - * Performs routine cleanup following a read. Normally cleanup happens during writes. If cleanup - * is not observed after a sufficient number of reads, try cleaning up from the read thread. - */ - void postReadCleanup() { - if ((readCount.incrementAndGet() & DRAIN_THRESHOLD) == 0) { - cleanUp(); - } - } - - /** - * Performs routine cleanup prior to executing a write. This should be called every time a - * write thread acquires the segment lock, immediately after acquiring the lock. - * - *

Post-condition: expireEntries has been run. - */ - @GuardedBy("this") - void preWriteCleanup(long now) { - runLockedCleanup(now); - } - - /** - * Performs routine cleanup following a write. - */ - void postWriteCleanup() { - runUnlockedCleanup(); - } - - void cleanUp() { - long now = map.ticker.read(); - runLockedCleanup(now); - runUnlockedCleanup(); - } - - void runLockedCleanup(long now) { - if (tryLock()) { - try { - drainReferenceQueues(); - expireEntries(now); // calls drainRecencyQueue - readCount.set(0); - } finally { - unlock(); - } - } - } - - void runUnlockedCleanup() { - // locked cleanup may generate notifications we can send unlocked - if (!isHeldByCurrentThread()) { - map.processPendingNotifications(); - } - } - - } - - static class LoadingValueReference implements ValueReference { - volatile ValueReference oldValue; - - // TODO(fry): rename get, then extend AbstractFuture instead of containing SettableFuture - final SettableFuture futureValue = SettableFuture.create(); - final Stopwatch stopwatch = Stopwatch.createUnstarted(); - - public LoadingValueReference() { - this(LocalCache.unset()); - } - - public LoadingValueReference(ValueReference oldValue) { - this.oldValue = oldValue; - } - - @Override - public boolean isLoading() { - return true; - } - - @Override - public boolean isActive() { - return oldValue.isActive(); - } - - @Override - public int getWeight() { - return oldValue.getWeight(); - } - - public boolean set(@Nullable V newValue) { - return futureValue.set(newValue); - } - - public boolean setException(Throwable t) { - return futureValue.setException(t); - } - - private ListenableFuture fullyFailedFuture(Throwable t) { - return Futures.immediateFailedFuture(t); - } - - @Override - public void notifyNewValue(@Nullable V newValue) { - if (newValue != null) { - // The pending load was clobbered by a manual write. - // Unblock all pending gets, and have them return the new value. - set(newValue); - } else { - // The pending load was removed. Delay notifications until loading completes. - oldValue = unset(); - } - - // TODO(fry): could also cancel loading if we had a handle on its future - } - - public ListenableFuture loadFuture(K key, CacheLoader loader) { - try { - stopwatch.start(); - V previousValue = oldValue.get(); - if (previousValue == null) { - V newValue = loader.load(key); - return set(newValue) ? futureValue : Futures.immediateFuture(newValue); - } - ListenableFuture newValue = loader.reload(key, previousValue); - if (newValue == null) { - return Futures.immediateFuture(null); - } - // To avoid a race, make sure the refreshed value is set into loadingValueReference - // *before* returning newValue from the cache query. - return Futures.transform(newValue, new Function() { - @Override - public V apply(V newValue) { - LoadingValueReference.this.set(newValue); - return newValue; - } - }); - } catch (Throwable t) { - ListenableFuture result = setException(t) ? futureValue : fullyFailedFuture(t); - if (t instanceof InterruptedException) { - Thread.currentThread().interrupt(); - } - return result; - } - } - - public long elapsedNanos() { - return stopwatch.elapsed(NANOSECONDS); - } - - @Override - public V waitForValue() throws ExecutionException { - return getUninterruptibly(futureValue); - } - - @Override - public V get() { - return oldValue.get(); - } - - public ValueReference getOldValue() { - return oldValue; - } - - @Override - public ReferenceEntry getEntry() { - return null; - } - - @Override - public ValueReference copyFor( - ReferenceQueue queue, @Nullable V value, ReferenceEntry entry) { - return this; - } - } - - // Queues - - /** - * A custom queue for managing eviction order. Note that this is tightly integrated with {@code - * ReferenceEntry}, upon which it relies to perform its linking. - * - *

Note that this entire implementation makes the assumption that all elements which are in - * the map are also in this queue, and that all elements not in the queue are not in the map. - * - *

The benefits of creating our own queue are that (1) we can replace elements in the middle - * of the queue as part of copyWriteEntry, and (2) the contains method is highly optimized - * for the current model. - */ - static final class WriteQueue extends AbstractQueue> { - final ReferenceEntry head = new AbstractReferenceEntry() { - - @Override - public long getWriteTime() { - return Long.MAX_VALUE; - } - - @Override - public void setWriteTime(long time) {} - - ReferenceEntry nextWrite = this; - - @Override - public ReferenceEntry getNextInWriteQueue() { - return nextWrite; - } - - @Override - public void setNextInWriteQueue(ReferenceEntry next) { - this.nextWrite = next; - } - - ReferenceEntry previousWrite = this; - - @Override - public ReferenceEntry getPreviousInWriteQueue() { - return previousWrite; - } - - @Override - public void setPreviousInWriteQueue(ReferenceEntry previous) { - this.previousWrite = previous; - } - }; - - // implements Queue - - @Override - public boolean offer(ReferenceEntry entry) { - // unlink - connectWriteOrder(entry.getPreviousInWriteQueue(), entry.getNextInWriteQueue()); - - // add to tail - connectWriteOrder(head.getPreviousInWriteQueue(), entry); - connectWriteOrder(entry, head); - - return true; - } - - @Override - public ReferenceEntry peek() { - ReferenceEntry next = head.getNextInWriteQueue(); - return (next == head) ? null : next; - } - - @Override - public ReferenceEntry poll() { - ReferenceEntry next = head.getNextInWriteQueue(); - if (next == head) { - return null; - } - - remove(next); - return next; - } - - @Override - @SuppressWarnings("unchecked") - public boolean remove(Object o) { - ReferenceEntry e = (ReferenceEntry) o; - ReferenceEntry previous = e.getPreviousInWriteQueue(); - ReferenceEntry next = e.getNextInWriteQueue(); - connectWriteOrder(previous, next); - nullifyWriteOrder(e); - - return next != NullEntry.INSTANCE; - } - - @Override - @SuppressWarnings("unchecked") - public boolean contains(Object o) { - ReferenceEntry e = (ReferenceEntry) o; - return e.getNextInWriteQueue() != NullEntry.INSTANCE; - } - - @Override - public boolean isEmpty() { - return head.getNextInWriteQueue() == head; - } - - @Override - public int size() { - int size = 0; - for (ReferenceEntry e = head.getNextInWriteQueue(); e != head; - e = e.getNextInWriteQueue()) { - size++; - } - return size; - } - - @Override - public void clear() { - ReferenceEntry e = head.getNextInWriteQueue(); - while (e != head) { - ReferenceEntry next = e.getNextInWriteQueue(); - nullifyWriteOrder(e); - e = next; - } - - head.setNextInWriteQueue(head); - head.setPreviousInWriteQueue(head); - } - - @Override - public Iterator> iterator() { - return new AbstractSequentialIterator>(peek()) { - @Override - protected ReferenceEntry computeNext(ReferenceEntry previous) { - ReferenceEntry next = previous.getNextInWriteQueue(); - return (next == head) ? null : next; - } - }; - } - } - - /** - * A custom queue for managing access order. Note that this is tightly integrated with - * {@code ReferenceEntry}, upon which it reliese to perform its linking. - * - *

Note that this entire implementation makes the assumption that all elements which are in - * the map are also in this queue, and that all elements not in the queue are not in the map. - * - *

The benefits of creating our own queue are that (1) we can replace elements in the middle - * of the queue as part of copyWriteEntry, and (2) the contains method is highly optimized - * for the current model. - */ - static final class AccessQueue extends AbstractQueue> { - final ReferenceEntry head = new AbstractReferenceEntry() { - - @Override - public long getAccessTime() { - return Long.MAX_VALUE; - } - - @Override - public void setAccessTime(long time) {} - - ReferenceEntry nextAccess = this; - - @Override - public ReferenceEntry getNextInAccessQueue() { - return nextAccess; - } - - @Override - public void setNextInAccessQueue(ReferenceEntry next) { - this.nextAccess = next; - } - - ReferenceEntry previousAccess = this; - - @Override - public ReferenceEntry getPreviousInAccessQueue() { - return previousAccess; - } - - @Override - public void setPreviousInAccessQueue(ReferenceEntry previous) { - this.previousAccess = previous; - } - }; - - // implements Queue - - @Override - public boolean offer(ReferenceEntry entry) { - // unlink - connectAccessOrder(entry.getPreviousInAccessQueue(), entry.getNextInAccessQueue()); - - // add to tail - connectAccessOrder(head.getPreviousInAccessQueue(), entry); - connectAccessOrder(entry, head); - - return true; - } - - @Override - public ReferenceEntry peek() { - ReferenceEntry next = head.getNextInAccessQueue(); - return (next == head) ? null : next; - } - - @Override - public ReferenceEntry poll() { - ReferenceEntry next = head.getNextInAccessQueue(); - if (next == head) { - return null; - } - - remove(next); - return next; - } - - @Override - @SuppressWarnings("unchecked") - public boolean remove(Object o) { - ReferenceEntry e = (ReferenceEntry) o; - ReferenceEntry previous = e.getPreviousInAccessQueue(); - ReferenceEntry next = e.getNextInAccessQueue(); - connectAccessOrder(previous, next); - nullifyAccessOrder(e); - - return next != NullEntry.INSTANCE; - } - - @Override - @SuppressWarnings("unchecked") - public boolean contains(Object o) { - ReferenceEntry e = (ReferenceEntry) o; - return e.getNextInAccessQueue() != NullEntry.INSTANCE; - } - - @Override - public boolean isEmpty() { - return head.getNextInAccessQueue() == head; - } - - @Override - public int size() { - int size = 0; - for (ReferenceEntry e = head.getNextInAccessQueue(); e != head; - e = e.getNextInAccessQueue()) { - size++; - } - return size; - } - - @Override - public void clear() { - ReferenceEntry e = head.getNextInAccessQueue(); - while (e != head) { - ReferenceEntry next = e.getNextInAccessQueue(); - nullifyAccessOrder(e); - e = next; - } - - head.setNextInAccessQueue(head); - head.setPreviousInAccessQueue(head); - } - - @Override - public Iterator> iterator() { - return new AbstractSequentialIterator>(peek()) { - @Override - protected ReferenceEntry computeNext(ReferenceEntry previous) { - ReferenceEntry next = previous.getNextInAccessQueue(); - return (next == head) ? null : next; - } - }; - } - } - - // Cache support - - public void cleanUp() { - for (Segment segment : segments) { - segment.cleanUp(); - } - } - - // ConcurrentMap methods - - @Override - public boolean isEmpty() { - /* - * Sum per-segment modCounts to avoid mis-reporting when elements are concurrently added and - * removed in one segment while checking another, in which case the table was never actually - * empty at any point. (The sum ensures accuracy up through at least 1<<31 per-segment - * modifications before recheck.) Method containsValue() uses similar constructions for - * stability checks. - */ - long sum = 0L; - Segment[] segments = this.segments; - for (int i = 0; i < segments.length; ++i) { - if (segments[i].count != 0) { - return false; - } - sum += segments[i].modCount; - } - - if (sum != 0L) { // recheck unless no modifications - for (int i = 0; i < segments.length; ++i) { - if (segments[i].count != 0) { - return false; - } - sum -= segments[i].modCount; - } - if (sum != 0L) { - return false; - } - } - return true; - } - - long longSize() { - Segment[] segments = this.segments; - long sum = 0; - for (int i = 0; i < segments.length; ++i) { - sum += Math.max(0, segments[i].count); // see https://github.com/google/guava/issues/2108 - } - return sum; - } - - @Override - public int size() { - return Ints.saturatedCast(longSize()); - } - - @Override - @Nullable - public V get(@Nullable Object key) { - if (key == null) { - return null; - } - int hash = hash(key); - return segmentFor(hash).get(key, hash); - } - - @Nullable - public V getIfPresent(Object key) { - int hash = hash(checkNotNull(key)); - V value = segmentFor(hash).get(key, hash); - if (value == null) { - globalStatsCounter.recordMisses(1); - } else { - globalStatsCounter.recordHits(1); - } - return value; - } - - V get(K key, CacheLoader loader) throws ExecutionException { - int hash = hash(checkNotNull(key)); - return segmentFor(hash).get(key, hash, loader); - } - - V getOrLoad(K key) throws ExecutionException { - return get(key, defaultLoader); - } - - ImmutableMap getAllPresent(Iterable keys) { - int hits = 0; - int misses = 0; - - Map result = Maps.newLinkedHashMap(); - for (Object key : keys) { - V value = get(key); - if (value == null) { - misses++; - } else { - // TODO(fry): store entry key instead of query key - @SuppressWarnings("unchecked") - K castKey = (K) key; - result.put(castKey, value); - hits++; - } - } - globalStatsCounter.recordHits(hits); - globalStatsCounter.recordMisses(misses); - return ImmutableMap.copyOf(result); - } - - ImmutableMap getAll(Iterable keys) throws ExecutionException { - int hits = 0; - int misses = 0; - - Map result = Maps.newLinkedHashMap(); - Set keysToLoad = Sets.newLinkedHashSet(); - for (K key : keys) { - V value = get(key); - if (!result.containsKey(key)) { - result.put(key, value); - if (value == null) { - misses++; - keysToLoad.add(key); - } else { - hits++; - } - } - } - - try { - if (!keysToLoad.isEmpty()) { - try { - Map newEntries = loadAll(keysToLoad, defaultLoader); - for (K key : keysToLoad) { - V value = newEntries.get(key); - if (value == null) { - throw new InvalidCacheLoadException("loadAll failed to return a value for " + key); - } - result.put(key, value); - } - } catch (UnsupportedLoadingOperationException e) { - // loadAll not implemented, fallback to load - for (K key : keysToLoad) { - misses--; // get will count this miss - result.put(key, get(key, defaultLoader)); - } - } - } - return ImmutableMap.copyOf(result); - } finally { - globalStatsCounter.recordHits(hits); - globalStatsCounter.recordMisses(misses); - } - } - - /** - * Returns the result of calling {@link CacheLoader#loadAll}, or null if {@code loader} doesn't - * implement {@code loadAll}. - */ - @Nullable - Map loadAll(Set keys, CacheLoader loader) - throws ExecutionException { - checkNotNull(loader); - checkNotNull(keys); - Stopwatch stopwatch = Stopwatch.createStarted(); - Map result; - boolean success = false; - try { - @SuppressWarnings("unchecked") // safe since all keys extend K - Map map = (Map) loader.loadAll(keys); - result = map; - success = true; - } catch (UnsupportedLoadingOperationException e) { - success = true; - throw e; - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new ExecutionException(e); - } catch (RuntimeException e) { - throw new UncheckedExecutionException(e); - } catch (Exception e) { - throw new ExecutionException(e); - } catch (Error e) { - throw new ExecutionError(e); - } finally { - if (!success) { - globalStatsCounter.recordLoadException(stopwatch.elapsed(NANOSECONDS)); - } - } - - if (result == null) { - globalStatsCounter.recordLoadException(stopwatch.elapsed(NANOSECONDS)); - throw new InvalidCacheLoadException(loader + " returned null map from loadAll"); - } - - stopwatch.stop(); - // TODO(fry): batch by segment - boolean nullsPresent = false; - for (Map.Entry entry : result.entrySet()) { - K key = entry.getKey(); - V value = entry.getValue(); - if (key == null || value == null) { - // delay failure until non-null entries are stored - nullsPresent = true; - } else { - put(key, value); - } - } - - if (nullsPresent) { - globalStatsCounter.recordLoadException(stopwatch.elapsed(NANOSECONDS)); - throw new InvalidCacheLoadException(loader + " returned null keys or values from loadAll"); - } - - // TODO(fry): record count of loaded entries - globalStatsCounter.recordLoadSuccess(stopwatch.elapsed(NANOSECONDS)); - return result; - } - - /** - * Returns the internal entry for the specified key. The entry may be loading, expired, or - * partially collected. - */ - ReferenceEntry getEntry(@Nullable Object key) { - // does not impact recency ordering - if (key == null) { - return null; - } - int hash = hash(key); - return segmentFor(hash).getEntry(key, hash); - } - - void refresh(K key) { - int hash = hash(checkNotNull(key)); - segmentFor(hash).refresh(key, hash, defaultLoader, false); - } - - @Override - public boolean containsKey(@Nullable Object key) { - // does not impact recency ordering - if (key == null) { - return false; - } - int hash = hash(key); - return segmentFor(hash).containsKey(key, hash); - } - - @Override - public boolean containsValue(@Nullable Object value) { - // does not impact recency ordering - if (value == null) { - return false; - } - - // This implementation is patterned after ConcurrentHashMap, but without the locking. The only - // way for it to return a false negative would be for the target value to jump around in the map - // such that none of the subsequent iterations observed it, despite the fact that at every point - // in time it was present somewhere int the map. This becomes increasingly unlikely as - // CONTAINS_VALUE_RETRIES increases, though without locking it is theoretically possible. - long now = ticker.read(); - final Segment[] segments = this.segments; - long last = -1L; - for (int i = 0; i < CONTAINS_VALUE_RETRIES; i++) { - long sum = 0L; - for (Segment segment : segments) { - // ensure visibility of most recent completed write - int unused = segment.count; // read-volatile - - AtomicReferenceArray> table = segment.table; - for (int j = 0; j < table.length(); j++) { - for (ReferenceEntry e = table.get(j); e != null; e = e.getNext()) { - V v = segment.getLiveValue(e, now); - if (v != null && valueEquivalence.equivalent(value, v)) { - return true; - } - } - } - sum += segment.modCount; - } - if (sum == last) { - break; - } - last = sum; - } - return false; - } - - @Override - public V put(K key, V value) { - checkNotNull(key); - checkNotNull(value); - int hash = hash(key); - return segmentFor(hash).put(key, hash, value, false); - } - - @Override - public V putIfAbsent(K key, V value) { - checkNotNull(key); - checkNotNull(value); - int hash = hash(key); - return segmentFor(hash).put(key, hash, value, true); - } - - @Override - public void putAll(Map m) { - for (Entry e : m.entrySet()) { - put(e.getKey(), e.getValue()); - } - } - - @Override - public V remove(@Nullable Object key) { - if (key == null) { - return null; - } - int hash = hash(key); - return segmentFor(hash).remove(key, hash); - } - - @Override - public boolean remove(@Nullable Object key, @Nullable Object value) { - if (key == null || value == null) { - return false; - } - int hash = hash(key); - return segmentFor(hash).remove(key, hash, value); - } - - @Override - public boolean replace(K key, @Nullable V oldValue, V newValue) { - checkNotNull(key); - checkNotNull(newValue); - if (oldValue == null) { - return false; - } - int hash = hash(key); - return segmentFor(hash).replace(key, hash, oldValue, newValue); - } - - @Override - public V replace(K key, V value) { - checkNotNull(key); - checkNotNull(value); - int hash = hash(key); - return segmentFor(hash).replace(key, hash, value); - } - - @Override - public void clear() { - for (Segment segment : segments) { - segment.clear(); - } - } - - void invalidateAll(Iterable keys) { - // TODO(fry): batch by segment - for (Object key : keys) { - remove(key); - } - } - - Set keySet; - - @Override - public Set keySet() { - // does not impact recency ordering - Set ks = keySet; - return (ks != null) ? ks : (keySet = new KeySet(this)); - } - - Collection values; - - @Override - public Collection values() { - // does not impact recency ordering - Collection vs = values; - return (vs != null) ? vs : (values = new Values(this)); - } - - Set> entrySet; - - @Override - @GwtIncompatible("Not supported.") - public Set> entrySet() { - // does not impact recency ordering - Set> es = entrySet; - return (es != null) ? es : (entrySet = new EntrySet(this)); - } - - // Iterator Support - - abstract class HashIterator implements Iterator { - - int nextSegmentIndex; - int nextTableIndex; - Segment currentSegment; - AtomicReferenceArray> currentTable; - ReferenceEntry nextEntry; - WriteThroughEntry nextExternal; - WriteThroughEntry lastReturned; - - HashIterator() { - nextSegmentIndex = segments.length - 1; - nextTableIndex = -1; - advance(); - } - - @Override - public abstract T next(); - - final void advance() { - nextExternal = null; - - if (nextInChain()) { - return; - } - - if (nextInTable()) { - return; - } - - while (nextSegmentIndex >= 0) { - currentSegment = segments[nextSegmentIndex--]; - if (currentSegment.count != 0) { - currentTable = currentSegment.table; - nextTableIndex = currentTable.length() - 1; - if (nextInTable()) { - return; - } - } - } - } - - /** - * Finds the next entry in the current chain. Returns true if an entry was found. - */ - boolean nextInChain() { - if (nextEntry != null) { - for (nextEntry = nextEntry.getNext(); nextEntry != null; nextEntry = nextEntry.getNext()) { - if (advanceTo(nextEntry)) { - return true; - } - } - } - return false; - } - - /** - * Finds the next entry in the current table. Returns true if an entry was found. - */ - boolean nextInTable() { - while (nextTableIndex >= 0) { - if ((nextEntry = currentTable.get(nextTableIndex--)) != null) { - if (advanceTo(nextEntry) || nextInChain()) { - return true; - } - } - } - return false; - } - - /** - * Advances to the given entry. Returns true if the entry was valid, false if it should be - * skipped. - */ - boolean advanceTo(ReferenceEntry entry) { - try { - long now = ticker.read(); - K key = entry.getKey(); - V value = getLiveValue(entry, now); - if (value != null) { - nextExternal = new WriteThroughEntry(key, value); - return true; - } else { - // Skip stale entry. - return false; - } - } finally { - currentSegment.postReadCleanup(); - } - } - - @Override - public boolean hasNext() { - return nextExternal != null; - } - - WriteThroughEntry nextEntry() { - if (nextExternal == null) { - throw new NoSuchElementException(); - } - lastReturned = nextExternal; - advance(); - return lastReturned; - } - - @Override - public void remove() { - checkState(lastReturned != null); - LocalCache.this.remove(lastReturned.getKey()); - lastReturned = null; - } - } - - final class KeyIterator extends HashIterator { - - @Override - public K next() { - return nextEntry().getKey(); - } - } - - final class ValueIterator extends HashIterator { - - @Override - public V next() { - return nextEntry().getValue(); - } - } - - /** - * Custom Entry class used by EntryIterator.next(), that relays setValue changes to the - * underlying map. - */ - final class WriteThroughEntry implements Entry { - final K key; // non-null - V value; // non-null - - WriteThroughEntry(K key, V value) { - this.key = key; - this.value = value; - } - - @Override - public K getKey() { - return key; - } - - @Override - public V getValue() { - return value; - } - - @Override - public boolean equals(@Nullable Object object) { - // Cannot use key and value equivalence - if (object instanceof Entry) { - Entry that = (Entry) object; - return key.equals(that.getKey()) && value.equals(that.getValue()); - } - return false; - } - - @Override - public int hashCode() { - // Cannot use key and value equivalence - return key.hashCode() ^ value.hashCode(); - } - - @Override - public V setValue(V newValue) { - throw new UnsupportedOperationException(); - } - - /** - * Returns a string representation of the form {key}={value}. - */ - @Override public String toString() { - return getKey() + "=" + getValue(); - } - } - - final class EntryIterator extends HashIterator> { - - @Override - public Entry next() { - return nextEntry(); - } - } - - abstract class AbstractCacheSet extends AbstractSet { - @Weak final ConcurrentMap map; - - AbstractCacheSet(ConcurrentMap map) { - this.map = map; - } - - @Override - public int size() { - return map.size(); - } - - @Override - public boolean isEmpty() { - return map.isEmpty(); - } - - @Override - public void clear() { - map.clear(); - } - - // super.toArray() may misbehave if size() is inaccurate, at least on old versions of Android. - // https://code.google.com/p/android/issues/detail?id=36519 / http://r.android.com/47508 - - @Override - public Object[] toArray() { - return toArrayList(this).toArray(); - } - - @Override - public E[] toArray(E[] a) { - return toArrayList(this).toArray(a); - } - } - - private static ArrayList toArrayList(Collection c) { - // Avoid calling ArrayList(Collection), which may call back into toArray. - ArrayList result = new ArrayList(c.size()); - Iterators.addAll(result, c.iterator()); - return result; - } - - @WeakOuter - final class KeySet extends AbstractCacheSet { - - KeySet(ConcurrentMap map) { - super(map); - } - - @Override - public Iterator iterator() { - return new KeyIterator(); - } - - @Override - public boolean contains(Object o) { - return map.containsKey(o); - } - - @Override - public boolean remove(Object o) { - return map.remove(o) != null; - } - } - - @WeakOuter - final class Values extends AbstractCollection { - private final ConcurrentMap map; - - Values(ConcurrentMap map) { - this.map = map; - } - - @Override public int size() { - return map.size(); - } - - @Override public boolean isEmpty() { - return map.isEmpty(); - } - - @Override public void clear() { - map.clear(); - } - - @Override - public Iterator iterator() { - return new ValueIterator(); - } - - @Override - public boolean contains(Object o) { - return map.containsValue(o); - } - - // super.toArray() may misbehave if size() is inaccurate, at least on old versions of Android. - // https://code.google.com/p/android/issues/detail?id=36519 / http://r.android.com/47508 - - @Override - public Object[] toArray() { - return toArrayList(this).toArray(); - } - - @Override - public E[] toArray(E[] a) { - return toArrayList(this).toArray(a); - } - } - - @WeakOuter - final class EntrySet extends AbstractCacheSet> { - - EntrySet(ConcurrentMap map) { - super(map); - } - - @Override - public Iterator> iterator() { - return new EntryIterator(); - } - - @Override - public boolean contains(Object o) { - if (!(o instanceof Entry)) { - return false; - } - Entry e = (Entry) o; - Object key = e.getKey(); - if (key == null) { - return false; - } - V v = LocalCache.this.get(key); - - return v != null && valueEquivalence.equivalent(e.getValue(), v); - } - - @Override - public boolean remove(Object o) { - if (!(o instanceof Entry)) { - return false; - } - Entry e = (Entry) o; - Object key = e.getKey(); - return key != null && LocalCache.this.remove(key, e.getValue()); - } - } - - // Serialization Support - - /** - * Serializes the configuration of a LocalCache, reconsitituting it as a Cache using - * CacheBuilder upon deserialization. An instance of this class is fit for use by the writeReplace - * of LocalManualCache. - * - * Unfortunately, readResolve() doesn't get called when a circular dependency is present, so the - * proxy must be able to behave as the cache itself. - */ - static class ManualSerializationProxy - extends ForwardingCache implements Serializable { - private static final long serialVersionUID = 1; - - final Strength keyStrength; - final Strength valueStrength; - final Equivalence keyEquivalence; - final Equivalence valueEquivalence; - final long expireAfterWriteNanos; - final long expireAfterAccessNanos; - final long maxWeight; - final Weigher weigher; - final int concurrencyLevel; - final RemovalListener removalListener; - final Ticker ticker; - final CacheLoader loader; - - transient Cache delegate; - - ManualSerializationProxy(LocalCache cache) { - this( - cache.keyStrength, - cache.valueStrength, - cache.keyEquivalence, - cache.valueEquivalence, - cache.expireAfterWriteNanos, - cache.expireAfterAccessNanos, - cache.maxWeight, - cache.weigher, - cache.concurrencyLevel, - cache.removalListener, - cache.ticker, - cache.defaultLoader); - } - - private ManualSerializationProxy( - Strength keyStrength, Strength valueStrength, - Equivalence keyEquivalence, Equivalence valueEquivalence, - long expireAfterWriteNanos, long expireAfterAccessNanos, long maxWeight, - Weigher weigher, int concurrencyLevel, - RemovalListener removalListener, - Ticker ticker, CacheLoader loader) { - this.keyStrength = keyStrength; - this.valueStrength = valueStrength; - this.keyEquivalence = keyEquivalence; - this.valueEquivalence = valueEquivalence; - this.expireAfterWriteNanos = expireAfterWriteNanos; - this.expireAfterAccessNanos = expireAfterAccessNanos; - this.maxWeight = maxWeight; - this.weigher = weigher; - this.concurrencyLevel = concurrencyLevel; - this.removalListener = removalListener; - this.ticker = (ticker == Ticker.systemTicker() || ticker == NULL_TICKER) - ? null : ticker; - this.loader = loader; - } - - CacheBuilder recreateCacheBuilder() { - CacheBuilder builder = CacheBuilder.newBuilder() - .setKeyStrength(keyStrength) - .setValueStrength(valueStrength) - .keyEquivalence(keyEquivalence) - .valueEquivalence(valueEquivalence) - .concurrencyLevel(concurrencyLevel) - .removalListener(removalListener); - builder.strictParsing = false; - if (expireAfterWriteNanos > 0) { - builder.expireAfterWrite(expireAfterWriteNanos, TimeUnit.NANOSECONDS); - } - if (expireAfterAccessNanos > 0) { - builder.expireAfterAccess(expireAfterAccessNanos, TimeUnit.NANOSECONDS); - } - if (weigher != OneWeigher.INSTANCE) { - builder.weigher(weigher); - if (maxWeight != UNSET_INT) { - builder.maximumWeight(maxWeight); - } - } else { - if (maxWeight != UNSET_INT) { - builder.maximumSize(maxWeight); - } - } - if (ticker != null) { - builder.ticker(ticker); - } - return builder; - } - - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - in.defaultReadObject(); - CacheBuilder builder = recreateCacheBuilder(); - this.delegate = builder.build(); - } - - private Object readResolve() { - return delegate; - } - - @Override - protected Cache delegate() { - return delegate; - } - } - - /** - * Serializes the configuration of a LocalCache, reconsitituting it as an LoadingCache using - * CacheBuilder upon deserialization. An instance of this class is fit for use by the writeReplace - * of LocalLoadingCache. - * - * Unfortunately, readResolve() doesn't get called when a circular dependency is present, so the - * proxy must be able to behave as the cache itself. - */ - static final class LoadingSerializationProxy - extends ManualSerializationProxy implements LoadingCache, Serializable { - private static final long serialVersionUID = 1; - - transient LoadingCache autoDelegate; - - LoadingSerializationProxy(LocalCache cache) { - super(cache); - } - - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - in.defaultReadObject(); - CacheBuilder builder = recreateCacheBuilder(); - this.autoDelegate = builder.build(loader); - } - - @Override - public V get(K key) throws ExecutionException { - return autoDelegate.get(key); - } - - @Override - public V getUnchecked(K key) { - return autoDelegate.getUnchecked(key); - } - - @Override - public ImmutableMap getAll(Iterable keys) throws ExecutionException { - return autoDelegate.getAll(keys); - } - - @Override - public final V apply(K key) { - return autoDelegate.apply(key); - } - - @Override - public void refresh(K key) { - autoDelegate.refresh(key); - } - - private Object readResolve() { - return autoDelegate; - } - } - - static class LocalManualCache implements Cache, Serializable { - final LocalCache localCache; - - LocalManualCache(CacheBuilder builder) { - this(new LocalCache(builder, null)); - } - - private LocalManualCache(LocalCache localCache) { - this.localCache = localCache; - } - - // Cache methods - - @Override - @Nullable - public V getIfPresent(Object key) { - return localCache.getIfPresent(key); - } - - @Override - public V get(K key, final Callable valueLoader) throws ExecutionException { - checkNotNull(valueLoader); - return localCache.get(key, new CacheLoader() { - @Override - public V load(Object key) throws Exception { - return valueLoader.call(); - } - }); - } - - @Override - public ImmutableMap getAllPresent(Iterable keys) { - return localCache.getAllPresent(keys); - } - - @Override - public void put(K key, V value) { - localCache.put(key, value); - } - - @Override - public void putAll(Map m) { - localCache.putAll(m); - } - - @Override - public void invalidate(Object key) { - checkNotNull(key); - localCache.remove(key); - } - - @Override - public void invalidateAll(Iterable keys) { - localCache.invalidateAll(keys); - } - - @Override - public void invalidateAll() { - localCache.clear(); - } - - @Override - public long size() { - return localCache.longSize(); - } - - @Override - public ConcurrentMap asMap() { - return localCache; - } - - @Override - public CacheStats stats() { - SimpleStatsCounter aggregator = new SimpleStatsCounter(); - aggregator.incrementBy(localCache.globalStatsCounter); - for (Segment segment : localCache.segments) { - aggregator.incrementBy(segment.statsCounter); - } - return aggregator.snapshot(); - } - - @Override - public void cleanUp() { - localCache.cleanUp(); - } - - // Serialization Support - - private static final long serialVersionUID = 1; - - Object writeReplace() { - return new ManualSerializationProxy(localCache); - } - } - - static class LocalLoadingCache - extends LocalManualCache implements LoadingCache { - - LocalLoadingCache(CacheBuilder builder, - CacheLoader loader) { - super(new LocalCache(builder, checkNotNull(loader))); - } - - // LoadingCache methods - - @Override - public V get(K key) throws ExecutionException { - return localCache.getOrLoad(key); - } - - @Override - public V getUnchecked(K key) { - try { - return get(key); - } catch (ExecutionException e) { - throw new UncheckedExecutionException(e.getCause()); - } - } - - @Override - public ImmutableMap getAll(Iterable keys) throws ExecutionException { - return localCache.getAll(keys); - } - - @Override - public void refresh(K key) { - localCache.refresh(key); - } - - @Override - public final V apply(K key) { - return getUnchecked(key); - } - - // Serialization Support - - private static final long serialVersionUID = 1; - - @Override - Object writeReplace() { - return new LoadingSerializationProxy(localCache); - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/cache/LongAddable.java b/thirdparty/google-guava/src/main/java/com/google/common/cache/LongAddable.java deleted file mode 100644 index 48ddbfc62df6..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/cache/LongAddable.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.cache; - -import com.google.common.annotations.GwtCompatible; - -/** - * Abstract interface for objects that can concurrently add longs. - * - * @author Louis Wasserman - */ -@GwtCompatible -interface LongAddable { - void increment(); - - void add(long x); - - long sum(); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/cache/LongAddables.java b/thirdparty/google-guava/src/main/java/com/google/common/cache/LongAddables.java deleted file mode 100644 index 4428d306d907..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/cache/LongAddables.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.cache; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Supplier; - -import java.util.concurrent.atomic.AtomicLong; - -/** - * Source of {@link LongAddable} objects that deals with GWT, Unsafe, and all - * that. - * - * @author Louis Wasserman - */ -@GwtCompatible(emulated = true) -final class LongAddables { - private static final Supplier SUPPLIER; - - static { - Supplier supplier; - try { - new LongAdder(); // trigger static initialization of the LongAdder class, which may fail - supplier = new Supplier() { - @Override - public LongAddable get() { - return new LongAdder(); - } - }; - } catch (Throwable t) { // we really want to catch *everything* - supplier = new Supplier() { - @Override - public LongAddable get() { - return new PureJavaLongAddable(); - } - }; - } - SUPPLIER = supplier; - } - - public static LongAddable create() { - return SUPPLIER.get(); - } - - private static final class PureJavaLongAddable extends AtomicLong implements LongAddable { - @Override - public void increment() { - getAndIncrement(); - } - - @Override - public void add(long x) { - getAndAdd(x); - } - - @Override - public long sum() { - return get(); - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/cache/LongAdder.java b/thirdparty/google-guava/src/main/java/com/google/common/cache/LongAdder.java deleted file mode 100644 index ffdd66bb8f5d..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/cache/LongAdder.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -/* - * Source: - * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/LongAdder.java?revision=1.17 - */ - -package com.google.common.cache; - -import com.google.common.annotations.GwtCompatible; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.util.concurrent.atomic.AtomicLong; - -/** - * One or more variables that together maintain an initially zero - * {@code long} sum. When updates (method {@link #add}) are contended - * across threads, the set of variables may grow dynamically to reduce - * contention. Method {@link #sum} (or, equivalently, {@link - * #longValue}) returns the current total combined across the - * variables maintaining the sum. - * - *

This class is usually preferable to {@link AtomicLong} when - * multiple threads update a common sum that is used for purposes such - * as collecting statistics, not for fine-grained synchronization - * control. Under low update contention, the two classes have similar - * characteristics. But under high contention, expected throughput of - * this class is significantly higher, at the expense of higher space - * consumption. - * - *

This class extends {@link Number}, but does not define - * methods such as {@code equals}, {@code hashCode} and {@code - * compareTo} because instances are expected to be mutated, and so are - * not useful as collection keys. - * - *

jsr166e note: This class is targeted to be placed in - * java.util.concurrent.atomic. - * - * @since 1.8 - * @author Doug Lea - */ -@GwtCompatible(emulated = true) -final class LongAdder extends Striped64 implements Serializable, LongAddable { - private static final long serialVersionUID = 7249069246863182397L; - - /** - * Version of plus for use in retryUpdate - */ - final long fn(long v, long x) { return v + x; } - - /** - * Creates a new adder with initial sum of zero. - */ - public LongAdder() { - } - - /** - * Adds the given value. - * - * @param x the value to add - */ - public void add(long x) { - Cell[] as; long b, v; int[] hc; Cell a; int n; - if ((as = cells) != null || !casBase(b = base, b + x)) { - boolean uncontended = true; - if ((hc = threadHashCode.get()) == null || - as == null || (n = as.length) < 1 || - (a = as[(n - 1) & hc[0]]) == null || - !(uncontended = a.cas(v = a.value, v + x))) - retryUpdate(x, hc, uncontended); - } - } - - /** - * Equivalent to {@code add(1)}. - */ - public void increment() { - add(1L); - } - - /** - * Equivalent to {@code add(-1)}. - */ - public void decrement() { - add(-1L); - } - - /** - * Returns the current sum. The returned value is NOT an - * atomic snapshot; invocation in the absence of concurrent - * updates returns an accurate result, but concurrent updates that - * occur while the sum is being calculated might not be - * incorporated. - * - * @return the sum - */ - public long sum() { - long sum = base; - Cell[] as = cells; - if (as != null) { - int n = as.length; - for (int i = 0; i < n; ++i) { - Cell a = as[i]; - if (a != null) - sum += a.value; - } - } - return sum; - } - - /** - * Resets variables maintaining the sum to zero. This method may - * be a useful alternative to creating a new adder, but is only - * effective if there are no concurrent updates. Because this - * method is intrinsically racy, it should only be used when it is - * known that no threads are concurrently updating. - */ - public void reset() { - internalReset(0L); - } - - /** - * Equivalent in effect to {@link #sum} followed by {@link - * #reset}. This method may apply for example during quiescent - * points between multithreaded computations. If there are - * updates concurrent with this method, the returned value is - * not guaranteed to be the final value occurring before - * the reset. - * - * @return the sum - */ - public long sumThenReset() { - long sum = base; - Cell[] as = cells; - base = 0L; - if (as != null) { - int n = as.length; - for (int i = 0; i < n; ++i) { - Cell a = as[i]; - if (a != null) { - sum += a.value; - a.value = 0L; - } - } - } - return sum; - } - - /** - * Returns the String representation of the {@link #sum}. - * @return the String representation of the {@link #sum} - */ - public String toString() { - return Long.toString(sum()); - } - - /** - * Equivalent to {@link #sum}. - * - * @return the sum - */ - public long longValue() { - return sum(); - } - - /** - * Returns the {@link #sum} as an {@code int} after a narrowing - * primitive conversion. - */ - public int intValue() { - return (int)sum(); - } - - /** - * Returns the {@link #sum} as a {@code float} - * after a widening primitive conversion. - */ - public float floatValue() { - return (float)sum(); - } - - /** - * Returns the {@link #sum} as a {@code double} after a widening - * primitive conversion. - */ - public double doubleValue() { - return (double)sum(); - } - - private void writeObject(ObjectOutputStream s) throws IOException { - s.defaultWriteObject(); - s.writeLong(sum()); - } - - private void readObject(ObjectInputStream s) - throws IOException, ClassNotFoundException { - s.defaultReadObject(); - busy = 0; - cells = null; - base = s.readLong(); - } - -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/cache/RemovalCause.java b/thirdparty/google-guava/src/main/java/com/google/common/cache/RemovalCause.java deleted file mode 100644 index 29082f02a71a..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/cache/RemovalCause.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.cache; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Iterator; -import java.util.Map; -import java.util.concurrent.ConcurrentMap; - -/** - * The reason why a cached entry was removed. - * - * @author Charles Fry - * @since 10.0 - */ -@GwtCompatible -public enum RemovalCause { - /** - * The entry was manually removed by the user. This can result from the user invoking - * {@link Cache#invalidate}, {@link Cache#invalidateAll(Iterable)}, {@link Cache#invalidateAll()}, - * {@link Map#remove}, {@link ConcurrentMap#remove}, or {@link Iterator#remove}. - */ - EXPLICIT { - @Override - boolean wasEvicted() { - return false; - } - }, - - /** - * The entry itself was not actually removed, but its value was replaced by the user. This can - * result from the user invoking {@link Cache#put}, {@link LoadingCache#refresh}, {@link Map#put}, - * {@link Map#putAll}, {@link ConcurrentMap#replace(Object, Object)}, or - * {@link ConcurrentMap#replace(Object, Object, Object)}. - */ - REPLACED { - @Override - boolean wasEvicted() { - return false; - } - }, - - /** - * The entry was removed automatically because its key or value was garbage-collected. This - * can occur when using {@link CacheBuilder#weakKeys}, {@link CacheBuilder#weakValues}, or - * {@link CacheBuilder#softValues}. - */ - COLLECTED { - @Override - boolean wasEvicted() { - return true; - } - }, - - /** - * The entry's expiration timestamp has passed. This can occur when using - * {@link CacheBuilder#expireAfterWrite} or {@link CacheBuilder#expireAfterAccess}. - */ - EXPIRED { - @Override - boolean wasEvicted() { - return true; - } - }, - - /** - * The entry was evicted due to size constraints. This can occur when using - * {@link CacheBuilder#maximumSize} or {@link CacheBuilder#maximumWeight}. - */ - SIZE { - @Override - boolean wasEvicted() { - return true; - } - }; - - /** - * Returns {@code true} if there was an automatic removal due to eviction (the cause is neither - * {@link #EXPLICIT} nor {@link #REPLACED}). - */ - abstract boolean wasEvicted(); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/cache/RemovalListener.java b/thirdparty/google-guava/src/main/java/com/google/common/cache/RemovalListener.java deleted file mode 100644 index 09bd3cf2b3f4..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/cache/RemovalListener.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.cache; - -import com.google.common.annotations.GwtCompatible; - -/** - * An object that can receive a notification when an entry is removed from a cache. The removal - * resulting in notification could have occured to an entry being manually removed or replaced, or - * due to eviction resulting from timed expiration, exceeding a maximum size, or garbage - * collection. - * - *

An instance may be called concurrently by multiple threads to process different entries. - * Implementations of this interface should avoid performing blocking calls or synchronizing on - * shared resources. - * - * @param the most general type of keys this listener can listen for; for - * example {@code Object} if any key is acceptable - * @param the most general type of values this listener can listen for; for - * example {@code Object} if any key is acceptable - * @author Charles Fry - * @since 10.0 - */ -@GwtCompatible -public interface RemovalListener { - /** - * Notifies the listener that a removal occurred at some point in the past. - * - *

This does not always signify that the key is now absent from the cache, - * as it may have already been re-added. - */ - // Technically should accept RemovalNotification, but because - // RemovalNotification is guaranteed covariant, let's make users' lives simpler. - void onRemoval(RemovalNotification notification); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/cache/RemovalListeners.java b/thirdparty/google-guava/src/main/java/com/google/common/cache/RemovalListeners.java deleted file mode 100644 index 974ef045f387..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/cache/RemovalListeners.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.cache; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.concurrent.Executor; - -/** - * A collection of common removal listeners. - * - * @author Charles Fry - * @since 10.0 - */ -public final class RemovalListeners { - - private RemovalListeners() {} - - /** - * Returns a {@code RemovalListener} which processes all eviction - * notifications using {@code executor}. - * - * @param listener the backing listener - * @param executor the executor with which removal notifications are - * asynchronously executed - */ - public static RemovalListener asynchronous( - final RemovalListener listener, final Executor executor) { - checkNotNull(listener); - checkNotNull(executor); - return new RemovalListener() { - @Override - public void onRemoval(final RemovalNotification notification) { - executor.execute(new Runnable() { - @Override - public void run() { - listener.onRemoval(notification); - } - }); - } - }; - } - -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/cache/RemovalNotification.java b/thirdparty/google-guava/src/main/java/com/google/common/cache/RemovalNotification.java deleted file mode 100644 index 7dd9ba415ae3..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/cache/RemovalNotification.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.cache; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Objects; - -import java.util.Map.Entry; - -import javax.annotation.Nullable; - -/** - * A notification of the removal of a single entry. The key and/or value may be null if they were - * already garbage collected. - * - *

Like other {@code Map.Entry} instances associated with {@code CacheBuilder}, this class holds - * strong references to the key and value, regardless of the type of references the cache may be - * using. - * - * @author Charles Fry - * @since 10.0 - */ -@GwtCompatible -public final class RemovalNotification implements Entry { - @Nullable private final K key; - @Nullable private final V value; - private final RemovalCause cause; - - /** - * Creates a new {@code RemovalNotification} for the given {@code key}/{@code value} pair, with - * the given {@code cause} for the removal. The {@code key} and/or {@code value} may be - * {@code null} if they were already garbage collected. - * - * @since 19.0 - */ - public static RemovalNotification create( - @Nullable K key, @Nullable V value, RemovalCause cause) { - return new RemovalNotification(key, value, cause); - } - - private RemovalNotification(@Nullable K key, @Nullable V value, RemovalCause cause) { - this.key = key; - this.value = value; - this.cause = checkNotNull(cause); - } - - /** - * Returns the cause for which the entry was removed. - */ - public RemovalCause getCause() { - return cause; - } - - /** - * Returns {@code true} if there was an automatic removal due to eviction (the cause is neither - * {@link RemovalCause#EXPLICIT} nor {@link RemovalCause#REPLACED}). - */ - public boolean wasEvicted() { - return cause.wasEvicted(); - } - - @Nullable @Override public K getKey() { - return key; - } - - @Nullable @Override public V getValue() { - return value; - } - - @Override public final V setValue(V value) { - throw new UnsupportedOperationException(); - } - - @Override public boolean equals(@Nullable Object object) { - if (object instanceof Entry) { - Entry that = (Entry) object; - return Objects.equal(this.getKey(), that.getKey()) - && Objects.equal(this.getValue(), that.getValue()); - } - return false; - } - - @Override public int hashCode() { - K k = getKey(); - V v = getValue(); - return ((k == null) ? 0 : k.hashCode()) ^ ((v == null) ? 0 : v.hashCode()); - } - - /** - * Returns a string representation of the form {key}={value}. - */ - @Override public String toString() { - return getKey() + "=" + getValue(); - } - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/cache/Striped64.java b/thirdparty/google-guava/src/main/java/com/google/common/cache/Striped64.java deleted file mode 100644 index 66574fe4b6b1..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/cache/Striped64.java +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -/* - * Source: - * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/Striped64.java?revision=1.9 - */ - -package com.google.common.cache; - -import java.util.Random; - -/** - * A package-local class holding common representation and mechanics - * for classes supporting dynamic striping on 64bit values. The class - * extends Number so that concrete subclasses must publicly do so. - */ -abstract class Striped64 extends Number { - /* - * This class maintains a lazily-initialized table of atomically - * updated variables, plus an extra "base" field. The table size - * is a power of two. Indexing uses masked per-thread hash codes. - * Nearly all declarations in this class are package-private, - * accessed directly by subclasses. - * - * Table entries are of class Cell; a variant of AtomicLong padded - * to reduce cache contention on most processors. Padding is - * overkill for most Atomics because they are usually irregularly - * scattered in memory and thus don't interfere much with each - * other. But Atomic objects residing in arrays will tend to be - * placed adjacent to each other, and so will most often share - * cache lines (with a huge negative performance impact) without - * this precaution. - * - * In part because Cells are relatively large, we avoid creating - * them until they are needed. When there is no contention, all - * updates are made to the base field. Upon first contention (a - * failed CAS on base update), the table is initialized to size 2. - * The table size is doubled upon further contention until - * reaching the nearest power of two greater than or equal to the - * number of CPUS. Table slots remain empty (null) until they are - * needed. - * - * A single spinlock ("busy") is used for initializing and - * resizing the table, as well as populating slots with new Cells. - * There is no need for a blocking lock; when the lock is not - * available, threads try other slots (or the base). During these - * retries, there is increased contention and reduced locality, - * which is still better than alternatives. - * - * Per-thread hash codes are initialized to random values. - * Contention and/or table collisions are indicated by failed - * CASes when performing an update operation (see method - * retryUpdate). Upon a collision, if the table size is less than - * the capacity, it is doubled in size unless some other thread - * holds the lock. If a hashed slot is empty, and lock is - * available, a new Cell is created. Otherwise, if the slot - * exists, a CAS is tried. Retries proceed by "double hashing", - * using a secondary hash (Marsaglia XorShift) to try to find a - * free slot. - * - * The table size is capped because, when there are more threads - * than CPUs, supposing that each thread were bound to a CPU, - * there would exist a perfect hash function mapping threads to - * slots that eliminates collisions. When we reach capacity, we - * search for this mapping by randomly varying the hash codes of - * colliding threads. Because search is random, and collisions - * only become known via CAS failures, convergence can be slow, - * and because threads are typically not bound to CPUS forever, - * may not occur at all. However, despite these limitations, - * observed contention rates are typically low in these cases. - * - * It is possible for a Cell to become unused when threads that - * once hashed to it terminate, as well as in the case where - * doubling the table causes no thread to hash to it under - * expanded mask. We do not try to detect or remove such cells, - * under the assumption that for long-running instances, observed - * contention levels will recur, so the cells will eventually be - * needed again; and for short-lived ones, it does not matter. - */ - - /** - * Padded variant of AtomicLong supporting only raw accesses plus CAS. - * The value field is placed between pads, hoping that the JVM doesn't - * reorder them. - * - * JVM intrinsics note: It would be possible to use a release-only - * form of CAS here, if it were provided. - */ - static final class Cell { - volatile long p0, p1, p2, p3, p4, p5, p6; - volatile long value; - volatile long q0, q1, q2, q3, q4, q5, q6; - Cell(long x) { value = x; } - - final boolean cas(long cmp, long val) { - return UNSAFE.compareAndSwapLong(this, valueOffset, cmp, val); - } - - // Unsafe mechanics - private static final sun.misc.Unsafe UNSAFE; - private static final long valueOffset; - static { - try { - UNSAFE = getUnsafe(); - Class ak = Cell.class; - valueOffset = UNSAFE.objectFieldOffset - (ak.getDeclaredField("value")); - } catch (Exception e) { - throw new Error(e); - } - } - - } - - /** - * ThreadLocal holding a single-slot int array holding hash code. - * Unlike the JDK8 version of this class, we use a suboptimal - * int[] representation to avoid introducing a new type that can - * impede class-unloading when ThreadLocals are not removed. - */ - static final ThreadLocal threadHashCode = new ThreadLocal(); - - /** - * Generator of new random hash codes - */ - static final Random rng = new Random(); - - /** Number of CPUS, to place bound on table size */ - static final int NCPU = Runtime.getRuntime().availableProcessors(); - - /** - * Table of cells. When non-null, size is a power of 2. - */ - transient volatile Cell[] cells; - - /** - * Base value, used mainly when there is no contention, but also as - * a fallback during table initialization races. Updated via CAS. - */ - transient volatile long base; - - /** - * Spinlock (locked via CAS) used when resizing and/or creating Cells. - */ - transient volatile int busy; - - /** - * Package-private default constructor - */ - Striped64() { - } - - /** - * CASes the base field. - */ - final boolean casBase(long cmp, long val) { - return UNSAFE.compareAndSwapLong(this, baseOffset, cmp, val); - } - - /** - * CASes the busy field from 0 to 1 to acquire lock. - */ - final boolean casBusy() { - return UNSAFE.compareAndSwapInt(this, busyOffset, 0, 1); - } - - /** - * Computes the function of current and new value. Subclasses - * should open-code this update function for most uses, but the - * virtualized form is needed within retryUpdate. - * - * @param currentValue the current value (of either base or a cell) - * @param newValue the argument from a user update call - * @return result of the update function - */ - abstract long fn(long currentValue, long newValue); - - /** - * Handles cases of updates involving initialization, resizing, - * creating new Cells, and/or contention. See above for - * explanation. This method suffers the usual non-modularity - * problems of optimistic retry code, relying on rechecked sets of - * reads. - * - * @param x the value - * @param hc the hash code holder - * @param wasUncontended false if CAS failed before call - */ - final void retryUpdate(long x, int[] hc, boolean wasUncontended) { - int h; - if (hc == null) { - threadHashCode.set(hc = new int[1]); // Initialize randomly - int r = rng.nextInt(); // Avoid zero to allow xorShift rehash - h = hc[0] = (r == 0) ? 1 : r; - } - else - h = hc[0]; - boolean collide = false; // True if last slot nonempty - for (;;) { - Cell[] as; Cell a; int n; long v; - if ((as = cells) != null && (n = as.length) > 0) { - if ((a = as[(n - 1) & h]) == null) { - if (busy == 0) { // Try to attach new Cell - Cell r = new Cell(x); // Optimistically create - if (busy == 0 && casBusy()) { - boolean created = false; - try { // Recheck under lock - Cell[] rs; int m, j; - if ((rs = cells) != null && - (m = rs.length) > 0 && - rs[j = (m - 1) & h] == null) { - rs[j] = r; - created = true; - } - } finally { - busy = 0; - } - if (created) - break; - continue; // Slot is now non-empty - } - } - collide = false; - } - else if (!wasUncontended) // CAS already known to fail - wasUncontended = true; // Continue after rehash - else if (a.cas(v = a.value, fn(v, x))) - break; - else if (n >= NCPU || cells != as) - collide = false; // At max size or stale - else if (!collide) - collide = true; - else if (busy == 0 && casBusy()) { - try { - if (cells == as) { // Expand table unless stale - Cell[] rs = new Cell[n << 1]; - for (int i = 0; i < n; ++i) - rs[i] = as[i]; - cells = rs; - } - } finally { - busy = 0; - } - collide = false; - continue; // Retry with expanded table - } - h ^= h << 13; // Rehash - h ^= h >>> 17; - h ^= h << 5; - hc[0] = h; // Record index for next time - } - else if (busy == 0 && cells == as && casBusy()) { - boolean init = false; - try { // Initialize table - if (cells == as) { - Cell[] rs = new Cell[2]; - rs[h & 1] = new Cell(x); - cells = rs; - init = true; - } - } finally { - busy = 0; - } - if (init) - break; - } - else if (casBase(v = base, fn(v, x))) - break; // Fall back on using base - } - } - - /** - * Sets base and all cells to the given value. - */ - final void internalReset(long initialValue) { - Cell[] as = cells; - base = initialValue; - if (as != null) { - int n = as.length; - for (int i = 0; i < n; ++i) { - Cell a = as[i]; - if (a != null) - a.value = initialValue; - } - } - } - - // Unsafe mechanics - private static final sun.misc.Unsafe UNSAFE; - private static final long baseOffset; - private static final long busyOffset; - static { - try { - UNSAFE = getUnsafe(); - Class sk = Striped64.class; - baseOffset = UNSAFE.objectFieldOffset - (sk.getDeclaredField("base")); - busyOffset = UNSAFE.objectFieldOffset - (sk.getDeclaredField("busy")); - } catch (Exception e) { - throw new Error(e); - } - } - - /** - * Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package. - * Replace with a simple call to Unsafe.getUnsafe when integrating - * into a jdk. - * - * @return a sun.misc.Unsafe - */ - private static sun.misc.Unsafe getUnsafe() { - try { - return sun.misc.Unsafe.getUnsafe(); - } catch (SecurityException tryReflectionInstead) {} - try { - return java.security.AccessController.doPrivileged - (new java.security.PrivilegedExceptionAction() { - public sun.misc.Unsafe run() throws Exception { - Class k = sun.misc.Unsafe.class; - for (java.lang.reflect.Field f : k.getDeclaredFields()) { - f.setAccessible(true); - Object x = f.get(null); - if (k.isInstance(x)) - return k.cast(x); - } - throw new NoSuchFieldError("the Unsafe"); - }}); - } catch (java.security.PrivilegedActionException e) { - throw new RuntimeException("Could not initialize intrinsics", - e.getCause()); - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/cache/Weigher.java b/thirdparty/google-guava/src/main/java/com/google/common/cache/Weigher.java deleted file mode 100644 index 9ed07d1199bf..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/cache/Weigher.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations - * under the License. - */ - -package com.google.common.cache; - -import com.google.common.annotations.GwtCompatible; - -/** - * Calculates the weights of cache entries. - * - * @author Charles Fry - * @since 11.0 - */ -@GwtCompatible -public interface Weigher { - - /** - * Returns the weight of a cache entry. There is no unit for entry weights; rather they are simply - * relative to each other. - * - * @return the weight of the entry; must be non-negative - */ - int weigh(K key, V value); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/cache/package-info.java b/thirdparty/google-guava/src/main/java/com/google/common/cache/package-info.java deleted file mode 100644 index 878f29e2d5ea..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/cache/package-info.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * This package contains caching utilities. - * - *

The core interface used to represent caches is {@link com.google.common.cache.Cache}. - * In-memory caches can be configured and created using - * {@link com.google.common.cache.CacheBuilder}, with cache entries being loaded by - * {@link com.google.common.cache.CacheLoader}. Statistics about cache performance are exposed using - * {@link com.google.common.cache.CacheStats}. - * - *

See the Guava User Guide article on caches. - * - *

This package is a part of the open-source - * Guava libraries. - * - * @author Charles Fry - */ -@ParametersAreNonnullByDefault -package com.google.common.cache; - -import javax.annotation.ParametersAreNonnullByDefault; - diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractBiMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractBiMap.java deleted file mode 100644 index 3ede3777c3a5..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractBiMap.java +++ /dev/null @@ -1,445 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkState; -import static com.google.common.collect.CollectPreconditions.checkRemove; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.base.Objects; -import com.google.j2objc.annotations.WeakOuter; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * A general-purpose bimap implementation using any two backing {@code Map} - * instances. - * - *

Note that this class contains {@code equals()} calls that keep it from - * supporting {@code IdentityHashMap} backing maps. - * - * @author Kevin Bourrillion - * @author Mike Bostock - */ -@GwtCompatible(emulated = true) -abstract class AbstractBiMap extends ForwardingMap - implements BiMap, Serializable { - - private transient Map delegate; - transient AbstractBiMap inverse; - - /** Package-private constructor for creating a map-backed bimap. */ - AbstractBiMap(Map forward, Map backward) { - setDelegates(forward, backward); - } - - /** Private constructor for inverse bimap. */ - private AbstractBiMap(Map backward, AbstractBiMap forward) { - delegate = backward; - inverse = forward; - } - - @Override - protected Map delegate() { - return delegate; - } - - /** - * Returns its input, or throws an exception if this is not a valid key. - */ - K checkKey(@Nullable K key) { - return key; - } - - /** - * Returns its input, or throws an exception if this is not a valid value. - */ - V checkValue(@Nullable V value) { - return value; - } - - /** - * Specifies the delegate maps going in each direction. Called by the - * constructor and by subclasses during deserialization. - */ - void setDelegates(Map forward, Map backward) { - checkState(delegate == null); - checkState(inverse == null); - checkArgument(forward.isEmpty()); - checkArgument(backward.isEmpty()); - checkArgument(forward != backward); - delegate = forward; - inverse = new Inverse(backward, this); - } - - void setInverse(AbstractBiMap inverse) { - this.inverse = inverse; - } - - // Query Operations (optimizations) - - @Override - public boolean containsValue(@Nullable Object value) { - return inverse.containsKey(value); - } - - // Modification Operations - - @Override - public V put(@Nullable K key, @Nullable V value) { - return putInBothMaps(key, value, false); - } - - @Override - public V forcePut(@Nullable K key, @Nullable V value) { - return putInBothMaps(key, value, true); - } - - private V putInBothMaps(@Nullable K key, @Nullable V value, boolean force) { - checkKey(key); - checkValue(value); - boolean containedKey = containsKey(key); - if (containedKey && Objects.equal(value, get(key))) { - return value; - } - if (force) { - inverse().remove(value); - } else { - checkArgument(!containsValue(value), "value already present: %s", value); - } - V oldValue = delegate.put(key, value); - updateInverseMap(key, containedKey, oldValue, value); - return oldValue; - } - - private void updateInverseMap(K key, boolean containedKey, V oldValue, V newValue) { - if (containedKey) { - removeFromInverseMap(oldValue); - } - inverse.delegate.put(newValue, key); - } - - @Override - public V remove(@Nullable Object key) { - return containsKey(key) ? removeFromBothMaps(key) : null; - } - - private V removeFromBothMaps(Object key) { - V oldValue = delegate.remove(key); - removeFromInverseMap(oldValue); - return oldValue; - } - - private void removeFromInverseMap(V oldValue) { - inverse.delegate.remove(oldValue); - } - - // Bulk Operations - - @Override - public void putAll(Map map) { - for (Entry entry : map.entrySet()) { - put(entry.getKey(), entry.getValue()); - } - } - - @Override - public void clear() { - delegate.clear(); - inverse.delegate.clear(); - } - - // Views - - @Override - public BiMap inverse() { - return inverse; - } - - private transient Set keySet; - - @Override - public Set keySet() { - Set result = keySet; - return (result == null) ? keySet = new KeySet() : result; - } - - @WeakOuter - private class KeySet extends ForwardingSet { - @Override - protected Set delegate() { - return delegate.keySet(); - } - - @Override - public void clear() { - AbstractBiMap.this.clear(); - } - - @Override - public boolean remove(Object key) { - if (!contains(key)) { - return false; - } - removeFromBothMaps(key); - return true; - } - - @Override - public boolean removeAll(Collection keysToRemove) { - return standardRemoveAll(keysToRemove); - } - - @Override - public boolean retainAll(Collection keysToRetain) { - return standardRetainAll(keysToRetain); - } - - @Override - public Iterator iterator() { - return Maps.keyIterator(entrySet().iterator()); - } - } - - private transient Set valueSet; - - @Override - public Set values() { - /* - * We can almost reuse the inverse's keySet, except we have to fix the - * iteration order so that it is consistent with the forward map. - */ - Set result = valueSet; - return (result == null) ? valueSet = new ValueSet() : result; - } - - @WeakOuter - private class ValueSet extends ForwardingSet { - final Set valuesDelegate = inverse.keySet(); - - @Override - protected Set delegate() { - return valuesDelegate; - } - - @Override - public Iterator iterator() { - return Maps.valueIterator(entrySet().iterator()); - } - - @Override - public Object[] toArray() { - return standardToArray(); - } - - @Override - public T[] toArray(T[] array) { - return standardToArray(array); - } - - @Override - public String toString() { - return standardToString(); - } - } - - private transient Set> entrySet; - - @Override - public Set> entrySet() { - Set> result = entrySet; - return (result == null) ? entrySet = new EntrySet() : result; - } - - @WeakOuter - private class EntrySet extends ForwardingSet> { - final Set> esDelegate = delegate.entrySet(); - - @Override - protected Set> delegate() { - return esDelegate; - } - - @Override - public void clear() { - AbstractBiMap.this.clear(); - } - - @Override - public boolean remove(Object object) { - if (!esDelegate.contains(object)) { - return false; - } - - // safe because esDelgate.contains(object). - Entry entry = (Entry) object; - inverse.delegate.remove(entry.getValue()); - /* - * Remove the mapping in inverse before removing from esDelegate because - * if entry is part of esDelegate, entry might be invalidated after the - * mapping is removed from esDelegate. - */ - esDelegate.remove(entry); - return true; - } - - @Override - public Iterator> iterator() { - final Iterator> iterator = esDelegate.iterator(); - return new Iterator>() { - Entry entry; - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public Entry next() { - entry = iterator.next(); - final Entry finalEntry = entry; - - return new ForwardingMapEntry() { - @Override - protected Entry delegate() { - return finalEntry; - } - - @Override - public V setValue(V value) { - // Preconditions keep the map and inverse consistent. - checkState(contains(this), "entry no longer in map"); - // similar to putInBothMaps, but set via entry - if (Objects.equal(value, getValue())) { - return value; - } - checkArgument(!containsValue(value), "value already present: %s", value); - V oldValue = finalEntry.setValue(value); - checkState(Objects.equal(value, get(getKey())), "entry no longer in map"); - updateInverseMap(getKey(), true, oldValue, value); - return oldValue; - } - }; - } - - @Override - public void remove() { - checkRemove(entry != null); - V value = entry.getValue(); - iterator.remove(); - removeFromInverseMap(value); - } - }; - } - - // See java.util.Collections.CheckedEntrySet for details on attacks. - - @Override - public Object[] toArray() { - return standardToArray(); - } - - @Override - public T[] toArray(T[] array) { - return standardToArray(array); - } - - @Override - public boolean contains(Object o) { - return Maps.containsEntryImpl(delegate(), o); - } - - @Override - public boolean containsAll(Collection c) { - return standardContainsAll(c); - } - - @Override - public boolean removeAll(Collection c) { - return standardRemoveAll(c); - } - - @Override - public boolean retainAll(Collection c) { - return standardRetainAll(c); - } - } - - /** The inverse of any other {@code AbstractBiMap} subclass. */ - private static class Inverse extends AbstractBiMap { - private Inverse(Map backward, AbstractBiMap forward) { - super(backward, forward); - } - - /* - * Serialization stores the forward bimap, the inverse of this inverse. - * Deserialization calls inverse() on the forward bimap and returns that - * inverse. - * - * If a bimap and its inverse are serialized together, the deserialized - * instances have inverse() methods that return the other. - */ - - @Override - K checkKey(K key) { - return inverse.checkValue(key); - } - - @Override - V checkValue(V value) { - return inverse.checkKey(value); - } - - /** - * @serialData the forward bimap - */ - @GwtIncompatible("java.io.ObjectOuputStream") - private void writeObject(ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); - stream.writeObject(inverse()); - } - - @GwtIncompatible("java.io.ObjectInputStream") - @SuppressWarnings("unchecked") // reading data stored by writeObject - private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - setInverse((AbstractBiMap) stream.readObject()); - } - - @GwtIncompatible("Not needed in the emulated source.") - Object readResolve() { - return inverse().inverse(); - } - - @GwtIncompatible("Not needed in emulated source.") - private static final long serialVersionUID = 0; - } - - @GwtIncompatible("Not needed in emulated source.") - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractIndexedListIterator.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractIndexedListIterator.java deleted file mode 100644 index 6072f2e43aad..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractIndexedListIterator.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkPositionIndex; - -import com.google.common.annotations.GwtCompatible; - -import java.util.ListIterator; -import java.util.NoSuchElementException; - -/** - * This class provides a skeletal implementation of the {@link ListIterator} - * interface across a fixed number of elements that may be retrieved by - * position. It does not support {@link #remove}, {@link #set}, or {@link #add}. - * - * @author Jared Levy - */ -@GwtCompatible -abstract class AbstractIndexedListIterator extends UnmodifiableListIterator { - private final int size; - private int position; - - /** - * Returns the element with the specified index. This method is called by - * {@link #next()}. - */ - protected abstract E get(int index); - - /** - * Constructs an iterator across a sequence of the given size whose initial - * position is 0. That is, the first call to {@link #next()} will return the - * first element (or throw {@link NoSuchElementException} if {@code size} is - * zero). - * - * @throws IllegalArgumentException if {@code size} is negative - */ - protected AbstractIndexedListIterator(int size) { - this(size, 0); - } - - /** - * Constructs an iterator across a sequence of the given size with the given - * initial position. That is, the first call to {@link #nextIndex()} will - * return {@code position}, and the first call to {@link #next()} will return - * the element at that index, if available. Calls to {@link #previous()} can - * retrieve the preceding {@code position} elements. - * - * @throws IndexOutOfBoundsException if {@code position} is negative or is - * greater than {@code size} - * @throws IllegalArgumentException if {@code size} is negative - */ - protected AbstractIndexedListIterator(int size, int position) { - checkPositionIndex(position, size); - this.size = size; - this.position = position; - } - - @Override - public final boolean hasNext() { - return position < size; - } - - @Override - public final E next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - return get(position++); - } - - @Override - public final int nextIndex() { - return position; - } - - @Override - public final boolean hasPrevious() { - return position > 0; - } - - @Override - public final E previous() { - if (!hasPrevious()) { - throw new NoSuchElementException(); - } - return get(--position); - } - - @Override - public final int previousIndex() { - return position - 1; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractIterator.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractIterator.java deleted file mode 100644 index 23a342195fe0..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractIterator.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.annotations.GwtCompatible; - -import java.util.NoSuchElementException; - -/** - * This class provides a skeletal implementation of the {@code Iterator} - * interface, to make this interface easier to implement for certain types of - * data sources. - * - *

{@code Iterator} requires its implementations to support querying the - * end-of-data status without changing the iterator's state, using the {@link - * #hasNext} method. But many data sources, such as {@link - * java.io.Reader#read()}, do not expose this information; the only way to - * discover whether there is any data left is by trying to retrieve it. These - * types of data sources are ordinarily difficult to write iterators for. But - * using this class, one must implement only the {@link #computeNext} method, - * and invoke the {@link #endOfData} method when appropriate. - * - *

Another example is an iterator that skips over null elements in a backing - * iterator. This could be implemented as:

   {@code
- *
- *   public static Iterator skipNulls(final Iterator in) {
- *     return new AbstractIterator() {
- *       protected String computeNext() {
- *         while (in.hasNext()) {
- *           String s = in.next();
- *           if (s != null) {
- *             return s;
- *           }
- *         }
- *         return endOfData();
- *       }
- *     };
- *   }}
- * - *

This class supports iterators that include null elements. - * - * @author Kevin Bourrillion - * @since 2.0 - */ -// When making changes to this class, please also update the copy at -// com.google.common.base.AbstractIterator -@GwtCompatible -public abstract class AbstractIterator extends UnmodifiableIterator { - private State state = State.NOT_READY; - - /** Constructor for use by subclasses. */ - protected AbstractIterator() {} - - private enum State { - /** We have computed the next element and haven't returned it yet. */ - READY, - - /** We haven't yet computed or have already returned the element. */ - NOT_READY, - - /** We have reached the end of the data and are finished. */ - DONE, - - /** We've suffered an exception and are kaput. */ - FAILED, - } - - private T next; - - /** - * Returns the next element. Note: the implementation must call {@link - * #endOfData()} when there are no elements left in the iteration. Failure to - * do so could result in an infinite loop. - * - *

The initial invocation of {@link #hasNext()} or {@link #next()} calls - * this method, as does the first invocation of {@code hasNext} or {@code - * next} following each successful call to {@code next}. Once the - * implementation either invokes {@code endOfData} or throws an exception, - * {@code computeNext} is guaranteed to never be called again. - * - *

If this method throws an exception, it will propagate outward to the - * {@code hasNext} or {@code next} invocation that invoked this method. Any - * further attempts to use the iterator will result in an {@link - * IllegalStateException}. - * - *

The implementation of this method may not invoke the {@code hasNext}, - * {@code next}, or {@link #peek()} methods on this instance; if it does, an - * {@code IllegalStateException} will result. - * - * @return the next element if there was one. If {@code endOfData} was called - * during execution, the return value will be ignored. - * @throws RuntimeException if any unrecoverable error happens. This exception - * will propagate outward to the {@code hasNext()}, {@code next()}, or - * {@code peek()} invocation that invoked this method. Any further - * attempts to use the iterator will result in an - * {@link IllegalStateException}. - */ - protected abstract T computeNext(); - - /** - * Implementations of {@link #computeNext} must invoke this method when - * there are no elements left in the iteration. - * - * @return {@code null}; a convenience so your {@code computeNext} - * implementation can use the simple statement {@code return endOfData();} - */ - protected final T endOfData() { - state = State.DONE; - return null; - } - - @Override - public final boolean hasNext() { - checkState(state != State.FAILED); - switch (state) { - case DONE: - return false; - case READY: - return true; - default: - } - return tryToComputeNext(); - } - - private boolean tryToComputeNext() { - state = State.FAILED; // temporary pessimism - next = computeNext(); - if (state != State.DONE) { - state = State.READY; - return true; - } - return false; - } - - @Override - public final T next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - state = State.NOT_READY; - T result = next; - next = null; - return result; - } - - /** - * Returns the next element in the iteration without advancing the iteration, - * according to the contract of {@link PeekingIterator#peek()}. - * - *

Implementations of {@code AbstractIterator} that wish to expose this - * functionality should implement {@code PeekingIterator}. - */ - public final T peek() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - return next; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractListMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractListMultimap.java deleted file mode 100644 index 3cedc6c51772..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractListMultimap.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nullable; - -/** - * Basic implementation of the {@link ListMultimap} interface. It's a wrapper - * around {@link AbstractMapBasedMultimap} that converts the returned collections into - * {@code Lists}. The {@link #createCollection} method must return a {@code - * List}. - * - * @author Jared Levy - * @since 2.0 - */ -@GwtCompatible -abstract class AbstractListMultimap extends AbstractMapBasedMultimap - implements ListMultimap { - /** - * Creates a new multimap that uses the provided map. - * - * @param map place to store the mapping from each key to its corresponding - * values - */ - protected AbstractListMultimap(Map> map) { - super(map); - } - - @Override - abstract List createCollection(); - - @Override - List createUnmodifiableEmptyCollection() { - return ImmutableList.of(); - } - - // Following Javadoc copied from ListMultimap. - - /** - * {@inheritDoc} - * - *

Because the values for a given key may have duplicates and follow the - * insertion ordering, this method returns a {@link List}, instead of the - * {@link Collection} specified in the {@link Multimap} interface. - */ - @Override - public List get(@Nullable K key) { - return (List) super.get(key); - } - - /** - * {@inheritDoc} - * - *

Because the values for a given key may have duplicates and follow the - * insertion ordering, this method returns a {@link List}, instead of the - * {@link Collection} specified in the {@link Multimap} interface. - */ - @Override - public List removeAll(@Nullable Object key) { - return (List) super.removeAll(key); - } - - /** - * {@inheritDoc} - * - *

Because the values for a given key may have duplicates and follow the - * insertion ordering, this method returns a {@link List}, instead of the - * {@link Collection} specified in the {@link Multimap} interface. - */ - @Override - public List replaceValues(@Nullable K key, Iterable values) { - return (List) super.replaceValues(key, values); - } - - /** - * Stores a key-value pair in the multimap. - * - * @param key key to store in the multimap - * @param value value to store in the multimap - * @return {@code true} always - */ - @Override - public boolean put(@Nullable K key, @Nullable V value) { - return super.put(key, value); - } - - /** - * {@inheritDoc} - * - *

Though the method signature doesn't say so explicitly, the returned map - * has {@link List} values. - */ - @Override - public Map> asMap() { - return super.asMap(); - } - - /** - * Compares the specified object to this multimap for equality. - * - *

Two {@code ListMultimap} instances are equal if, for each key, they - * contain the same values in the same order. If the value orderings disagree, - * the multimaps will not be considered equal. - */ - @Override - public boolean equals(@Nullable Object object) { - return super.equals(object); - } - - private static final long serialVersionUID = 6588350623831699109L; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractMapBasedMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractMapBasedMultimap.java deleted file mode 100644 index fa4eae89ad05..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractMapBasedMultimap.java +++ /dev/null @@ -1,1604 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.CollectPreconditions.checkRemove; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.collect.Maps.ViewCachingAbstractMap; -import com.google.j2objc.annotations.WeakOuter; - -import java.io.Serializable; -import java.util.AbstractCollection; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.ConcurrentModificationException; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.NavigableMap; -import java.util.NavigableSet; -import java.util.RandomAccess; -import java.util.Set; -import java.util.SortedMap; -import java.util.SortedSet; - -import javax.annotation.Nullable; - -/** - * Basic implementation of the {@link Multimap} interface. This class represents - * a multimap as a map that associates each key with a collection of values. All - * methods of {@link Multimap} are supported, including those specified as - * optional in the interface. - * - *

To implement a multimap, a subclass must define the method {@link - * #createCollection()}, which creates an empty collection of values for a key. - * - *

The multimap constructor takes a map that has a single entry for each - * distinct key. When you insert a key-value pair with a key that isn't already - * in the multimap, {@code AbstractMapBasedMultimap} calls {@link #createCollection()} - * to create the collection of values for that key. The subclass should not call - * {@link #createCollection()} directly, and a new instance should be created - * every time the method is called. - * - *

For example, the subclass could pass a {@link java.util.TreeMap} during - * construction, and {@link #createCollection()} could return a {@link - * java.util.TreeSet}, in which case the multimap's iterators would propagate - * through the keys and values in sorted order. - * - *

Keys and values may be null, as long as the underlying collection classes - * support null elements. - * - *

The collections created by {@link #createCollection()} may or may not - * allow duplicates. If the collection, such as a {@link Set}, does not support - * duplicates, an added key-value pair will replace an existing pair with the - * same key and value, if such a pair is present. With collections like {@link - * List} that allow duplicates, the collection will keep the existing key-value - * pairs while adding a new pair. - * - *

This class is not threadsafe when any concurrent operations update the - * multimap, even if the underlying map and {@link #createCollection()} method - * return threadsafe classes. Concurrent read operations will work correctly. To - * allow concurrent update operations, wrap your multimap with a call to {@link - * Multimaps#synchronizedMultimap}. - * - *

For serialization to work, the subclass must specify explicit - * {@code readObject} and {@code writeObject} methods. - * - * @author Jared Levy - * @author Louis Wasserman - */ -@GwtCompatible(emulated = true) -abstract class AbstractMapBasedMultimap extends AbstractMultimap - implements Serializable { - /* - * Here's an outline of the overall design. - * - * The map variable contains the collection of values associated with each - * key. When a key-value pair is added to a multimap that didn't previously - * contain any values for that key, a new collection generated by - * createCollection is added to the map. That same collection instance - * remains in the map as long as the multimap has any values for the key. If - * all values for the key are removed, the key and collection are removed - * from the map. - * - * The get method returns a WrappedCollection, which decorates the collection - * in the map (if the key is present) or an empty collection (if the key is - * not present). When the collection delegate in the WrappedCollection is - * empty, the multimap may contain subsequently added values for that key. To - * handle that situation, the WrappedCollection checks whether map contains - * an entry for the provided key, and if so replaces the delegate. - */ - - private transient Map> map; - private transient int totalSize; - - /** - * Creates a new multimap that uses the provided map. - * - * @param map place to store the mapping from each key to its corresponding - * values - * @throws IllegalArgumentException if {@code map} is not empty - */ - protected AbstractMapBasedMultimap(Map> map) { - checkArgument(map.isEmpty()); - this.map = map; - } - - /** Used during deserialization only. */ - final void setMap(Map> map) { - this.map = map; - totalSize = 0; - for (Collection values : map.values()) { - checkArgument(!values.isEmpty()); - totalSize += values.size(); - } - } - - /** - * Creates an unmodifiable, empty collection of values. - * - *

This is used in {@link #removeAll} on an empty key. - */ - Collection createUnmodifiableEmptyCollection() { - return unmodifiableCollectionSubclass(createCollection()); - } - - /** - * Creates the collection of values for a single key. - * - *

Collections with weak, soft, or phantom references are not supported. - * Each call to {@code createCollection} should create a new instance. - * - *

The returned collection class determines whether duplicate key-value - * pairs are allowed. - * - * @return an empty collection of values - */ - abstract Collection createCollection(); - - /** - * Creates the collection of values for an explicitly provided key. By - * default, it simply calls {@link #createCollection()}, which is the correct - * behavior for most implementations. The {@link LinkedHashMultimap} class - * overrides it. - * - * @param key key to associate with values in the collection - * @return an empty collection of values - */ - Collection createCollection(@Nullable K key) { - return createCollection(); - } - - Map> backingMap() { - return map; - } - - // Query Operations - - @Override - public int size() { - return totalSize; - } - - @Override - public boolean containsKey(@Nullable Object key) { - return map.containsKey(key); - } - - // Modification Operations - - @Override - public boolean put(@Nullable K key, @Nullable V value) { - Collection collection = map.get(key); - if (collection == null) { - collection = createCollection(key); - if (collection.add(value)) { - totalSize++; - map.put(key, collection); - return true; - } else { - throw new AssertionError("New Collection violated the Collection spec"); - } - } else if (collection.add(value)) { - totalSize++; - return true; - } else { - return false; - } - } - - private Collection getOrCreateCollection(@Nullable K key) { - Collection collection = map.get(key); - if (collection == null) { - collection = createCollection(key); - map.put(key, collection); - } - return collection; - } - - // Bulk Operations - - /** - * {@inheritDoc} - * - *

The returned collection is immutable. - */ - @Override - public Collection replaceValues(@Nullable K key, Iterable values) { - Iterator iterator = values.iterator(); - if (!iterator.hasNext()) { - return removeAll(key); - } - - // TODO(lowasser): investigate atomic failure? - Collection collection = getOrCreateCollection(key); - Collection oldValues = createCollection(); - oldValues.addAll(collection); - - totalSize -= collection.size(); - collection.clear(); - - while (iterator.hasNext()) { - if (collection.add(iterator.next())) { - totalSize++; - } - } - - return unmodifiableCollectionSubclass(oldValues); - } - - /** - * {@inheritDoc} - * - *

The returned collection is immutable. - */ - @Override - public Collection removeAll(@Nullable Object key) { - Collection collection = map.remove(key); - - if (collection == null) { - return createUnmodifiableEmptyCollection(); - } - - Collection output = createCollection(); - output.addAll(collection); - totalSize -= collection.size(); - collection.clear(); - - return unmodifiableCollectionSubclass(output); - } - - Collection unmodifiableCollectionSubclass(Collection collection) { - // We don't deal with NavigableSet here yet for GWT reasons -- instead, - // non-GWT TreeMultimap explicitly overrides this and uses NavigableSet. - if (collection instanceof SortedSet) { - return Collections.unmodifiableSortedSet((SortedSet) collection); - } else if (collection instanceof Set) { - return Collections.unmodifiableSet((Set) collection); - } else if (collection instanceof List) { - return Collections.unmodifiableList((List) collection); - } else { - return Collections.unmodifiableCollection(collection); - } - } - - @Override - public void clear() { - // Clear each collection, to make previously returned collections empty. - for (Collection collection : map.values()) { - collection.clear(); - } - map.clear(); - totalSize = 0; - } - - // Views - - /** - * {@inheritDoc} - * - *

The returned collection is not serializable. - */ - @Override - public Collection get(@Nullable K key) { - Collection collection = map.get(key); - if (collection == null) { - collection = createCollection(key); - } - return wrapCollection(key, collection); - } - - /** - * Generates a decorated collection that remains consistent with the values in - * the multimap for the provided key. Changes to the multimap may alter the - * returned collection, and vice versa. - */ - Collection wrapCollection(@Nullable K key, Collection collection) { - // We don't deal with NavigableSet here yet for GWT reasons -- instead, - // non-GWT TreeMultimap explicitly overrides this and uses NavigableSet. - if (collection instanceof SortedSet) { - return new WrappedSortedSet(key, (SortedSet) collection, null); - } else if (collection instanceof Set) { - return new WrappedSet(key, (Set) collection); - } else if (collection instanceof List) { - return wrapList(key, (List) collection, null); - } else { - return new WrappedCollection(key, collection, null); - } - } - - private List wrapList(@Nullable K key, List list, @Nullable WrappedCollection ancestor) { - return (list instanceof RandomAccess) - ? new RandomAccessWrappedList(key, list, ancestor) - : new WrappedList(key, list, ancestor); - } - - /** - * Collection decorator that stays in sync with the multimap values for a key. - * There are two kinds of wrapped collections: full and subcollections. Both - * have a delegate pointing to the underlying collection class. - * - *

Full collections, identified by a null ancestor field, contain all - * multimap values for a given key. Its delegate is a value in {@link - * AbstractMapBasedMultimap#map} whenever the delegate is non-empty. The {@code - * refreshIfEmpty}, {@code removeIfEmpty}, and {@code addToMap} methods ensure - * that the {@code WrappedCollection} and map remain consistent. - * - *

A subcollection, such as a sublist, contains some of the values for a - * given key. Its ancestor field points to the full wrapped collection with - * all values for the key. The subcollection {@code refreshIfEmpty}, {@code - * removeIfEmpty}, and {@code addToMap} methods call the corresponding methods - * of the full wrapped collection. - */ - @WeakOuter - private class WrappedCollection extends AbstractCollection { - final K key; - Collection delegate; - final WrappedCollection ancestor; - final Collection ancestorDelegate; - - WrappedCollection( - @Nullable K key, Collection delegate, @Nullable WrappedCollection ancestor) { - this.key = key; - this.delegate = delegate; - this.ancestor = ancestor; - this.ancestorDelegate = (ancestor == null) ? null : ancestor.getDelegate(); - } - - /** - * If the delegate collection is empty, but the multimap has values for the - * key, replace the delegate with the new collection for the key. - * - *

For a subcollection, refresh its ancestor and validate that the - * ancestor delegate hasn't changed. - */ - void refreshIfEmpty() { - if (ancestor != null) { - ancestor.refreshIfEmpty(); - if (ancestor.getDelegate() != ancestorDelegate) { - throw new ConcurrentModificationException(); - } - } else if (delegate.isEmpty()) { - Collection newDelegate = map.get(key); - if (newDelegate != null) { - delegate = newDelegate; - } - } - } - - /** - * If collection is empty, remove it from {@code AbstractMapBasedMultimap.this.map}. - * For subcollections, check whether the ancestor collection is empty. - */ - void removeIfEmpty() { - if (ancestor != null) { - ancestor.removeIfEmpty(); - } else if (delegate.isEmpty()) { - map.remove(key); - } - } - - K getKey() { - return key; - } - - /** - * Add the delegate to the map. Other {@code WrappedCollection} methods - * should call this method after adding elements to a previously empty - * collection. - * - *

Subcollection add the ancestor's delegate instead. - */ - void addToMap() { - if (ancestor != null) { - ancestor.addToMap(); - } else { - map.put(key, delegate); - } - } - - @Override - public int size() { - refreshIfEmpty(); - return delegate.size(); - } - - @Override - public boolean equals(@Nullable Object object) { - if (object == this) { - return true; - } - refreshIfEmpty(); - return delegate.equals(object); - } - - @Override - public int hashCode() { - refreshIfEmpty(); - return delegate.hashCode(); - } - - @Override - public String toString() { - refreshIfEmpty(); - return delegate.toString(); - } - - Collection getDelegate() { - return delegate; - } - - @Override - public Iterator iterator() { - refreshIfEmpty(); - return new WrappedIterator(); - } - - /** Collection iterator for {@code WrappedCollection}. */ - class WrappedIterator implements Iterator { - final Iterator delegateIterator; - final Collection originalDelegate = delegate; - - WrappedIterator() { - delegateIterator = iteratorOrListIterator(delegate); - } - - WrappedIterator(Iterator delegateIterator) { - this.delegateIterator = delegateIterator; - } - - /** - * If the delegate changed since the iterator was created, the iterator is - * no longer valid. - */ - void validateIterator() { - refreshIfEmpty(); - if (delegate != originalDelegate) { - throw new ConcurrentModificationException(); - } - } - - @Override - public boolean hasNext() { - validateIterator(); - return delegateIterator.hasNext(); - } - - @Override - public V next() { - validateIterator(); - return delegateIterator.next(); - } - - @Override - public void remove() { - delegateIterator.remove(); - totalSize--; - removeIfEmpty(); - } - - Iterator getDelegateIterator() { - validateIterator(); - return delegateIterator; - } - } - - @Override - public boolean add(V value) { - refreshIfEmpty(); - boolean wasEmpty = delegate.isEmpty(); - boolean changed = delegate.add(value); - if (changed) { - totalSize++; - if (wasEmpty) { - addToMap(); - } - } - return changed; - } - - WrappedCollection getAncestor() { - return ancestor; - } - - // The following methods are provided for better performance. - - @Override - public boolean addAll(Collection collection) { - if (collection.isEmpty()) { - return false; - } - int oldSize = size(); // calls refreshIfEmpty - boolean changed = delegate.addAll(collection); - if (changed) { - int newSize = delegate.size(); - totalSize += (newSize - oldSize); - if (oldSize == 0) { - addToMap(); - } - } - return changed; - } - - @Override - public boolean contains(Object o) { - refreshIfEmpty(); - return delegate.contains(o); - } - - @Override - public boolean containsAll(Collection c) { - refreshIfEmpty(); - return delegate.containsAll(c); - } - - @Override - public void clear() { - int oldSize = size(); // calls refreshIfEmpty - if (oldSize == 0) { - return; - } - delegate.clear(); - totalSize -= oldSize; - removeIfEmpty(); // maybe shouldn't be removed if this is a sublist - } - - @Override - public boolean remove(Object o) { - refreshIfEmpty(); - boolean changed = delegate.remove(o); - if (changed) { - totalSize--; - removeIfEmpty(); - } - return changed; - } - - @Override - public boolean removeAll(Collection c) { - if (c.isEmpty()) { - return false; - } - int oldSize = size(); // calls refreshIfEmpty - boolean changed = delegate.removeAll(c); - if (changed) { - int newSize = delegate.size(); - totalSize += (newSize - oldSize); - removeIfEmpty(); - } - return changed; - } - - @Override - public boolean retainAll(Collection c) { - checkNotNull(c); - int oldSize = size(); // calls refreshIfEmpty - boolean changed = delegate.retainAll(c); - if (changed) { - int newSize = delegate.size(); - totalSize += (newSize - oldSize); - removeIfEmpty(); - } - return changed; - } - } - - private Iterator iteratorOrListIterator(Collection collection) { - return (collection instanceof List) - ? ((List) collection).listIterator() - : collection.iterator(); - } - - /** Set decorator that stays in sync with the multimap values for a key. */ - @WeakOuter - private class WrappedSet extends WrappedCollection implements Set { - WrappedSet(@Nullable K key, Set delegate) { - super(key, delegate, null); - } - - @Override - public boolean removeAll(Collection c) { - if (c.isEmpty()) { - return false; - } - int oldSize = size(); // calls refreshIfEmpty - - // Guava issue 1013: AbstractSet and most JDK set implementations are - // susceptible to quadratic removeAll performance on lists; - // use a slightly smarter implementation here - boolean changed = Sets.removeAllImpl((Set) delegate, c); - if (changed) { - int newSize = delegate.size(); - totalSize += (newSize - oldSize); - removeIfEmpty(); - } - return changed; - } - } - - /** - * SortedSet decorator that stays in sync with the multimap values for a key. - */ - @WeakOuter - private class WrappedSortedSet extends WrappedCollection implements SortedSet { - WrappedSortedSet(@Nullable K key, SortedSet delegate, @Nullable WrappedCollection ancestor) { - super(key, delegate, ancestor); - } - - SortedSet getSortedSetDelegate() { - return (SortedSet) getDelegate(); - } - - @Override - public Comparator comparator() { - return getSortedSetDelegate().comparator(); - } - - @Override - public V first() { - refreshIfEmpty(); - return getSortedSetDelegate().first(); - } - - @Override - public V last() { - refreshIfEmpty(); - return getSortedSetDelegate().last(); - } - - @Override - public SortedSet headSet(V toElement) { - refreshIfEmpty(); - return new WrappedSortedSet( - getKey(), - getSortedSetDelegate().headSet(toElement), - (getAncestor() == null) ? this : getAncestor()); - } - - @Override - public SortedSet subSet(V fromElement, V toElement) { - refreshIfEmpty(); - return new WrappedSortedSet( - getKey(), - getSortedSetDelegate().subSet(fromElement, toElement), - (getAncestor() == null) ? this : getAncestor()); - } - - @Override - public SortedSet tailSet(V fromElement) { - refreshIfEmpty(); - return new WrappedSortedSet( - getKey(), - getSortedSetDelegate().tailSet(fromElement), - (getAncestor() == null) ? this : getAncestor()); - } - } - - @GwtIncompatible("NavigableSet") - @WeakOuter - class WrappedNavigableSet extends WrappedSortedSet implements NavigableSet { - WrappedNavigableSet( - @Nullable K key, NavigableSet delegate, @Nullable WrappedCollection ancestor) { - super(key, delegate, ancestor); - } - - @Override - NavigableSet getSortedSetDelegate() { - return (NavigableSet) super.getSortedSetDelegate(); - } - - @Override - public V lower(V v) { - return getSortedSetDelegate().lower(v); - } - - @Override - public V floor(V v) { - return getSortedSetDelegate().floor(v); - } - - @Override - public V ceiling(V v) { - return getSortedSetDelegate().ceiling(v); - } - - @Override - public V higher(V v) { - return getSortedSetDelegate().higher(v); - } - - @Override - public V pollFirst() { - return Iterators.pollNext(iterator()); - } - - @Override - public V pollLast() { - return Iterators.pollNext(descendingIterator()); - } - - private NavigableSet wrap(NavigableSet wrapped) { - return new WrappedNavigableSet(key, wrapped, (getAncestor() == null) ? this : getAncestor()); - } - - @Override - public NavigableSet descendingSet() { - return wrap(getSortedSetDelegate().descendingSet()); - } - - @Override - public Iterator descendingIterator() { - return new WrappedIterator(getSortedSetDelegate().descendingIterator()); - } - - @Override - public NavigableSet subSet( - V fromElement, boolean fromInclusive, V toElement, boolean toInclusive) { - return wrap( - getSortedSetDelegate().subSet(fromElement, fromInclusive, toElement, toInclusive)); - } - - @Override - public NavigableSet headSet(V toElement, boolean inclusive) { - return wrap(getSortedSetDelegate().headSet(toElement, inclusive)); - } - - @Override - public NavigableSet tailSet(V fromElement, boolean inclusive) { - return wrap(getSortedSetDelegate().tailSet(fromElement, inclusive)); - } - } - - /** List decorator that stays in sync with the multimap values for a key. */ - @WeakOuter - private class WrappedList extends WrappedCollection implements List { - WrappedList(@Nullable K key, List delegate, @Nullable WrappedCollection ancestor) { - super(key, delegate, ancestor); - } - - List getListDelegate() { - return (List) getDelegate(); - } - - @Override - public boolean addAll(int index, Collection c) { - if (c.isEmpty()) { - return false; - } - int oldSize = size(); // calls refreshIfEmpty - boolean changed = getListDelegate().addAll(index, c); - if (changed) { - int newSize = getDelegate().size(); - totalSize += (newSize - oldSize); - if (oldSize == 0) { - addToMap(); - } - } - return changed; - } - - @Override - public V get(int index) { - refreshIfEmpty(); - return getListDelegate().get(index); - } - - @Override - public V set(int index, V element) { - refreshIfEmpty(); - return getListDelegate().set(index, element); - } - - @Override - public void add(int index, V element) { - refreshIfEmpty(); - boolean wasEmpty = getDelegate().isEmpty(); - getListDelegate().add(index, element); - totalSize++; - if (wasEmpty) { - addToMap(); - } - } - - @Override - public V remove(int index) { - refreshIfEmpty(); - V value = getListDelegate().remove(index); - totalSize--; - removeIfEmpty(); - return value; - } - - @Override - public int indexOf(Object o) { - refreshIfEmpty(); - return getListDelegate().indexOf(o); - } - - @Override - public int lastIndexOf(Object o) { - refreshIfEmpty(); - return getListDelegate().lastIndexOf(o); - } - - @Override - public ListIterator listIterator() { - refreshIfEmpty(); - return new WrappedListIterator(); - } - - @Override - public ListIterator listIterator(int index) { - refreshIfEmpty(); - return new WrappedListIterator(index); - } - - @Override - public List subList(int fromIndex, int toIndex) { - refreshIfEmpty(); - return wrapList( - getKey(), - getListDelegate().subList(fromIndex, toIndex), - (getAncestor() == null) ? this : getAncestor()); - } - - /** ListIterator decorator. */ - private class WrappedListIterator extends WrappedIterator implements ListIterator { - WrappedListIterator() {} - - public WrappedListIterator(int index) { - super(getListDelegate().listIterator(index)); - } - - private ListIterator getDelegateListIterator() { - return (ListIterator) getDelegateIterator(); - } - - @Override - public boolean hasPrevious() { - return getDelegateListIterator().hasPrevious(); - } - - @Override - public V previous() { - return getDelegateListIterator().previous(); - } - - @Override - public int nextIndex() { - return getDelegateListIterator().nextIndex(); - } - - @Override - public int previousIndex() { - return getDelegateListIterator().previousIndex(); - } - - @Override - public void set(V value) { - getDelegateListIterator().set(value); - } - - @Override - public void add(V value) { - boolean wasEmpty = isEmpty(); - getDelegateListIterator().add(value); - totalSize++; - if (wasEmpty) { - addToMap(); - } - } - } - } - - /** - * List decorator that stays in sync with the multimap values for a key and - * supports rapid random access. - */ - private class RandomAccessWrappedList extends WrappedList implements RandomAccess { - RandomAccessWrappedList( - @Nullable K key, List delegate, @Nullable WrappedCollection ancestor) { - super(key, delegate, ancestor); - } - } - - @Override - Set createKeySet() { - // TreeMultimap uses NavigableKeySet explicitly, but we don't handle that here for GWT - // compatibility reasons - return (map instanceof SortedMap) - ? new SortedKeySet((SortedMap>) map) - : new KeySet(map); - } - - @WeakOuter - private class KeySet extends Maps.KeySet> { - KeySet(final Map> subMap) { - super(subMap); - } - - @Override - public Iterator iterator() { - final Iterator>> entryIterator = map().entrySet().iterator(); - return new Iterator() { - Map.Entry> entry; - - @Override - public boolean hasNext() { - return entryIterator.hasNext(); - } - - @Override - public K next() { - entry = entryIterator.next(); - return entry.getKey(); - } - - @Override - public void remove() { - checkRemove(entry != null); - Collection collection = entry.getValue(); - entryIterator.remove(); - totalSize -= collection.size(); - collection.clear(); - } - }; - } - - // The following methods are included for better performance. - - @Override - public boolean remove(Object key) { - int count = 0; - Collection collection = map().remove(key); - if (collection != null) { - count = collection.size(); - collection.clear(); - totalSize -= count; - } - return count > 0; - } - - @Override - public void clear() { - Iterators.clear(iterator()); - } - - @Override - public boolean containsAll(Collection c) { - return map().keySet().containsAll(c); - } - - @Override - public boolean equals(@Nullable Object object) { - return this == object || this.map().keySet().equals(object); - } - - @Override - public int hashCode() { - return map().keySet().hashCode(); - } - } - - @WeakOuter - private class SortedKeySet extends KeySet implements SortedSet { - - SortedKeySet(SortedMap> subMap) { - super(subMap); - } - - SortedMap> sortedMap() { - return (SortedMap>) super.map(); - } - - @Override - public Comparator comparator() { - return sortedMap().comparator(); - } - - @Override - public K first() { - return sortedMap().firstKey(); - } - - @Override - public SortedSet headSet(K toElement) { - return new SortedKeySet(sortedMap().headMap(toElement)); - } - - @Override - public K last() { - return sortedMap().lastKey(); - } - - @Override - public SortedSet subSet(K fromElement, K toElement) { - return new SortedKeySet(sortedMap().subMap(fromElement, toElement)); - } - - @Override - public SortedSet tailSet(K fromElement) { - return new SortedKeySet(sortedMap().tailMap(fromElement)); - } - } - - @GwtIncompatible("NavigableSet") - @WeakOuter - class NavigableKeySet extends SortedKeySet implements NavigableSet { - NavigableKeySet(NavigableMap> subMap) { - super(subMap); - } - - @Override - NavigableMap> sortedMap() { - return (NavigableMap>) super.sortedMap(); - } - - @Override - public K lower(K k) { - return sortedMap().lowerKey(k); - } - - @Override - public K floor(K k) { - return sortedMap().floorKey(k); - } - - @Override - public K ceiling(K k) { - return sortedMap().ceilingKey(k); - } - - @Override - public K higher(K k) { - return sortedMap().higherKey(k); - } - - @Override - public K pollFirst() { - return Iterators.pollNext(iterator()); - } - - @Override - public K pollLast() { - return Iterators.pollNext(descendingIterator()); - } - - @Override - public NavigableSet descendingSet() { - return new NavigableKeySet(sortedMap().descendingMap()); - } - - @Override - public Iterator descendingIterator() { - return descendingSet().iterator(); - } - - @Override - public NavigableSet headSet(K toElement) { - return headSet(toElement, false); - } - - @Override - public NavigableSet headSet(K toElement, boolean inclusive) { - return new NavigableKeySet(sortedMap().headMap(toElement, inclusive)); - } - - @Override - public NavigableSet subSet(K fromElement, K toElement) { - return subSet(fromElement, true, toElement, false); - } - - @Override - public NavigableSet subSet( - K fromElement, boolean fromInclusive, K toElement, boolean toInclusive) { - return new NavigableKeySet( - sortedMap().subMap(fromElement, fromInclusive, toElement, toInclusive)); - } - - @Override - public NavigableSet tailSet(K fromElement) { - return tailSet(fromElement, true); - } - - @Override - public NavigableSet tailSet(K fromElement, boolean inclusive) { - return new NavigableKeySet(sortedMap().tailMap(fromElement, inclusive)); - } - } - - /** - * Removes all values for the provided key. Unlike {@link #removeAll}, it - * returns the number of removed mappings. - */ - private int removeValuesForKey(Object key) { - Collection collection = Maps.safeRemove(map, key); - - int count = 0; - if (collection != null) { - count = collection.size(); - collection.clear(); - totalSize -= count; - } - return count; - } - - private abstract class Itr implements Iterator { - final Iterator>> keyIterator; - K key; - Collection collection; - Iterator valueIterator; - - Itr() { - keyIterator = map.entrySet().iterator(); - key = null; - collection = null; - valueIterator = Iterators.emptyModifiableIterator(); - } - - abstract T output(K key, V value); - - @Override - public boolean hasNext() { - return keyIterator.hasNext() || valueIterator.hasNext(); - } - - @Override - public T next() { - if (!valueIterator.hasNext()) { - Map.Entry> mapEntry = keyIterator.next(); - key = mapEntry.getKey(); - collection = mapEntry.getValue(); - valueIterator = collection.iterator(); - } - return output(key, valueIterator.next()); - } - - @Override - public void remove() { - valueIterator.remove(); - if (collection.isEmpty()) { - keyIterator.remove(); - } - totalSize--; - } - } - - /** - * {@inheritDoc} - * - *

The iterator generated by the returned collection traverses the values - * for one key, followed by the values of a second key, and so on. - */ - @Override - public Collection values() { - return super.values(); - } - - @Override - Iterator valueIterator() { - return new Itr() { - @Override - V output(K key, V value) { - return value; - } - }; - } - - /* - * TODO(kevinb): should we copy this javadoc to each concrete class, so that - * classes like LinkedHashMultimap that need to say something different are - * still able to {@inheritDoc} all the way from Multimap? - */ - - /** - * {@inheritDoc} - * - *

The iterator generated by the returned collection traverses the values - * for one key, followed by the values of a second key, and so on. - * - *

Each entry is an immutable snapshot of a key-value mapping in the - * multimap, taken at the time the entry is returned by a method call to the - * collection or its iterator. - */ - @Override - public Collection> entries() { - return super.entries(); - } - - /** - * Returns an iterator across all key-value map entries, used by {@code - * entries().iterator()} and {@code values().iterator()}. The default - * behavior, which traverses the values for one key, the values for a second - * key, and so on, suffices for most {@code AbstractMapBasedMultimap} implementations. - * - * @return an iterator across map entries - */ - @Override - Iterator> entryIterator() { - return new Itr>() { - @Override - Entry output(K key, V value) { - return Maps.immutableEntry(key, value); - } - }; - } - - @Override - Map> createAsMap() { - // TreeMultimap uses NavigableAsMap explicitly, but we don't handle that here for GWT - // compatibility reasons - return (map instanceof SortedMap) - ? new SortedAsMap((SortedMap>) map) - : new AsMap(map); - } - - @WeakOuter - private class AsMap extends ViewCachingAbstractMap> { - /** - * Usually the same as map, but smaller for the headMap(), tailMap(), or - * subMap() of a SortedAsMap. - */ - final transient Map> submap; - - AsMap(Map> submap) { - this.submap = submap; - } - - @Override - protected Set>> createEntrySet() { - return new AsMapEntries(); - } - - // The following methods are included for performance. - - @Override - public boolean containsKey(Object key) { - return Maps.safeContainsKey(submap, key); - } - - @Override - public Collection get(Object key) { - Collection collection = Maps.safeGet(submap, key); - if (collection == null) { - return null; - } - @SuppressWarnings("unchecked") - K k = (K) key; - return wrapCollection(k, collection); - } - - @Override - public Set keySet() { - return AbstractMapBasedMultimap.this.keySet(); - } - - @Override - public int size() { - return submap.size(); - } - - @Override - public Collection remove(Object key) { - Collection collection = submap.remove(key); - if (collection == null) { - return null; - } - - Collection output = createCollection(); - output.addAll(collection); - totalSize -= collection.size(); - collection.clear(); - return output; - } - - @Override - public boolean equals(@Nullable Object object) { - return this == object || submap.equals(object); - } - - @Override - public int hashCode() { - return submap.hashCode(); - } - - @Override - public String toString() { - return submap.toString(); - } - - @Override - public void clear() { - if (submap == map) { - AbstractMapBasedMultimap.this.clear(); - } else { - Iterators.clear(new AsMapIterator()); - } - } - - Entry> wrapEntry(Entry> entry) { - K key = entry.getKey(); - return Maps.immutableEntry(key, wrapCollection(key, entry.getValue())); - } - - @WeakOuter - class AsMapEntries extends Maps.EntrySet> { - @Override - Map> map() { - return AsMap.this; - } - - @Override - public Iterator>> iterator() { - return new AsMapIterator(); - } - - // The following methods are included for performance. - - @Override - public boolean contains(Object o) { - return Collections2.safeContains(submap.entrySet(), o); - } - - @Override - public boolean remove(Object o) { - if (!contains(o)) { - return false; - } - Map.Entry entry = (Map.Entry) o; - removeValuesForKey(entry.getKey()); - return true; - } - } - - /** Iterator across all keys and value collections. */ - class AsMapIterator implements Iterator>> { - final Iterator>> delegateIterator = submap.entrySet().iterator(); - Collection collection; - - @Override - public boolean hasNext() { - return delegateIterator.hasNext(); - } - - @Override - public Map.Entry> next() { - Map.Entry> entry = delegateIterator.next(); - collection = entry.getValue(); - return wrapEntry(entry); - } - - @Override - public void remove() { - delegateIterator.remove(); - totalSize -= collection.size(); - collection.clear(); - } - } - } - - @WeakOuter - private class SortedAsMap extends AsMap implements SortedMap> { - SortedAsMap(SortedMap> submap) { - super(submap); - } - - SortedMap> sortedMap() { - return (SortedMap>) submap; - } - - @Override - public Comparator comparator() { - return sortedMap().comparator(); - } - - @Override - public K firstKey() { - return sortedMap().firstKey(); - } - - @Override - public K lastKey() { - return sortedMap().lastKey(); - } - - @Override - public SortedMap> headMap(K toKey) { - return new SortedAsMap(sortedMap().headMap(toKey)); - } - - @Override - public SortedMap> subMap(K fromKey, K toKey) { - return new SortedAsMap(sortedMap().subMap(fromKey, toKey)); - } - - @Override - public SortedMap> tailMap(K fromKey) { - return new SortedAsMap(sortedMap().tailMap(fromKey)); - } - - SortedSet sortedKeySet; - - // returns a SortedSet, even though returning a Set would be sufficient to - // satisfy the SortedMap.keySet() interface - @Override - public SortedSet keySet() { - SortedSet result = sortedKeySet; - return (result == null) ? sortedKeySet = createKeySet() : result; - } - - @Override - SortedSet createKeySet() { - return new SortedKeySet(sortedMap()); - } - } - - @GwtIncompatible("NavigableAsMap") - class NavigableAsMap extends SortedAsMap implements NavigableMap> { - - NavigableAsMap(NavigableMap> submap) { - super(submap); - } - - @Override - NavigableMap> sortedMap() { - return (NavigableMap>) super.sortedMap(); - } - - @Override - public Entry> lowerEntry(K key) { - Entry> entry = sortedMap().lowerEntry(key); - return (entry == null) ? null : wrapEntry(entry); - } - - @Override - public K lowerKey(K key) { - return sortedMap().lowerKey(key); - } - - @Override - public Entry> floorEntry(K key) { - Entry> entry = sortedMap().floorEntry(key); - return (entry == null) ? null : wrapEntry(entry); - } - - @Override - public K floorKey(K key) { - return sortedMap().floorKey(key); - } - - @Override - public Entry> ceilingEntry(K key) { - Entry> entry = sortedMap().ceilingEntry(key); - return (entry == null) ? null : wrapEntry(entry); - } - - @Override - public K ceilingKey(K key) { - return sortedMap().ceilingKey(key); - } - - @Override - public Entry> higherEntry(K key) { - Entry> entry = sortedMap().higherEntry(key); - return (entry == null) ? null : wrapEntry(entry); - } - - @Override - public K higherKey(K key) { - return sortedMap().higherKey(key); - } - - @Override - public Entry> firstEntry() { - Entry> entry = sortedMap().firstEntry(); - return (entry == null) ? null : wrapEntry(entry); - } - - @Override - public Entry> lastEntry() { - Entry> entry = sortedMap().lastEntry(); - return (entry == null) ? null : wrapEntry(entry); - } - - @Override - public Entry> pollFirstEntry() { - return pollAsMapEntry(entrySet().iterator()); - } - - @Override - public Entry> pollLastEntry() { - return pollAsMapEntry(descendingMap().entrySet().iterator()); - } - - Map.Entry> pollAsMapEntry(Iterator>> entryIterator) { - if (!entryIterator.hasNext()) { - return null; - } - Entry> entry = entryIterator.next(); - Collection output = createCollection(); - output.addAll(entry.getValue()); - entryIterator.remove(); - return Maps.immutableEntry(entry.getKey(), unmodifiableCollectionSubclass(output)); - } - - @Override - public NavigableMap> descendingMap() { - return new NavigableAsMap(sortedMap().descendingMap()); - } - - @Override - public NavigableSet keySet() { - return (NavigableSet) super.keySet(); - } - - @Override - NavigableSet createKeySet() { - return new NavigableKeySet(sortedMap()); - } - - @Override - public NavigableSet navigableKeySet() { - return keySet(); - } - - @Override - public NavigableSet descendingKeySet() { - return descendingMap().navigableKeySet(); - } - - @Override - public NavigableMap> subMap(K fromKey, K toKey) { - return subMap(fromKey, true, toKey, false); - } - - @Override - public NavigableMap> subMap( - K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { - return new NavigableAsMap(sortedMap().subMap(fromKey, fromInclusive, toKey, toInclusive)); - } - - @Override - public NavigableMap> headMap(K toKey) { - return headMap(toKey, false); - } - - @Override - public NavigableMap> headMap(K toKey, boolean inclusive) { - return new NavigableAsMap(sortedMap().headMap(toKey, inclusive)); - } - - @Override - public NavigableMap> tailMap(K fromKey) { - return tailMap(fromKey, true); - } - - @Override - public NavigableMap> tailMap(K fromKey, boolean inclusive) { - return new NavigableAsMap(sortedMap().tailMap(fromKey, inclusive)); - } - } - - private static final long serialVersionUID = 2447537837011683357L; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractMapBasedMultiset.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractMapBasedMultiset.java deleted file mode 100644 index 7bfc37fb515f..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractMapBasedMultiset.java +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.CollectPreconditions.checkNonnegative; -import static com.google.common.collect.CollectPreconditions.checkRemove; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.primitives.Ints; - -import java.io.InvalidObjectException; -import java.io.ObjectStreamException; -import java.io.Serializable; -import java.util.ConcurrentModificationException; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * Basic implementation of {@code Multiset} backed by an instance of {@code - * Map}. - * - *

For serialization to work, the subclass must specify explicit {@code - * readObject} and {@code writeObject} methods. - * - * @author Kevin Bourrillion - */ -@GwtCompatible(emulated = true) -abstract class AbstractMapBasedMultiset extends AbstractMultiset implements Serializable { - - private transient Map backingMap; - - /* - * Cache the size for efficiency. Using a long lets us avoid the need for - * overflow checking and ensures that size() will function correctly even if - * the multiset had once been larger than Integer.MAX_VALUE. - */ - private transient long size; - - /** Standard constructor. */ - protected AbstractMapBasedMultiset(Map backingMap) { - this.backingMap = checkNotNull(backingMap); - this.size = super.size(); - } - - /** Used during deserialization only. The backing map must be empty. */ - void setBackingMap(Map backingMap) { - this.backingMap = backingMap; - } - - // Required Implementations - - /** - * {@inheritDoc} - * - *

Invoking {@link Multiset.Entry#getCount} on an entry in the returned - * set always returns the current count of that element in the multiset, as - * opposed to the count at the time the entry was retrieved. - */ - @Override - public Set> entrySet() { - return super.entrySet(); - } - - @Override - Iterator> entryIterator() { - final Iterator> backingEntries = backingMap.entrySet().iterator(); - return new Iterator>() { - Map.Entry toRemove; - - @Override - public boolean hasNext() { - return backingEntries.hasNext(); - } - - @Override - public Multiset.Entry next() { - final Map.Entry mapEntry = backingEntries.next(); - toRemove = mapEntry; - return new Multisets.AbstractEntry() { - @Override - public E getElement() { - return mapEntry.getKey(); - } - - @Override - public int getCount() { - Count count = mapEntry.getValue(); - if (count == null || count.get() == 0) { - Count frequency = backingMap.get(getElement()); - if (frequency != null) { - return frequency.get(); - } - } - return (count == null) ? 0 : count.get(); - } - }; - } - - @Override - public void remove() { - checkRemove(toRemove != null); - size -= toRemove.getValue().getAndSet(0); - backingEntries.remove(); - toRemove = null; - } - }; - } - - @Override - public void clear() { - for (Count frequency : backingMap.values()) { - frequency.set(0); - } - backingMap.clear(); - size = 0L; - } - - @Override - int distinctElements() { - return backingMap.size(); - } - - // Optimizations - Query Operations - - @Override - public int size() { - return Ints.saturatedCast(size); - } - - @Override - public Iterator iterator() { - return new MapBasedMultisetIterator(); - } - - /* - * Not subclassing AbstractMultiset$MultisetIterator because next() needs to - * retrieve the Map.Entry entry, which can then be used for - * a more efficient remove() call. - */ - private class MapBasedMultisetIterator implements Iterator { - final Iterator> entryIterator; - Map.Entry currentEntry; - int occurrencesLeft; - boolean canRemove; - - MapBasedMultisetIterator() { - this.entryIterator = backingMap.entrySet().iterator(); - } - - @Override - public boolean hasNext() { - return occurrencesLeft > 0 || entryIterator.hasNext(); - } - - @Override - public E next() { - if (occurrencesLeft == 0) { - currentEntry = entryIterator.next(); - occurrencesLeft = currentEntry.getValue().get(); - } - occurrencesLeft--; - canRemove = true; - return currentEntry.getKey(); - } - - @Override - public void remove() { - checkRemove(canRemove); - int frequency = currentEntry.getValue().get(); - if (frequency <= 0) { - throw new ConcurrentModificationException(); - } - if (currentEntry.getValue().addAndGet(-1) == 0) { - entryIterator.remove(); - } - size--; - canRemove = false; - } - } - - @Override - public int count(@Nullable Object element) { - Count frequency = Maps.safeGet(backingMap, element); - return (frequency == null) ? 0 : frequency.get(); - } - - // Optional Operations - Modification Operations - - /** - * {@inheritDoc} - * - * @throws IllegalArgumentException if the call would result in more than - * {@link Integer#MAX_VALUE} occurrences of {@code element} in this - * multiset. - */ - @Override - public int add(@Nullable E element, int occurrences) { - if (occurrences == 0) { - return count(element); - } - checkArgument(occurrences > 0, "occurrences cannot be negative: %s", occurrences); - Count frequency = backingMap.get(element); - int oldCount; - if (frequency == null) { - oldCount = 0; - backingMap.put(element, new Count(occurrences)); - } else { - oldCount = frequency.get(); - long newCount = (long) oldCount + (long) occurrences; - checkArgument(newCount <= Integer.MAX_VALUE, "too many occurrences: %s", newCount); - frequency.getAndAdd(occurrences); - } - size += occurrences; - return oldCount; - } - - @Override - public int remove(@Nullable Object element, int occurrences) { - if (occurrences == 0) { - return count(element); - } - checkArgument(occurrences > 0, "occurrences cannot be negative: %s", occurrences); - Count frequency = backingMap.get(element); - if (frequency == null) { - return 0; - } - - int oldCount = frequency.get(); - - int numberRemoved; - if (oldCount > occurrences) { - numberRemoved = occurrences; - } else { - numberRemoved = oldCount; - backingMap.remove(element); - } - - frequency.addAndGet(-numberRemoved); - size -= numberRemoved; - return oldCount; - } - - // Roughly a 33% performance improvement over AbstractMultiset.setCount(). - @Override - public int setCount(@Nullable E element, int count) { - checkNonnegative(count, "count"); - - Count existingCounter; - int oldCount; - if (count == 0) { - existingCounter = backingMap.remove(element); - oldCount = getAndSet(existingCounter, count); - } else { - existingCounter = backingMap.get(element); - oldCount = getAndSet(existingCounter, count); - - if (existingCounter == null) { - backingMap.put(element, new Count(count)); - } - } - - size += (count - oldCount); - return oldCount; - } - - private static int getAndSet(Count i, int count) { - if (i == null) { - return 0; - } - - return i.getAndSet(count); - } - - // Don't allow default serialization. - @GwtIncompatible("java.io.ObjectStreamException") - private void readObjectNoData() throws ObjectStreamException { - throw new InvalidObjectException("Stream data required"); - } - - @GwtIncompatible("not needed in emulated source.") - private static final long serialVersionUID = -2250766705698539974L; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractMapEntry.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractMapEntry.java deleted file mode 100644 index 198212a7aa35..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractMapEntry.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Objects; - -import java.util.Map.Entry; - -import javax.annotation.Nullable; - -/** - * Implementation of the {@code equals}, {@code hashCode}, and {@code toString} - * methods of {@code Entry}. - * - * @author Jared Levy - */ -@GwtCompatible -abstract class AbstractMapEntry implements Entry { - - @Override - public abstract K getKey(); - - @Override - public abstract V getValue(); - - @Override - public V setValue(V value) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean equals(@Nullable Object object) { - if (object instanceof Entry) { - Entry that = (Entry) object; - return Objects.equal(this.getKey(), that.getKey()) - && Objects.equal(this.getValue(), that.getValue()); - } - return false; - } - - @Override - public int hashCode() { - K k = getKey(); - V v = getValue(); - return ((k == null) ? 0 : k.hashCode()) ^ ((v == null) ? 0 : v.hashCode()); - } - - /** - * Returns a string representation of the form {@code {key}={value}}. - */ - @Override - public String toString() { - return getKey() + "=" + getValue(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractMultimap.java deleted file mode 100644 index 6b94c1260707..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractMultimap.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; -import com.google.j2objc.annotations.WeakOuter; - -import java.util.AbstractCollection; -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * A skeleton {@code Multimap} implementation, not necessarily in terms of a {@code Map}. - * - * @author Louis Wasserman - */ -@GwtCompatible -abstract class AbstractMultimap implements Multimap { - @Override - public boolean isEmpty() { - return size() == 0; - } - - @Override - public boolean containsValue(@Nullable Object value) { - for (Collection collection : asMap().values()) { - if (collection.contains(value)) { - return true; - } - } - - return false; - } - - @Override - public boolean containsEntry(@Nullable Object key, @Nullable Object value) { - Collection collection = asMap().get(key); - return collection != null && collection.contains(value); - } - - @Override - public boolean remove(@Nullable Object key, @Nullable Object value) { - Collection collection = asMap().get(key); - return collection != null && collection.remove(value); - } - - @Override - public boolean put(@Nullable K key, @Nullable V value) { - return get(key).add(value); - } - - @Override - public boolean putAll(@Nullable K key, Iterable values) { - checkNotNull(values); - // make sure we only call values.iterator() once - // and we only call get(key) if values is nonempty - if (values instanceof Collection) { - Collection valueCollection = (Collection) values; - return !valueCollection.isEmpty() && get(key).addAll(valueCollection); - } else { - Iterator valueItr = values.iterator(); - return valueItr.hasNext() && Iterators.addAll(get(key), valueItr); - } - } - - @Override - public boolean putAll(Multimap multimap) { - boolean changed = false; - for (Map.Entry entry : multimap.entries()) { - changed |= put(entry.getKey(), entry.getValue()); - } - return changed; - } - - @Override - public Collection replaceValues(@Nullable K key, Iterable values) { - checkNotNull(values); - Collection result = removeAll(key); - putAll(key, values); - return result; - } - - private transient Collection> entries; - - @Override - public Collection> entries() { - Collection> result = entries; - return (result == null) ? entries = createEntries() : result; - } - - Collection> createEntries() { - if (this instanceof SetMultimap) { - return new EntrySet(); - } else { - return new Entries(); - } - } - - @WeakOuter - private class Entries extends Multimaps.Entries { - @Override - Multimap multimap() { - return AbstractMultimap.this; - } - - @Override - public Iterator> iterator() { - return entryIterator(); - } - } - - @WeakOuter - private class EntrySet extends Entries implements Set> { - @Override - public int hashCode() { - return Sets.hashCodeImpl(this); - } - - @Override - public boolean equals(@Nullable Object obj) { - return Sets.equalsImpl(this, obj); - } - } - - abstract Iterator> entryIterator(); - - private transient Set keySet; - - @Override - public Set keySet() { - Set result = keySet; - return (result == null) ? keySet = createKeySet() : result; - } - - Set createKeySet() { - return new Maps.KeySet>(asMap()); - } - - private transient Multiset keys; - - @Override - public Multiset keys() { - Multiset result = keys; - return (result == null) ? keys = createKeys() : result; - } - - Multiset createKeys() { - return new Multimaps.Keys(this); - } - - private transient Collection values; - - @Override - public Collection values() { - Collection result = values; - return (result == null) ? values = createValues() : result; - } - - Collection createValues() { - return new Values(); - } - - @WeakOuter - class Values extends AbstractCollection { - @Override - public Iterator iterator() { - return valueIterator(); - } - - @Override - public int size() { - return AbstractMultimap.this.size(); - } - - @Override - public boolean contains(@Nullable Object o) { - return AbstractMultimap.this.containsValue(o); - } - - @Override - public void clear() { - AbstractMultimap.this.clear(); - } - } - - Iterator valueIterator() { - return Maps.valueIterator(entries().iterator()); - } - - private transient Map> asMap; - - @Override - public Map> asMap() { - Map> result = asMap; - return (result == null) ? asMap = createAsMap() : result; - } - - abstract Map> createAsMap(); - - // Comparison and hashing - - @Override - public boolean equals(@Nullable Object object) { - return Multimaps.equalsImpl(this, object); - } - - /** - * Returns the hash code for this multimap. - * - *

The hash code of a multimap is defined as the hash code of the map view, - * as returned by {@link Multimap#asMap}. - * - * @see Map#hashCode - */ - @Override - public int hashCode() { - return asMap().hashCode(); - } - - /** - * Returns a string representation of the multimap, generated by calling - * {@code toString} on the map returned by {@link Multimap#asMap}. - * - * @return a string representation of the multimap - */ - @Override - public String toString() { - return asMap().toString(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractMultiset.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractMultiset.java deleted file mode 100644 index c55373fbce7e..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractMultiset.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.collect.Multisets.setCountImpl; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Objects; -import com.google.j2objc.annotations.WeakOuter; - -import java.util.AbstractCollection; -import java.util.Collection; -import java.util.Iterator; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * This class provides a skeletal implementation of the {@link Multiset} - * interface. A new multiset implementation can be created easily by extending - * this class and implementing the {@link Multiset#entrySet()} method, plus - * optionally overriding {@link #add(Object, int)} and - * {@link #remove(Object, int)} to enable modifications to the multiset. - * - *

The {@link #count} and {@link #size} implementations all iterate across - * the set returned by {@link Multiset#entrySet()}, as do many methods acting on - * the set returned by {@link #elementSet()}. Override those methods for better - * performance. - * - * @author Kevin Bourrillion - * @author Louis Wasserman - */ -@GwtCompatible -abstract class AbstractMultiset extends AbstractCollection implements Multiset { - // Query Operations - - @Override - public int size() { - return Multisets.sizeImpl(this); - } - - @Override - public boolean isEmpty() { - return entrySet().isEmpty(); - } - - @Override - public boolean contains(@Nullable Object element) { - return count(element) > 0; - } - - @Override - public Iterator iterator() { - return Multisets.iteratorImpl(this); - } - - @Override - public int count(@Nullable Object element) { - for (Entry entry : entrySet()) { - if (Objects.equal(entry.getElement(), element)) { - return entry.getCount(); - } - } - return 0; - } - - // Modification Operations - - @Override - public boolean add(@Nullable E element) { - add(element, 1); - return true; - } - - @Override - public int add(@Nullable E element, int occurrences) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean remove(@Nullable Object element) { - return remove(element, 1) > 0; - } - - @Override - public int remove(@Nullable Object element, int occurrences) { - throw new UnsupportedOperationException(); - } - - @Override - public int setCount(@Nullable E element, int count) { - return setCountImpl(this, element, count); - } - - @Override - public boolean setCount(@Nullable E element, int oldCount, int newCount) { - return setCountImpl(this, element, oldCount, newCount); - } - - // Bulk Operations - - /** - * {@inheritDoc} - * - *

This implementation is highly efficient when {@code elementsToAdd} - * is itself a {@link Multiset}. - */ - @Override - public boolean addAll(Collection elementsToAdd) { - return Multisets.addAllImpl(this, elementsToAdd); - } - - @Override - public boolean removeAll(Collection elementsToRemove) { - return Multisets.removeAllImpl(this, elementsToRemove); - } - - @Override - public boolean retainAll(Collection elementsToRetain) { - return Multisets.retainAllImpl(this, elementsToRetain); - } - - @Override - public void clear() { - Iterators.clear(entryIterator()); - } - - // Views - - private transient Set elementSet; - - @Override - public Set elementSet() { - Set result = elementSet; - if (result == null) { - elementSet = result = createElementSet(); - } - return result; - } - - /** - * Creates a new instance of this multiset's element set, which will be - * returned by {@link #elementSet()}. - */ - Set createElementSet() { - return new ElementSet(); - } - - @WeakOuter - class ElementSet extends Multisets.ElementSet { - @Override - Multiset multiset() { - return AbstractMultiset.this; - } - } - - abstract Iterator> entryIterator(); - - abstract int distinctElements(); - - private transient Set> entrySet; - - @Override - public Set> entrySet() { - Set> result = entrySet; - if (result == null) { - entrySet = result = createEntrySet(); - } - return result; - } - - @WeakOuter - class EntrySet extends Multisets.EntrySet { - @Override - Multiset multiset() { - return AbstractMultiset.this; - } - - @Override - public Iterator> iterator() { - return entryIterator(); - } - - @Override - public int size() { - return distinctElements(); - } - } - - Set> createEntrySet() { - return new EntrySet(); - } - - // Object methods - - /** - * {@inheritDoc} - * - *

This implementation returns {@code true} if {@code object} is a multiset - * of the same size and if, for each element, the two multisets have the same - * count. - */ - @Override - public boolean equals(@Nullable Object object) { - return Multisets.equalsImpl(this, object); - } - - /** - * {@inheritDoc} - * - *

This implementation returns the hash code of {@link - * Multiset#entrySet()}. - */ - @Override - public int hashCode() { - return entrySet().hashCode(); - } - - /** - * {@inheritDoc} - * - *

This implementation returns the result of invoking {@code toString} on - * {@link Multiset#entrySet()}. - */ - @Override - public String toString() { - return entrySet().toString(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractNavigableMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractNavigableMap.java deleted file mode 100644 index cef48599f120..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractNavigableMap.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.collect.Maps.IteratorBasedAbstractMap; - -import java.util.Iterator; -import java.util.NavigableMap; -import java.util.NavigableSet; -import java.util.NoSuchElementException; -import java.util.Set; -import java.util.SortedMap; - -import javax.annotation.Nullable; - -/** - * Skeletal implementation of {@link NavigableMap}. - * - * @author Louis Wasserman - */ -abstract class AbstractNavigableMap extends IteratorBasedAbstractMap - implements NavigableMap { - - @Override - @Nullable - public abstract V get(@Nullable Object key); - - @Override - @Nullable - public Entry firstEntry() { - return Iterators.getNext(entryIterator(), null); - } - - @Override - @Nullable - public Entry lastEntry() { - return Iterators.getNext(descendingEntryIterator(), null); - } - - @Override - @Nullable - public Entry pollFirstEntry() { - return Iterators.pollNext(entryIterator()); - } - - @Override - @Nullable - public Entry pollLastEntry() { - return Iterators.pollNext(descendingEntryIterator()); - } - - @Override - public K firstKey() { - Entry entry = firstEntry(); - if (entry == null) { - throw new NoSuchElementException(); - } else { - return entry.getKey(); - } - } - - @Override - public K lastKey() { - Entry entry = lastEntry(); - if (entry == null) { - throw new NoSuchElementException(); - } else { - return entry.getKey(); - } - } - - @Override - @Nullable - public Entry lowerEntry(K key) { - return headMap(key, false).lastEntry(); - } - - @Override - @Nullable - public Entry floorEntry(K key) { - return headMap(key, true).lastEntry(); - } - - @Override - @Nullable - public Entry ceilingEntry(K key) { - return tailMap(key, true).firstEntry(); - } - - @Override - @Nullable - public Entry higherEntry(K key) { - return tailMap(key, false).firstEntry(); - } - - @Override - public K lowerKey(K key) { - return Maps.keyOrNull(lowerEntry(key)); - } - - @Override - public K floorKey(K key) { - return Maps.keyOrNull(floorEntry(key)); - } - - @Override - public K ceilingKey(K key) { - return Maps.keyOrNull(ceilingEntry(key)); - } - - @Override - public K higherKey(K key) { - return Maps.keyOrNull(higherEntry(key)); - } - - abstract Iterator> descendingEntryIterator(); - - @Override - public SortedMap subMap(K fromKey, K toKey) { - return subMap(fromKey, true, toKey, false); - } - - @Override - public SortedMap headMap(K toKey) { - return headMap(toKey, false); - } - - @Override - public SortedMap tailMap(K fromKey) { - return tailMap(fromKey, true); - } - - @Override - public NavigableSet navigableKeySet() { - return new Maps.NavigableKeySet(this); - } - - @Override - public Set keySet() { - return navigableKeySet(); - } - - @Override - public NavigableSet descendingKeySet() { - return descendingMap().navigableKeySet(); - } - - @Override - public NavigableMap descendingMap() { - return new DescendingMap(); - } - - private final class DescendingMap extends Maps.DescendingMap { - @Override - NavigableMap forward() { - return AbstractNavigableMap.this; - } - - @Override - Iterator> entryIterator() { - return descendingEntryIterator(); - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractRangeSet.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractRangeSet.java deleted file mode 100644 index 19af0e7e04b8..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractRangeSet.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import javax.annotation.Nullable; - -/** - * A skeletal implementation of {@code RangeSet}. - * - * @author Louis Wasserman - */ -abstract class AbstractRangeSet implements RangeSet { - AbstractRangeSet() {} - - @Override - public boolean contains(C value) { - return rangeContaining(value) != null; - } - - @Override - public abstract Range rangeContaining(C value); - - @Override - public boolean isEmpty() { - return asRanges().isEmpty(); - } - - @Override - public void add(Range range) { - throw new UnsupportedOperationException(); - } - - @Override - public void remove(Range range) { - throw new UnsupportedOperationException(); - } - - @Override - public void clear() { - remove(Range.all()); - } - - @Override - public boolean enclosesAll(RangeSet other) { - for (Range range : other.asRanges()) { - if (!encloses(range)) { - return false; - } - } - return true; - } - - @Override - public void addAll(RangeSet other) { - for (Range range : other.asRanges()) { - add(range); - } - } - - @Override - public void removeAll(RangeSet other) { - for (Range range : other.asRanges()) { - remove(range); - } - } - - @Override - public abstract boolean encloses(Range otherRange); - - @Override - public boolean equals(@Nullable Object obj) { - if (obj == this) { - return true; - } else if (obj instanceof RangeSet) { - RangeSet other = (RangeSet) obj; - return this.asRanges().equals(other.asRanges()); - } - return false; - } - - @Override - public final int hashCode() { - return asRanges().hashCode(); - } - - @Override - public final String toString() { - return asRanges().toString(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractSequentialIterator.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractSequentialIterator.java deleted file mode 100644 index b933a5743bd0..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractSequentialIterator.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2010 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.NoSuchElementException; - -import javax.annotation.Nullable; - -/** - * This class provides a skeletal implementation of the {@code Iterator} - * interface for sequences whose next element can always be derived from the - * previous element. Null elements are not supported, nor is the - * {@link #remove()} method. - * - *

Example:

   {@code
- *
- *   Iterator powersOfTwo =
- *       new AbstractSequentialIterator(1) {
- *         protected Integer computeNext(Integer previous) {
- *           return (previous == 1 << 30) ? null : previous * 2;
- *         }
- *       };}
- * - * @author Chris Povirk - * @since 12.0 (in Guava as {@code AbstractLinkedIterator} since 8.0) - */ -@GwtCompatible -public abstract class AbstractSequentialIterator extends UnmodifiableIterator { - private T nextOrNull; - - /** - * Creates a new iterator with the given first element, or, if {@code - * firstOrNull} is null, creates a new empty iterator. - */ - protected AbstractSequentialIterator(@Nullable T firstOrNull) { - this.nextOrNull = firstOrNull; - } - - /** - * Returns the element that follows {@code previous}, or returns {@code null} - * if no elements remain. This method is invoked during each call to - * {@link #next()} in order to compute the result of a future call to - * {@code next()}. - */ - protected abstract T computeNext(T previous); - - @Override - public final boolean hasNext() { - return nextOrNull != null; - } - - @Override - public final T next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - try { - return nextOrNull; - } finally { - nextOrNull = computeNext(nextOrNull); - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractSetMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractSetMultimap.java deleted file mode 100644 index 94b71367b95c..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractSetMultimap.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Collection; -import java.util.Map; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * Basic implementation of the {@link SetMultimap} interface. It's a wrapper - * around {@link AbstractMapBasedMultimap} that converts the returned collections into - * {@code Sets}. The {@link #createCollection} method must return a {@code Set}. - * - * @author Jared Levy - */ -@GwtCompatible -abstract class AbstractSetMultimap extends AbstractMapBasedMultimap - implements SetMultimap { - /** - * Creates a new multimap that uses the provided map. - * - * @param map place to store the mapping from each key to its corresponding - * values - */ - protected AbstractSetMultimap(Map> map) { - super(map); - } - - @Override - abstract Set createCollection(); - - @Override - Set createUnmodifiableEmptyCollection() { - return ImmutableSet.of(); - } - - // Following Javadoc copied from SetMultimap. - - /** - * {@inheritDoc} - * - *

Because a {@code SetMultimap} has unique values for a given key, this - * method returns a {@link Set}, instead of the {@link Collection} specified - * in the {@link Multimap} interface. - */ - @Override - public Set get(@Nullable K key) { - return (Set) super.get(key); - } - - /** - * {@inheritDoc} - * - *

Because a {@code SetMultimap} has unique values for a given key, this - * method returns a {@link Set}, instead of the {@link Collection} specified - * in the {@link Multimap} interface. - */ - @Override - public Set> entries() { - return (Set>) super.entries(); - } - - /** - * {@inheritDoc} - * - *

Because a {@code SetMultimap} has unique values for a given key, this - * method returns a {@link Set}, instead of the {@link Collection} specified - * in the {@link Multimap} interface. - */ - @Override - public Set removeAll(@Nullable Object key) { - return (Set) super.removeAll(key); - } - - /** - * {@inheritDoc} - * - *

Because a {@code SetMultimap} has unique values for a given key, this - * method returns a {@link Set}, instead of the {@link Collection} specified - * in the {@link Multimap} interface. - * - *

Any duplicates in {@code values} will be stored in the multimap once. - */ - @Override - public Set replaceValues(@Nullable K key, Iterable values) { - return (Set) super.replaceValues(key, values); - } - - /** - * {@inheritDoc} - * - *

Though the method signature doesn't say so explicitly, the returned map - * has {@link Set} values. - */ - @Override - public Map> asMap() { - return super.asMap(); - } - - /** - * Stores a key-value pair in the multimap. - * - * @param key key to store in the multimap - * @param value value to store in the multimap - * @return {@code true} if the method increased the size of the multimap, or - * {@code false} if the multimap already contained the key-value pair - */ - @Override - public boolean put(@Nullable K key, @Nullable V value) { - return super.put(key, value); - } - - /** - * Compares the specified object to this multimap for equality. - * - *

Two {@code SetMultimap} instances are equal if, for each key, they - * contain the same values. Equality does not depend on the ordering of keys - * or values. - */ - @Override - public boolean equals(@Nullable Object object) { - return super.equals(object); - } - - private static final long serialVersionUID = 7431625294878419160L; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractSortedKeySortedSetMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractSortedKeySortedSetMultimap.java deleted file mode 100644 index 8cf09dde4158..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractSortedKeySortedSetMultimap.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Collection; -import java.util.SortedMap; -import java.util.SortedSet; - -/** - * Basic implementation of a {@link SortedSetMultimap} with a sorted key set. - * - *

This superclass allows {@code TreeMultimap} to override methods to return - * navigable set and map types in non-GWT only, while GWT code will inherit the - * SortedMap/SortedSet overrides. - * - * @author Louis Wasserman - */ -@GwtCompatible -abstract class AbstractSortedKeySortedSetMultimap extends AbstractSortedSetMultimap { - - AbstractSortedKeySortedSetMultimap(SortedMap> map) { - super(map); - } - - @Override - public SortedMap> asMap() { - return (SortedMap>) super.asMap(); - } - - @Override - SortedMap> backingMap() { - return (SortedMap>) super.backingMap(); - } - - @Override - public SortedSet keySet() { - return (SortedSet) super.keySet(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractSortedMultiset.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractSortedMultiset.java deleted file mode 100644 index 7bec2dbf2135..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractSortedMultiset.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; -import com.google.j2objc.annotations.WeakOuter; - -import java.util.Comparator; -import java.util.Iterator; -import java.util.NavigableSet; - -import javax.annotation.Nullable; - -/** - * This class provides a skeletal implementation of the {@link SortedMultiset} interface. - * - *

The {@link #count} and {@link #size} implementations all iterate across the set returned by - * {@link Multiset#entrySet()}, as do many methods acting on the set returned by - * {@link #elementSet()}. Override those methods for better performance. - * - * @author Louis Wasserman - */ -@GwtCompatible(emulated = true) -abstract class AbstractSortedMultiset extends AbstractMultiset implements SortedMultiset { - @GwtTransient final Comparator comparator; - - // needed for serialization - @SuppressWarnings("unchecked") - AbstractSortedMultiset() { - this((Comparator) Ordering.natural()); - } - - AbstractSortedMultiset(Comparator comparator) { - this.comparator = checkNotNull(comparator); - } - - @Override - public NavigableSet elementSet() { - return (NavigableSet) super.elementSet(); - } - - @Override - NavigableSet createElementSet() { - return new SortedMultisets.NavigableElementSet(this); - } - - @Override - public Comparator comparator() { - return comparator; - } - - @Override - public Entry firstEntry() { - Iterator> entryIterator = entryIterator(); - return entryIterator.hasNext() ? entryIterator.next() : null; - } - - @Override - public Entry lastEntry() { - Iterator> entryIterator = descendingEntryIterator(); - return entryIterator.hasNext() ? entryIterator.next() : null; - } - - @Override - public Entry pollFirstEntry() { - Iterator> entryIterator = entryIterator(); - if (entryIterator.hasNext()) { - Entry result = entryIterator.next(); - result = Multisets.immutableEntry(result.getElement(), result.getCount()); - entryIterator.remove(); - return result; - } - return null; - } - - @Override - public Entry pollLastEntry() { - Iterator> entryIterator = descendingEntryIterator(); - if (entryIterator.hasNext()) { - Entry result = entryIterator.next(); - result = Multisets.immutableEntry(result.getElement(), result.getCount()); - entryIterator.remove(); - return result; - } - return null; - } - - @Override - public SortedMultiset subMultiset( - @Nullable E fromElement, - BoundType fromBoundType, - @Nullable E toElement, - BoundType toBoundType) { - // These are checked elsewhere, but NullPointerTester wants them checked eagerly. - checkNotNull(fromBoundType); - checkNotNull(toBoundType); - return tailMultiset(fromElement, fromBoundType).headMultiset(toElement, toBoundType); - } - - abstract Iterator> descendingEntryIterator(); - - Iterator descendingIterator() { - return Multisets.iteratorImpl(descendingMultiset()); - } - - private transient SortedMultiset descendingMultiset; - - @Override - public SortedMultiset descendingMultiset() { - SortedMultiset result = descendingMultiset; - return (result == null) ? descendingMultiset = createDescendingMultiset() : result; - } - - SortedMultiset createDescendingMultiset() { - @WeakOuter - class DescendingMultisetImpl extends DescendingMultiset { - @Override - SortedMultiset forwardMultiset() { - return AbstractSortedMultiset.this; - } - - @Override - Iterator> entryIterator() { - return descendingEntryIterator(); - } - - @Override - public Iterator iterator() { - return descendingIterator(); - } - } - return new DescendingMultisetImpl(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractSortedSetMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractSortedSetMultimap.java deleted file mode 100644 index 9826c5fdb780..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractSortedSetMultimap.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.Map; -import java.util.SortedSet; - -import javax.annotation.Nullable; - -/** - * Basic implementation of the {@link SortedSetMultimap} interface. It's a - * wrapper around {@link AbstractMapBasedMultimap} that converts the returned - * collections into sorted sets. The {@link #createCollection} method - * must return a {@code SortedSet}. - * - * @author Jared Levy - */ -@GwtCompatible -abstract class AbstractSortedSetMultimap extends AbstractSetMultimap - implements SortedSetMultimap { - /** - * Creates a new multimap that uses the provided map. - * - * @param map place to store the mapping from each key to its corresponding - * values - */ - protected AbstractSortedSetMultimap(Map> map) { - super(map); - } - - @Override - abstract SortedSet createCollection(); - - @Override - SortedSet createUnmodifiableEmptyCollection() { - Comparator comparator = valueComparator(); - if (comparator == null) { - return Collections.unmodifiableSortedSet(createCollection()); - } else { - return ImmutableSortedSet.emptySet(valueComparator()); - } - } - - // Following Javadoc copied from Multimap and SortedSetMultimap. - - /** - * Returns a collection view of all values associated with a key. If no - * mappings in the multimap have the provided key, an empty collection is - * returned. - * - *

Changes to the returned collection will update the underlying multimap, - * and vice versa. - * - *

Because a {@code SortedSetMultimap} has unique sorted values for a given - * key, this method returns a {@link SortedSet}, instead of the - * {@link Collection} specified in the {@link Multimap} interface. - */ - @Override - public SortedSet get(@Nullable K key) { - return (SortedSet) super.get(key); - } - - /** - * Removes all values associated with a given key. The returned collection is - * immutable. - * - *

Because a {@code SortedSetMultimap} has unique sorted values for a given - * key, this method returns a {@link SortedSet}, instead of the - * {@link Collection} specified in the {@link Multimap} interface. - */ - @Override - public SortedSet removeAll(@Nullable Object key) { - return (SortedSet) super.removeAll(key); - } - - /** - * Stores a collection of values with the same key, replacing any existing - * values for that key. The returned collection is immutable. - * - *

Because a {@code SortedSetMultimap} has unique sorted values for a given - * key, this method returns a {@link SortedSet}, instead of the - * {@link Collection} specified in the {@link Multimap} interface. - * - *

Any duplicates in {@code values} will be stored in the multimap once. - */ - @Override - public SortedSet replaceValues(@Nullable K key, Iterable values) { - return (SortedSet) super.replaceValues(key, values); - } - - /** - * Returns a map view that associates each key with the corresponding values - * in the multimap. Changes to the returned map, such as element removal, will - * update the underlying multimap. The map does not support {@code setValue} - * on its entries, {@code put}, or {@code putAll}. - * - *

When passed a key that is present in the map, {@code - * asMap().get(Object)} has the same behavior as {@link #get}, returning a - * live collection. When passed a key that is not present, however, {@code - * asMap().get(Object)} returns {@code null} instead of an empty collection. - * - *

Though the method signature doesn't say so explicitly, the returned map - * has {@link SortedSet} values. - */ - @Override - public Map> asMap() { - return super.asMap(); - } - - /** - * {@inheritDoc} - * - * Consequently, the values do not follow their natural ordering or the - * ordering of the value comparator. - */ - @Override - public Collection values() { - return super.values(); - } - - private static final long serialVersionUID = 430848587173315748L; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractTable.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractTable.java deleted file mode 100644 index 6a68f4cd6d0e..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/AbstractTable.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 2013 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.j2objc.annotations.WeakOuter; - -import java.util.AbstractCollection; -import java.util.AbstractSet; -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * Skeletal, implementation-agnostic implementation of the {@link Table} interface. - * - * @author Louis Wasserman - */ -@GwtCompatible -abstract class AbstractTable implements Table { - - @Override - public boolean containsRow(@Nullable Object rowKey) { - return Maps.safeContainsKey(rowMap(), rowKey); - } - - @Override - public boolean containsColumn(@Nullable Object columnKey) { - return Maps.safeContainsKey(columnMap(), columnKey); - } - - @Override - public Set rowKeySet() { - return rowMap().keySet(); - } - - @Override - public Set columnKeySet() { - return columnMap().keySet(); - } - - @Override - public boolean containsValue(@Nullable Object value) { - for (Map row : rowMap().values()) { - if (row.containsValue(value)) { - return true; - } - } - return false; - } - - @Override - public boolean contains(@Nullable Object rowKey, @Nullable Object columnKey) { - Map row = Maps.safeGet(rowMap(), rowKey); - return row != null && Maps.safeContainsKey(row, columnKey); - } - - @Override - public V get(@Nullable Object rowKey, @Nullable Object columnKey) { - Map row = Maps.safeGet(rowMap(), rowKey); - return (row == null) ? null : Maps.safeGet(row, columnKey); - } - - @Override - public boolean isEmpty() { - return size() == 0; - } - - @Override - public void clear() { - Iterators.clear(cellSet().iterator()); - } - - @Override - public V remove(@Nullable Object rowKey, @Nullable Object columnKey) { - Map row = Maps.safeGet(rowMap(), rowKey); - return (row == null) ? null : Maps.safeRemove(row, columnKey); - } - - @Override - public V put(R rowKey, C columnKey, V value) { - return row(rowKey).put(columnKey, value); - } - - @Override - public void putAll(Table table) { - for (Table.Cell cell : table.cellSet()) { - put(cell.getRowKey(), cell.getColumnKey(), cell.getValue()); - } - } - - private transient Set> cellSet; - - @Override - public Set> cellSet() { - Set> result = cellSet; - return (result == null) ? cellSet = createCellSet() : result; - } - - Set> createCellSet() { - return new CellSet(); - } - - abstract Iterator> cellIterator(); - - @WeakOuter - class CellSet extends AbstractSet> { - @Override - public boolean contains(Object o) { - if (o instanceof Cell) { - Cell cell = (Cell) o; - Map row = Maps.safeGet(rowMap(), cell.getRowKey()); - return row != null - && Collections2.safeContains( - row.entrySet(), Maps.immutableEntry(cell.getColumnKey(), cell.getValue())); - } - return false; - } - - @Override - public boolean remove(@Nullable Object o) { - if (o instanceof Cell) { - Cell cell = (Cell) o; - Map row = Maps.safeGet(rowMap(), cell.getRowKey()); - return row != null - && Collections2.safeRemove( - row.entrySet(), Maps.immutableEntry(cell.getColumnKey(), cell.getValue())); - } - return false; - } - - @Override - public void clear() { - AbstractTable.this.clear(); - } - - @Override - public Iterator> iterator() { - return cellIterator(); - } - - @Override - public int size() { - return AbstractTable.this.size(); - } - } - - private transient Collection values; - - @Override - public Collection values() { - Collection result = values; - return (result == null) ? values = createValues() : result; - } - - Collection createValues() { - return new Values(); - } - - Iterator valuesIterator() { - return new TransformedIterator, V>(cellSet().iterator()) { - @Override - V transform(Cell cell) { - return cell.getValue(); - } - }; - } - - @WeakOuter - class Values extends AbstractCollection { - @Override - public Iterator iterator() { - return valuesIterator(); - } - - @Override - public boolean contains(Object o) { - return containsValue(o); - } - - @Override - public void clear() { - AbstractTable.this.clear(); - } - - @Override - public int size() { - return AbstractTable.this.size(); - } - } - - @Override - public boolean equals(@Nullable Object obj) { - return Tables.equalsImpl(this, obj); - } - - @Override - public int hashCode() { - return cellSet().hashCode(); - } - - /** - * Returns the string representation {@code rowMap().toString()}. - */ - @Override - public String toString() { - return rowMap().toString(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/AllEqualOrdering.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/AllEqualOrdering.java deleted file mode 100644 index c30164b9e0f5..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/AllEqualOrdering.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; -import java.util.List; - -import javax.annotation.Nullable; - -/** - * An ordering that treats all references as equals, even nulls. - * - * @author Emily Soldal - */ -@GwtCompatible(serializable = true) -final class AllEqualOrdering extends Ordering implements Serializable { - static final AllEqualOrdering INSTANCE = new AllEqualOrdering(); - - @Override - public int compare(@Nullable Object left, @Nullable Object right) { - return 0; - } - - @Override - public List sortedCopy(Iterable iterable) { - return Lists.newArrayList(iterable); - } - - @Override - public ImmutableList immutableSortedCopy(Iterable iterable) { - return ImmutableList.copyOf(iterable); - } - - @SuppressWarnings("unchecked") - @Override - public Ordering reverse() { - return (Ordering) this; - } - - private Object readResolve() { - return INSTANCE; - } - - @Override - public String toString() { - return "Ordering.allEqual()"; - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ArrayListMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ArrayListMultimap.java deleted file mode 100644 index 33147ab87c93..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ArrayListMultimap.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.collect.CollectPreconditions.checkNonnegative; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.annotations.VisibleForTesting; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Implementation of {@code Multimap} that uses an {@code ArrayList} to store - * the values for a given key. A {@link HashMap} associates each key with an - * {@link ArrayList} of values. - * - *

When iterating through the collections supplied by this class, the - * ordering of values for a given key agrees with the order in which the values - * were added. - * - *

This multimap allows duplicate key-value pairs. After adding a new - * key-value pair equal to an existing key-value pair, the {@code - * ArrayListMultimap} will contain entries for both the new value and the old - * value. - * - *

Keys and values may be null. All optional multimap methods are supported, - * and all returned views are modifiable. - * - *

The lists returned by {@link #get}, {@link #removeAll}, and {@link - * #replaceValues} all implement {@link java.util.RandomAccess}. - * - *

This class is not threadsafe when any concurrent operations update the - * multimap. Concurrent read operations will work correctly. To allow concurrent - * update operations, wrap your multimap with a call to {@link - * Multimaps#synchronizedListMultimap}. - * - *

See the Guava User Guide article on - * {@code Multimap}. - * - * @author Jared Levy - * @since 2.0 - */ -@GwtCompatible(serializable = true, emulated = true) -public final class ArrayListMultimap extends AbstractListMultimap { - // Default from ArrayList - private static final int DEFAULT_VALUES_PER_KEY = 3; - - @VisibleForTesting transient int expectedValuesPerKey; - - /** - * Creates a new, empty {@code ArrayListMultimap} with the default initial - * capacities. - */ - public static ArrayListMultimap create() { - return new ArrayListMultimap(); - } - - /** - * Constructs an empty {@code ArrayListMultimap} with enough capacity to hold - * the specified numbers of keys and values without resizing. - * - * @param expectedKeys the expected number of distinct keys - * @param expectedValuesPerKey the expected average number of values per key - * @throws IllegalArgumentException if {@code expectedKeys} or {@code - * expectedValuesPerKey} is negative - */ - public static ArrayListMultimap create(int expectedKeys, int expectedValuesPerKey) { - return new ArrayListMultimap(expectedKeys, expectedValuesPerKey); - } - - /** - * Constructs an {@code ArrayListMultimap} with the same mappings as the - * specified multimap. - * - * @param multimap the multimap whose contents are copied to this multimap - */ - public static ArrayListMultimap create(Multimap multimap) { - return new ArrayListMultimap(multimap); - } - - private ArrayListMultimap() { - super(new HashMap>()); - expectedValuesPerKey = DEFAULT_VALUES_PER_KEY; - } - - private ArrayListMultimap(int expectedKeys, int expectedValuesPerKey) { - super(Maps.>newHashMapWithExpectedSize(expectedKeys)); - checkNonnegative(expectedValuesPerKey, "expectedValuesPerKey"); - this.expectedValuesPerKey = expectedValuesPerKey; - } - - private ArrayListMultimap(Multimap multimap) { - this( - multimap.keySet().size(), - (multimap instanceof ArrayListMultimap) - ? ((ArrayListMultimap) multimap).expectedValuesPerKey - : DEFAULT_VALUES_PER_KEY); - putAll(multimap); - } - - /** - * Creates a new, empty {@code ArrayList} to hold the collection of values for - * an arbitrary key. - */ - @Override - List createCollection() { - return new ArrayList(expectedValuesPerKey); - } - - /** - * Reduces the memory used by this {@code ArrayListMultimap}, if feasible. - */ - public void trimToSize() { - for (Collection collection : backingMap().values()) { - ArrayList arrayList = (ArrayList) collection; - arrayList.trimToSize(); - } - } - - /** - * @serialData expectedValuesPerKey, number of distinct keys, and then for - * each distinct key: the key, number of values for that key, and the - * key's values - */ - @GwtIncompatible("java.io.ObjectOutputStream") - private void writeObject(ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); - Serialization.writeMultimap(this, stream); - } - - @GwtIncompatible("java.io.ObjectOutputStream") - private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - expectedValuesPerKey = DEFAULT_VALUES_PER_KEY; - int distinctKeys = Serialization.readCount(stream); - Map> map = Maps.newHashMap(); - setMap(map); - Serialization.populateMultimap(this, stream, distinctKeys); - } - - @GwtIncompatible("Not needed in emulated source.") - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ArrayTable.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ArrayTable.java deleted file mode 100644 index c1a9348e29f9..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ArrayTable.java +++ /dev/null @@ -1,762 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkElementIndex; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.base.Objects; -import com.google.common.collect.Maps.IteratorBasedAbstractMap; -import com.google.j2objc.annotations.WeakOuter; - -import java.io.Serializable; -import java.lang.reflect.Array; -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * Fixed-size {@link Table} implementation backed by a two-dimensional array. - * - *

The allowed row and column keys must be supplied when the table is - * created. The table always contains a mapping for every row key / column pair. - * The value corresponding to a given row and column is null unless another - * value is provided. - * - *

The table's size is constant: the product of the number of supplied row - * keys and the number of supplied column keys. The {@code remove} and {@code - * clear} methods are not supported by the table or its views. The {@link - * #erase} and {@link #eraseAll} methods may be used instead. - * - *

The ordering of the row and column keys provided when the table is - * constructed determines the iteration ordering across rows and columns in the - * table's views. None of the view iterators support {@link Iterator#remove}. - * If the table is modified after an iterator is created, the iterator remains - * valid. - * - *

This class requires less memory than the {@link HashBasedTable} and {@link - * TreeBasedTable} implementations, except when the table is sparse. - * - *

Null row keys or column keys are not permitted. - * - *

This class provides methods involving the underlying array structure, - * where the array indices correspond to the position of a row or column in the - * lists of allowed keys and values. See the {@link #at}, {@link #set}, {@link - * #toArray}, {@link #rowKeyList}, and {@link #columnKeyList} methods for more - * details. - * - *

Note that this implementation is not synchronized. If multiple threads - * access the same cell of an {@code ArrayTable} concurrently and one of the - * threads modifies its value, there is no guarantee that the new value will be - * fully visible to the other threads. To guarantee that modifications are - * visible, synchronize access to the table. Unlike other {@code Table} - * implementations, synchronization is unnecessary between a thread that writes - * to one cell and a thread that reads from another. - * - *

See the Guava User Guide article on - * {@code Table}. - * - * @author Jared Levy - * @since 10.0 - */ -@Beta -@GwtCompatible(emulated = true) -public final class ArrayTable extends AbstractTable implements Serializable { - - /** - * Creates an empty {@code ArrayTable}. - * - * @param rowKeys row keys that may be stored in the generated table - * @param columnKeys column keys that may be stored in the generated table - * @throws NullPointerException if any of the provided keys is null - * @throws IllegalArgumentException if {@code rowKeys} or {@code columnKeys} - * contains duplicates or is empty - */ - public static ArrayTable create( - Iterable rowKeys, Iterable columnKeys) { - return new ArrayTable(rowKeys, columnKeys); - } - - /* - * TODO(jlevy): Add factory methods taking an Enum class, instead of an - * iterable, to specify the allowed row keys and/or column keys. Note that - * custom serialization logic is needed to support different enum sizes during - * serialization and deserialization. - */ - - /** - * Creates an {@code ArrayTable} with the mappings in the provided table. - * - *

If {@code table} includes a mapping with row key {@code r} and a - * separate mapping with column key {@code c}, the returned table contains a - * mapping with row key {@code r} and column key {@code c}. If that row key / - * column key pair in not in {@code table}, the pair maps to {@code null} in - * the generated table. - * - *

The returned table allows subsequent {@code put} calls with the row keys - * in {@code table.rowKeySet()} and the column keys in {@code - * table.columnKeySet()}. Calling {@link #put} with other keys leads to an - * {@code IllegalArgumentException}. - * - *

The ordering of {@code table.rowKeySet()} and {@code - * table.columnKeySet()} determines the row and column iteration ordering of - * the returned table. - * - * @throws NullPointerException if {@code table} has a null key - * @throws IllegalArgumentException if the provided table is empty - */ - public static ArrayTable create(Table table) { - return (table instanceof ArrayTable) - ? new ArrayTable((ArrayTable) table) - : new ArrayTable(table); - } - - private final ImmutableList rowList; - private final ImmutableList columnList; - - // TODO(jlevy): Add getters returning rowKeyToIndex and columnKeyToIndex? - private final ImmutableMap rowKeyToIndex; - private final ImmutableMap columnKeyToIndex; - private final V[][] array; - - private ArrayTable(Iterable rowKeys, Iterable columnKeys) { - this.rowList = ImmutableList.copyOf(rowKeys); - this.columnList = ImmutableList.copyOf(columnKeys); - checkArgument(!rowList.isEmpty()); - checkArgument(!columnList.isEmpty()); - - /* - * TODO(jlevy): Support empty rowKeys or columnKeys? If we do, when - * columnKeys is empty but rowKeys isn't, the table is empty but - * containsRow() can return true and rowKeySet() isn't empty. - */ - rowKeyToIndex = Maps.indexMap(rowList); - columnKeyToIndex = Maps.indexMap(columnList); - - @SuppressWarnings("unchecked") - V[][] tmpArray = (V[][]) new Object[rowList.size()][columnList.size()]; - array = tmpArray; - // Necessary because in GWT the arrays are initialized with "undefined" instead of null. - eraseAll(); - } - - private ArrayTable(Table table) { - this(table.rowKeySet(), table.columnKeySet()); - putAll(table); - } - - private ArrayTable(ArrayTable table) { - rowList = table.rowList; - columnList = table.columnList; - rowKeyToIndex = table.rowKeyToIndex; - columnKeyToIndex = table.columnKeyToIndex; - @SuppressWarnings("unchecked") - V[][] copy = (V[][]) new Object[rowList.size()][columnList.size()]; - array = copy; - // Necessary because in GWT the arrays are initialized with "undefined" instead of null. - eraseAll(); - for (int i = 0; i < rowList.size(); i++) { - System.arraycopy(table.array[i], 0, copy[i], 0, table.array[i].length); - } - } - - private abstract static class ArrayMap extends IteratorBasedAbstractMap { - private final ImmutableMap keyIndex; - - private ArrayMap(ImmutableMap keyIndex) { - this.keyIndex = keyIndex; - } - - @Override - public Set keySet() { - return keyIndex.keySet(); - } - - K getKey(int index) { - return keyIndex.keySet().asList().get(index); - } - - abstract String getKeyRole(); - - @Nullable - abstract V getValue(int index); - - @Nullable - abstract V setValue(int index, V newValue); - - @Override - public int size() { - return keyIndex.size(); - } - - @Override - public boolean isEmpty() { - return keyIndex.isEmpty(); - } - - @Override - Iterator> entryIterator() { - return new AbstractIndexedListIterator>(size()) { - @Override - protected Entry get(final int index) { - return new AbstractMapEntry() { - @Override - public K getKey() { - return ArrayMap.this.getKey(index); - } - - @Override - public V getValue() { - return ArrayMap.this.getValue(index); - } - - @Override - public V setValue(V value) { - return ArrayMap.this.setValue(index, value); - } - }; - } - }; - } - - // TODO(lowasser): consider an optimized values() implementation - - @Override - public boolean containsKey(@Nullable Object key) { - return keyIndex.containsKey(key); - } - - @Override - public V get(@Nullable Object key) { - Integer index = keyIndex.get(key); - if (index == null) { - return null; - } else { - return getValue(index); - } - } - - @Override - public V put(K key, V value) { - Integer index = keyIndex.get(key); - if (index == null) { - throw new IllegalArgumentException( - getKeyRole() + " " + key + " not in " + keyIndex.keySet()); - } - return setValue(index, value); - } - - @Override - public V remove(Object key) { - throw new UnsupportedOperationException(); - } - - @Override - public void clear() { - throw new UnsupportedOperationException(); - } - } - - /** - * Returns, as an immutable list, the row keys provided when the table was - * constructed, including those that are mapped to null values only. - */ - public ImmutableList rowKeyList() { - return rowList; - } - - /** - * Returns, as an immutable list, the column keys provided when the table was - * constructed, including those that are mapped to null values only. - */ - public ImmutableList columnKeyList() { - return columnList; - } - - /** - * Returns the value corresponding to the specified row and column indices. - * The same value is returned by {@code - * get(rowKeyList().get(rowIndex), columnKeyList().get(columnIndex))}, but - * this method runs more quickly. - * - * @param rowIndex position of the row key in {@link #rowKeyList()} - * @param columnIndex position of the row key in {@link #columnKeyList()} - * @return the value with the specified row and column - * @throws IndexOutOfBoundsException if either index is negative, {@code - * rowIndex} is greater then or equal to the number of allowed row keys, - * or {@code columnIndex} is greater then or equal to the number of - * allowed column keys - */ - public V at(int rowIndex, int columnIndex) { - // In GWT array access never throws IndexOutOfBoundsException. - checkElementIndex(rowIndex, rowList.size()); - checkElementIndex(columnIndex, columnList.size()); - return array[rowIndex][columnIndex]; - } - - /** - * Associates {@code value} with the specified row and column indices. The - * logic {@code - * put(rowKeyList().get(rowIndex), columnKeyList().get(columnIndex), value)} - * has the same behavior, but this method runs more quickly. - * - * @param rowIndex position of the row key in {@link #rowKeyList()} - * @param columnIndex position of the row key in {@link #columnKeyList()} - * @param value value to store in the table - * @return the previous value with the specified row and column - * @throws IndexOutOfBoundsException if either index is negative, {@code - * rowIndex} is greater then or equal to the number of allowed row keys, - * or {@code columnIndex} is greater then or equal to the number of - * allowed column keys - */ - public V set(int rowIndex, int columnIndex, @Nullable V value) { - // In GWT array access never throws IndexOutOfBoundsException. - checkElementIndex(rowIndex, rowList.size()); - checkElementIndex(columnIndex, columnList.size()); - V oldValue = array[rowIndex][columnIndex]; - array[rowIndex][columnIndex] = value; - return oldValue; - } - - /** - * Returns a two-dimensional array with the table contents. The row and column - * indices correspond to the positions of the row and column in the iterables - * provided during table construction. If the table lacks a mapping for a - * given row and column, the corresponding array element is null. - * - *

Subsequent table changes will not modify the array, and vice versa. - * - * @param valueClass class of values stored in the returned array - */ - @GwtIncompatible("reflection") - public V[][] toArray(Class valueClass) { - // Can change to use varargs in JDK 1.6 if we want - @SuppressWarnings("unchecked") // TODO: safe? - V[][] copy = - (V[][]) Array.newInstance(valueClass, new int[] {rowList.size(), columnList.size()}); - for (int i = 0; i < rowList.size(); i++) { - System.arraycopy(array[i], 0, copy[i], 0, array[i].length); - } - return copy; - } - - /** - * Not supported. Use {@link #eraseAll} instead. - * - * @throws UnsupportedOperationException always - * @deprecated Use {@link #eraseAll} - */ - @Override - @Deprecated - public void clear() { - throw new UnsupportedOperationException(); - } - - /** - * Associates the value {@code null} with every pair of allowed row and column - * keys. - */ - public void eraseAll() { - for (V[] row : array) { - Arrays.fill(row, null); - } - } - - /** - * Returns {@code true} if the provided keys are among the keys provided when - * the table was constructed. - */ - @Override - public boolean contains(@Nullable Object rowKey, @Nullable Object columnKey) { - return containsRow(rowKey) && containsColumn(columnKey); - } - - /** - * Returns {@code true} if the provided column key is among the column keys - * provided when the table was constructed. - */ - @Override - public boolean containsColumn(@Nullable Object columnKey) { - return columnKeyToIndex.containsKey(columnKey); - } - - /** - * Returns {@code true} if the provided row key is among the row keys - * provided when the table was constructed. - */ - @Override - public boolean containsRow(@Nullable Object rowKey) { - return rowKeyToIndex.containsKey(rowKey); - } - - @Override - public boolean containsValue(@Nullable Object value) { - for (V[] row : array) { - for (V element : row) { - if (Objects.equal(value, element)) { - return true; - } - } - } - return false; - } - - @Override - public V get(@Nullable Object rowKey, @Nullable Object columnKey) { - Integer rowIndex = rowKeyToIndex.get(rowKey); - Integer columnIndex = columnKeyToIndex.get(columnKey); - return (rowIndex == null || columnIndex == null) ? null : at(rowIndex, columnIndex); - } - - /** - * Always returns {@code false}. - */ - @Override - public boolean isEmpty() { - return false; - } - - /** - * {@inheritDoc} - * - * @throws IllegalArgumentException if {@code rowKey} is not in {@link - * #rowKeySet()} or {@code columnKey} is not in {@link #columnKeySet()}. - */ - @Override - public V put(R rowKey, C columnKey, @Nullable V value) { - checkNotNull(rowKey); - checkNotNull(columnKey); - Integer rowIndex = rowKeyToIndex.get(rowKey); - checkArgument(rowIndex != null, "Row %s not in %s", rowKey, rowList); - Integer columnIndex = columnKeyToIndex.get(columnKey); - checkArgument(columnIndex != null, "Column %s not in %s", columnKey, columnList); - return set(rowIndex, columnIndex, value); - } - - /* - * TODO(jlevy): Consider creating a merge() method, similar to putAll() but - * copying non-null values only. - */ - - /** - * {@inheritDoc} - * - *

If {@code table} is an {@code ArrayTable}, its null values will be - * stored in this table, possibly replacing values that were previously - * non-null. - * - * @throws NullPointerException if {@code table} has a null key - * @throws IllegalArgumentException if any of the provided table's row keys or - * column keys is not in {@link #rowKeySet()} or {@link #columnKeySet()} - */ - @Override - public void putAll(Table table) { - super.putAll(table); - } - - /** - * Not supported. Use {@link #erase} instead. - * - * @throws UnsupportedOperationException always - * @deprecated Use {@link #erase} - */ - @Override - @Deprecated - public V remove(Object rowKey, Object columnKey) { - throw new UnsupportedOperationException(); - } - - /** - * Associates the value {@code null} with the specified keys, assuming both - * keys are valid. If either key is null or isn't among the keys provided - * during construction, this method has no effect. - * - *

This method is equivalent to {@code put(rowKey, columnKey, null)} when - * both provided keys are valid. - * - * @param rowKey row key of mapping to be erased - * @param columnKey column key of mapping to be erased - * @return the value previously associated with the keys, or {@code null} if - * no mapping existed for the keys - */ - public V erase(@Nullable Object rowKey, @Nullable Object columnKey) { - Integer rowIndex = rowKeyToIndex.get(rowKey); - Integer columnIndex = columnKeyToIndex.get(columnKey); - if (rowIndex == null || columnIndex == null) { - return null; - } - return set(rowIndex, columnIndex, null); - } - - // TODO(jlevy): Add eraseRow and eraseColumn methods? - - @Override - public int size() { - return rowList.size() * columnList.size(); - } - - /** - * Returns an unmodifiable set of all row key / column key / value - * triplets. Changes to the table will update the returned set. - * - *

The returned set's iterator traverses the mappings with the first row - * key, the mappings with the second row key, and so on. - * - *

The value in the returned cells may change if the table subsequently - * changes. - * - * @return set of table cells consisting of row key / column key / value - * triplets - */ - @Override - public Set> cellSet() { - return super.cellSet(); - } - - @Override - Iterator> cellIterator() { - return new AbstractIndexedListIterator>(size()) { - @Override - protected Cell get(final int index) { - return new Tables.AbstractCell() { - final int rowIndex = index / columnList.size(); - final int columnIndex = index % columnList.size(); - - @Override - public R getRowKey() { - return rowList.get(rowIndex); - } - - @Override - public C getColumnKey() { - return columnList.get(columnIndex); - } - - @Override - public V getValue() { - return at(rowIndex, columnIndex); - } - }; - } - }; - } - - /** - * Returns a view of all mappings that have the given column key. If the - * column key isn't in {@link #columnKeySet()}, an empty immutable map is - * returned. - * - *

Otherwise, for each row key in {@link #rowKeySet()}, the returned map - * associates the row key with the corresponding value in the table. Changes - * to the returned map will update the underlying table, and vice versa. - * - * @param columnKey key of column to search for in the table - * @return the corresponding map from row keys to values - */ - @Override - public Map column(C columnKey) { - checkNotNull(columnKey); - Integer columnIndex = columnKeyToIndex.get(columnKey); - return (columnIndex == null) ? ImmutableMap.of() : new Column(columnIndex); - } - - private class Column extends ArrayMap { - final int columnIndex; - - Column(int columnIndex) { - super(rowKeyToIndex); - this.columnIndex = columnIndex; - } - - @Override - String getKeyRole() { - return "Row"; - } - - @Override - V getValue(int index) { - return at(index, columnIndex); - } - - @Override - V setValue(int index, V newValue) { - return set(index, columnIndex, newValue); - } - } - - /** - * Returns an immutable set of the valid column keys, including those that - * are associated with null values only. - * - * @return immutable set of column keys - */ - @Override - public ImmutableSet columnKeySet() { - return columnKeyToIndex.keySet(); - } - - private transient ColumnMap columnMap; - - @Override - public Map> columnMap() { - ColumnMap map = columnMap; - return (map == null) ? columnMap = new ColumnMap() : map; - } - - @WeakOuter - private class ColumnMap extends ArrayMap> { - private ColumnMap() { - super(columnKeyToIndex); - } - - @Override - String getKeyRole() { - return "Column"; - } - - @Override - Map getValue(int index) { - return new Column(index); - } - - @Override - Map setValue(int index, Map newValue) { - throw new UnsupportedOperationException(); - } - - @Override - public Map put(C key, Map value) { - throw new UnsupportedOperationException(); - } - } - - /** - * Returns a view of all mappings that have the given row key. If the - * row key isn't in {@link #rowKeySet()}, an empty immutable map is - * returned. - * - *

Otherwise, for each column key in {@link #columnKeySet()}, the returned - * map associates the column key with the corresponding value in the - * table. Changes to the returned map will update the underlying table, and - * vice versa. - * - * @param rowKey key of row to search for in the table - * @return the corresponding map from column keys to values - */ - @Override - public Map row(R rowKey) { - checkNotNull(rowKey); - Integer rowIndex = rowKeyToIndex.get(rowKey); - return (rowIndex == null) ? ImmutableMap.of() : new Row(rowIndex); - } - - private class Row extends ArrayMap { - final int rowIndex; - - Row(int rowIndex) { - super(columnKeyToIndex); - this.rowIndex = rowIndex; - } - - @Override - String getKeyRole() { - return "Column"; - } - - @Override - V getValue(int index) { - return at(rowIndex, index); - } - - @Override - V setValue(int index, V newValue) { - return set(rowIndex, index, newValue); - } - } - - /** - * Returns an immutable set of the valid row keys, including those that are - * associated with null values only. - * - * @return immutable set of row keys - */ - @Override - public ImmutableSet rowKeySet() { - return rowKeyToIndex.keySet(); - } - - private transient RowMap rowMap; - - @Override - public Map> rowMap() { - RowMap map = rowMap; - return (map == null) ? rowMap = new RowMap() : map; - } - - @WeakOuter - private class RowMap extends ArrayMap> { - private RowMap() { - super(rowKeyToIndex); - } - - @Override - String getKeyRole() { - return "Row"; - } - - @Override - Map getValue(int index) { - return new Row(index); - } - - @Override - Map setValue(int index, Map newValue) { - throw new UnsupportedOperationException(); - } - - @Override - public Map put(R key, Map value) { - throw new UnsupportedOperationException(); - } - } - - /** - * Returns an unmodifiable collection of all values, which may contain - * duplicates. Changes to the table will update the returned collection. - * - *

The returned collection's iterator traverses the values of the first row - * key, the values of the second row key, and so on. - * - * @return collection of values - */ - @Override - public Collection values() { - return super.values(); - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/BiMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/BiMap.java deleted file mode 100644 index e8ddf9dfc805..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/BiMap.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Map; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * A bimap (or "bidirectional map") is a map that preserves the uniqueness of - * its values as well as that of its keys. This constraint enables bimaps to - * support an "inverse view", which is another bimap containing the same entries - * as this bimap but with reversed keys and values. - * - *

See the Guava User Guide article on - * {@code BiMap}. - * - * @author Kevin Bourrillion - * @since 2.0 - */ -@GwtCompatible -public interface BiMap extends Map { - // Modification Operations - - /** - * {@inheritDoc} - * - * @throws IllegalArgumentException if the given value is already bound to a - * different key in this bimap. The bimap will remain unmodified in this - * event. To avoid this exception, call {@link #forcePut} instead. - */ - @Override - @Nullable - V put(@Nullable K key, @Nullable V value); - - /** - * An alternate form of {@code put} that silently removes any existing entry - * with the value {@code value} before proceeding with the {@link #put} - * operation. If the bimap previously contained the provided key-value - * mapping, this method has no effect. - * - *

Note that a successful call to this method could cause the size of the - * bimap to increase by one, stay the same, or even decrease by one. - * - *

Warning: If an existing entry with this value is removed, the key - * for that entry is discarded and not returned. - * - * @param key the key with which the specified value is to be associated - * @param value the value to be associated with the specified key - * @return the value which was previously associated with the key, which may - * be {@code null}, or {@code null} if there was no previous entry - */ - @Nullable - V forcePut(@Nullable K key, @Nullable V value); - - // Bulk Operations - - /** - * {@inheritDoc} - * - *

Warning: the results of calling this method may vary depending on - * the iteration order of {@code map}. - * - * @throws IllegalArgumentException if an attempt to {@code put} any - * entry fails. Note that some map entries may have been added to the - * bimap before the exception was thrown. - */ - @Override - void putAll(Map map); - - // Views - - /** - * {@inheritDoc} - * - *

Because a bimap has unique values, this method returns a {@link Set}, - * instead of the {@link java.util.Collection} specified in the {@link Map} - * interface. - */ - @Override - Set values(); - - /** - * Returns the inverse view of this bimap, which maps each of this bimap's - * values to its associated key. The two bimaps are backed by the same data; - * any changes to one will appear in the other. - * - *

Note:There is no guaranteed correspondence between the iteration - * order of a bimap and that of its inverse. - * - * @return the inverse view of this bimap - */ - BiMap inverse(); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/BinaryTreeTraverser.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/BinaryTreeTraverser.java deleted file mode 100644 index 9eca1a891d38..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/BinaryTreeTraverser.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Optional; - -import java.util.ArrayDeque; -import java.util.BitSet; -import java.util.Deque; -import java.util.Iterator; - -/** - * A variant of {@link TreeTraverser} for binary trees, providing additional traversals specific to - * binary trees. - * - * @author Louis Wasserman - * @since 15.0 - */ -@Beta -@GwtCompatible(emulated = true) -public abstract class BinaryTreeTraverser extends TreeTraverser { - // TODO(lowasser): make this GWT-compatible when we've checked in ArrayDeque and BitSet emulation - - /** - * Returns the left child of the specified node, or {@link Optional#absent()} if the specified - * node has no left child. - */ - public abstract Optional leftChild(T root); - - /** - * Returns the right child of the specified node, or {@link Optional#absent()} if the specified - * node has no right child. - */ - public abstract Optional rightChild(T root); - - /** - * Returns the children of this node, in left-to-right order. - */ - @Override - public final Iterable children(final T root) { - checkNotNull(root); - return new FluentIterable() { - @Override - public Iterator iterator() { - return new AbstractIterator() { - boolean doneLeft; - boolean doneRight; - - @Override - protected T computeNext() { - if (!doneLeft) { - doneLeft = true; - Optional left = leftChild(root); - if (left.isPresent()) { - return left.get(); - } - } - if (!doneRight) { - doneRight = true; - Optional right = rightChild(root); - if (right.isPresent()) { - return right.get(); - } - } - return endOfData(); - } - }; - } - }; - } - - @Override - UnmodifiableIterator preOrderIterator(T root) { - return new PreOrderIterator(root); - } - - /* - * Optimized implementation of preOrderIterator for binary trees. - */ - private final class PreOrderIterator extends UnmodifiableIterator - implements PeekingIterator { - private final Deque stack; - - PreOrderIterator(T root) { - this.stack = new ArrayDeque(); - stack.addLast(root); - } - - @Override - public boolean hasNext() { - return !stack.isEmpty(); - } - - @Override - public T next() { - T result = stack.removeLast(); - pushIfPresent(stack, rightChild(result)); - pushIfPresent(stack, leftChild(result)); - return result; - } - - @Override - public T peek() { - return stack.getLast(); - } - } - - @Override - UnmodifiableIterator postOrderIterator(T root) { - return new PostOrderIterator(root); - } - - /* - * Optimized implementation of postOrderIterator for binary trees. - */ - private final class PostOrderIterator extends UnmodifiableIterator { - private final Deque stack; - private final BitSet hasExpanded; - - PostOrderIterator(T root) { - this.stack = new ArrayDeque(); - stack.addLast(root); - this.hasExpanded = new BitSet(); - } - - @Override - public boolean hasNext() { - return !stack.isEmpty(); - } - - @Override - public T next() { - while (true) { - T node = stack.getLast(); - boolean expandedNode = hasExpanded.get(stack.size() - 1); - if (expandedNode) { - stack.removeLast(); - hasExpanded.clear(stack.size()); - return node; - } else { - hasExpanded.set(stack.size() - 1); - pushIfPresent(stack, rightChild(node)); - pushIfPresent(stack, leftChild(node)); - } - } - } - } - - // TODO(lowasser): see if any significant optimizations are possible for breadthFirstIterator - - public final FluentIterable inOrderTraversal(final T root) { - checkNotNull(root); - return new FluentIterable() { - @Override - public UnmodifiableIterator iterator() { - return new InOrderIterator(root); - } - }; - } - - private final class InOrderIterator extends AbstractIterator { - private final Deque stack; - private final BitSet hasExpandedLeft; - - InOrderIterator(T root) { - this.stack = new ArrayDeque(); - this.hasExpandedLeft = new BitSet(); - stack.addLast(root); - } - - @Override - protected T computeNext() { - while (!stack.isEmpty()) { - T node = stack.getLast(); - if (hasExpandedLeft.get(stack.size() - 1)) { - stack.removeLast(); - hasExpandedLeft.clear(stack.size()); - pushIfPresent(stack, rightChild(node)); - return node; - } else { - hasExpandedLeft.set(stack.size() - 1); - pushIfPresent(stack, leftChild(node)); - } - } - return endOfData(); - } - } - - private static void pushIfPresent(Deque stack, Optional node) { - if (node.isPresent()) { - stack.addLast(node.get()); - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/BoundType.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/BoundType.java deleted file mode 100644 index 7b8f34ba5c89..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/BoundType.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -/** - * Indicates whether an endpoint of some range is contained in the range itself ("closed") or not - * ("open"). If a range is unbounded on a side, it is neither open nor closed on that side; the - * bound simply does not exist. - * - * @since 10.0 - */ -@GwtCompatible -public enum BoundType { - /** - * The endpoint value is not considered part of the set ("exclusive"). - */ - OPEN { - @Override - BoundType flip() { - return CLOSED; - } - }, - /** - * The endpoint value is considered part of the set ("inclusive"). - */ - CLOSED { - @Override - BoundType flip() { - return OPEN; - } - }; - - /** - * Returns the bound type corresponding to a boolean value for inclusivity. - */ - static BoundType forBoolean(boolean inclusive) { - return inclusive ? CLOSED : OPEN; - } - - abstract BoundType flip(); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ByFunctionOrdering.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ByFunctionOrdering.java deleted file mode 100644 index 82d84e16460a..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ByFunctionOrdering.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Function; -import com.google.common.base.Objects; - -import java.io.Serializable; - -import javax.annotation.Nullable; - -/** - * An ordering that orders elements by applying an order to the result of a - * function on those elements. - */ -@GwtCompatible(serializable = true) -final class ByFunctionOrdering extends Ordering implements Serializable { - final Function function; - final Ordering ordering; - - ByFunctionOrdering(Function function, Ordering ordering) { - this.function = checkNotNull(function); - this.ordering = checkNotNull(ordering); - } - - @Override - public int compare(F left, F right) { - return ordering.compare(function.apply(left), function.apply(right)); - } - - @Override - public boolean equals(@Nullable Object object) { - if (object == this) { - return true; - } - if (object instanceof ByFunctionOrdering) { - ByFunctionOrdering that = (ByFunctionOrdering) object; - return this.function.equals(that.function) && this.ordering.equals(that.ordering); - } - return false; - } - - @Override - public int hashCode() { - return Objects.hashCode(function, ordering); - } - - @Override - public String toString() { - return ordering + ".onResultOf(" + function + ")"; - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/CartesianList.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/CartesianList.java deleted file mode 100644 index e27de142c800..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/CartesianList.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkElementIndex; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.math.IntMath; - -import java.util.AbstractList; -import java.util.List; -import java.util.ListIterator; -import java.util.RandomAccess; - -import javax.annotation.Nullable; - -/** - * Implementation of {@link Lists#cartesianProduct(List)}. - * - * @author Louis Wasserman - */ -@GwtCompatible -final class CartesianList extends AbstractList> implements RandomAccess { - - private transient final ImmutableList> axes; - private transient final int[] axesSizeProduct; - - static List> create(List> lists) { - ImmutableList.Builder> axesBuilder = new ImmutableList.Builder>(lists.size()); - for (List list : lists) { - List copy = ImmutableList.copyOf(list); - if (copy.isEmpty()) { - return ImmutableList.of(); - } - axesBuilder.add(copy); - } - return new CartesianList(axesBuilder.build()); - } - - CartesianList(ImmutableList> axes) { - this.axes = axes; - int[] axesSizeProduct = new int[axes.size() + 1]; - axesSizeProduct[axes.size()] = 1; - try { - for (int i = axes.size() - 1; i >= 0; i--) { - axesSizeProduct[i] = IntMath.checkedMultiply(axesSizeProduct[i + 1], axes.get(i).size()); - } - } catch (ArithmeticException e) { - throw new IllegalArgumentException( - "Cartesian product too large; must have size at most Integer.MAX_VALUE"); - } - this.axesSizeProduct = axesSizeProduct; - } - - private int getAxisIndexForProductIndex(int index, int axis) { - return (index / axesSizeProduct[axis + 1]) % axes.get(axis).size(); - } - - @Override - public ImmutableList get(final int index) { - checkElementIndex(index, size()); - return new ImmutableList() { - - @Override - public int size() { - return axes.size(); - } - - @Override - public E get(int axis) { - checkElementIndex(axis, size()); - int axisIndex = getAxisIndexForProductIndex(index, axis); - return axes.get(axis).get(axisIndex); - } - - @Override - boolean isPartialView() { - return true; - } - }; - } - - @Override - public int size() { - return axesSizeProduct[0]; - } - - @Override - public boolean contains(@Nullable Object o) { - if (!(o instanceof List)) { - return false; - } - List list = (List) o; - if (list.size() != axes.size()) { - return false; - } - ListIterator itr = list.listIterator(); - while (itr.hasNext()) { - int index = itr.nextIndex(); - if (!axes.get(index).contains(itr.next())) { - return false; - } - } - return true; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ClassToInstanceMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ClassToInstanceMap.java deleted file mode 100644 index 8c39210ed316..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ClassToInstanceMap.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Map; - -import javax.annotation.Nullable; - -/** - * A map, each entry of which maps a Java - * raw type to an instance of that type. - * In addition to implementing {@code Map}, the additional type-safe operations - * {@link #putInstance} and {@link #getInstance} are available. - * - *

Like any other {@code Map}, this map may contain entries - * for primitive types, and a primitive type and its corresponding wrapper type - * may map to different values. - * - *

See the Guava User Guide article on - * {@code ClassToInstanceMap}. - * - *

To map a generic type to an instance of that type, use {@link - * com.google.common.reflect.TypeToInstanceMap} instead. - * - * @param the common supertype that all entries must share; often this is - * simply {@link Object} - * - * @author Kevin Bourrillion - * @since 2.0 - */ -@GwtCompatible -public interface ClassToInstanceMap extends Map, B> { - /** - * Returns the value the specified class is mapped to, or {@code null} if no - * entry for this class is present. This will only return a value that was - * bound to this specific class, not a value that may have been bound to a - * subtype. - */ - T getInstance(Class type); - - /** - * Maps the specified class to the specified value. Does not associate - * this value with any of the class's supertypes. - * - * @return the value previously associated with this class (possibly {@code - * null}), or {@code null} if there was no previous entry. - */ - T putInstance(Class type, @Nullable T value); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/CollectPreconditions.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/CollectPreconditions.java deleted file mode 100644 index f19f47582f0e..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/CollectPreconditions.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.annotations.GwtCompatible; - -/** - * Precondition checks useful in collection implementations. - */ -@GwtCompatible -final class CollectPreconditions { - - static void checkEntryNotNull(Object key, Object value) { - if (key == null) { - throw new NullPointerException("null key in entry: null=" + value); - } else if (value == null) { - throw new NullPointerException("null value in entry: " + key + "=null"); - } - } - - static int checkNonnegative(int value, String name) { - if (value < 0) { - throw new IllegalArgumentException(name + " cannot be negative but was: " + value); - } - return value; - } - - static void checkPositive(int value, String name) { - if (value <= 0) { - throw new IllegalArgumentException(name + " must be positive but was: " + value); - } - } - - /** - * Precondition tester for {@code Iterator.remove()} that throws an exception with a consistent - * error message. - */ - static void checkRemove(boolean canRemove) { - checkState(canRemove, "no calls to next() since the last call to remove()"); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Collections2.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Collections2.java deleted file mode 100644 index 4c549bad0fc7..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Collections2.java +++ /dev/null @@ -1,682 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Predicates.and; -import static com.google.common.base.Predicates.not; -import static com.google.common.collect.CollectPreconditions.checkNonnegative; -import static com.google.common.math.LongMath.binomial; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Function; -import com.google.common.base.Joiner; -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import com.google.common.math.IntMath; -import com.google.common.primitives.Ints; - -import java.util.AbstractCollection; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * Provides static methods for working with {@code Collection} instances. - * - * @author Chris Povirk - * @author Mike Bostock - * @author Jared Levy - * @since 2.0 - */ -@CheckReturnValue -@GwtCompatible -public final class Collections2 { - private Collections2() {} - - /** - * Returns the elements of {@code unfiltered} that satisfy a predicate. The - * returned collection is a live view of {@code unfiltered}; changes to one - * affect the other. - * - *

The resulting collection's iterator does not support {@code remove()}, - * but all other collection methods are supported. When given an element that - * doesn't satisfy the predicate, the collection's {@code add()} and {@code - * addAll()} methods throw an {@link IllegalArgumentException}. When methods - * such as {@code removeAll()} and {@code clear()} are called on the filtered - * collection, only elements that satisfy the filter will be removed from the - * underlying collection. - * - *

The returned collection isn't threadsafe or serializable, even if - * {@code unfiltered} is. - * - *

Many of the filtered collection's methods, such as {@code size()}, - * iterate across every element in the underlying collection and determine - * which elements satisfy the filter. When a live view is not needed, - * it may be faster to copy {@code Iterables.filter(unfiltered, predicate)} - * and use the copy. - * - *

Warning: {@code predicate} must be consistent with equals, - * as documented at {@link Predicate#apply}. Do not provide a predicate such - * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent - * with equals. (See {@link Iterables#filter(Iterable, Class)} for related - * functionality.) - */ - // TODO(kevinb): how can we omit that Iterables link when building gwt - // javadoc? - @CheckReturnValue - public static Collection filter(Collection unfiltered, Predicate predicate) { - if (unfiltered instanceof FilteredCollection) { - // Support clear(), removeAll(), and retainAll() when filtering a filtered - // collection. - return ((FilteredCollection) unfiltered).createCombined(predicate); - } - - return new FilteredCollection(checkNotNull(unfiltered), checkNotNull(predicate)); - } - - /** - * Delegates to {@link Collection#contains}. Returns {@code false} if the - * {@code contains} method throws a {@code ClassCastException} or - * {@code NullPointerException}. - */ - static boolean safeContains(Collection collection, @Nullable Object object) { - checkNotNull(collection); - try { - return collection.contains(object); - } catch (ClassCastException e) { - return false; - } catch (NullPointerException e) { - return false; - } - } - - /** - * Delegates to {@link Collection#remove}. Returns {@code false} if the - * {@code remove} method throws a {@code ClassCastException} or - * {@code NullPointerException}. - */ - static boolean safeRemove(Collection collection, @Nullable Object object) { - checkNotNull(collection); - try { - return collection.remove(object); - } catch (ClassCastException e) { - return false; - } catch (NullPointerException e) { - return false; - } - } - - static class FilteredCollection extends AbstractCollection { - final Collection unfiltered; - final Predicate predicate; - - FilteredCollection(Collection unfiltered, Predicate predicate) { - this.unfiltered = unfiltered; - this.predicate = predicate; - } - - FilteredCollection createCombined(Predicate newPredicate) { - return new FilteredCollection(unfiltered, Predicates.and(predicate, newPredicate)); - // . above needed to compile in JDK 5 - } - - @Override - public boolean add(E element) { - checkArgument(predicate.apply(element)); - return unfiltered.add(element); - } - - @Override - public boolean addAll(Collection collection) { - for (E element : collection) { - checkArgument(predicate.apply(element)); - } - return unfiltered.addAll(collection); - } - - @Override - public void clear() { - Iterables.removeIf(unfiltered, predicate); - } - - @Override - public boolean contains(@Nullable Object element) { - if (safeContains(unfiltered, element)) { - @SuppressWarnings("unchecked") // element is in unfiltered, so it must be an E - E e = (E) element; - return predicate.apply(e); - } - return false; - } - - @Override - public boolean containsAll(Collection collection) { - return containsAllImpl(this, collection); - } - - @Override - public boolean isEmpty() { - return !Iterables.any(unfiltered, predicate); - } - - @Override - public Iterator iterator() { - return Iterators.filter(unfiltered.iterator(), predicate); - } - - @Override - public boolean remove(Object element) { - return contains(element) && unfiltered.remove(element); - } - - @Override - public boolean removeAll(final Collection collection) { - return Iterables.removeIf(unfiltered, and(predicate, Predicates.in(collection))); - } - - @Override - public boolean retainAll(final Collection collection) { - return Iterables.removeIf(unfiltered, and(predicate, not(Predicates.in(collection)))); - } - - @Override - public int size() { - return Iterators.size(iterator()); - } - - @Override - public Object[] toArray() { - // creating an ArrayList so filtering happens once - return Lists.newArrayList(iterator()).toArray(); - } - - @Override - public T[] toArray(T[] array) { - return Lists.newArrayList(iterator()).toArray(array); - } - } - - /** - * Returns a collection that applies {@code function} to each element of - * {@code fromCollection}. The returned collection is a live view of {@code - * fromCollection}; changes to one affect the other. - * - *

The returned collection's {@code add()} and {@code addAll()} methods - * throw an {@link UnsupportedOperationException}. All other collection - * methods are supported, as long as {@code fromCollection} supports them. - * - *

The returned collection isn't threadsafe or serializable, even if - * {@code fromCollection} is. - * - *

When a live view is not needed, it may be faster to copy the - * transformed collection and use the copy. - * - *

If the input {@code Collection} is known to be a {@code List}, consider - * {@link Lists#transform}. If only an {@code Iterable} is available, use - * {@link Iterables#transform}. - */ - public static Collection transform( - Collection fromCollection, Function function) { - return new TransformedCollection(fromCollection, function); - } - - static class TransformedCollection extends AbstractCollection { - final Collection fromCollection; - final Function function; - - TransformedCollection(Collection fromCollection, Function function) { - this.fromCollection = checkNotNull(fromCollection); - this.function = checkNotNull(function); - } - - @Override - public void clear() { - fromCollection.clear(); - } - - @Override - public boolean isEmpty() { - return fromCollection.isEmpty(); - } - - @Override - public Iterator iterator() { - return Iterators.transform(fromCollection.iterator(), function); - } - - @Override - public int size() { - return fromCollection.size(); - } - } - - /** - * Returns {@code true} if the collection {@code self} contains all of the - * elements in the collection {@code c}. - * - *

This method iterates over the specified collection {@code c}, checking - * each element returned by the iterator in turn to see if it is contained in - * the specified collection {@code self}. If all elements are so contained, - * {@code true} is returned, otherwise {@code false}. - * - * @param self a collection which might contain all elements in {@code c} - * @param c a collection whose elements might be contained by {@code self} - */ - static boolean containsAllImpl(Collection self, Collection c) { - return Iterables.all(c, Predicates.in(self)); - } - - /** - * An implementation of {@link Collection#toString()}. - */ - static String toStringImpl(final Collection collection) { - StringBuilder sb = newStringBuilderForCollection(collection.size()).append('['); - STANDARD_JOINER.appendTo( - sb, - Iterables.transform( - collection, - new Function() { - @Override - public Object apply(Object input) { - return input == collection ? "(this Collection)" : input; - } - })); - return sb.append(']').toString(); - } - - /** - * Returns best-effort-sized StringBuilder based on the given collection size. - */ - static StringBuilder newStringBuilderForCollection(int size) { - checkNonnegative(size, "size"); - return new StringBuilder((int) Math.min(size * 8L, Ints.MAX_POWER_OF_TWO)); - } - - /** - * Used to avoid http://bugs.sun.com/view_bug.do?bug_id=6558557 - */ - static Collection cast(Iterable iterable) { - return (Collection) iterable; - } - - static final Joiner STANDARD_JOINER = Joiner.on(", ").useForNull("null"); - - /** - * Returns a {@link Collection} of all the permutations of the specified - * {@link Iterable}. - * - *

Notes: This is an implementation of the algorithm for - * Lexicographical Permutations Generation, described in Knuth's "The Art of - * Computer Programming", Volume 4, Chapter 7, Section 7.2.1.2. The - * iteration order follows the lexicographical order. This means that - * the first permutation will be in ascending order, and the last will be in - * descending order. - * - *

Duplicate elements are considered equal. For example, the list [1, 1] - * will have only one permutation, instead of two. This is why the elements - * have to implement {@link Comparable}. - * - *

An empty iterable has only one permutation, which is an empty list. - * - *

This method is equivalent to - * {@code Collections2.orderedPermutations(list, Ordering.natural())}. - * - * @param elements the original iterable whose elements have to be permuted. - * @return an immutable {@link Collection} containing all the different - * permutations of the original iterable. - * @throws NullPointerException if the specified iterable is null or has any - * null elements. - * @since 12.0 - */ - @Beta - public static > Collection> orderedPermutations( - Iterable elements) { - return orderedPermutations(elements, Ordering.natural()); - } - - /** - * Returns a {@link Collection} of all the permutations of the specified - * {@link Iterable} using the specified {@link Comparator} for establishing - * the lexicographical ordering. - * - *

Examples:

   {@code
-   *
-   *   for (List perm : orderedPermutations(asList("b", "c", "a"))) {
-   *     println(perm);
-   *   }
-   *   // -> ["a", "b", "c"]
-   *   // -> ["a", "c", "b"]
-   *   // -> ["b", "a", "c"]
-   *   // -> ["b", "c", "a"]
-   *   // -> ["c", "a", "b"]
-   *   // -> ["c", "b", "a"]
-   *
-   *   for (List perm : orderedPermutations(asList(1, 2, 2, 1))) {
-   *     println(perm);
-   *   }
-   *   // -> [1, 1, 2, 2]
-   *   // -> [1, 2, 1, 2]
-   *   // -> [1, 2, 2, 1]
-   *   // -> [2, 1, 1, 2]
-   *   // -> [2, 1, 2, 1]
-   *   // -> [2, 2, 1, 1]}
- * - *

Notes: This is an implementation of the algorithm for - * Lexicographical Permutations Generation, described in Knuth's "The Art of - * Computer Programming", Volume 4, Chapter 7, Section 7.2.1.2. The - * iteration order follows the lexicographical order. This means that - * the first permutation will be in ascending order, and the last will be in - * descending order. - * - *

Elements that compare equal are considered equal and no new permutations - * are created by swapping them. - * - *

An empty iterable has only one permutation, which is an empty list. - * - * @param elements the original iterable whose elements have to be permuted. - * @param comparator a comparator for the iterable's elements. - * @return an immutable {@link Collection} containing all the different - * permutations of the original iterable. - * @throws NullPointerException If the specified iterable is null, has any - * null elements, or if the specified comparator is null. - * @since 12.0 - */ - @Beta - public static Collection> orderedPermutations( - Iterable elements, Comparator comparator) { - return new OrderedPermutationCollection(elements, comparator); - } - - private static final class OrderedPermutationCollection extends AbstractCollection> { - final ImmutableList inputList; - final Comparator comparator; - final int size; - - OrderedPermutationCollection(Iterable input, Comparator comparator) { - this.inputList = Ordering.from(comparator).immutableSortedCopy(input); - this.comparator = comparator; - this.size = calculateSize(inputList, comparator); - } - - /** - * The number of permutations with repeated elements is calculated as - * follows: - *

    - *
  • For an empty list, it is 1 (base case).
  • - *
  • When r numbers are added to a list of n-r elements, the number of - * permutations is increased by a factor of (n choose r).
  • - *
- */ - private static int calculateSize( - List sortedInputList, Comparator comparator) { - long permutations = 1; - int n = 1; - int r = 1; - while (n < sortedInputList.size()) { - int comparison = comparator.compare(sortedInputList.get(n - 1), sortedInputList.get(n)); - if (comparison < 0) { - // We move to the next non-repeated element. - permutations *= binomial(n, r); - r = 0; - if (!isPositiveInt(permutations)) { - return Integer.MAX_VALUE; - } - } - n++; - r++; - } - permutations *= binomial(n, r); - if (!isPositiveInt(permutations)) { - return Integer.MAX_VALUE; - } - return (int) permutations; - } - - @Override - public int size() { - return size; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public Iterator> iterator() { - return new OrderedPermutationIterator(inputList, comparator); - } - - @Override - public boolean contains(@Nullable Object obj) { - if (obj instanceof List) { - List list = (List) obj; - return isPermutation(inputList, list); - } - return false; - } - - @Override - public String toString() { - return "orderedPermutationCollection(" + inputList + ")"; - } - } - - private static final class OrderedPermutationIterator extends AbstractIterator> { - - List nextPermutation; - final Comparator comparator; - - OrderedPermutationIterator(List list, Comparator comparator) { - this.nextPermutation = Lists.newArrayList(list); - this.comparator = comparator; - } - - @Override - protected List computeNext() { - if (nextPermutation == null) { - return endOfData(); - } - ImmutableList next = ImmutableList.copyOf(nextPermutation); - calculateNextPermutation(); - return next; - } - - void calculateNextPermutation() { - int j = findNextJ(); - if (j == -1) { - nextPermutation = null; - return; - } - - int l = findNextL(j); - Collections.swap(nextPermutation, j, l); - int n = nextPermutation.size(); - Collections.reverse(nextPermutation.subList(j + 1, n)); - } - - int findNextJ() { - for (int k = nextPermutation.size() - 2; k >= 0; k--) { - if (comparator.compare(nextPermutation.get(k), nextPermutation.get(k + 1)) < 0) { - return k; - } - } - return -1; - } - - int findNextL(int j) { - E ak = nextPermutation.get(j); - for (int l = nextPermutation.size() - 1; l > j; l--) { - if (comparator.compare(ak, nextPermutation.get(l)) < 0) { - return l; - } - } - throw new AssertionError("this statement should be unreachable"); - } - } - - /** - * Returns a {@link Collection} of all the permutations of the specified - * {@link Collection}. - * - *

Notes: This is an implementation of the Plain Changes algorithm - * for permutations generation, described in Knuth's "The Art of Computer - * Programming", Volume 4, Chapter 7, Section 7.2.1.2. - * - *

If the input list contains equal elements, some of the generated - * permutations will be equal. - * - *

An empty collection has only one permutation, which is an empty list. - * - * @param elements the original collection whose elements have to be permuted. - * @return an immutable {@link Collection} containing all the different - * permutations of the original collection. - * @throws NullPointerException if the specified collection is null or has any - * null elements. - * @since 12.0 - */ - @Beta - public static Collection> permutations(Collection elements) { - return new PermutationCollection(ImmutableList.copyOf(elements)); - } - - private static final class PermutationCollection extends AbstractCollection> { - final ImmutableList inputList; - - PermutationCollection(ImmutableList input) { - this.inputList = input; - } - - @Override - public int size() { - return IntMath.factorial(inputList.size()); - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public Iterator> iterator() { - return new PermutationIterator(inputList); - } - - @Override - public boolean contains(@Nullable Object obj) { - if (obj instanceof List) { - List list = (List) obj; - return isPermutation(inputList, list); - } - return false; - } - - @Override - public String toString() { - return "permutations(" + inputList + ")"; - } - } - - private static class PermutationIterator extends AbstractIterator> { - final List list; - final int[] c; - final int[] o; - int j; - - PermutationIterator(List list) { - this.list = new ArrayList(list); - int n = list.size(); - c = new int[n]; - o = new int[n]; - Arrays.fill(c, 0); - Arrays.fill(o, 1); - j = Integer.MAX_VALUE; - } - - @Override - protected List computeNext() { - if (j <= 0) { - return endOfData(); - } - ImmutableList next = ImmutableList.copyOf(list); - calculateNextPermutation(); - return next; - } - - void calculateNextPermutation() { - j = list.size() - 1; - int s = 0; - - // Handle the special case of an empty list. Skip the calculation of the - // next permutation. - if (j == -1) { - return; - } - - while (true) { - int q = c[j] + o[j]; - if (q < 0) { - switchDirection(); - continue; - } - if (q == j + 1) { - if (j == 0) { - break; - } - s++; - switchDirection(); - continue; - } - - Collections.swap(list, j - c[j] + s, j - q + s); - c[j] = q; - break; - } - } - - void switchDirection() { - o[j] = -o[j]; - j--; - } - } - - /** - * Returns {@code true} if the second list is a permutation of the first. - */ - private static boolean isPermutation(List first, List second) { - if (first.size() != second.size()) { - return false; - } - Multiset firstMultiset = HashMultiset.create(first); - Multiset secondMultiset = HashMultiset.create(second); - return firstMultiset.equals(secondMultiset); - } - - private static boolean isPositiveInt(long n) { - return n >= 0 && n <= Integer.MAX_VALUE; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ComparatorOrdering.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ComparatorOrdering.java deleted file mode 100644 index eec524653c04..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ComparatorOrdering.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; -import java.util.Comparator; - -import javax.annotation.Nullable; - -/** An ordering for a pre-existing comparator. */ -@GwtCompatible(serializable = true) -final class ComparatorOrdering extends Ordering implements Serializable { - final Comparator comparator; - - ComparatorOrdering(Comparator comparator) { - this.comparator = checkNotNull(comparator); - } - - @Override - public int compare(T a, T b) { - return comparator.compare(a, b); - } - - @Override - public boolean equals(@Nullable Object object) { - if (object == this) { - return true; - } - if (object instanceof ComparatorOrdering) { - ComparatorOrdering that = (ComparatorOrdering) object; - return this.comparator.equals(that.comparator); - } - return false; - } - - @Override - public int hashCode() { - return comparator.hashCode(); - } - - @Override - public String toString() { - return comparator.toString(); - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ComparisonChain.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ComparisonChain.java deleted file mode 100644 index 43bbc9edd6f2..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ComparisonChain.java +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.primitives.Booleans; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; - -import java.util.Comparator; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * A utility for performing a chained comparison statement. For example: - *

   {@code
- *
- *   public int compareTo(Foo that) {
- *     return ComparisonChain.start()
- *         .compare(this.aString, that.aString)
- *         .compare(this.anInt, that.anInt)
- *         .compare(this.anEnum, that.anEnum, Ordering.natural().nullsLast())
- *         .result();
- *   }}
- * - *

The value of this expression will have the same sign as the first - * nonzero comparison result in the chain, or will be zero if every - * comparison result was zero. - * - *

Note: {@code ComparisonChain} instances are immutable. For - * this utility to work correctly, calls must be chained as illustrated above. - * - *

Performance note: Even though the {@code ComparisonChain} caller always - * invokes its {@code compare} methods unconditionally, the {@code - * ComparisonChain} implementation stops calling its inputs' {@link - * Comparable#compareTo compareTo} and {@link Comparator#compare compare} - * methods as soon as one of them returns a nonzero result. This optimization is - * typically important only in the presence of expensive {@code compareTo} and - * {@code compare} implementations. - * - *

See the Guava User Guide article on - * {@code ComparisonChain}. - * - * @author Mark Davis - * @author Kevin Bourrillion - * @since 2.0 - */ -@CheckReturnValue -@GwtCompatible -public abstract class ComparisonChain { - private ComparisonChain() {} - - /** - * Begins a new chained comparison statement. See example in the class - * documentation. - */ - public static ComparisonChain start() { - return ACTIVE; - } - - private static final ComparisonChain ACTIVE = - new ComparisonChain() { - @SuppressWarnings("unchecked") - @Override - public ComparisonChain compare(Comparable left, Comparable right) { - return classify(left.compareTo(right)); - } - - @Override - public ComparisonChain compare( - @Nullable T left, @Nullable T right, Comparator comparator) { - return classify(comparator.compare(left, right)); - } - - @Override - public ComparisonChain compare(int left, int right) { - return classify(Ints.compare(left, right)); - } - - @Override - public ComparisonChain compare(long left, long right) { - return classify(Longs.compare(left, right)); - } - - @Override - public ComparisonChain compare(float left, float right) { - return classify(Float.compare(left, right)); - } - - @Override - public ComparisonChain compare(double left, double right) { - return classify(Double.compare(left, right)); - } - - @Override - public ComparisonChain compareTrueFirst(boolean left, boolean right) { - return classify(Booleans.compare(right, left)); // reversed - } - - @Override - public ComparisonChain compareFalseFirst(boolean left, boolean right) { - return classify(Booleans.compare(left, right)); - } - - ComparisonChain classify(int result) { - return (result < 0) ? LESS : (result > 0) ? GREATER : ACTIVE; - } - - @Override - public int result() { - return 0; - } - }; - - private static final ComparisonChain LESS = new InactiveComparisonChain(-1); - - private static final ComparisonChain GREATER = new InactiveComparisonChain(1); - - private static final class InactiveComparisonChain extends ComparisonChain { - final int result; - - InactiveComparisonChain(int result) { - this.result = result; - } - - @Override - public ComparisonChain compare(@Nullable Comparable left, @Nullable Comparable right) { - return this; - } - - @Override - public ComparisonChain compare( - @Nullable T left, @Nullable T right, @Nullable Comparator comparator) { - return this; - } - - @Override - public ComparisonChain compare(int left, int right) { - return this; - } - - @Override - public ComparisonChain compare(long left, long right) { - return this; - } - - @Override - public ComparisonChain compare(float left, float right) { - return this; - } - - @Override - public ComparisonChain compare(double left, double right) { - return this; - } - - @Override - public ComparisonChain compareTrueFirst(boolean left, boolean right) { - return this; - } - - @Override - public ComparisonChain compareFalseFirst(boolean left, boolean right) { - return this; - } - - @Override - public int result() { - return result; - } - } - - /** - * Compares two comparable objects as specified by {@link - * Comparable#compareTo}, if the result of this comparison chain - * has not already been determined. - */ - public abstract ComparisonChain compare(Comparable left, Comparable right); - - /** - * Compares two objects using a comparator, if the result of this - * comparison chain has not already been determined. - */ - public abstract ComparisonChain compare( - @Nullable T left, @Nullable T right, Comparator comparator); - - /** - * Compares two {@code int} values as specified by {@link Ints#compare}, - * if the result of this comparison chain has not already been - * determined. - */ - public abstract ComparisonChain compare(int left, int right); - - /** - * Compares two {@code long} values as specified by {@link Longs#compare}, - * if the result of this comparison chain has not already been - * determined. - */ - public abstract ComparisonChain compare(long left, long right); - - /** - * Compares two {@code float} values as specified by {@link - * Float#compare}, if the result of this comparison chain has not - * already been determined. - */ - public abstract ComparisonChain compare(float left, float right); - - /** - * Compares two {@code double} values as specified by {@link - * Double#compare}, if the result of this comparison chain has not - * already been determined. - */ - public abstract ComparisonChain compare(double left, double right); - - /** - * Discouraged synonym for {@link #compareFalseFirst}. - * - * @deprecated Use {@link #compareFalseFirst}; or, if the parameters passed - * are being either negated or reversed, undo the negation or reversal and - * use {@link #compareTrueFirst}. - * @since 19.0 - */ - @Deprecated - public final ComparisonChain compare(Boolean left, Boolean right) { - return compareFalseFirst(left, right); - } - - /** - * Compares two {@code boolean} values, considering {@code true} to be less - * than {@code false}, if the result of this comparison chain has not - * already been determined. - * - * @since 12.0 - */ - public abstract ComparisonChain compareTrueFirst(boolean left, boolean right); - - /** - * Compares two {@code boolean} values, considering {@code false} to be less - * than {@code true}, if the result of this comparison chain has not - * already been determined. - * - * @since 12.0 (present as {@code compare} since 2.0) - */ - public abstract ComparisonChain compareFalseFirst(boolean left, boolean right); - - /** - * Ends this comparison chain and returns its result: a value having the - * same sign as the first nonzero comparison result in the chain, or zero if - * every result was zero. - */ - public abstract int result(); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/CompoundOrdering.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/CompoundOrdering.java deleted file mode 100644 index 385d0a9136b4..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/CompoundOrdering.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; -import java.util.Comparator; - -/** An ordering that tries several comparators in order. */ -@GwtCompatible(serializable = true) -final class CompoundOrdering extends Ordering implements Serializable { - final ImmutableList> comparators; - - CompoundOrdering(Comparator primary, Comparator secondary) { - this.comparators = ImmutableList.>of(primary, secondary); - } - - CompoundOrdering(Iterable> comparators) { - this.comparators = ImmutableList.copyOf(comparators); - } - - @Override - public int compare(T left, T right) { - // Avoid using the Iterator to avoid generating garbage (issue 979). - int size = comparators.size(); - for (int i = 0; i < size; i++) { - int result = comparators.get(i).compare(left, right); - if (result != 0) { - return result; - } - } - return 0; - } - - @Override - public boolean equals(Object object) { - if (object == this) { - return true; - } - if (object instanceof CompoundOrdering) { - CompoundOrdering that = (CompoundOrdering) object; - return this.comparators.equals(that.comparators); - } - return false; - } - - @Override - public int hashCode() { - return comparators.hashCode(); - } - - @Override - public String toString() { - return "Ordering.compound(" + comparators + ")"; - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ComputationException.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ComputationException.java deleted file mode 100644 index 80b2f5dc3f8b..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ComputationException.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import javax.annotation.Nullable; - -/** - * Wraps an exception that occurred during a computation. - * - * @author Bob Lee - * @since 2.0 - */ -@GwtCompatible -public class ComputationException extends RuntimeException { - /** - * Creates a new instance with the given cause. - */ - public ComputationException(@Nullable Throwable cause) { - super(cause); - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ComputingConcurrentHashMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ComputingConcurrentHashMap.java deleted file mode 100644 index 87d75bb324f7..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ComputingConcurrentHashMap.java +++ /dev/null @@ -1,448 +0,0 @@ -/* - * Copyright (C) 2010 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.base.Equivalence; -import com.google.common.base.Function; -import com.google.common.collect.MapMaker.RemovalCause; -import com.google.common.collect.MapMaker.RemovalListener; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.lang.ref.ReferenceQueue; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.atomic.AtomicReferenceArray; - -import javax.annotation.Nullable; -import javax.annotation.concurrent.GuardedBy; - -/** - * Adds computing functionality to {@link MapMakerInternalMap}. - * - * @author Bob Lee - * @author Charles Fry - */ -class ComputingConcurrentHashMap extends MapMakerInternalMap { - final Function computingFunction; - - /** - * Creates a new, empty map with the specified strategy, initial capacity, load factor and - * concurrency level. - */ - ComputingConcurrentHashMap(MapMaker builder, Function computingFunction) { - super(builder); - this.computingFunction = checkNotNull(computingFunction); - } - - @Override - Segment createSegment(int initialCapacity, int maxSegmentSize) { - return new ComputingSegment(this, initialCapacity, maxSegmentSize); - } - - @Override - ComputingSegment segmentFor(int hash) { - return (ComputingSegment) super.segmentFor(hash); - } - - V getOrCompute(K key) throws ExecutionException { - int hash = hash(checkNotNull(key)); - return segmentFor(hash).getOrCompute(key, hash, computingFunction); - } - - @SuppressWarnings("serial") // This class is never serialized. - static final class ComputingSegment extends Segment { - ComputingSegment(MapMakerInternalMap map, int initialCapacity, int maxSegmentSize) { - super(map, initialCapacity, maxSegmentSize); - } - - V getOrCompute(K key, int hash, Function computingFunction) - throws ExecutionException { - try { - outer: - while (true) { - // don't call getLiveEntry, which would ignore computing values - ReferenceEntry e = getEntry(key, hash); - if (e != null) { - V value = getLiveValue(e); - if (value != null) { - recordRead(e); - return value; - } - } - - // at this point e is either null, computing, or expired; - // avoid locking if it's already computing - if (e == null || !e.getValueReference().isComputingReference()) { - boolean createNewEntry = true; - ComputingValueReference computingValueReference = null; - lock(); - try { - preWriteCleanup(); - - int newCount = this.count - 1; - AtomicReferenceArray> table = this.table; - int index = hash & (table.length() - 1); - ReferenceEntry first = table.get(index); - - for (e = first; e != null; e = e.getNext()) { - K entryKey = e.getKey(); - if (e.getHash() == hash - && entryKey != null - && map.keyEquivalence.equivalent(key, entryKey)) { - ValueReference valueReference = e.getValueReference(); - if (valueReference.isComputingReference()) { - createNewEntry = false; - } else { - V value = e.getValueReference().get(); - if (value == null) { - enqueueNotification(entryKey, hash, value, RemovalCause.COLLECTED); - } else if (map.expires() && map.isExpired(e)) { - // This is a duplicate check, as preWriteCleanup already purged expired - // entries, but let's accomodate an incorrect expiration queue. - enqueueNotification(entryKey, hash, value, RemovalCause.EXPIRED); - } else { - recordLockedRead(e); - return value; - } - - // immediately reuse invalid entries - evictionQueue.remove(e); - expirationQueue.remove(e); - this.count = newCount; // write-volatile - } - break; - } - } - - if (createNewEntry) { - computingValueReference = new ComputingValueReference(computingFunction); - - if (e == null) { - e = newEntry(key, hash, first); - e.setValueReference(computingValueReference); - table.set(index, e); - } else { - e.setValueReference(computingValueReference); - } - } - } finally { - unlock(); - postWriteCleanup(); - } - - if (createNewEntry) { - // This thread solely created the entry. - return compute(key, hash, e, computingValueReference); - } - } - - // The entry already exists. Wait for the computation. - checkState(!Thread.holdsLock(e), "Recursive computation"); - // don't consider expiration as we're concurrent with computation - V value = e.getValueReference().waitForValue(); - if (value != null) { - recordRead(e); - return value; - } - // else computing thread will clearValue - continue outer; - } - } finally { - postReadCleanup(); - } - } - - V compute( - K key, - int hash, - ReferenceEntry e, - ComputingValueReference computingValueReference) throws ExecutionException { - V value = null; - long start = System.nanoTime(); - long end = 0; - try { - // Synchronizes on the entry to allow failing fast when a recursive computation is - // detected. This is not fool-proof since the entry may be copied when the segment - // is written to. - synchronized (e) { - value = computingValueReference.compute(key, hash); - end = System.nanoTime(); - } - if (value != null) { - // putIfAbsent - V oldValue = put(key, hash, value, true); - if (oldValue != null) { - // the computed value was already clobbered - enqueueNotification(key, hash, value, RemovalCause.REPLACED); - } - } - return value; - } finally { - if (end == 0) { - end = System.nanoTime(); - } - if (value == null) { - clearValue(key, hash, computingValueReference); - } - } - } - } - - /** - * Used to provide computation exceptions to other threads. - */ - private static final class ComputationExceptionReference implements ValueReference { - final Throwable t; - - ComputationExceptionReference(Throwable t) { - this.t = t; - } - - @Override - public V get() { - return null; - } - - @Override - public ReferenceEntry getEntry() { - return null; - } - - @Override - public ValueReference copyFor( - ReferenceQueue queue, V value, ReferenceEntry entry) { - return this; - } - - @Override - public boolean isComputingReference() { - return false; - } - - @Override - public V waitForValue() throws ExecutionException { - throw new ExecutionException(t); - } - - @Override - public void clear(ValueReference newValue) {} - } - - /** - * Used to provide computation result to other threads. - */ - private static final class ComputedReference implements ValueReference { - final V value; - - ComputedReference(@Nullable V value) { - this.value = value; - } - - @Override - public V get() { - return value; - } - - @Override - public ReferenceEntry getEntry() { - return null; - } - - @Override - public ValueReference copyFor( - ReferenceQueue queue, V value, ReferenceEntry entry) { - return this; - } - - @Override - public boolean isComputingReference() { - return false; - } - - @Override - public V waitForValue() { - return get(); - } - - @Override - public void clear(ValueReference newValue) {} - } - - private static final class ComputingValueReference implements ValueReference { - final Function computingFunction; - - @GuardedBy("this") // writes - volatile ValueReference computedReference = unset(); - - public ComputingValueReference(Function computingFunction) { - this.computingFunction = computingFunction; - } - - @Override - public V get() { - // All computation lookups go through waitForValue. This method thus is - // only used by put, to whom we always want to appear absent. - return null; - } - - @Override - public ReferenceEntry getEntry() { - return null; - } - - @Override - public ValueReference copyFor( - ReferenceQueue queue, @Nullable V value, ReferenceEntry entry) { - return this; - } - - @Override - public boolean isComputingReference() { - return true; - } - - /** - * Waits for a computation to complete. Returns the result of the computation. - */ - @Override - public V waitForValue() throws ExecutionException { - if (computedReference == UNSET) { - boolean interrupted = false; - try { - synchronized (this) { - while (computedReference == UNSET) { - try { - wait(); - } catch (InterruptedException ie) { - interrupted = true; - } - } - } - } finally { - if (interrupted) { - Thread.currentThread().interrupt(); - } - } - } - return computedReference.waitForValue(); - } - - @Override - public void clear(ValueReference newValue) { - // The pending computation was clobbered by a manual write. Unblock all - // pending gets, and have them return the new value. - setValueReference(newValue); - - // TODO(fry): could also cancel computation if we had a thread handle - } - - V compute(K key, int hash) throws ExecutionException { - V value; - try { - value = computingFunction.apply(key); - } catch (Throwable t) { - setValueReference(new ComputationExceptionReference(t)); - throw new ExecutionException(t); - } - - setValueReference(new ComputedReference(value)); - return value; - } - - void setValueReference(ValueReference valueReference) { - synchronized (this) { - if (computedReference == UNSET) { - computedReference = valueReference; - notifyAll(); - } - } - } - } - - // Serialization Support - - private static final long serialVersionUID = 4; - - @Override - Object writeReplace() { - return new ComputingSerializationProxy( - keyStrength, - valueStrength, - keyEquivalence, - valueEquivalence, - expireAfterWriteNanos, - expireAfterAccessNanos, - maximumSize, - concurrencyLevel, - removalListener, - this, - computingFunction); - } - - static final class ComputingSerializationProxy extends AbstractSerializationProxy { - - final Function computingFunction; - - ComputingSerializationProxy( - Strength keyStrength, - Strength valueStrength, - Equivalence keyEquivalence, - Equivalence valueEquivalence, - long expireAfterWriteNanos, - long expireAfterAccessNanos, - int maximumSize, - int concurrencyLevel, - RemovalListener removalListener, - ConcurrentMap delegate, - Function computingFunction) { - super( - keyStrength, - valueStrength, - keyEquivalence, - valueEquivalence, - expireAfterWriteNanos, - expireAfterAccessNanos, - maximumSize, - concurrencyLevel, - removalListener, - delegate); - this.computingFunction = computingFunction; - } - - private void writeObject(ObjectOutputStream out) throws IOException { - out.defaultWriteObject(); - writeMapTo(out); - } - - @SuppressWarnings("deprecation") // self-use - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - in.defaultReadObject(); - MapMaker mapMaker = readMapMaker(in); - delegate = mapMaker.makeComputingMap(computingFunction); - readEntries(in); - } - - Object readResolve() { - return delegate; - } - - private static final long serialVersionUID = 4; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ConcurrentHashMultiset.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ConcurrentHashMultiset.java deleted file mode 100644 index e3cb9820e1aa..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ConcurrentHashMultiset.java +++ /dev/null @@ -1,603 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.CollectPreconditions.checkNonnegative; -import static com.google.common.collect.CollectPreconditions.checkRemove; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.Serialization.FieldSetter; -import com.google.common.math.IntMath; -import com.google.common.primitives.Ints; -import com.google.j2objc.annotations.WeakOuter; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicInteger; - -import javax.annotation.Nullable; - -/** - * A multiset that supports concurrent modifications and that provides atomic versions of most - * {@code Multiset} operations (exceptions where noted). Null elements are not supported. - * - *

See the Guava User Guide article on - * {@code Multiset}. - * - * @author Cliff L. Biffle - * @author mike nonemacher - * @since 2.0 - */ -public final class ConcurrentHashMultiset extends AbstractMultiset implements Serializable { - - /* - * The ConcurrentHashMultiset's atomic operations are implemented primarily in terms of - * AtomicInteger's atomic operations, with some help from ConcurrentMap's atomic operations on - * creation and removal (including automatic removal of zeroes). If the modification of an - * AtomicInteger results in zero, we compareAndSet the value to zero; if that succeeds, we remove - * the entry from the Map. If another operation sees a zero in the map, it knows that the entry is - * about to be removed, so this operation may remove it (often by replacing it with a new - * AtomicInteger). - */ - - /** The number of occurrences of each element. */ - private final transient ConcurrentMap countMap; - - // This constant allows the deserialization code to set a final field. This holder class - // makes sure it is not initialized unless an instance is deserialized. - private static class FieldSettersHolder { - static final FieldSetter COUNT_MAP_FIELD_SETTER = - Serialization.getFieldSetter(ConcurrentHashMultiset.class, "countMap"); - } - - /** - * Creates a new, empty {@code ConcurrentHashMultiset} using the default - * initial capacity, load factor, and concurrency settings. - */ - public static ConcurrentHashMultiset create() { - // TODO(schmoe): provide a way to use this class with other (possibly arbitrary) - // ConcurrentMap implementors. One possibility is to extract most of this class into - // an AbstractConcurrentMapMultiset. - return new ConcurrentHashMultiset(new ConcurrentHashMap()); - } - - /** - * Creates a new {@code ConcurrentHashMultiset} containing the specified elements, using - * the default initial capacity, load factor, and concurrency settings. - * - *

This implementation is highly efficient when {@code elements} is itself a {@link Multiset}. - * - * @param elements the elements that the multiset should contain - */ - public static ConcurrentHashMultiset create(Iterable elements) { - ConcurrentHashMultiset multiset = ConcurrentHashMultiset.create(); - Iterables.addAll(multiset, elements); - return multiset; - } - - /** - * Creates a new, empty {@code ConcurrentHashMultiset} using {@code mapMaker} - * to construct the internal backing map. - * - *

If this {@link MapMaker} is configured to use entry eviction of any kind, this eviction - * applies to all occurrences of a given element as a single unit. However, most updates to the - * multiset do not count as map updates at all, since we're usually just mutating the value - * stored in the map, so {@link MapMaker#expireAfterAccess} makes sense (evict the entry that - * was queried or updated longest ago), but {@link MapMaker#expireAfterWrite} doesn't, because - * the eviction time is measured from when we saw the first occurrence of the object. - * - *

The returned multiset is serializable but any serialization caveats - * given in {@code MapMaker} apply. - * - *

Finally, soft/weak values can be used but are not very useful: the values are created - * internally and not exposed externally, so no one else will have a strong reference to the - * values. Weak keys on the other hand can be useful in some scenarios. - * - * @since 15.0 (source compatible (accepting the since removed {@code GenericMapMaker} class) - * since 7.0) - */ - @Beta - public static ConcurrentHashMultiset create(MapMaker mapMaker) { - return new ConcurrentHashMultiset(mapMaker.makeMap()); - } - - /** - * Creates an instance using {@code countMap} to store elements and their counts. - * - *

This instance will assume ownership of {@code countMap}, and other code - * should not maintain references to the map or modify it in any way. - * - * @param countMap backing map for storing the elements in the multiset and - * their counts. It must be empty. - * @throws IllegalArgumentException if {@code countMap} is not empty - */ - @VisibleForTesting - ConcurrentHashMultiset(ConcurrentMap countMap) { - checkArgument(countMap.isEmpty()); - this.countMap = countMap; - } - - // Query Operations - - /** - * Returns the number of occurrences of {@code element} in this multiset. - * - * @param element the element to look for - * @return the nonnegative number of occurrences of the element - */ - @Override - public int count(@Nullable Object element) { - AtomicInteger existingCounter = Maps.safeGet(countMap, element); - return (existingCounter == null) ? 0 : existingCounter.get(); - } - - /** - * {@inheritDoc} - * - *

If the data in the multiset is modified by any other threads during this method, - * it is undefined which (if any) of these modifications will be reflected in the result. - */ - @Override - public int size() { - long sum = 0L; - for (AtomicInteger value : countMap.values()) { - sum += value.get(); - } - return Ints.saturatedCast(sum); - } - - /* - * Note: the superclass toArray() methods assume that size() gives a correct - * answer, which ours does not. - */ - - @Override - public Object[] toArray() { - return snapshot().toArray(); - } - - @Override - public T[] toArray(T[] array) { - return snapshot().toArray(array); - } - - /* - * We'd love to use 'new ArrayList(this)' or 'list.addAll(this)', but - * either of these would recurse back to us again! - */ - private List snapshot() { - List list = Lists.newArrayListWithExpectedSize(size()); - for (Multiset.Entry entry : entrySet()) { - E element = entry.getElement(); - for (int i = entry.getCount(); i > 0; i--) { - list.add(element); - } - } - return list; - } - - // Modification Operations - - /** - * Adds a number of occurrences of the specified element to this multiset. - * - * @param element the element to add - * @param occurrences the number of occurrences to add - * @return the previous count of the element before the operation; possibly zero - * @throws IllegalArgumentException if {@code occurrences} is negative, or if - * the resulting amount would exceed {@link Integer#MAX_VALUE} - */ - @Override - public int add(E element, int occurrences) { - checkNotNull(element); - if (occurrences == 0) { - return count(element); - } - CollectPreconditions.checkPositive(occurrences, "occurences"); - - while (true) { - AtomicInteger existingCounter = Maps.safeGet(countMap, element); - if (existingCounter == null) { - existingCounter = countMap.putIfAbsent(element, new AtomicInteger(occurrences)); - if (existingCounter == null) { - return 0; - } - // existingCounter != null: fall through to operate against the existing AtomicInteger - } - - while (true) { - int oldValue = existingCounter.get(); - if (oldValue != 0) { - try { - int newValue = IntMath.checkedAdd(oldValue, occurrences); - if (existingCounter.compareAndSet(oldValue, newValue)) { - // newValue can't == 0, so no need to check & remove - return oldValue; - } - } catch (ArithmeticException overflow) { - throw new IllegalArgumentException( - "Overflow adding " + occurrences + " occurrences to a count of " + oldValue); - } - } else { - // In the case of a concurrent remove, we might observe a zero value, which means another - // thread is about to remove (element, existingCounter) from the map. Rather than wait, - // we can just do that work here. - AtomicInteger newCounter = new AtomicInteger(occurrences); - if ((countMap.putIfAbsent(element, newCounter) == null) - || countMap.replace(element, existingCounter, newCounter)) { - return 0; - } - break; - } - } - - // If we're still here, there was a race, so just try again. - } - } - - /** - * Removes a number of occurrences of the specified element from this multiset. If the multiset - * contains fewer than this number of occurrences to begin with, all occurrences will be removed. - * - * @param element the element whose occurrences should be removed - * @param occurrences the number of occurrences of the element to remove - * @return the count of the element before the operation; possibly zero - * @throws IllegalArgumentException if {@code occurrences} is negative - */ - /* - * TODO(cpovirk): remove and removeExactly currently accept null inputs only - * if occurrences == 0. This satisfies both NullPointerTester and - * CollectionRemoveTester.testRemove_nullAllowed, but it's not clear that it's - * a good policy, especially because, in order for the test to pass, the - * parameter must be misleadingly annotated as @Nullable. I suspect that - * we'll want to remove @Nullable, add an eager checkNotNull, and loosen up - * testRemove_nullAllowed. - */ - @Override - public int remove(@Nullable Object element, int occurrences) { - if (occurrences == 0) { - return count(element); - } - CollectPreconditions.checkPositive(occurrences, "occurences"); - - AtomicInteger existingCounter = Maps.safeGet(countMap, element); - if (existingCounter == null) { - return 0; - } - while (true) { - int oldValue = existingCounter.get(); - if (oldValue != 0) { - int newValue = Math.max(0, oldValue - occurrences); - if (existingCounter.compareAndSet(oldValue, newValue)) { - if (newValue == 0) { - // Just CASed to 0; remove the entry to clean up the map. If the removal fails, - // another thread has already replaced it with a new counter, which is fine. - countMap.remove(element, existingCounter); - } - return oldValue; - } - } else { - return 0; - } - } - } - - /** - * Removes exactly the specified number of occurrences of {@code element}, or makes no - * change if this is not possible. - * - *

This method, in contrast to {@link #remove(Object, int)}, has no effect when the - * element count is smaller than {@code occurrences}. - * - * @param element the element to remove - * @param occurrences the number of occurrences of {@code element} to remove - * @return {@code true} if the removal was possible (including if {@code occurrences} is zero) - * @throws IllegalArgumentException if {@code occurrences} is negative - */ - public boolean removeExactly(@Nullable Object element, int occurrences) { - if (occurrences == 0) { - return true; - } - CollectPreconditions.checkPositive(occurrences, "occurences"); - - AtomicInteger existingCounter = Maps.safeGet(countMap, element); - if (existingCounter == null) { - return false; - } - while (true) { - int oldValue = existingCounter.get(); - if (oldValue < occurrences) { - return false; - } - int newValue = oldValue - occurrences; - if (existingCounter.compareAndSet(oldValue, newValue)) { - if (newValue == 0) { - // Just CASed to 0; remove the entry to clean up the map. If the removal fails, - // another thread has already replaced it with a new counter, which is fine. - countMap.remove(element, existingCounter); - } - return true; - } - } - } - - /** - * Adds or removes occurrences of {@code element} such that the {@link #count} of the - * element becomes {@code count}. - * - * @return the count of {@code element} in the multiset before this call - * @throws IllegalArgumentException if {@code count} is negative - */ - @Override - public int setCount(E element, int count) { - checkNotNull(element); - checkNonnegative(count, "count"); - while (true) { - AtomicInteger existingCounter = Maps.safeGet(countMap, element); - if (existingCounter == null) { - if (count == 0) { - return 0; - } else { - existingCounter = countMap.putIfAbsent(element, new AtomicInteger(count)); - if (existingCounter == null) { - return 0; - } - // existingCounter != null: fall through - } - } - - while (true) { - int oldValue = existingCounter.get(); - if (oldValue == 0) { - if (count == 0) { - return 0; - } else { - AtomicInteger newCounter = new AtomicInteger(count); - if ((countMap.putIfAbsent(element, newCounter) == null) - || countMap.replace(element, existingCounter, newCounter)) { - return 0; - } - } - break; - } else { - if (existingCounter.compareAndSet(oldValue, count)) { - if (count == 0) { - // Just CASed to 0; remove the entry to clean up the map. If the removal fails, - // another thread has already replaced it with a new counter, which is fine. - countMap.remove(element, existingCounter); - } - return oldValue; - } - } - } - } - } - - /** - * Sets the number of occurrences of {@code element} to {@code newCount}, but only if - * the count is currently {@code expectedOldCount}. If {@code element} does not appear - * in the multiset exactly {@code expectedOldCount} times, no changes will be made. - * - * @return {@code true} if the change was successful. This usually indicates - * that the multiset has been modified, but not always: in the case that - * {@code expectedOldCount == newCount}, the method will return {@code true} if - * the condition was met. - * @throws IllegalArgumentException if {@code expectedOldCount} or {@code newCount} is negative - */ - @Override - public boolean setCount(E element, int expectedOldCount, int newCount) { - checkNotNull(element); - checkNonnegative(expectedOldCount, "oldCount"); - checkNonnegative(newCount, "newCount"); - - AtomicInteger existingCounter = Maps.safeGet(countMap, element); - if (existingCounter == null) { - if (expectedOldCount != 0) { - return false; - } else if (newCount == 0) { - return true; - } else { - // if our write lost the race, it must have lost to a nonzero value, so we can stop - return countMap.putIfAbsent(element, new AtomicInteger(newCount)) == null; - } - } - int oldValue = existingCounter.get(); - if (oldValue == expectedOldCount) { - if (oldValue == 0) { - if (newCount == 0) { - // Just observed a 0; try to remove the entry to clean up the map - countMap.remove(element, existingCounter); - return true; - } else { - AtomicInteger newCounter = new AtomicInteger(newCount); - return (countMap.putIfAbsent(element, newCounter) == null) - || countMap.replace(element, existingCounter, newCounter); - } - } else { - if (existingCounter.compareAndSet(oldValue, newCount)) { - if (newCount == 0) { - // Just CASed to 0; remove the entry to clean up the map. If the removal fails, - // another thread has already replaced it with a new counter, which is fine. - countMap.remove(element, existingCounter); - } - return true; - } - } - } - return false; - } - - // Views - - @Override - Set createElementSet() { - final Set delegate = countMap.keySet(); - return new ForwardingSet() { - @Override - protected Set delegate() { - return delegate; - } - - @Override - public boolean contains(@Nullable Object object) { - return object != null && Collections2.safeContains(delegate, object); - } - - @Override - public boolean containsAll(Collection collection) { - return standardContainsAll(collection); - } - - @Override - public boolean remove(Object object) { - return object != null && Collections2.safeRemove(delegate, object); - } - - @Override - public boolean removeAll(Collection c) { - return standardRemoveAll(c); - } - }; - } - - @Override - public Set> createEntrySet() { - return new EntrySet(); - } - - @Override - int distinctElements() { - return countMap.size(); - } - - @Override - public boolean isEmpty() { - return countMap.isEmpty(); - } - - @Override - Iterator> entryIterator() { - // AbstractIterator makes this fairly clean, but it doesn't support remove(). To support - // remove(), we create an AbstractIterator, and then use ForwardingIterator to delegate to it. - final Iterator> readOnlyIterator = - new AbstractIterator>() { - private Iterator> mapEntries = countMap.entrySet().iterator(); - - @Override - protected Entry computeNext() { - while (true) { - if (!mapEntries.hasNext()) { - return endOfData(); - } - Map.Entry mapEntry = mapEntries.next(); - int count = mapEntry.getValue().get(); - if (count != 0) { - return Multisets.immutableEntry(mapEntry.getKey(), count); - } - } - } - }; - - return new ForwardingIterator>() { - private Entry last; - - @Override - protected Iterator> delegate() { - return readOnlyIterator; - } - - @Override - public Entry next() { - last = super.next(); - return last; - } - - @Override - public void remove() { - checkRemove(last != null); - ConcurrentHashMultiset.this.setCount(last.getElement(), 0); - last = null; - } - }; - } - - @Override - public void clear() { - countMap.clear(); - } - - @WeakOuter - private class EntrySet extends AbstractMultiset.EntrySet { - @Override - ConcurrentHashMultiset multiset() { - return ConcurrentHashMultiset.this; - } - - /* - * Note: the superclass toArray() methods assume that size() gives a correct - * answer, which ours does not. - */ - - @Override - public Object[] toArray() { - return snapshot().toArray(); - } - - @Override - public T[] toArray(T[] array) { - return snapshot().toArray(array); - } - - private List> snapshot() { - List> list = Lists.newArrayListWithExpectedSize(size()); - // Not Iterables.addAll(list, this), because that'll forward right back here. - Iterators.addAll(list, iterator()); - return list; - } - } - - /** - * @serialData the ConcurrentMap of elements and their counts. - */ - private void writeObject(ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); - stream.writeObject(countMap); - } - - private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - @SuppressWarnings("unchecked") // reading data stored by writeObject - ConcurrentMap deserializedCountMap = - (ConcurrentMap) stream.readObject(); - FieldSettersHolder.COUNT_MAP_FIELD_SETTER.set(this, deserializedCountMap); - } - - private static final long serialVersionUID = 1; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Constraint.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Constraint.java deleted file mode 100644 index d8f510a6d091..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Constraint.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -/** - * A constraint that an element must satisfy in order to be added to a - * collection. For example, {@link Constraints#notNull()}, which prevents a - * collection from including any null elements, could be implemented like this: - *

   {@code
- *
- *   public Object checkElement(Object element) {
- *     if (element == null) {
- *       throw new NullPointerException();
- *     }
- *     return element;
- *   }}
- * - *

In order to be effective, constraints should be deterministic; that is, - * they should not depend on state that can change (such as external state, - * random variables, and time) and should only depend on the value of the - * passed-in element. A non-deterministic constraint cannot reliably enforce - * that all the collection's elements meet the constraint, since the constraint - * is only enforced when elements are added. - * - * @author Mike Bostock - */ -@GwtCompatible -interface Constraint { - /** - * Throws a suitable {@code RuntimeException} if the specified element is - * illegal. Typically this is either a {@link NullPointerException}, an - * {@link IllegalArgumentException}, or a {@link ClassCastException}, though - * an application-specific exception class may be used if appropriate. - * - * @param element the element to check - * @return the provided element - */ - E checkElement(E element); - - /** - * Returns a brief human readable description of this constraint, such as - * "Not null" or "Positive number". - */ - @Override - String toString(); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Constraints.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Constraints.java deleted file mode 100644 index 505f31e6eea4..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Constraints.java +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Collection; -import java.util.List; -import java.util.ListIterator; -import java.util.RandomAccess; -import java.util.Set; -import java.util.SortedSet; - -/** - * Factories and utilities pertaining to the {@link Constraint} interface. - * - * @author Mike Bostock - * @author Jared Levy - */ -@GwtCompatible -final class Constraints { - private Constraints() {} - - /** - * Returns a constrained view of the specified collection, using the specified - * constraint. Any operations that add new elements to the collection will - * call the provided constraint. However, this method does not verify that - * existing elements satisfy the constraint. - * - *

The returned collection is not serializable. - * - * @param collection the collection to constrain - * @param constraint the constraint that validates added elements - * @return a constrained view of the collection - */ - public static Collection constrainedCollection( - Collection collection, Constraint constraint) { - return new ConstrainedCollection(collection, constraint); - } - - /** @see Constraints#constrainedCollection */ - static class ConstrainedCollection extends ForwardingCollection { - private final Collection delegate; - private final Constraint constraint; - - public ConstrainedCollection(Collection delegate, Constraint constraint) { - this.delegate = checkNotNull(delegate); - this.constraint = checkNotNull(constraint); - } - - @Override - protected Collection delegate() { - return delegate; - } - - @Override - public boolean add(E element) { - constraint.checkElement(element); - return delegate.add(element); - } - - @Override - public boolean addAll(Collection elements) { - return delegate.addAll(checkElements(elements, constraint)); - } - } - - /** - * Returns a constrained view of the specified set, using the specified - * constraint. Any operations that add new elements to the set will call the - * provided constraint. However, this method does not verify that existing - * elements satisfy the constraint. - * - *

The returned set is not serializable. - * - * @param set the set to constrain - * @param constraint the constraint that validates added elements - * @return a constrained view of the set - */ - public static Set constrainedSet(Set set, Constraint constraint) { - return new ConstrainedSet(set, constraint); - } - - /** @see Constraints#constrainedSet */ - static class ConstrainedSet extends ForwardingSet { - private final Set delegate; - private final Constraint constraint; - - public ConstrainedSet(Set delegate, Constraint constraint) { - this.delegate = checkNotNull(delegate); - this.constraint = checkNotNull(constraint); - } - - @Override - protected Set delegate() { - return delegate; - } - - @Override - public boolean add(E element) { - constraint.checkElement(element); - return delegate.add(element); - } - - @Override - public boolean addAll(Collection elements) { - return delegate.addAll(checkElements(elements, constraint)); - } - } - - /** - * Returns a constrained view of the specified sorted set, using the specified - * constraint. Any operations that add new elements to the sorted set will - * call the provided constraint. However, this method does not verify that - * existing elements satisfy the constraint. - * - *

The returned set is not serializable. - * - * @param sortedSet the sorted set to constrain - * @param constraint the constraint that validates added elements - * @return a constrained view of the sorted set - */ - public static SortedSet constrainedSortedSet( - SortedSet sortedSet, Constraint constraint) { - return new ConstrainedSortedSet(sortedSet, constraint); - } - - /** @see Constraints#constrainedSortedSet */ - private static class ConstrainedSortedSet extends ForwardingSortedSet { - final SortedSet delegate; - final Constraint constraint; - - ConstrainedSortedSet(SortedSet delegate, Constraint constraint) { - this.delegate = checkNotNull(delegate); - this.constraint = checkNotNull(constraint); - } - - @Override - protected SortedSet delegate() { - return delegate; - } - - @Override - public SortedSet headSet(E toElement) { - return constrainedSortedSet(delegate.headSet(toElement), constraint); - } - - @Override - public SortedSet subSet(E fromElement, E toElement) { - return constrainedSortedSet(delegate.subSet(fromElement, toElement), constraint); - } - - @Override - public SortedSet tailSet(E fromElement) { - return constrainedSortedSet(delegate.tailSet(fromElement), constraint); - } - - @Override - public boolean add(E element) { - constraint.checkElement(element); - return delegate.add(element); - } - - @Override - public boolean addAll(Collection elements) { - return delegate.addAll(checkElements(elements, constraint)); - } - } - - /** - * Returns a constrained view of the specified list, using the specified - * constraint. Any operations that add new elements to the list will call the - * provided constraint. However, this method does not verify that existing - * elements satisfy the constraint. - * - *

If {@code list} implements {@link RandomAccess}, so will the returned - * list. The returned list is not serializable. - * - * @param list the list to constrain - * @param constraint the constraint that validates added elements - * @return a constrained view of the list - */ - public static List constrainedList(List list, Constraint constraint) { - return (list instanceof RandomAccess) - ? new ConstrainedRandomAccessList(list, constraint) - : new ConstrainedList(list, constraint); - } - - /** @see Constraints#constrainedList */ - @GwtCompatible - private static class ConstrainedList extends ForwardingList { - final List delegate; - final Constraint constraint; - - ConstrainedList(List delegate, Constraint constraint) { - this.delegate = checkNotNull(delegate); - this.constraint = checkNotNull(constraint); - } - - @Override - protected List delegate() { - return delegate; - } - - @Override - public boolean add(E element) { - constraint.checkElement(element); - return delegate.add(element); - } - - @Override - public void add(int index, E element) { - constraint.checkElement(element); - delegate.add(index, element); - } - - @Override - public boolean addAll(Collection elements) { - return delegate.addAll(checkElements(elements, constraint)); - } - - @Override - public boolean addAll(int index, Collection elements) { - return delegate.addAll(index, checkElements(elements, constraint)); - } - - @Override - public ListIterator listIterator() { - return constrainedListIterator(delegate.listIterator(), constraint); - } - - @Override - public ListIterator listIterator(int index) { - return constrainedListIterator(delegate.listIterator(index), constraint); - } - - @Override - public E set(int index, E element) { - constraint.checkElement(element); - return delegate.set(index, element); - } - - @Override - public List subList(int fromIndex, int toIndex) { - return constrainedList(delegate.subList(fromIndex, toIndex), constraint); - } - } - - /** @see Constraints#constrainedList */ - static class ConstrainedRandomAccessList extends ConstrainedList implements RandomAccess { - ConstrainedRandomAccessList(List delegate, Constraint constraint) { - super(delegate, constraint); - } - } - - /** - * Returns a constrained view of the specified list iterator, using the - * specified constraint. Any operations that would add new elements to the - * underlying list will be verified by the constraint. - * - * @param listIterator the iterator for which to return a constrained view - * @param constraint the constraint for elements in the list - * @return a constrained view of the specified iterator - */ - private static ListIterator constrainedListIterator( - ListIterator listIterator, Constraint constraint) { - return new ConstrainedListIterator(listIterator, constraint); - } - - /** @see Constraints#constrainedListIterator */ - static class ConstrainedListIterator extends ForwardingListIterator { - private final ListIterator delegate; - private final Constraint constraint; - - public ConstrainedListIterator(ListIterator delegate, Constraint constraint) { - this.delegate = delegate; - this.constraint = constraint; - } - - @Override - protected ListIterator delegate() { - return delegate; - } - - @Override - public void add(E element) { - constraint.checkElement(element); - delegate.add(element); - } - - @Override - public void set(E element) { - constraint.checkElement(element); - delegate.set(element); - } - } - - static Collection constrainedTypePreservingCollection( - Collection collection, Constraint constraint) { - if (collection instanceof SortedSet) { - return constrainedSortedSet((SortedSet) collection, constraint); - } else if (collection instanceof Set) { - return constrainedSet((Set) collection, constraint); - } else if (collection instanceof List) { - return constrainedList((List) collection, constraint); - } else { - return constrainedCollection(collection, constraint); - } - } - - /* - * TODO(kevinb): For better performance, avoid making a copy of the elements - * by having addAll() call add() repeatedly instead. - */ - - private static Collection checkElements( - Collection elements, Constraint constraint) { - Collection copy = Lists.newArrayList(elements); - for (E element : copy) { - constraint.checkElement(element); - } - return copy; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ConsumingQueueIterator.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ConsumingQueueIterator.java deleted file mode 100644 index bf48a7d466f3..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ConsumingQueueIterator.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2015 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Collections; -import java.util.Queue; - -/** - * An Iterator implementation which draws elements from a queue, removing them from the queue as it - * iterates. - */ -@GwtCompatible -class ConsumingQueueIterator extends AbstractIterator { - private final Queue queue; - - ConsumingQueueIterator(T... elements) { - // Uses LinkedList because ArrayDeque isn't GWT-compatible for now =( - this.queue = Lists.newLinkedList(); - Collections.addAll(queue, elements); - } - - ConsumingQueueIterator(Queue queue) { - this.queue = checkNotNull(queue); - } - - @Override - public T computeNext() { - return queue.isEmpty() ? endOfData() : queue.remove(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ContiguousSet.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ContiguousSet.java deleted file mode 100644 index 1bd285683ba0..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ContiguousSet.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (C) 2010 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; - -import java.util.Collections; -import java.util.NoSuchElementException; -import java.util.Set; - -/** - * A sorted set of contiguous values in a given {@link DiscreteDomain}. - * - *

Warning: Be extremely careful what you do with conceptually large instances (such as - * {@code ContiguousSet.create(Range.greaterThan(0), DiscreteDomain.integers()}). Certain - * operations on such a set can be performed efficiently, but others (such as {@link Set#hashCode} - * or {@link Collections#frequency}) can cause major performance problems. - * - * @author Gregory Kick - * @since 10.0 - */ -@Beta -@GwtCompatible(emulated = true) -@SuppressWarnings("rawtypes") // allow ungenerified Comparable types -public abstract class ContiguousSet extends ImmutableSortedSet { - /** - * Returns a {@code ContiguousSet} containing the same values in the given domain - * {@linkplain Range#contains contained} by the range. - * - * @throws IllegalArgumentException if neither range nor the domain has a lower bound, or if - * neither has an upper bound - * - * @since 13.0 - */ - public static ContiguousSet create( - Range range, DiscreteDomain domain) { - checkNotNull(range); - checkNotNull(domain); - Range effectiveRange = range; - try { - if (!range.hasLowerBound()) { - effectiveRange = effectiveRange.intersection(Range.atLeast(domain.minValue())); - } - if (!range.hasUpperBound()) { - effectiveRange = effectiveRange.intersection(Range.atMost(domain.maxValue())); - } - } catch (NoSuchElementException e) { - throw new IllegalArgumentException(e); - } - - // Per class spec, we are allowed to throw CCE if necessary - boolean empty = - effectiveRange.isEmpty() - || Range.compareOrThrow( - range.lowerBound.leastValueAbove(domain), - range.upperBound.greatestValueBelow(domain)) - > 0; - - return empty - ? new EmptyContiguousSet(domain) - : new RegularContiguousSet(effectiveRange, domain); - } - - final DiscreteDomain domain; - - ContiguousSet(DiscreteDomain domain) { - super(Ordering.natural()); - this.domain = domain; - } - - @Override - public ContiguousSet headSet(C toElement) { - return headSetImpl(checkNotNull(toElement), false); - } - - /** - * @since 12.0 - */ - @GwtIncompatible("NavigableSet") - @Override - public ContiguousSet headSet(C toElement, boolean inclusive) { - return headSetImpl(checkNotNull(toElement), inclusive); - } - - @Override - public ContiguousSet subSet(C fromElement, C toElement) { - checkNotNull(fromElement); - checkNotNull(toElement); - checkArgument(comparator().compare(fromElement, toElement) <= 0); - return subSetImpl(fromElement, true, toElement, false); - } - - /** - * @since 12.0 - */ - @GwtIncompatible("NavigableSet") - @Override - public ContiguousSet subSet( - C fromElement, boolean fromInclusive, C toElement, boolean toInclusive) { - checkNotNull(fromElement); - checkNotNull(toElement); - checkArgument(comparator().compare(fromElement, toElement) <= 0); - return subSetImpl(fromElement, fromInclusive, toElement, toInclusive); - } - - @Override - public ContiguousSet tailSet(C fromElement) { - return tailSetImpl(checkNotNull(fromElement), true); - } - - /** - * @since 12.0 - */ - @GwtIncompatible("NavigableSet") - @Override - public ContiguousSet tailSet(C fromElement, boolean inclusive) { - return tailSetImpl(checkNotNull(fromElement), inclusive); - } - - /* - * These methods perform most headSet, subSet, and tailSet logic, besides parameter validation. - */ - // TODO(kevinb): we can probably make these real @Overrides now - /*@Override*/ - abstract ContiguousSet headSetImpl(C toElement, boolean inclusive); - - /*@Override*/ - abstract ContiguousSet subSetImpl( - C fromElement, boolean fromInclusive, C toElement, boolean toInclusive); - - /*@Override*/ - abstract ContiguousSet tailSetImpl(C fromElement, boolean inclusive); - - /** - * Returns the set of values that are contained in both this set and the other. - * - *

This method should always be used instead of - * {@link Sets#intersection} for {@link ContiguousSet} instances. - */ - public abstract ContiguousSet intersection(ContiguousSet other); - - /** - * Returns a range, closed on both ends, whose endpoints are the minimum and maximum values - * contained in this set. This is equivalent to {@code range(CLOSED, CLOSED)}. - * - * @throws NoSuchElementException if this set is empty - */ - public abstract Range range(); - - /** - * Returns the minimal range with the given boundary types for which all values in this set are - * {@linkplain Range#contains(Comparable) contained} within the range. - * - *

Note that this method will return ranges with unbounded endpoints if {@link BoundType#OPEN} - * is requested for a domain minimum or maximum. For example, if {@code set} was created from the - * range {@code [1..Integer.MAX_VALUE]} then {@code set.range(CLOSED, OPEN)} must return - * {@code [1..∞)}. - * - * @throws NoSuchElementException if this set is empty - */ - public abstract Range range(BoundType lowerBoundType, BoundType upperBoundType); - - /** Returns a short-hand representation of the contents such as {@code "[1..100]"}. */ - @Override - public String toString() { - return range().toString(); - } - - /** - * Not supported. {@code ContiguousSet} instances are constructed with {@link #create}. This - * method exists only to hide {@link ImmutableSet#builder} from consumers of {@code - * ContiguousSet}. - * - * @throws UnsupportedOperationException always - * @deprecated Use {@link #create}. - */ - @Deprecated - public static ImmutableSortedSet.Builder builder() { - throw new UnsupportedOperationException(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Count.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Count.java deleted file mode 100644 index 768e298584bf..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Count.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; - -import javax.annotation.Nullable; - -/** - * A mutable value of type {@code int}, for multisets to use in tracking counts of values. - * - * @author Louis Wasserman - */ -@GwtCompatible -final class Count implements Serializable { - private int value; - - Count(int value) { - this.value = value; - } - - public int get() { - return value; - } - - public int getAndAdd(int delta) { - int result = value; - value = result + delta; - return result; - } - - public int addAndGet(int delta) { - return value += delta; - } - - public void set(int newValue) { - value = newValue; - } - - public int getAndSet(int newValue) { - int result = value; - value = newValue; - return result; - } - - @Override - public int hashCode() { - return value; - } - - @Override - public boolean equals(@Nullable Object obj) { - return obj instanceof Count && ((Count) obj).value == value; - } - - @Override - public String toString() { - return Integer.toString(value); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Cut.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Cut.java deleted file mode 100644 index 087b23492062..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Cut.java +++ /dev/null @@ -1,458 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.primitives.Booleans; - -import java.io.Serializable; -import java.util.NoSuchElementException; - -import javax.annotation.Nullable; - -/** - * Implementation detail for the internal structure of {@link Range} instances. Represents - * a unique way of "cutting" a "number line" (actually of instances of type {@code C}, not - * necessarily "numbers") into two sections; this can be done below a certain value, above - * a certain value, below all values or above all values. With this object defined in this - * way, an interval can always be represented by a pair of {@code Cut} instances. - * - * @author Kevin Bourrillion - */ -@GwtCompatible -abstract class Cut implements Comparable>, Serializable { - final C endpoint; - - Cut(@Nullable C endpoint) { - this.endpoint = endpoint; - } - - abstract boolean isLessThan(C value); - - abstract BoundType typeAsLowerBound(); - - abstract BoundType typeAsUpperBound(); - - abstract Cut withLowerBoundType(BoundType boundType, DiscreteDomain domain); - - abstract Cut withUpperBoundType(BoundType boundType, DiscreteDomain domain); - - abstract void describeAsLowerBound(StringBuilder sb); - - abstract void describeAsUpperBound(StringBuilder sb); - - abstract C leastValueAbove(DiscreteDomain domain); - - abstract C greatestValueBelow(DiscreteDomain domain); - - /* - * The canonical form is a BelowValue cut whenever possible, otherwise ABOVE_ALL, or - * (only in the case of types that are unbounded below) BELOW_ALL. - */ - Cut canonical(DiscreteDomain domain) { - return this; - } - - // note: overriden by {BELOW,ABOVE}_ALL - @Override - public int compareTo(Cut that) { - if (that == belowAll()) { - return 1; - } - if (that == aboveAll()) { - return -1; - } - int result = Range.compareOrThrow(endpoint, that.endpoint); - if (result != 0) { - return result; - } - // same value. below comes before above - return Booleans.compare(this instanceof AboveValue, that instanceof AboveValue); - } - - C endpoint() { - return endpoint; - } - - @SuppressWarnings("unchecked") // catching CCE - @Override - public boolean equals(Object obj) { - if (obj instanceof Cut) { - // It might not really be a Cut, but we'll catch a CCE if it's not - Cut that = (Cut) obj; - try { - int compareResult = compareTo(that); - return compareResult == 0; - } catch (ClassCastException ignored) { - } - } - return false; - } - - /* - * The implementation neither produces nor consumes any non-null instance of type C, so - * casting the type parameter is safe. - */ - @SuppressWarnings("unchecked") - static Cut belowAll() { - return (Cut) BelowAll.INSTANCE; - } - - private static final long serialVersionUID = 0; - - private static final class BelowAll extends Cut> { - private static final BelowAll INSTANCE = new BelowAll(); - - private BelowAll() { - super(null); - } - - @Override - Comparable endpoint() { - throw new IllegalStateException("range unbounded on this side"); - } - - @Override - boolean isLessThan(Comparable value) { - return true; - } - - @Override - BoundType typeAsLowerBound() { - throw new IllegalStateException(); - } - - @Override - BoundType typeAsUpperBound() { - throw new AssertionError("this statement should be unreachable"); - } - - @Override - Cut> withLowerBoundType( - BoundType boundType, DiscreteDomain> domain) { - throw new IllegalStateException(); - } - - @Override - Cut> withUpperBoundType( - BoundType boundType, DiscreteDomain> domain) { - throw new AssertionError("this statement should be unreachable"); - } - - @Override - void describeAsLowerBound(StringBuilder sb) { - sb.append("(-\u221e"); - } - - @Override - void describeAsUpperBound(StringBuilder sb) { - throw new AssertionError(); - } - - @Override - Comparable leastValueAbove(DiscreteDomain> domain) { - return domain.minValue(); - } - - @Override - Comparable greatestValueBelow(DiscreteDomain> domain) { - throw new AssertionError(); - } - - @Override - Cut> canonical(DiscreteDomain> domain) { - try { - return Cut.>belowValue(domain.minValue()); - } catch (NoSuchElementException e) { - return this; - } - } - - @Override - public int compareTo(Cut> o) { - return (o == this) ? 0 : -1; - } - - @Override - public String toString() { - return "-\u221e"; - } - - private Object readResolve() { - return INSTANCE; - } - - private static final long serialVersionUID = 0; - } - - /* - * The implementation neither produces nor consumes any non-null instance of - * type C, so casting the type parameter is safe. - */ - @SuppressWarnings("unchecked") - static Cut aboveAll() { - return (Cut) AboveAll.INSTANCE; - } - - private static final class AboveAll extends Cut> { - private static final AboveAll INSTANCE = new AboveAll(); - - private AboveAll() { - super(null); - } - - @Override - Comparable endpoint() { - throw new IllegalStateException("range unbounded on this side"); - } - - @Override - boolean isLessThan(Comparable value) { - return false; - } - - @Override - BoundType typeAsLowerBound() { - throw new AssertionError("this statement should be unreachable"); - } - - @Override - BoundType typeAsUpperBound() { - throw new IllegalStateException(); - } - - @Override - Cut> withLowerBoundType( - BoundType boundType, DiscreteDomain> domain) { - throw new AssertionError("this statement should be unreachable"); - } - - @Override - Cut> withUpperBoundType( - BoundType boundType, DiscreteDomain> domain) { - throw new IllegalStateException(); - } - - @Override - void describeAsLowerBound(StringBuilder sb) { - throw new AssertionError(); - } - - @Override - void describeAsUpperBound(StringBuilder sb) { - sb.append("+\u221e)"); - } - - @Override - Comparable leastValueAbove(DiscreteDomain> domain) { - throw new AssertionError(); - } - - @Override - Comparable greatestValueBelow(DiscreteDomain> domain) { - return domain.maxValue(); - } - - @Override - public int compareTo(Cut> o) { - return (o == this) ? 0 : 1; - } - - @Override - public String toString() { - return "+\u221e"; - } - - private Object readResolve() { - return INSTANCE; - } - - private static final long serialVersionUID = 0; - } - - static Cut belowValue(C endpoint) { - return new BelowValue(endpoint); - } - - private static final class BelowValue extends Cut { - BelowValue(C endpoint) { - super(checkNotNull(endpoint)); - } - - @Override - boolean isLessThan(C value) { - return Range.compareOrThrow(endpoint, value) <= 0; - } - - @Override - BoundType typeAsLowerBound() { - return BoundType.CLOSED; - } - - @Override - BoundType typeAsUpperBound() { - return BoundType.OPEN; - } - - @Override - Cut withLowerBoundType(BoundType boundType, DiscreteDomain domain) { - switch (boundType) { - case CLOSED: - return this; - case OPEN: - @Nullable C previous = domain.previous(endpoint); - return (previous == null) ? Cut.belowAll() : new AboveValue(previous); - default: - throw new AssertionError(); - } - } - - @Override - Cut withUpperBoundType(BoundType boundType, DiscreteDomain domain) { - switch (boundType) { - case CLOSED: - @Nullable C previous = domain.previous(endpoint); - return (previous == null) ? Cut.aboveAll() : new AboveValue(previous); - case OPEN: - return this; - default: - throw new AssertionError(); - } - } - - @Override - void describeAsLowerBound(StringBuilder sb) { - sb.append('[').append(endpoint); - } - - @Override - void describeAsUpperBound(StringBuilder sb) { - sb.append(endpoint).append(')'); - } - - @Override - C leastValueAbove(DiscreteDomain domain) { - return endpoint; - } - - @Override - C greatestValueBelow(DiscreteDomain domain) { - return domain.previous(endpoint); - } - - @Override - public int hashCode() { - return endpoint.hashCode(); - } - - @Override - public String toString() { - return "\\" + endpoint + "/"; - } - - private static final long serialVersionUID = 0; - } - - static Cut aboveValue(C endpoint) { - return new AboveValue(endpoint); - } - - private static final class AboveValue extends Cut { - AboveValue(C endpoint) { - super(checkNotNull(endpoint)); - } - - @Override - boolean isLessThan(C value) { - return Range.compareOrThrow(endpoint, value) < 0; - } - - @Override - BoundType typeAsLowerBound() { - return BoundType.OPEN; - } - - @Override - BoundType typeAsUpperBound() { - return BoundType.CLOSED; - } - - @Override - Cut withLowerBoundType(BoundType boundType, DiscreteDomain domain) { - switch (boundType) { - case OPEN: - return this; - case CLOSED: - @Nullable C next = domain.next(endpoint); - return (next == null) ? Cut.belowAll() : belowValue(next); - default: - throw new AssertionError(); - } - } - - @Override - Cut withUpperBoundType(BoundType boundType, DiscreteDomain domain) { - switch (boundType) { - case OPEN: - @Nullable C next = domain.next(endpoint); - return (next == null) ? Cut.aboveAll() : belowValue(next); - case CLOSED: - return this; - default: - throw new AssertionError(); - } - } - - @Override - void describeAsLowerBound(StringBuilder sb) { - sb.append('(').append(endpoint); - } - - @Override - void describeAsUpperBound(StringBuilder sb) { - sb.append(endpoint).append(']'); - } - - @Override - C leastValueAbove(DiscreteDomain domain) { - return domain.next(endpoint); - } - - @Override - C greatestValueBelow(DiscreteDomain domain) { - return endpoint; - } - - @Override - Cut canonical(DiscreteDomain domain) { - C next = leastValueAbove(domain); - return (next != null) ? belowValue(next) : Cut.aboveAll(); - } - - @Override - public int hashCode() { - return ~endpoint.hashCode(); - } - - @Override - public String toString() { - return "/" + endpoint + "\\"; - } - - private static final long serialVersionUID = 0; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/DenseImmutableTable.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/DenseImmutableTable.java deleted file mode 100644 index 81f26ad46730..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/DenseImmutableTable.java +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.collect.ImmutableMap.IteratorBasedImmutableMap; -import com.google.j2objc.annotations.WeakOuter; - -import java.util.Map; -import java.util.Map.Entry; - -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; - -/** - * A {@code RegularImmutableTable} optimized for dense data. - */ -@GwtCompatible -@Immutable -final class DenseImmutableTable extends RegularImmutableTable { - private final ImmutableMap rowKeyToIndex; - private final ImmutableMap columnKeyToIndex; - private final ImmutableMap> rowMap; - private final ImmutableMap> columnMap; - private final int[] rowCounts; - private final int[] columnCounts; - private final V[][] values; - private final int[] iterationOrderRow; - private final int[] iterationOrderColumn; - - DenseImmutableTable( - ImmutableList> cellList, - ImmutableSet rowSpace, - ImmutableSet columnSpace) { - @SuppressWarnings("unchecked") - V[][] array = (V[][]) new Object[rowSpace.size()][columnSpace.size()]; - this.values = array; - this.rowKeyToIndex = Maps.indexMap(rowSpace); - this.columnKeyToIndex = Maps.indexMap(columnSpace); - rowCounts = new int[rowKeyToIndex.size()]; - columnCounts = new int[columnKeyToIndex.size()]; - int[] iterationOrderRow = new int[cellList.size()]; - int[] iterationOrderColumn = new int[cellList.size()]; - for (int i = 0; i < cellList.size(); i++) { - Cell cell = cellList.get(i); - R rowKey = cell.getRowKey(); - C columnKey = cell.getColumnKey(); - int rowIndex = rowKeyToIndex.get(rowKey); - int columnIndex = columnKeyToIndex.get(columnKey); - V existingValue = values[rowIndex][columnIndex]; - checkArgument(existingValue == null, "duplicate key: (%s, %s)", rowKey, columnKey); - values[rowIndex][columnIndex] = cell.getValue(); - rowCounts[rowIndex]++; - columnCounts[columnIndex]++; - iterationOrderRow[i] = rowIndex; - iterationOrderColumn[i] = columnIndex; - } - this.iterationOrderRow = iterationOrderRow; - this.iterationOrderColumn = iterationOrderColumn; - this.rowMap = new RowMap(); - this.columnMap = new ColumnMap(); - } - - /** - * An immutable map implementation backed by an indexed nullable array. - */ - private abstract static class ImmutableArrayMap extends IteratorBasedImmutableMap { - private final int size; - - ImmutableArrayMap(int size) { - this.size = size; - } - - abstract ImmutableMap keyToIndex(); - - // True if getValue never returns null. - private boolean isFull() { - return size == keyToIndex().size(); - } - - K getKey(int index) { - return keyToIndex().keySet().asList().get(index); - } - - @Nullable - abstract V getValue(int keyIndex); - - @Override - ImmutableSet createKeySet() { - return isFull() ? keyToIndex().keySet() : super.createKeySet(); - } - - @Override - public int size() { - return size; - } - - @Override - public V get(@Nullable Object key) { - Integer keyIndex = keyToIndex().get(key); - return (keyIndex == null) ? null : getValue(keyIndex); - } - - @Override - UnmodifiableIterator> entryIterator() { - return new AbstractIterator>() { - private int index = -1; - private final int maxIndex = keyToIndex().size(); - - @Override - protected Entry computeNext() { - for (index++; index < maxIndex; index++) { - V value = getValue(index); - if (value != null) { - return Maps.immutableEntry(getKey(index), value); - } - } - return endOfData(); - } - }; - } - } - - private final class Row extends ImmutableArrayMap { - private final int rowIndex; - - Row(int rowIndex) { - super(rowCounts[rowIndex]); - this.rowIndex = rowIndex; - } - - @Override - ImmutableMap keyToIndex() { - return columnKeyToIndex; - } - - @Override - V getValue(int keyIndex) { - return values[rowIndex][keyIndex]; - } - - @Override - boolean isPartialView() { - return true; - } - } - - private final class Column extends ImmutableArrayMap { - private final int columnIndex; - - Column(int columnIndex) { - super(columnCounts[columnIndex]); - this.columnIndex = columnIndex; - } - - @Override - ImmutableMap keyToIndex() { - return rowKeyToIndex; - } - - @Override - V getValue(int keyIndex) { - return values[keyIndex][columnIndex]; - } - - @Override - boolean isPartialView() { - return true; - } - } - - @WeakOuter - private final class RowMap extends ImmutableArrayMap> { - private RowMap() { - super(rowCounts.length); - } - - @Override - ImmutableMap keyToIndex() { - return rowKeyToIndex; - } - - @Override - Map getValue(int keyIndex) { - return new Row(keyIndex); - } - - @Override - boolean isPartialView() { - return false; - } - } - - @WeakOuter - private final class ColumnMap extends ImmutableArrayMap> { - private ColumnMap() { - super(columnCounts.length); - } - - @Override - ImmutableMap keyToIndex() { - return columnKeyToIndex; - } - - @Override - Map getValue(int keyIndex) { - return new Column(keyIndex); - } - - @Override - boolean isPartialView() { - return false; - } - } - - @Override - public ImmutableMap> columnMap() { - return columnMap; - } - - @Override - public ImmutableMap> rowMap() { - return rowMap; - } - - @Override - public V get(@Nullable Object rowKey, @Nullable Object columnKey) { - Integer rowIndex = rowKeyToIndex.get(rowKey); - Integer columnIndex = columnKeyToIndex.get(columnKey); - return ((rowIndex == null) || (columnIndex == null)) ? null : values[rowIndex][columnIndex]; - } - - @Override - public int size() { - return iterationOrderRow.length; - } - - @Override - Cell getCell(int index) { - int rowIndex = iterationOrderRow[index]; - int columnIndex = iterationOrderColumn[index]; - R rowKey = rowKeySet().asList().get(rowIndex); - C columnKey = columnKeySet().asList().get(columnIndex); - V value = values[rowIndex][columnIndex]; - return cellOf(rowKey, columnKey, value); - } - - @Override - V getValue(int index) { - return values[iterationOrderRow[index]][iterationOrderColumn[index]]; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/DescendingImmutableSortedMultiset.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/DescendingImmutableSortedMultiset.java deleted file mode 100644 index 0246b405890a..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/DescendingImmutableSortedMultiset.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import javax.annotation.Nullable; - -/** - * A descending wrapper around an {@code ImmutableSortedMultiset} - * - * @author Louis Wasserman - */ -@SuppressWarnings("serial") // uses writeReplace, not default serialization -final class DescendingImmutableSortedMultiset extends ImmutableSortedMultiset { - private final transient ImmutableSortedMultiset forward; - - DescendingImmutableSortedMultiset(ImmutableSortedMultiset forward) { - this.forward = forward; - } - - @Override - public int count(@Nullable Object element) { - return forward.count(element); - } - - @Override - public Entry firstEntry() { - return forward.lastEntry(); - } - - @Override - public Entry lastEntry() { - return forward.firstEntry(); - } - - @Override - public int size() { - return forward.size(); - } - - @Override - public ImmutableSortedSet elementSet() { - return forward.elementSet().descendingSet(); - } - - @Override - Entry getEntry(int index) { - return forward - .entrySet() - .asList() - .reverse() - .get(index); - } - - @Override - public ImmutableSortedMultiset descendingMultiset() { - return forward; - } - - @Override - public ImmutableSortedMultiset headMultiset(E upperBound, BoundType boundType) { - return forward.tailMultiset(upperBound, boundType).descendingMultiset(); - } - - @Override - public ImmutableSortedMultiset tailMultiset(E lowerBound, BoundType boundType) { - return forward.headMultiset(lowerBound, boundType).descendingMultiset(); - } - - @Override - boolean isPartialView() { - return forward.isPartialView(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/DescendingImmutableSortedSet.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/DescendingImmutableSortedSet.java deleted file mode 100644 index d30b0fd2bfc2..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/DescendingImmutableSortedSet.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtIncompatible; - -import javax.annotation.Nullable; - -/** - * Skeletal implementation of {@link ImmutableSortedSet#descendingSet()}. - * - * @author Louis Wasserman - */ -class DescendingImmutableSortedSet extends ImmutableSortedSet { - private final ImmutableSortedSet forward; - - DescendingImmutableSortedSet(ImmutableSortedSet forward) { - super(Ordering.from(forward.comparator()).reverse()); - this.forward = forward; - } - - @Override - public boolean contains(@Nullable Object object) { - return forward.contains(object); - } - - @Override - public int size() { - return forward.size(); - } - - @Override - public UnmodifiableIterator iterator() { - return forward.descendingIterator(); - } - - @Override - ImmutableSortedSet headSetImpl(E toElement, boolean inclusive) { - return forward.tailSet(toElement, inclusive).descendingSet(); - } - - @Override - ImmutableSortedSet subSetImpl( - E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { - return forward.subSet(toElement, toInclusive, fromElement, fromInclusive).descendingSet(); - } - - @Override - ImmutableSortedSet tailSetImpl(E fromElement, boolean inclusive) { - return forward.headSet(fromElement, inclusive).descendingSet(); - } - - @Override - @GwtIncompatible("NavigableSet") - public ImmutableSortedSet descendingSet() { - return forward; - } - - @Override - @GwtIncompatible("NavigableSet") - public UnmodifiableIterator descendingIterator() { - return forward.iterator(); - } - - @Override - @GwtIncompatible("NavigableSet") - ImmutableSortedSet createDescendingSet() { - throw new AssertionError("should never be called"); - } - - @Override - public E lower(E element) { - return forward.higher(element); - } - - @Override - public E floor(E element) { - return forward.ceiling(element); - } - - @Override - public E ceiling(E element) { - return forward.floor(element); - } - - @Override - public E higher(E element) { - return forward.lower(element); - } - - @Override - int indexOf(@Nullable Object target) { - int index = forward.indexOf(target); - if (index == -1) { - return index; - } else { - return size() - 1 - index; - } - } - - @Override - boolean isPartialView() { - return forward.isPartialView(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/DescendingMultiset.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/DescendingMultiset.java deleted file mode 100644 index 0be951b59a29..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/DescendingMultiset.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.j2objc.annotations.WeakOuter; - -import java.util.Comparator; -import java.util.Iterator; -import java.util.NavigableSet; -import java.util.Set; - -/** - * A skeleton implementation of a descending multiset. Only needs - * {@code forwardMultiset()} and {@code entryIterator()}. - * - * @author Louis Wasserman - */ -@GwtCompatible(emulated = true) -abstract class DescendingMultiset extends ForwardingMultiset implements SortedMultiset { - abstract SortedMultiset forwardMultiset(); - - private transient Comparator comparator; - - @Override - public Comparator comparator() { - Comparator result = comparator; - if (result == null) { - return comparator = Ordering.from(forwardMultiset().comparator()).reverse(); - } - return result; - } - - private transient NavigableSet elementSet; - - @Override - public NavigableSet elementSet() { - NavigableSet result = elementSet; - if (result == null) { - return elementSet = new SortedMultisets.NavigableElementSet(this); - } - return result; - } - - @Override - public Entry pollFirstEntry() { - return forwardMultiset().pollLastEntry(); - } - - @Override - public Entry pollLastEntry() { - return forwardMultiset().pollFirstEntry(); - } - - @Override - public SortedMultiset headMultiset(E toElement, BoundType boundType) { - return forwardMultiset().tailMultiset(toElement, boundType).descendingMultiset(); - } - - @Override - public SortedMultiset subMultiset( - E fromElement, BoundType fromBoundType, E toElement, BoundType toBoundType) { - return forwardMultiset() - .subMultiset(toElement, toBoundType, fromElement, fromBoundType) - .descendingMultiset(); - } - - @Override - public SortedMultiset tailMultiset(E fromElement, BoundType boundType) { - return forwardMultiset().headMultiset(fromElement, boundType).descendingMultiset(); - } - - @Override - protected Multiset delegate() { - return forwardMultiset(); - } - - @Override - public SortedMultiset descendingMultiset() { - return forwardMultiset(); - } - - @Override - public Entry firstEntry() { - return forwardMultiset().lastEntry(); - } - - @Override - public Entry lastEntry() { - return forwardMultiset().firstEntry(); - } - - abstract Iterator> entryIterator(); - - private transient Set> entrySet; - - @Override - public Set> entrySet() { - Set> result = entrySet; - return (result == null) ? entrySet = createEntrySet() : result; - } - - Set> createEntrySet() { - @WeakOuter - class EntrySetImpl extends Multisets.EntrySet { - @Override - Multiset multiset() { - return DescendingMultiset.this; - } - - @Override - public Iterator> iterator() { - return entryIterator(); - } - - @Override - public int size() { - return forwardMultiset().entrySet().size(); - } - } - return new EntrySetImpl(); - } - - @Override - public Iterator iterator() { - return Multisets.iteratorImpl(this); - } - - @Override - public Object[] toArray() { - return standardToArray(); - } - - @Override - public T[] toArray(T[] array) { - return standardToArray(array); - } - - @Override - public String toString() { - return entrySet().toString(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/DiscreteDomain.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/DiscreteDomain.java deleted file mode 100644 index 1f11dcb1891a..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/DiscreteDomain.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; -import java.math.BigInteger; -import java.util.NoSuchElementException; - -/** - * A descriptor for a discrete {@code Comparable} domain such as all - * {@link Integer} instances. A discrete domain is one that supports the three basic - * operations: {@link #next}, {@link #previous} and {@link #distance}, according - * to their specifications. The methods {@link #minValue} and {@link #maxValue} - * should also be overridden for bounded types. - * - *

A discrete domain always represents the entire set of values of its - * type; it cannot represent partial domains such as "prime integers" or - * "strings of length 5." - * - *

See the Guava User Guide section on - * {@code DiscreteDomain}. - * - * @author Kevin Bourrillion - * @since 10.0 - */ -@GwtCompatible -@Beta -public abstract class DiscreteDomain { - - /** - * Returns the discrete domain for values of type {@code Integer}. - * - * @since 14.0 (since 10.0 as {@code DiscreteDomains.integers()}) - */ - public static DiscreteDomain integers() { - return IntegerDomain.INSTANCE; - } - - private static final class IntegerDomain extends DiscreteDomain implements Serializable { - private static final IntegerDomain INSTANCE = new IntegerDomain(); - - @Override - public Integer next(Integer value) { - int i = value; - return (i == Integer.MAX_VALUE) ? null : i + 1; - } - - @Override - public Integer previous(Integer value) { - int i = value; - return (i == Integer.MIN_VALUE) ? null : i - 1; - } - - @Override - public long distance(Integer start, Integer end) { - return (long) end - start; - } - - @Override - public Integer minValue() { - return Integer.MIN_VALUE; - } - - @Override - public Integer maxValue() { - return Integer.MAX_VALUE; - } - - private Object readResolve() { - return INSTANCE; - } - - @Override - public String toString() { - return "DiscreteDomain.integers()"; - } - - private static final long serialVersionUID = 0; - } - - /** - * Returns the discrete domain for values of type {@code Long}. - * - * @since 14.0 (since 10.0 as {@code DiscreteDomains.longs()}) - */ - public static DiscreteDomain longs() { - return LongDomain.INSTANCE; - } - - private static final class LongDomain extends DiscreteDomain implements Serializable { - private static final LongDomain INSTANCE = new LongDomain(); - - @Override - public Long next(Long value) { - long l = value; - return (l == Long.MAX_VALUE) ? null : l + 1; - } - - @Override - public Long previous(Long value) { - long l = value; - return (l == Long.MIN_VALUE) ? null : l - 1; - } - - @Override - public long distance(Long start, Long end) { - long result = end - start; - if (end > start && result < 0) { // overflow - return Long.MAX_VALUE; - } - if (end < start && result > 0) { // underflow - return Long.MIN_VALUE; - } - return result; - } - - @Override - public Long minValue() { - return Long.MIN_VALUE; - } - - @Override - public Long maxValue() { - return Long.MAX_VALUE; - } - - private Object readResolve() { - return INSTANCE; - } - - @Override - public String toString() { - return "DiscreteDomain.longs()"; - } - - private static final long serialVersionUID = 0; - } - - /** - * Returns the discrete domain for values of type {@code BigInteger}. - * - * @since 15.0 - */ - public static DiscreteDomain bigIntegers() { - return BigIntegerDomain.INSTANCE; - } - - private static final class BigIntegerDomain extends DiscreteDomain - implements Serializable { - private static final BigIntegerDomain INSTANCE = new BigIntegerDomain(); - - private static final BigInteger MIN_LONG = BigInteger.valueOf(Long.MIN_VALUE); - private static final BigInteger MAX_LONG = BigInteger.valueOf(Long.MAX_VALUE); - - @Override - public BigInteger next(BigInteger value) { - return value.add(BigInteger.ONE); - } - - @Override - public BigInteger previous(BigInteger value) { - return value.subtract(BigInteger.ONE); - } - - @Override - public long distance(BigInteger start, BigInteger end) { - return end - .subtract(start) - .max(MIN_LONG) - .min(MAX_LONG) - .longValue(); - } - - private Object readResolve() { - return INSTANCE; - } - - @Override - public String toString() { - return "DiscreteDomain.bigIntegers()"; - } - - private static final long serialVersionUID = 0; - } - - /** Constructor for use by subclasses. */ - protected DiscreteDomain() {} - - /** - * Returns the unique least value of type {@code C} that is greater than - * {@code value}, or {@code null} if none exists. Inverse operation to {@link - * #previous}. - * - * @param value any value of type {@code C} - * @return the least value greater than {@code value}, or {@code null} if - * {@code value} is {@code maxValue()} - */ - public abstract C next(C value); - - /** - * Returns the unique greatest value of type {@code C} that is less than - * {@code value}, or {@code null} if none exists. Inverse operation to {@link - * #next}. - * - * @param value any value of type {@code C} - * @return the greatest value less than {@code value}, or {@code null} if - * {@code value} is {@code minValue()} - */ - public abstract C previous(C value); - - /** - * Returns a signed value indicating how many nested invocations of {@link - * #next} (if positive) or {@link #previous} (if negative) are needed to reach - * {@code end} starting from {@code start}. For example, if {@code end = - * next(next(next(start)))}, then {@code distance(start, end) == 3} and {@code - * distance(end, start) == -3}. As well, {@code distance(a, a)} is always - * zero. - * - *

Note that this function is necessarily well-defined for any discrete - * type. - * - * @return the distance as described above, or {@link Long#MIN_VALUE} or - * {@link Long#MAX_VALUE} if the distance is too small or too large, - * respectively. - */ - public abstract long distance(C start, C end); - - /** - * Returns the minimum value of type {@code C}, if it has one. The minimum - * value is the unique value for which {@link Comparable#compareTo(Object)} - * never returns a positive value for any input of type {@code C}. - * - *

The default implementation throws {@code NoSuchElementException}. - * - * @return the minimum value of type {@code C}; never null - * @throws NoSuchElementException if the type has no (practical) minimum - * value; for example, {@link java.math.BigInteger} - */ - public C minValue() { - throw new NoSuchElementException(); - } - - /** - * Returns the maximum value of type {@code C}, if it has one. The maximum - * value is the unique value for which {@link Comparable#compareTo(Object)} - * never returns a negative value for any input of type {@code C}. - * - *

The default implementation throws {@code NoSuchElementException}. - * - * @return the maximum value of type {@code C}; never null - * @throws NoSuchElementException if the type has no (practical) maximum - * value; for example, {@link java.math.BigInteger} - */ - public C maxValue() { - throw new NoSuchElementException(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/EmptyContiguousSet.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/EmptyContiguousSet.java deleted file mode 100644 index 2c08e697062a..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/EmptyContiguousSet.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; - -import java.io.Serializable; -import java.util.NoSuchElementException; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * An empty contiguous set. - * - * @author Gregory Kick - */ -@GwtCompatible(emulated = true) -@SuppressWarnings("unchecked") // allow ungenerified Comparable types -final class EmptyContiguousSet extends ContiguousSet { - EmptyContiguousSet(DiscreteDomain domain) { - super(domain); - } - - @Override - public C first() { - throw new NoSuchElementException(); - } - - @Override - public C last() { - throw new NoSuchElementException(); - } - - @Override - public int size() { - return 0; - } - - @Override - public ContiguousSet intersection(ContiguousSet other) { - return this; - } - - @Override - public Range range() { - throw new NoSuchElementException(); - } - - @Override - public Range range(BoundType lowerBoundType, BoundType upperBoundType) { - throw new NoSuchElementException(); - } - - @Override - ContiguousSet headSetImpl(C toElement, boolean inclusive) { - return this; - } - - @Override - ContiguousSet subSetImpl( - C fromElement, boolean fromInclusive, C toElement, boolean toInclusive) { - return this; - } - - @Override - ContiguousSet tailSetImpl(C fromElement, boolean fromInclusive) { - return this; - } - - @Override - public boolean contains(Object object) { - return false; - } - - @GwtIncompatible("not used by GWT emulation") - @Override - int indexOf(Object target) { - return -1; - } - - @Override - public UnmodifiableIterator iterator() { - return Iterators.emptyIterator(); - } - - @GwtIncompatible("NavigableSet") - @Override - public UnmodifiableIterator descendingIterator() { - return Iterators.emptyIterator(); - } - - @Override - boolean isPartialView() { - return false; - } - - @Override - public boolean isEmpty() { - return true; - } - - @Override - public ImmutableList asList() { - return ImmutableList.of(); - } - - @Override - public String toString() { - return "[]"; - } - - @Override - public boolean equals(@Nullable Object object) { - if (object instanceof Set) { - Set that = (Set) object; - return that.isEmpty(); - } - return false; - } - - @GwtIncompatible("not used in GWT") - @Override - boolean isHashCodeFast() { - return true; - } - - @Override - public int hashCode() { - return 0; - } - - @GwtIncompatible("serialization") - private static final class SerializedForm implements Serializable { - private final DiscreteDomain domain; - - private SerializedForm(DiscreteDomain domain) { - this.domain = domain; - } - - private Object readResolve() { - return new EmptyContiguousSet(domain); - } - - private static final long serialVersionUID = 0; - } - - @GwtIncompatible("serialization") - @Override - Object writeReplace() { - return new SerializedForm(domain); - } - - @GwtIncompatible("NavigableSet") - ImmutableSortedSet createDescendingSet() { - return ImmutableSortedSet.emptySet(Ordering.natural().reverse()); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/EmptyImmutableListMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/EmptyImmutableListMultimap.java deleted file mode 100644 index 9b167fb38772..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/EmptyImmutableListMultimap.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -/** - * Implementation of {@link ImmutableListMultimap} with no entries. - * - * @author Jared Levy - */ -@GwtCompatible(serializable = true) -class EmptyImmutableListMultimap extends ImmutableListMultimap { - static final EmptyImmutableListMultimap INSTANCE = new EmptyImmutableListMultimap(); - - private EmptyImmutableListMultimap() { - super(ImmutableMap.>of(), 0); - } - - private Object readResolve() { - return INSTANCE; // preserve singleton property - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/EmptyImmutableSetMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/EmptyImmutableSetMultimap.java deleted file mode 100644 index ec2ce2e192b8..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/EmptyImmutableSetMultimap.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -/** - * Implementation of {@link ImmutableListMultimap} with no entries. - * - * @author Mike Ward - */ -@GwtCompatible(serializable = true) -class EmptyImmutableSetMultimap extends ImmutableSetMultimap { - static final EmptyImmutableSetMultimap INSTANCE = new EmptyImmutableSetMultimap(); - - private EmptyImmutableSetMultimap() { - super(ImmutableMap.>of(), 0, null); - } - - private Object readResolve() { - return INSTANCE; // preserve singleton property - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/EnumBiMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/EnumBiMap.java deleted file mode 100644 index 7696ffead311..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/EnumBiMap.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.EnumMap; -import java.util.Map; - -/** - * A {@code BiMap} backed by two {@code EnumMap} instances. Null keys and values - * are not permitted. An {@code EnumBiMap} and its inverse are both - * serializable. - * - *

See the Guava User Guide article on - * {@code BiMap}. - * - * @author Mike Bostock - * @since 2.0 - */ -@GwtCompatible(emulated = true) -public final class EnumBiMap, V extends Enum> extends AbstractBiMap { - private transient Class keyType; - private transient Class valueType; - - /** - * Returns a new, empty {@code EnumBiMap} using the specified key and value - * types. - * - * @param keyType the key type - * @param valueType the value type - */ - public static , V extends Enum> EnumBiMap create( - Class keyType, Class valueType) { - return new EnumBiMap(keyType, valueType); - } - - /** - * Returns a new bimap with the same mappings as the specified map. If the - * specified map is an {@code EnumBiMap}, the new bimap has the same types as - * the provided map. Otherwise, the specified map must contain at least one - * mapping, in order to determine the key and value types. - * - * @param map the map whose mappings are to be placed in this map - * @throws IllegalArgumentException if map is not an {@code EnumBiMap} - * instance and contains no mappings - */ - public static , V extends Enum> EnumBiMap create(Map map) { - EnumBiMap bimap = create(inferKeyType(map), inferValueType(map)); - bimap.putAll(map); - return bimap; - } - - private EnumBiMap(Class keyType, Class valueType) { - super( - WellBehavedMap.wrap(new EnumMap(keyType)), - WellBehavedMap.wrap(new EnumMap(valueType))); - this.keyType = keyType; - this.valueType = valueType; - } - - static > Class inferKeyType(Map map) { - if (map instanceof EnumBiMap) { - return ((EnumBiMap) map).keyType(); - } - if (map instanceof EnumHashBiMap) { - return ((EnumHashBiMap) map).keyType(); - } - checkArgument(!map.isEmpty()); - return map - .keySet() - .iterator() - .next() - .getDeclaringClass(); - } - - private static > Class inferValueType(Map map) { - if (map instanceof EnumBiMap) { - return ((EnumBiMap) map).valueType; - } - checkArgument(!map.isEmpty()); - return map - .values() - .iterator() - .next() - .getDeclaringClass(); - } - - /** Returns the associated key type. */ - public Class keyType() { - return keyType; - } - - /** Returns the associated value type. */ - public Class valueType() { - return valueType; - } - - @Override - K checkKey(K key) { - return checkNotNull(key); - } - - @Override - V checkValue(V value) { - return checkNotNull(value); - } - - /** - * @serialData the key class, value class, number of entries, first key, first - * value, second key, second value, and so on. - */ - @GwtIncompatible("java.io.ObjectOutputStream") - private void writeObject(ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); - stream.writeObject(keyType); - stream.writeObject(valueType); - Serialization.writeMap(this, stream); - } - - @SuppressWarnings("unchecked") // reading fields populated by writeObject - @GwtIncompatible("java.io.ObjectInputStream") - private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - keyType = (Class) stream.readObject(); - valueType = (Class) stream.readObject(); - setDelegates( - WellBehavedMap.wrap(new EnumMap(keyType)), - WellBehavedMap.wrap(new EnumMap(valueType))); - Serialization.populateMap(this, stream); - } - - @GwtIncompatible("not needed in emulated source.") - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/EnumHashBiMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/EnumHashBiMap.java deleted file mode 100644 index 566b3fe88b50..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/EnumHashBiMap.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.Map; - -import javax.annotation.Nullable; - -/** - * A {@code BiMap} backed by an {@code EnumMap} instance for keys-to-values, and - * a {@code HashMap} instance for values-to-keys. Null keys are not permitted, - * but null values are. An {@code EnumHashBiMap} and its inverse are both - * serializable. - * - *

See the Guava User Guide article on - * {@code BiMap}. - * - * @author Mike Bostock - * @since 2.0 - */ -@GwtCompatible(emulated = true) -public final class EnumHashBiMap, V> extends AbstractBiMap { - private transient Class keyType; - - /** - * Returns a new, empty {@code EnumHashBiMap} using the specified key type. - * - * @param keyType the key type - */ - public static , V> EnumHashBiMap create(Class keyType) { - return new EnumHashBiMap(keyType); - } - - /** - * Constructs a new bimap with the same mappings as the specified map. If the - * specified map is an {@code EnumHashBiMap} or an {@link EnumBiMap}, the new - * bimap has the same key type as the input bimap. Otherwise, the specified - * map must contain at least one mapping, in order to determine the key type. - * - * @param map the map whose mappings are to be placed in this map - * @throws IllegalArgumentException if map is not an {@code EnumBiMap} or an - * {@code EnumHashBiMap} instance and contains no mappings - */ - public static , V> EnumHashBiMap create(Map map) { - EnumHashBiMap bimap = create(EnumBiMap.inferKeyType(map)); - bimap.putAll(map); - return bimap; - } - - private EnumHashBiMap(Class keyType) { - super( - WellBehavedMap.wrap(new EnumMap(keyType)), - Maps.newHashMapWithExpectedSize(keyType.getEnumConstants().length)); - this.keyType = keyType; - } - - // Overriding these 3 methods to show that values may be null (but not keys) - - @Override - K checkKey(K key) { - return checkNotNull(key); - } - - @Override - public V put(K key, @Nullable V value) { - return super.put(key, value); - } - - @Override - public V forcePut(K key, @Nullable V value) { - return super.forcePut(key, value); - } - - /** Returns the associated key type. */ - public Class keyType() { - return keyType; - } - - /** - * @serialData the key class, number of entries, first key, first value, - * second key, second value, and so on. - */ - @GwtIncompatible("java.io.ObjectOutputStream") - private void writeObject(ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); - stream.writeObject(keyType); - Serialization.writeMap(this, stream); - } - - @SuppressWarnings("unchecked") // reading field populated by writeObject - @GwtIncompatible("java.io.ObjectInputStream") - private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - keyType = (Class) stream.readObject(); - setDelegates( - WellBehavedMap.wrap(new EnumMap(keyType)), - new HashMap(keyType.getEnumConstants().length * 3 / 2)); - Serialization.populateMap(this, stream); - } - - @GwtIncompatible("only needed in emulated source.") - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/EnumMultiset.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/EnumMultiset.java deleted file mode 100644 index 1ed31a01ca35..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/EnumMultiset.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.EnumMap; -import java.util.Iterator; - -/** - * Multiset implementation backed by an {@link EnumMap}. - * - *

See the Guava User Guide article on - * {@code Multiset}. - * - * @author Jared Levy - * @since 2.0 - */ -@GwtCompatible(emulated = true) -public final class EnumMultiset> extends AbstractMapBasedMultiset { - /** Creates an empty {@code EnumMultiset}. */ - public static > EnumMultiset create(Class type) { - return new EnumMultiset(type); - } - - /** - * Creates a new {@code EnumMultiset} containing the specified elements. - * - *

This implementation is highly efficient when {@code elements} is itself a {@link - * Multiset}. - * - * @param elements the elements that the multiset should contain - * @throws IllegalArgumentException if {@code elements} is empty - */ - public static > EnumMultiset create(Iterable elements) { - Iterator iterator = elements.iterator(); - checkArgument(iterator.hasNext(), "EnumMultiset constructor passed empty Iterable"); - EnumMultiset multiset = new EnumMultiset(iterator.next().getDeclaringClass()); - Iterables.addAll(multiset, elements); - return multiset; - } - - /** - * Returns a new {@code EnumMultiset} instance containing the given elements. Unlike - * {@link EnumMultiset#create(Iterable)}, this method does not produce an exception on an empty - * iterable. - * - * @since 14.0 - */ - public static > EnumMultiset create(Iterable elements, Class type) { - EnumMultiset result = create(type); - Iterables.addAll(result, elements); - return result; - } - - private transient Class type; - - /** Creates an empty {@code EnumMultiset}. */ - private EnumMultiset(Class type) { - super(WellBehavedMap.wrap(new EnumMap(type))); - this.type = type; - } - - @GwtIncompatible("java.io.ObjectOutputStream") - private void writeObject(ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); - stream.writeObject(type); - Serialization.writeMultiset(this, stream); - } - - /** - * @serialData the {@code Class} for the enum type, the number of distinct - * elements, the first element, its count, the second element, its - * count, and so on - */ - @GwtIncompatible("java.io.ObjectInputStream") - private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - @SuppressWarnings("unchecked") // reading data stored by writeObject - Class localType = (Class) stream.readObject(); - type = localType; - setBackingMap(WellBehavedMap.wrap(new EnumMap(type))); - Serialization.populateMultiset(this, stream); - } - - @GwtIncompatible("Not needed in emulated source") - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/EvictingQueue.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/EvictingQueue.java deleted file mode 100644 index 56eaffc820e6..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/EvictingQueue.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.VisibleForTesting; - -import java.io.Serializable; -import java.util.Collection; -import java.util.Queue; - -/** - * A non-blocking queue which automatically evicts elements from the head of the queue when - * attempting to add new elements onto the queue and it is full. This data structure is logically - * equivalent to a circular buffer (i.e., cyclic buffer or ring buffer). - * - *

An evicting queue must be configured with a maximum size. Each time an element is added - * to a full queue, the queue automatically removes its head element. This is different from - * conventional bounded queues, which either block or reject new elements when full. - * - *

This class is not thread-safe, and does not accept null elements. - * - * @author Kurt Alfred Kluever - * @since 15.0 - */ -@Beta -@GwtCompatible -public final class EvictingQueue extends ForwardingQueue implements Serializable { - - private final Queue delegate; - - @VisibleForTesting final int maxSize; - - private EvictingQueue(int maxSize) { - checkArgument(maxSize >= 0, "maxSize (%s) must >= 0", maxSize); - this.delegate = Platform.newFastestQueue(maxSize); - this.maxSize = maxSize; - } - - /** - * Creates and returns a new evicting queue that will hold up to {@code maxSize} elements. - * - *

When {@code maxSize} is zero, elements will be evicted immediately after being added to the - * queue. - */ - public static EvictingQueue create(int maxSize) { - return new EvictingQueue(maxSize); - } - - /** - * Returns the number of additional elements that this queue can accept without evicting; - * zero if the queue is currently full. - * - * @since 16.0 - */ - public int remainingCapacity() { - return maxSize - size(); - } - - @Override - protected Queue delegate() { - return delegate; - } - - /** - * Adds the given element to this queue. If the queue is currently full, the element at the head - * of the queue is evicted to make room. - * - * @return {@code true} always - */ - @Override - public boolean offer(E e) { - return add(e); - } - - /** - * Adds the given element to this queue. If the queue is currently full, the element at the head - * of the queue is evicted to make room. - * - * @return {@code true} always - */ - @Override - public boolean add(E e) { - checkNotNull(e); // check before removing - if (maxSize == 0) { - return true; - } - if (size() == maxSize) { - delegate.remove(); - } - delegate.add(e); - return true; - } - - @Override - public boolean addAll(Collection collection) { - return standardAddAll(collection); - } - - @Override - public boolean contains(Object object) { - return delegate().contains(checkNotNull(object)); - } - - @Override - public boolean remove(Object object) { - return delegate().remove(checkNotNull(object)); - } - - // TODO(kak): Do we want to checkNotNull each element in containsAll, removeAll, and retainAll? - - private static final long serialVersionUID = 0L; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ExplicitOrdering.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ExplicitOrdering.java deleted file mode 100644 index d31e4a53a109..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ExplicitOrdering.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; -import java.util.List; - -import javax.annotation.Nullable; - -/** An ordering that compares objects according to a given order. */ -@GwtCompatible(serializable = true) -final class ExplicitOrdering extends Ordering implements Serializable { - final ImmutableMap rankMap; - - ExplicitOrdering(List valuesInOrder) { - this(Maps.indexMap(valuesInOrder)); - } - - ExplicitOrdering(ImmutableMap rankMap) { - this.rankMap = rankMap; - } - - @Override - public int compare(T left, T right) { - return rank(left) - rank(right); // safe because both are nonnegative - } - - private int rank(T value) { - Integer rank = rankMap.get(value); - if (rank == null) { - throw new IncomparableValueException(value); - } - return rank; - } - - @Override - public boolean equals(@Nullable Object object) { - if (object instanceof ExplicitOrdering) { - ExplicitOrdering that = (ExplicitOrdering) object; - return this.rankMap.equals(that.rankMap); - } - return false; - } - - @Override - public int hashCode() { - return rankMap.hashCode(); - } - - @Override - public String toString() { - return "Ordering.explicit(" + rankMap.keySet() + ")"; - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredEntryMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredEntryMultimap.java deleted file mode 100644 index 261c9a54de26..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredEntryMultimap.java +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Predicates.in; -import static com.google.common.base.Predicates.not; -import static com.google.common.collect.CollectPreconditions.checkNonnegative; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.MoreObjects; -import com.google.common.base.Predicate; -import com.google.common.collect.Maps.ViewCachingAbstractMap; -import com.google.j2objc.annotations.WeakOuter; - -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * Implementation of {@link Multimaps#filterEntries(Multimap, Predicate)}. - * - * @author Jared Levy - * @author Louis Wasserman - */ -@GwtCompatible -class FilteredEntryMultimap extends AbstractMultimap implements FilteredMultimap { - final Multimap unfiltered; - final Predicate> predicate; - - FilteredEntryMultimap(Multimap unfiltered, Predicate> predicate) { - this.unfiltered = checkNotNull(unfiltered); - this.predicate = checkNotNull(predicate); - } - - @Override - public Multimap unfiltered() { - return unfiltered; - } - - @Override - public Predicate> entryPredicate() { - return predicate; - } - - @Override - public int size() { - return entries().size(); - } - - private boolean satisfies(K key, V value) { - return predicate.apply(Maps.immutableEntry(key, value)); - } - - final class ValuePredicate implements Predicate { - private final K key; - - ValuePredicate(K key) { - this.key = key; - } - - @Override - public boolean apply(@Nullable V value) { - return satisfies(key, value); - } - } - - static Collection filterCollection( - Collection collection, Predicate predicate) { - if (collection instanceof Set) { - return Sets.filter((Set) collection, predicate); - } else { - return Collections2.filter(collection, predicate); - } - } - - @Override - public boolean containsKey(@Nullable Object key) { - return asMap().get(key) != null; - } - - @Override - public Collection removeAll(@Nullable Object key) { - return MoreObjects.firstNonNull(asMap().remove(key), unmodifiableEmptyCollection()); - } - - Collection unmodifiableEmptyCollection() { - // These return false, rather than throwing a UOE, on remove calls. - return (unfiltered instanceof SetMultimap) - ? Collections.emptySet() - : Collections.emptyList(); - } - - @Override - public void clear() { - entries().clear(); - } - - @Override - public Collection get(final K key) { - return filterCollection(unfiltered.get(key), new ValuePredicate(key)); - } - - @Override - Collection> createEntries() { - return filterCollection(unfiltered.entries(), predicate); - } - - @Override - Collection createValues() { - return new FilteredMultimapValues(this); - } - - @Override - Iterator> entryIterator() { - throw new AssertionError("should never be called"); - } - - @Override - Map> createAsMap() { - return new AsMap(); - } - - @Override - public Set keySet() { - return asMap().keySet(); - } - - boolean removeEntriesIf(Predicate>> predicate) { - Iterator>> entryIterator = unfiltered.asMap().entrySet().iterator(); - boolean changed = false; - while (entryIterator.hasNext()) { - Entry> entry = entryIterator.next(); - K key = entry.getKey(); - Collection collection = filterCollection(entry.getValue(), new ValuePredicate(key)); - if (!collection.isEmpty() && predicate.apply(Maps.immutableEntry(key, collection))) { - if (collection.size() == entry.getValue().size()) { - entryIterator.remove(); - } else { - collection.clear(); - } - changed = true; - } - } - return changed; - } - - @WeakOuter - class AsMap extends ViewCachingAbstractMap> { - @Override - public boolean containsKey(@Nullable Object key) { - return get(key) != null; - } - - @Override - public void clear() { - FilteredEntryMultimap.this.clear(); - } - - @Override - public Collection get(@Nullable Object key) { - Collection result = unfiltered.asMap().get(key); - if (result == null) { - return null; - } - @SuppressWarnings("unchecked") // key is equal to a K, if not a K itself - K k = (K) key; - result = filterCollection(result, new ValuePredicate(k)); - return result.isEmpty() ? null : result; - } - - @Override - public Collection remove(@Nullable Object key) { - Collection collection = unfiltered.asMap().get(key); - if (collection == null) { - return null; - } - @SuppressWarnings("unchecked") // it's definitely equal to a K - K k = (K) key; - List result = Lists.newArrayList(); - Iterator itr = collection.iterator(); - while (itr.hasNext()) { - V v = itr.next(); - if (satisfies(k, v)) { - itr.remove(); - result.add(v); - } - } - if (result.isEmpty()) { - return null; - } else if (unfiltered instanceof SetMultimap) { - return Collections.unmodifiableSet(Sets.newLinkedHashSet(result)); - } else { - return Collections.unmodifiableList(result); - } - } - - @Override - Set createKeySet() { - @WeakOuter - class KeySetImpl extends Maps.KeySet> { - KeySetImpl() { - super(AsMap.this); - } - - @Override - public boolean removeAll(Collection c) { - return removeEntriesIf(Maps.keyPredicateOnEntries(in(c))); - } - - @Override - public boolean retainAll(Collection c) { - return removeEntriesIf(Maps.keyPredicateOnEntries(not(in(c)))); - } - - @Override - public boolean remove(@Nullable Object o) { - return AsMap.this.remove(o) != null; - } - } - return new KeySetImpl(); - } - - @Override - Set>> createEntrySet() { - @WeakOuter - class EntrySetImpl extends Maps.EntrySet> { - @Override - Map> map() { - return AsMap.this; - } - - @Override - public Iterator>> iterator() { - return new AbstractIterator>>() { - final Iterator>> backingIterator = - unfiltered.asMap().entrySet().iterator(); - - @Override - protected Entry> computeNext() { - while (backingIterator.hasNext()) { - Entry> entry = backingIterator.next(); - K key = entry.getKey(); - Collection collection = - filterCollection(entry.getValue(), new ValuePredicate(key)); - if (!collection.isEmpty()) { - return Maps.immutableEntry(key, collection); - } - } - return endOfData(); - } - }; - } - - @Override - public boolean removeAll(Collection c) { - return removeEntriesIf(in(c)); - } - - @Override - public boolean retainAll(Collection c) { - return removeEntriesIf(not(in(c))); - } - - @Override - public int size() { - return Iterators.size(iterator()); - } - } - return new EntrySetImpl(); - } - - @Override - Collection> createValues() { - @WeakOuter - class ValuesImpl extends Maps.Values> { - ValuesImpl() { - super(AsMap.this); - } - - @Override - public boolean remove(@Nullable Object o) { - if (o instanceof Collection) { - Collection c = (Collection) o; - Iterator>> entryIterator = - unfiltered.asMap().entrySet().iterator(); - while (entryIterator.hasNext()) { - Entry> entry = entryIterator.next(); - K key = entry.getKey(); - Collection collection = - filterCollection(entry.getValue(), new ValuePredicate(key)); - if (!collection.isEmpty() && c.equals(collection)) { - if (collection.size() == entry.getValue().size()) { - entryIterator.remove(); - } else { - collection.clear(); - } - return true; - } - } - } - return false; - } - - @Override - public boolean removeAll(Collection c) { - return removeEntriesIf(Maps.>valuePredicateOnEntries(in(c))); - } - - @Override - public boolean retainAll(Collection c) { - return removeEntriesIf(Maps.>valuePredicateOnEntries(not(in(c)))); - } - } - return new ValuesImpl(); - } - } - - @Override - Multiset createKeys() { - return new Keys(); - } - - @WeakOuter - class Keys extends Multimaps.Keys { - Keys() { - super(FilteredEntryMultimap.this); - } - - @Override - public int remove(@Nullable Object key, int occurrences) { - checkNonnegative(occurrences, "occurrences"); - if (occurrences == 0) { - return count(key); - } - Collection collection = unfiltered.asMap().get(key); - if (collection == null) { - return 0; - } - @SuppressWarnings("unchecked") // key is equal to a K, if not a K itself - K k = (K) key; - int oldCount = 0; - Iterator itr = collection.iterator(); - while (itr.hasNext()) { - V v = itr.next(); - if (satisfies(k, v)) { - oldCount++; - if (oldCount <= occurrences) { - itr.remove(); - } - } - } - return oldCount; - } - - @Override - public Set> entrySet() { - return new Multisets.EntrySet() { - - @Override - Multiset multiset() { - return Keys.this; - } - - @Override - public Iterator> iterator() { - return Keys.this.entryIterator(); - } - - @Override - public int size() { - return FilteredEntryMultimap.this.keySet().size(); - } - - private boolean removeEntriesIf(final Predicate> predicate) { - return FilteredEntryMultimap.this - .removeEntriesIf( - new Predicate>>() { - @Override - public boolean apply(Map.Entry> entry) { - return predicate.apply( - Multisets.immutableEntry(entry.getKey(), entry.getValue().size())); - } - }); - } - - @Override - public boolean removeAll(Collection c) { - return removeEntriesIf(in(c)); - } - - @Override - public boolean retainAll(Collection c) { - return removeEntriesIf(not(in(c))); - } - }; - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredEntrySetMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredEntrySetMultimap.java deleted file mode 100644 index 674144c57b35..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredEntrySetMultimap.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Predicate; - -import java.util.Map.Entry; -import java.util.Set; - -/** - * Implementation of {@link Multimaps#filterEntries(SetMultimap, Predicate)}. - * - * @author Louis Wasserman - */ -@GwtCompatible -final class FilteredEntrySetMultimap extends FilteredEntryMultimap - implements FilteredSetMultimap { - - FilteredEntrySetMultimap(SetMultimap unfiltered, Predicate> predicate) { - super(unfiltered, predicate); - } - - @Override - public SetMultimap unfiltered() { - return (SetMultimap) unfiltered; - } - - @Override - public Set get(K key) { - return (Set) super.get(key); - } - - @Override - public Set removeAll(Object key) { - return (Set) super.removeAll(key); - } - - @Override - public Set replaceValues(K key, Iterable values) { - return (Set) super.replaceValues(key, values); - } - - @Override - Set> createEntries() { - return Sets.filter(unfiltered().entries(), entryPredicate()); - } - - @Override - public Set> entries() { - return (Set>) super.entries(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredKeyListMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredKeyListMultimap.java deleted file mode 100644 index 27041aa9997a..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredKeyListMultimap.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Predicate; - -import java.util.List; - -import javax.annotation.Nullable; - -/** - * Implementation of {@link Multimaps#filterKeys(ListMultimap, Predicate)}. - * - * @author Louis Wasserman - */ -@GwtCompatible -final class FilteredKeyListMultimap extends FilteredKeyMultimap - implements ListMultimap { - FilteredKeyListMultimap(ListMultimap unfiltered, Predicate keyPredicate) { - super(unfiltered, keyPredicate); - } - - @Override - public ListMultimap unfiltered() { - return (ListMultimap) super.unfiltered(); - } - - @Override - public List get(K key) { - return (List) super.get(key); - } - - @Override - public List removeAll(@Nullable Object key) { - return (List) super.removeAll(key); - } - - @Override - public List replaceValues(K key, Iterable values) { - return (List) super.replaceValues(key, values); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredKeyMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredKeyMultimap.java deleted file mode 100644 index 027169f776b7..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredKeyMultimap.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkPositionIndex; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Predicate; -import com.google.j2objc.annotations.WeakOuter; - -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * Implementation of {@link Multimaps#filterKeys(Multimap, Predicate)}. - * - * @author Louis Wasserman - */ -@GwtCompatible -class FilteredKeyMultimap extends AbstractMultimap implements FilteredMultimap { - final Multimap unfiltered; - final Predicate keyPredicate; - - FilteredKeyMultimap(Multimap unfiltered, Predicate keyPredicate) { - this.unfiltered = checkNotNull(unfiltered); - this.keyPredicate = checkNotNull(keyPredicate); - } - - @Override - public Multimap unfiltered() { - return unfiltered; - } - - @Override - public Predicate> entryPredicate() { - return Maps.keyPredicateOnEntries(keyPredicate); - } - - @Override - public int size() { - int size = 0; - for (Collection collection : asMap().values()) { - size += collection.size(); - } - return size; - } - - @Override - public boolean containsKey(@Nullable Object key) { - if (unfiltered.containsKey(key)) { - @SuppressWarnings("unchecked") // k is equal to a K, if not one itself - K k = (K) key; - return keyPredicate.apply(k); - } - return false; - } - - @Override - public Collection removeAll(Object key) { - return containsKey(key) ? unfiltered.removeAll(key) : unmodifiableEmptyCollection(); - } - - Collection unmodifiableEmptyCollection() { - if (unfiltered instanceof SetMultimap) { - return ImmutableSet.of(); - } else { - return ImmutableList.of(); - } - } - - @Override - public void clear() { - keySet().clear(); - } - - @Override - Set createKeySet() { - return Sets.filter(unfiltered.keySet(), keyPredicate); - } - - @Override - public Collection get(K key) { - if (keyPredicate.apply(key)) { - return unfiltered.get(key); - } else if (unfiltered instanceof SetMultimap) { - return new AddRejectingSet(key); - } else { - return new AddRejectingList(key); - } - } - - static class AddRejectingSet extends ForwardingSet { - final K key; - - AddRejectingSet(K key) { - this.key = key; - } - - @Override - public boolean add(V element) { - throw new IllegalArgumentException("Key does not satisfy predicate: " + key); - } - - @Override - public boolean addAll(Collection collection) { - checkNotNull(collection); - throw new IllegalArgumentException("Key does not satisfy predicate: " + key); - } - - @Override - protected Set delegate() { - return Collections.emptySet(); - } - } - - static class AddRejectingList extends ForwardingList { - final K key; - - AddRejectingList(K key) { - this.key = key; - } - - @Override - public boolean add(V v) { - add(0, v); - return true; - } - - @Override - public boolean addAll(Collection collection) { - addAll(0, collection); - return true; - } - - @Override - public void add(int index, V element) { - checkPositionIndex(index, 0); - throw new IllegalArgumentException("Key does not satisfy predicate: " + key); - } - - @Override - public boolean addAll(int index, Collection elements) { - checkNotNull(elements); - checkPositionIndex(index, 0); - throw new IllegalArgumentException("Key does not satisfy predicate: " + key); - } - - @Override - protected List delegate() { - return Collections.emptyList(); - } - } - - @Override - Iterator> entryIterator() { - throw new AssertionError("should never be called"); - } - - @Override - Collection> createEntries() { - return new Entries(); - } - - @WeakOuter - class Entries extends ForwardingCollection> { - @Override - protected Collection> delegate() { - return Collections2.filter(unfiltered.entries(), entryPredicate()); - } - - @Override - @SuppressWarnings("unchecked") - public boolean remove(@Nullable Object o) { - if (o instanceof Entry) { - Entry entry = (Entry) o; - if (unfiltered.containsKey(entry.getKey()) - // if this holds, then we know entry.getKey() is a K - && keyPredicate.apply((K) entry.getKey())) { - return unfiltered.remove(entry.getKey(), entry.getValue()); - } - } - return false; - } - } - - @Override - Collection createValues() { - return new FilteredMultimapValues(this); - } - - @Override - Map> createAsMap() { - return Maps.filterKeys(unfiltered.asMap(), keyPredicate); - } - - @Override - Multiset createKeys() { - return Multisets.filter(unfiltered.keys(), keyPredicate); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredKeySetMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredKeySetMultimap.java deleted file mode 100644 index 29dc13382ac0..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredKeySetMultimap.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Predicate; - -import java.util.Map.Entry; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * Implementation of {@link Multimaps#filterKeys(SetMultimap, Predicate)}. - * - * @author Louis Wasserman - */ -@GwtCompatible -final class FilteredKeySetMultimap extends FilteredKeyMultimap - implements FilteredSetMultimap { - - FilteredKeySetMultimap(SetMultimap unfiltered, Predicate keyPredicate) { - super(unfiltered, keyPredicate); - } - - @Override - public SetMultimap unfiltered() { - return (SetMultimap) unfiltered; - } - - @Override - public Set get(K key) { - return (Set) super.get(key); - } - - @Override - public Set removeAll(Object key) { - return (Set) super.removeAll(key); - } - - @Override - public Set replaceValues(K key, Iterable values) { - return (Set) super.replaceValues(key, values); - } - - @Override - public Set> entries() { - return (Set>) super.entries(); - } - - @Override - Set> createEntries() { - return new EntrySet(); - } - - class EntrySet extends Entries implements Set> { - @Override - public int hashCode() { - return Sets.hashCodeImpl(this); - } - - @Override - public boolean equals(@Nullable Object o) { - return Sets.equalsImpl(this, o); - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredMultimap.java deleted file mode 100644 index 22c2b3d3b744..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredMultimap.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Predicate; - -import java.util.Map.Entry; - -/** - * An interface for all filtered multimap types. - * - * @author Louis Wasserman - */ -@GwtCompatible -interface FilteredMultimap extends Multimap { - Multimap unfiltered(); - - Predicate> entryPredicate(); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredMultimapValues.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredMultimapValues.java deleted file mode 100644 index c34e92ff15fb..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredMultimapValues.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2013 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Objects; -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import com.google.j2objc.annotations.Weak; - -import java.util.AbstractCollection; -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; - -import javax.annotation.Nullable; - -/** - * Implementation for {@link FilteredMultimap#values()}. - * - * @author Louis Wasserman - */ -@GwtCompatible -final class FilteredMultimapValues extends AbstractCollection { - @Weak private final FilteredMultimap multimap; - - FilteredMultimapValues(FilteredMultimap multimap) { - this.multimap = checkNotNull(multimap); - } - - @Override - public Iterator iterator() { - return Maps.valueIterator(multimap.entries().iterator()); - } - - @Override - public boolean contains(@Nullable Object o) { - return multimap.containsValue(o); - } - - @Override - public int size() { - return multimap.size(); - } - - @Override - public boolean remove(@Nullable Object o) { - Predicate> entryPredicate = multimap.entryPredicate(); - for (Iterator> unfilteredItr = multimap.unfiltered().entries().iterator(); - unfilteredItr.hasNext();) { - Map.Entry entry = unfilteredItr.next(); - if (entryPredicate.apply(entry) && Objects.equal(entry.getValue(), o)) { - unfilteredItr.remove(); - return true; - } - } - return false; - } - - @Override - public boolean removeAll(Collection c) { - return Iterables.removeIf( - multimap.unfiltered().entries(), - // explicit > is required to build with JDK6 - Predicates.>and( - multimap.entryPredicate(), Maps.valuePredicateOnEntries(Predicates.in(c)))); - } - - @Override - public boolean retainAll(Collection c) { - return Iterables.removeIf( - multimap.unfiltered().entries(), - // explicit > is required to build with JDK6 - Predicates.>and( - multimap.entryPredicate(), - Maps.valuePredicateOnEntries(Predicates.not(Predicates.in(c))))); - } - - @Override - public void clear() { - multimap.clear(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredSetMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredSetMultimap.java deleted file mode 100644 index a0a149fd7d5b..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/FilteredSetMultimap.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -/** - * A supertype for filtered {@link SetMultimap} implementations. - * - * @author Louis Wasserman - */ -@GwtCompatible -interface FilteredSetMultimap extends FilteredMultimap, SetMultimap { - @Override - SetMultimap unfiltered(); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/FluentIterable.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/FluentIterable.java deleted file mode 100644 index 59c2a6436a00..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/FluentIterable.java +++ /dev/null @@ -1,716 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.base.Function; -import com.google.common.base.Joiner; -import com.google.common.base.Optional; -import com.google.common.base.Predicate; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.SortedSet; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * An expanded {@code Iterable} API, providing functionality similar to Java 8's powerful streams library in a slightly different way. - * - *

The following types of methods are provided: - * - *

    - *
  • chaining methods which return a new {@code FluentIterable} based in some way on the contents - * of the current one (for example {@link #transform}) - *
  • element extraction methods which facilitate the retrieval of certain elements (for example - * {@link #last}) - *
  • query methods which answer questions about the {@code FluentIterable}'s contents (for example - * {@link #anyMatch}) - *
  • conversion methods which copy the {@code FluentIterable}'s contents into a new collection or - * array (for example {@link #toList}) - *
- * - *

Several lesser-used features are currently available only as static methods on the {@link - * Iterables} class. - * - * - *

Comparison to streams

- * - *

Starting with Java 8, the core Java class libraries provide a new "Streams" library (in {@code - * java.util.stream}), which is similar to {@code FluentIterable} but generally more powerful. Key - * differences include: - * - *

    - *
  • A stream is single-use; it becomes invalid as soon as any "terminal operation" such as - * {@code findFirst()} or {@code iterator()} is invoked. (Even though {@code Stream} contains - * all the right method signatures to implement {@link Iterable}, it does not actually - * do so, to avoid implying repeat-iterability.) {@code FluentIterable}, on the other hand, is - * multiple-use, and does implement {@link Iterable}. - *
  • Streams offer many features not found here, including {@code min/max}, {@code - * distinct}, {@code reduce}, {@code sorted}, the very powerful {@code collect}, and built-in - * support for parallelizing stream operations. - *
  • {@code FluentIterable} contains several features not available on {@code Stream}, which are - * noted in the method descriptions below. - *
  • Streams include primitive-specialized variants such as {@code IntStream}, the use of which is - * strongly recommended. - *
  • Streams are standard Java, not requiring a third-party dependency (but do render your code - * incompatible with Java 7 and earlier). - *
- * - *

Example

- * - *

Here is an example that accepts a list from a database call, filters it based on a predicate, - * transforms it by invoking {@code toString()} on each element, and returns the first 10 elements - * as a {@code List}:

   {@code
- *
- *   List results =
- *       FluentIterable.from(database.getClientList())
- *           .filter(activeInLastMonthPredicate)
- *           .transform(Functions.toStringFunction())
- *           .limit(10)
- *           .toList();}
- * - * The approximate stream equivalent is:
   {@code
- *
- *   List results =
- *       database.getClientList()
- *           .stream()
- *           .filter(activeInLastMonthPredicate)
- *           .map(Functions.toStringFunction())
- *           .limit(10)
- *           .collect(Collectors.toList());}
- * - * @author Marcin Mikosik - * @since 12.0 - */ -@GwtCompatible(emulated = true) -public abstract class FluentIterable implements Iterable { - // We store 'iterable' and use it instead of 'this' to allow Iterables to perform instanceof - // checks on the _original_ iterable when FluentIterable.from is used. - private final Iterable iterable; - - /** Constructor for use by subclasses. */ - protected FluentIterable() { - this.iterable = this; - } - - FluentIterable(Iterable iterable) { - this.iterable = checkNotNull(iterable); - } - - /** - * Returns a fluent iterable that wraps {@code iterable}, or {@code iterable} itself if it - * is already a {@code FluentIterable}. - * - *

{@code Stream} equivalent: {@code iterable.stream()} if {@code iterable} is a - * {@link Collection}; {@code StreamSupport.stream(iterable.spliterator(), false)} otherwise. - */ - @CheckReturnValue - public static FluentIterable from(final Iterable iterable) { - return (iterable instanceof FluentIterable) - ? (FluentIterable) iterable - : new FluentIterable(iterable) { - @Override - public Iterator iterator() { - return iterable.iterator(); - } - }; - } - - /** - * Construct a fluent iterable from another fluent iterable. This is obviously never necessary, - * but is intended to help call out cases where one migration from {@code Iterable} to - * {@code FluentIterable} has obviated the need to explicitly convert to a {@code FluentIterable}. - * - * @deprecated instances of {@code FluentIterable} don't need to be converted to - * {@code FluentIterable} - */ - @Deprecated - @CheckReturnValue - public static FluentIterable from(FluentIterable iterable) { - return checkNotNull(iterable); - } - - /** - * Returns a fluent iterable containing {@code elements} in the specified order. - * - *

{@code Stream} equivalent: {@code Stream.of(elements)} or {@code - * Arrays.stream(elements)}. - * - * @since 18.0 - */ - @Beta - @CheckReturnValue - public static FluentIterable of(E[] elements) { - return from(Lists.newArrayList(elements)); - } - - /** - * Returns a string representation of this fluent iterable, with the format - * {@code [e1, e2, ..., en]}. - * - *

{@code Stream} equivalent: {@code stream.collect(Collectors.joining(", ", "[", "]"))} - * or (less efficiently) {@code collect(Collectors.toList()).toString()}. - */ - @Override - @CheckReturnValue - public String toString() { - return Iterables.toString(iterable); - } - - /** - * Returns the number of elements in this fluent iterable. - * - *

{@code Stream} equivalent: {@code stream.count()}. - */ - @CheckReturnValue - public final int size() { - return Iterables.size(iterable); - } - - /** - * Returns {@code true} if this fluent iterable contains any object for which - * {@code equals(target)} is true. - * - *

{@code Stream} equivalent: {@code stream.anyMatch(Predicate.isEqual(target))}. - */ - @CheckReturnValue - public final boolean contains(@Nullable Object target) { - return Iterables.contains(iterable, target); - } - - /** - * Returns a fluent iterable whose {@code Iterator} cycles indefinitely over the elements of - * this fluent iterable. - * - *

That iterator supports {@code remove()} if {@code iterable.iterator()} does. After - * {@code remove()} is called, subsequent cycles omit the removed element, which is no longer in - * this fluent iterable. The iterator's {@code hasNext()} method returns {@code true} until - * this fluent iterable is empty. - * - *

Warning: Typical uses of the resulting iterator may produce an infinite loop. You - * should use an explicit {@code break} or be certain that you will eventually remove all the - * elements. - * - *

{@code Stream} equivalent: if the source iterable has only a single element {@code - * element}, use {@code Stream.generate(() -> element)}. Otherwise, if the source iterable has - * a {@code stream} method (for example, if it is a {@link Collection}), use - * {@code Stream.generate(iterable::stream).flatMap(s -> s)}. - */ - @CheckReturnValue - public final FluentIterable cycle() { - return from(Iterables.cycle(iterable)); - } - - /** - * Returns a fluent iterable whose iterators traverse first the elements of this fluent iterable, - * followed by those of {@code other}. The iterators are not polled until necessary. - * - *

The returned iterable's {@code Iterator} supports {@code remove()} when the corresponding - * {@code Iterator} supports it. - * - *

{@code Stream} equivalent: {@code Stream.concat(thisStream, otherStream)}. - * - * @since 18.0 - */ - @Beta - @CheckReturnValue - public final FluentIterable append(Iterable other) { - return from(Iterables.concat(iterable, other)); - } - - /** - * Returns a fluent iterable whose iterators traverse first the elements of this fluent iterable, - * followed by {@code elements}. - * - *

{@code Stream} equivalent: {@code Stream.concat(thisStream, Stream.of(elements))}. - * - * @since 18.0 - */ - @Beta - @CheckReturnValue - public final FluentIterable append(E... elements) { - return from(Iterables.concat(iterable, Arrays.asList(elements))); - } - - /** - * Returns the elements from this fluent iterable that satisfy a predicate. The - * resulting fluent iterable's iterator does not support {@code remove()}. - * - *

{@code Stream} equivalent: {@code stream.filter(predicate)} (same). - */ - @CheckReturnValue - public final FluentIterable filter(Predicate predicate) { - return from(Iterables.filter(iterable, predicate)); - } - - /** - * Returns the elements from this fluent iterable that are instances of class {@code type}. - * - * @param type the type of elements desired - * - *

{@code Stream} equivalent:

   {@code
-   *
-   *   @SuppressWarnings("unchecked") // safe by runtime check
-   *   Stream result = (Stream) stream.filter(type::isInstance);}
- * - * ... or if {@code type} is a class literal {@code MyType.class},
   {@code
-   *
-   *   @SuppressWarnings("unchecked") // safe by runtime check
-   *   Stream result = (Stream) stream.filter(e -> e instanceof MyType);}
- */ - @GwtIncompatible("Class.isInstance") - @CheckReturnValue - public final FluentIterable filter(Class type) { - return from(Iterables.filter(iterable, type)); - } - - /** - * Returns {@code true} if any element in this fluent iterable satisfies the predicate. - * - *

{@code Stream} equivalent: {@code stream.anyMatch(predicate)} (same). - */ - @CheckReturnValue - public final boolean anyMatch(Predicate predicate) { - return Iterables.any(iterable, predicate); - } - - /** - * Returns {@code true} if every element in this fluent iterable satisfies the predicate. - * If this fluent iterable is empty, {@code true} is returned. - * - *

{@code Stream} equivalent: {@code stream.allMatch(predicate)} (same). - */ - @CheckReturnValue - public final boolean allMatch(Predicate predicate) { - return Iterables.all(iterable, predicate); - } - - /** - * Returns an {@link Optional} containing the first element in this fluent iterable that - * satisfies the given predicate, if such an element exists. - * - *

Warning: avoid using a {@code predicate} that matches {@code null}. If {@code null} - * is matched in this fluent iterable, a {@link NullPointerException} will be thrown. - * - *

{@code Stream} equivalent: {@code stream.filter(predicate).findFirst()}. - */ - @CheckReturnValue - public final Optional firstMatch(Predicate predicate) { - return Iterables.tryFind(iterable, predicate); - } - - /** - * Returns a fluent iterable that applies {@code function} to each element of this - * fluent iterable. - * - *

The returned fluent iterable's iterator supports {@code remove()} if this iterable's - * iterator does. After a successful {@code remove()} call, this fluent iterable no longer - * contains the corresponding element. - * - *

{@code Stream} equivalent: {@code stream.map(function)}. - */ - @CheckReturnValue - public final FluentIterable transform(Function function) { - return from(Iterables.transform(iterable, function)); - } - - /** - * Applies {@code function} to each element of this fluent iterable and returns - * a fluent iterable with the concatenated combination of results. {@code function} - * returns an Iterable of results. - * - *

The returned fluent iterable's iterator supports {@code remove()} if this - * function-returned iterables' iterator does. After a successful {@code remove()} call, - * the returned fluent iterable no longer contains the corresponding element. - * - *

{@code Stream} equivalent: {@code stream.flatMap(function)} (using a function that - * produces streams, not iterables). - * - * @since 13.0 (required {@code Function>} until 14.0) - */ - @CheckReturnValue - public FluentIterable transformAndConcat( - Function> function) { - return from(Iterables.concat(transform(function))); - } - - /** - * Returns an {@link Optional} containing the first element in this fluent iterable. - * If the iterable is empty, {@code Optional.absent()} is returned. - * - *

{@code Stream} equivalent: if the goal is to obtain any element, {@code - * stream.findAny()}; if it must specifically be the first element, {@code - * stream.findFirst()}. - * - * @throws NullPointerException if the first element is null; if this is a possibility, use - * {@code iterator().next()} or {@link Iterables#getFirst} instead. - */ - @CheckReturnValue - public final Optional first() { - Iterator iterator = iterable.iterator(); - return iterator.hasNext() ? Optional.of(iterator.next()) : Optional.absent(); - } - - /** - * Returns an {@link Optional} containing the last element in this fluent iterable. - * If the iterable is empty, {@code Optional.absent()} is returned. - * - *

{@code Stream} equivalent: {@code stream.reduce((a, b) -> b)}. - * - * @throws NullPointerException if the last element is null; if this is a possibility, use - * {@link Iterables#getLast} instead. - */ - @CheckReturnValue - public final Optional last() { - // Iterables#getLast was inlined here so we don't have to throw/catch a NSEE - - // TODO(kevinb): Support a concurrently modified collection? - if (iterable instanceof List) { - List list = (List) iterable; - if (list.isEmpty()) { - return Optional.absent(); - } - return Optional.of(list.get(list.size() - 1)); - } - Iterator iterator = iterable.iterator(); - if (!iterator.hasNext()) { - return Optional.absent(); - } - - /* - * TODO(kevinb): consider whether this "optimization" is worthwhile. Users - * with SortedSets tend to know they are SortedSets and probably would not - * call this method. - */ - if (iterable instanceof SortedSet) { - SortedSet sortedSet = (SortedSet) iterable; - return Optional.of(sortedSet.last()); - } - - while (true) { - E current = iterator.next(); - if (!iterator.hasNext()) { - return Optional.of(current); - } - } - } - - /** - * Returns a view of this fluent iterable that skips its first {@code numberToSkip} - * elements. If this fluent iterable contains fewer than {@code numberToSkip} elements, - * the returned fluent iterable skips all of its elements. - * - *

Modifications to this fluent iterable before a call to {@code iterator()} are - * reflected in the returned fluent iterable. That is, the its iterator skips the first - * {@code numberToSkip} elements that exist when the iterator is created, not when {@code skip()} - * is called. - * - *

The returned fluent iterable's iterator supports {@code remove()} if the - * {@code Iterator} of this fluent iterable supports it. Note that it is not - * possible to delete the last skipped element by immediately calling {@code remove()} on the - * returned fluent iterable's iterator, as the {@code Iterator} contract states that a call - * to {@code * remove()} before a call to {@code next()} will throw an - * {@link IllegalStateException}. - * - *

{@code Stream} equivalent: {@code stream.skip(numberToSkip)} (same). - */ - @CheckReturnValue - public final FluentIterable skip(int numberToSkip) { - return from(Iterables.skip(iterable, numberToSkip)); - } - - /** - * Creates a fluent iterable with the first {@code size} elements of this - * fluent iterable. If this fluent iterable does not contain that many elements, - * the returned fluent iterable will have the same behavior as this fluent iterable. - * The returned fluent iterable's iterator supports {@code remove()} if this - * fluent iterable's iterator does. - * - *

{@code Stream} equivalent: {@code stream.limit(maxSize)} (same). - * - * @param maxSize the maximum number of elements in the returned fluent iterable - * @throws IllegalArgumentException if {@code size} is negative - */ - @CheckReturnValue - public final FluentIterable limit(int maxSize) { - return from(Iterables.limit(iterable, maxSize)); - } - - /** - * Determines whether this fluent iterable is empty. - * - *

{@code Stream} equivalent: {@code !stream.findAny().isPresent()}. - */ - @CheckReturnValue - public final boolean isEmpty() { - return !iterable.iterator().hasNext(); - } - - /** - * Returns an {@code ImmutableList} containing all of the elements from this fluent iterable in - * proper sequence. - * - *

{@code Stream} equivalent: {@code ImmutableList.copyOf(stream.iterator())}. - * - * @since 14.0 (since 12.0 as {@code toImmutableList()}). - */ - @CheckReturnValue - public final ImmutableList toList() { - return ImmutableList.copyOf(iterable); - } - - /** - * Returns an {@code ImmutableList} containing all of the elements from this {@code - * FluentIterable} in the order specified by {@code comparator}. To produce an {@code - * ImmutableList} sorted by its natural ordering, use {@code toSortedList(Ordering.natural())}. - * - *

{@code Stream} equivalent: - * {@code ImmutableList.copyOf(stream.sorted(comparator).iterator())}. - * - * @param comparator the function by which to sort list elements - * @throws NullPointerException if any element is null - * @since 14.0 (since 13.0 as {@code toSortedImmutableList()}). - */ - @CheckReturnValue - public final ImmutableList toSortedList(Comparator comparator) { - return Ordering.from(comparator).immutableSortedCopy(iterable); - } - - /** - * Returns an {@code ImmutableSet} containing all of the elements from this fluent iterable with - * duplicates removed. - * - *

{@code Stream} equivalent: {@code ImmutableSet.copyOf(stream.iterator())}. - * - * @since 14.0 (since 12.0 as {@code toImmutableSet()}). - */ - @CheckReturnValue - public final ImmutableSet toSet() { - return ImmutableSet.copyOf(iterable); - } - - /** - * Returns an {@code ImmutableSortedSet} containing all of the elements from this {@code - * FluentIterable} in the order specified by {@code comparator}, with duplicates (determined by - * {@code comparator.compare(x, y) == 0}) removed. To produce an {@code ImmutableSortedSet} sorted - * by its natural ordering, use {@code toSortedSet(Ordering.natural())}. - * - *

{@code Stream} equivalent: - * {@code ImmutableSortedSet.copyOf(comparator, stream.iterator())}. - * - * @param comparator the function by which to sort set elements - * @throws NullPointerException if any element is null - * @since 14.0 (since 12.0 as {@code toImmutableSortedSet()}). - */ - @CheckReturnValue - public final ImmutableSortedSet toSortedSet(Comparator comparator) { - return ImmutableSortedSet.copyOf(comparator, iterable); - } - - /** - * Returns an {@code ImmutableMultiset} containing all of the elements from this fluent iterable. - * - *

{@code Stream} equivalent: {@code ImmutableMultiset.copyOf(stream.iterator())}. - * - * @since 19.0 - */ - @CheckReturnValue - public final ImmutableMultiset toMultiset() { - return ImmutableMultiset.copyOf(iterable); - } - - /** - * Returns an immutable map whose keys are the distinct elements of this {@code FluentIterable} - * and whose value for each key was computed by {@code valueFunction}. The map's iteration order - * is the order of the first appearance of each key in this iterable. - * - *

When there are multiple instances of a key in this iterable, it is unspecified whether - * {@code valueFunction} will be applied to more than one instance of that key and, if it is, - * which result will be mapped to that key in the returned map. - * - *

{@code Stream} equivalent: {@code - * ImmutableMap.copyOf(stream.collect(Collectors.toMap(k -> k, valueFunction)))} (but note that - * this may not preserve the order of entries). - * - * @throws NullPointerException if any element of this iterable is {@code null}, or if {@code - * valueFunction} produces {@code null} for any key - * @since 14.0 - */ - @CheckReturnValue - public final ImmutableMap toMap(Function valueFunction) { - return Maps.toMap(iterable, valueFunction); - } - - /** - * Creates an index {@code ImmutableListMultimap} that contains the results of applying a - * specified function to each item in this {@code FluentIterable} of values. Each element of this - * iterable will be stored as a value in the resulting multimap, yielding a multimap with the same - * size as this iterable. The key used to store that value in the multimap will be the result of - * calling the function on that value. The resulting multimap is created as an immutable snapshot. - * In the returned multimap, keys appear in the order they are first encountered, and the values - * corresponding to each key appear in the same order as they are encountered. - * - * @param keyFunction the function used to produce the key for each value - * @throws NullPointerException if any of the following cases is true: - *

    - *
  • {@code keyFunction} is null - *
  • An element in this fluent iterable is null - *
  • {@code keyFunction} returns {@code null} for any element of this iterable - *
- * - *

{@code Stream} equivalent: {@code stream.collect(Collectors.groupingBy(keyFunction))} - * behaves similarly, but returns a mutable {@code Map>} instead, and may not preserve - * the order of entries). - * - * @since 14.0 - */ - @CheckReturnValue - public final ImmutableListMultimap index(Function keyFunction) { - return Multimaps.index(iterable, keyFunction); - } - - /** - * Returns a map with the contents of this {@code FluentIterable} as its {@code values}, indexed - * by keys derived from those values. In other words, each input value produces an entry in the - * map whose key is the result of applying {@code keyFunction} to that value. These entries appear - * in the same order as they appeared in this fluent iterable. Example usage: - *

   {@code
-   *
-   *   Color red = new Color("red", 255, 0, 0);
-   *   ...
-   *   FluentIterable allColors = FluentIterable.from(ImmutableSet.of(red, green, blue));
-   *
-   *   Map colorForName = allColors.uniqueIndex(toStringFunction());
-   *   assertThat(colorForName).containsEntry("red", red);}
- * - *

If your index may associate multiple values with each key, use {@link #index(Function) - * index}. - * - *

{@code Stream} equivalent: {@code - * ImmutableMap.copyOf(stream.collect(Collectors.toMap(keyFunction, v -> v)))} (but note that this - * may not preserve the order of entries). - * - * @param keyFunction the function used to produce the key for each value - * @return a map mapping the result of evaluating the function {@code - * keyFunction} on each value in this fluent iterable to that value - * @throws IllegalArgumentException if {@code keyFunction} produces the same - * key for more than one value in this fluent iterable - * @throws NullPointerException if any elements of this fluent iterable is null, or - * if {@code keyFunction} produces {@code null} for any value - * @since 14.0 - */ - @CheckReturnValue - public final ImmutableMap uniqueIndex(Function keyFunction) { - return Maps.uniqueIndex(iterable, keyFunction); - } - - /** - * Returns an array containing all of the elements from this fluent iterable in iteration order. - * - *

{@code Stream} equivalent: if an object array is acceptable, use - * {@code stream.toArray()}; if {@code type} is a class literal such as {@code MyType.class}, use - * {@code stream.toArray(MyType[]::new)}. Otherwise use {@code stream.toArray( - * len -> (E[]) Array.newInstance(type, len))}. - * - * @param type the type of the elements - * @return a newly-allocated array into which all the elements of this fluent iterable have - * been copied - */ - @GwtIncompatible("Array.newArray(Class, int)") - @CheckReturnValue - public final E[] toArray(Class type) { - return Iterables.toArray(iterable, type); - } - - /** - * Copies all the elements from this fluent iterable to {@code collection}. This is equivalent to - * calling {@code Iterables.addAll(collection, this)}. - * - *

{@code Stream} equivalent: {@code stream.forEachOrdered(collection::add)} or - * {@code stream.forEach(collection::add)}. - * - * @param collection the collection to copy elements to - * @return {@code collection}, for convenience - * @since 14.0 - */ - public final > C copyInto(C collection) { - checkNotNull(collection); - if (iterable instanceof Collection) { - collection.addAll(Collections2.cast(iterable)); - } else { - for (E item : iterable) { - collection.add(item); - } - } - return collection; - } - - /** - * Returns a {@link String} containing all of the elements of this fluent iterable joined with - * {@code joiner}. - * - *

{@code Stream} equivalent: {@code joiner.join(stream.iterator())}, or, if you are not - * using any optional {@code Joiner} features, - * {@code stream.collect(Collectors.joining(delimiter)}. - * - * @since 18.0 - */ - @Beta - @CheckReturnValue - public final String join(Joiner joiner) { - return joiner.join(this); - } - - /** - * Returns the element at the specified position in this fluent iterable. - * - *

{@code Stream} equivalent: {@code stream.skip(position).findFirst().get()} (but note - * that this throws different exception types, and throws an exception if {@code null} would be - * returned). - * - * @param position position of the element to return - * @return the element at the specified position in this fluent iterable - * @throws IndexOutOfBoundsException if {@code position} is negative or greater than or equal to - * the size of this fluent iterable - */ - // TODO(kevinb): add @Nullable? - @CheckReturnValue - public final E get(int position) { - return Iterables.get(iterable, position); - } - - /** - * Function that transforms {@code Iterable} into a fluent iterable. - */ - private static class FromIterableFunction implements Function, FluentIterable> { - @Override - public FluentIterable apply(Iterable fromObject) { - return FluentIterable.from(fromObject); - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingBlockingDeque.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingBlockingDeque.java deleted file mode 100644 index ad3a21e364d9..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingBlockingDeque.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import java.util.Collection; -import java.util.concurrent.BlockingDeque; -import java.util.concurrent.TimeUnit; - -/** - * A {@link BlockingDeque} which forwards all its method calls to another {@code BlockingDeque}. - * Subclasses should override one or more methods to modify the behavior of the backing deque as - * desired per the decorator pattern. - * - *

Warning: The methods of {@code ForwardingBlockingDeque} forward - * indiscriminately to the methods of the delegate. For example, overriding {@link #add} - * alone will not change the behaviour of {@link #offer} which can lead to unexpected - * behaviour. In this case, you should override {@code offer} as well, either providing your own - * implementation, or delegating to the provided {@code standardOffer} method. - * - *

- * The {@code standard} methods are not guaranteed to be thread-safe, even when all of the methods - * that they depend on are thread-safe. - * - * @author Emily Soldal - * @since 14.0 - */ -public abstract class ForwardingBlockingDeque extends ForwardingDeque - implements BlockingDeque { - - /** Constructor for use by subclasses. */ - protected ForwardingBlockingDeque() {} - - @Override - protected abstract BlockingDeque delegate(); - - @Override - public int remainingCapacity() { - return delegate().remainingCapacity(); - } - - @Override - public void putFirst(E e) throws InterruptedException { - delegate().putFirst(e); - } - - @Override - public void putLast(E e) throws InterruptedException { - delegate().putLast(e); - } - - @Override - public boolean offerFirst(E e, long timeout, TimeUnit unit) throws InterruptedException { - return delegate().offerFirst(e, timeout, unit); - } - - @Override - public boolean offerLast(E e, long timeout, TimeUnit unit) throws InterruptedException { - return delegate().offerLast(e, timeout, unit); - } - - @Override - public E takeFirst() throws InterruptedException { - return delegate().takeFirst(); - } - - @Override - public E takeLast() throws InterruptedException { - return delegate().takeLast(); - } - - @Override - public E pollFirst(long timeout, TimeUnit unit) throws InterruptedException { - return delegate().pollFirst(timeout, unit); - } - - @Override - public E pollLast(long timeout, TimeUnit unit) throws InterruptedException { - return delegate().pollLast(timeout, unit); - } - - @Override - public void put(E e) throws InterruptedException { - delegate().put(e); - } - - @Override - public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException { - return delegate().offer(e, timeout, unit); - } - - @Override - public E take() throws InterruptedException { - return delegate().take(); - } - - @Override - public E poll(long timeout, TimeUnit unit) throws InterruptedException { - return delegate().poll(timeout, unit); - } - - @Override - public int drainTo(Collection c) { - return delegate().drainTo(c); - } - - @Override - public int drainTo(Collection c, int maxElements) { - return delegate().drainTo(c, maxElements); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingCollection.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingCollection.java deleted file mode 100644 index 434e471e9300..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingCollection.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Objects; - -import java.util.Collection; -import java.util.Iterator; - -import javax.annotation.Nullable; - -/** - * A collection which forwards all its method calls to another collection. - * Subclasses should override one or more methods to modify the behavior of the - * backing collection as desired per the decorator pattern. - * - *

Warning: The methods of {@code ForwardingCollection} forward - * indiscriminately to the methods of the delegate. For example, - * overriding {@link #add} alone will not change the behavior of {@link - * #addAll}, which can lead to unexpected behavior. In this case, you should - * override {@code addAll} as well, either providing your own implementation, or - * delegating to the provided {@code standardAddAll} method. - * - *

The {@code standard} methods are not guaranteed to be thread-safe, even - * when all of the methods that they depend on are thread-safe. - * - * @author Kevin Bourrillion - * @author Louis Wasserman - * @since 2.0 - */ -@GwtCompatible -public abstract class ForwardingCollection extends ForwardingObject implements Collection { - // TODO(lowasser): identify places where thread safety is actually lost - - /** Constructor for use by subclasses. */ - protected ForwardingCollection() {} - - @Override - protected abstract Collection delegate(); - - @Override - public Iterator iterator() { - return delegate().iterator(); - } - - @Override - public int size() { - return delegate().size(); - } - - @Override - public boolean removeAll(Collection collection) { - return delegate().removeAll(collection); - } - - @Override - public boolean isEmpty() { - return delegate().isEmpty(); - } - - @Override - public boolean contains(Object object) { - return delegate().contains(object); - } - - @Override - public boolean add(E element) { - return delegate().add(element); - } - - @Override - public boolean remove(Object object) { - return delegate().remove(object); - } - - @Override - public boolean containsAll(Collection collection) { - return delegate().containsAll(collection); - } - - @Override - public boolean addAll(Collection collection) { - return delegate().addAll(collection); - } - - @Override - public boolean retainAll(Collection collection) { - return delegate().retainAll(collection); - } - - @Override - public void clear() { - delegate().clear(); - } - - @Override - public Object[] toArray() { - return delegate().toArray(); - } - - @Override - public T[] toArray(T[] array) { - return delegate().toArray(array); - } - - /** - * A sensible definition of {@link #contains} in terms of {@link #iterator}. - * If you override {@link #iterator}, you may wish to override {@link - * #contains} to forward to this implementation. - * - * @since 7.0 - */ - protected boolean standardContains(@Nullable Object object) { - return Iterators.contains(iterator(), object); - } - - /** - * A sensible definition of {@link #containsAll} in terms of {@link #contains} - * . If you override {@link #contains}, you may wish to override {@link - * #containsAll} to forward to this implementation. - * - * @since 7.0 - */ - protected boolean standardContainsAll(Collection collection) { - return Collections2.containsAllImpl(this, collection); - } - - /** - * A sensible definition of {@link #addAll} in terms of {@link #add}. If you - * override {@link #add}, you may wish to override {@link #addAll} to forward - * to this implementation. - * - * @since 7.0 - */ - protected boolean standardAddAll(Collection collection) { - return Iterators.addAll(this, collection.iterator()); - } - - /** - * A sensible definition of {@link #remove} in terms of {@link #iterator}, - * using the iterator's {@code remove} method. If you override {@link - * #iterator}, you may wish to override {@link #remove} to forward to this - * implementation. - * - * @since 7.0 - */ - protected boolean standardRemove(@Nullable Object object) { - Iterator iterator = iterator(); - while (iterator.hasNext()) { - if (Objects.equal(iterator.next(), object)) { - iterator.remove(); - return true; - } - } - return false; - } - - /** - * A sensible definition of {@link #removeAll} in terms of {@link #iterator}, - * using the iterator's {@code remove} method. If you override {@link - * #iterator}, you may wish to override {@link #removeAll} to forward to this - * implementation. - * - * @since 7.0 - */ - protected boolean standardRemoveAll(Collection collection) { - return Iterators.removeAll(iterator(), collection); - } - - /** - * A sensible definition of {@link #retainAll} in terms of {@link #iterator}, - * using the iterator's {@code remove} method. If you override {@link - * #iterator}, you may wish to override {@link #retainAll} to forward to this - * implementation. - * - * @since 7.0 - */ - protected boolean standardRetainAll(Collection collection) { - return Iterators.retainAll(iterator(), collection); - } - - /** - * A sensible definition of {@link #clear} in terms of {@link #iterator}, - * using the iterator's {@code remove} method. If you override {@link - * #iterator}, you may wish to override {@link #clear} to forward to this - * implementation. - * - * @since 7.0 - */ - protected void standardClear() { - Iterators.clear(iterator()); - } - - /** - * A sensible definition of {@link #isEmpty} as {@code !iterator().hasNext}. - * If you override {@link #isEmpty}, you may wish to override {@link #isEmpty} - * to forward to this implementation. Alternately, it may be more efficient to - * implement {@code isEmpty} as {@code size() == 0}. - * - * @since 7.0 - */ - protected boolean standardIsEmpty() { - return !iterator().hasNext(); - } - - /** - * A sensible definition of {@link #toString} in terms of {@link #iterator}. - * If you override {@link #iterator}, you may wish to override {@link - * #toString} to forward to this implementation. - * - * @since 7.0 - */ - protected String standardToString() { - return Collections2.toStringImpl(this); - } - - /** - * A sensible definition of {@link #toArray()} in terms of {@link - * #toArray(Object[])}. If you override {@link #toArray(Object[])}, you may - * wish to override {@link #toArray} to forward to this implementation. - * - * @since 7.0 - */ - protected Object[] standardToArray() { - Object[] newArray = new Object[size()]; - return toArray(newArray); - } - - /** - * A sensible definition of {@link #toArray(Object[])} in terms of {@link - * #size} and {@link #iterator}. If you override either of these methods, you - * may wish to override {@link #toArray} to forward to this implementation. - * - * @since 7.0 - */ - protected T[] standardToArray(T[] array) { - return ObjectArrays.toArrayImpl(this, array); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingConcurrentMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingConcurrentMap.java deleted file mode 100644 index de420660e3fc..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingConcurrentMap.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.concurrent.ConcurrentMap; - -/** - * A concurrent map which forwards all its method calls to another concurrent - * map. Subclasses should override one or more methods to modify the behavior of - * the backing map as desired per the decorator pattern. - * - * @author Charles Fry - * @since 2.0 - */ -@GwtCompatible -public abstract class ForwardingConcurrentMap extends ForwardingMap - implements ConcurrentMap { - - /** Constructor for use by subclasses. */ - protected ForwardingConcurrentMap() {} - - @Override - protected abstract ConcurrentMap delegate(); - - @Override - public V putIfAbsent(K key, V value) { - return delegate().putIfAbsent(key, value); - } - - @Override - public boolean remove(Object key, Object value) { - return delegate().remove(key, value); - } - - @Override - public V replace(K key, V value) { - return delegate().replace(key, value); - } - - @Override - public boolean replace(K key, V oldValue, V newValue) { - return delegate().replace(key, oldValue, newValue); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingDeque.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingDeque.java deleted file mode 100644 index a58636a7704b..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingDeque.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import java.util.Deque; -import java.util.Iterator; - -/** - * A deque which forwards all its method calls to another deque. Subclasses - * should override one or more methods to modify the behavior of the backing - * deque as desired per the decorator pattern. - * - *

Warning: The methods of {@code ForwardingDeque} forward - * indiscriminately to the methods of the delegate. For example, - * overriding {@link #add} alone will not change the behavior of {@link - * #offer} which can lead to unexpected behavior. In this case, you should - * override {@code offer} as well. - * - * @author Kurt Alfred Kluever - * @since 12.0 - */ -public abstract class ForwardingDeque extends ForwardingQueue implements Deque { - - /** Constructor for use by subclasses. */ - protected ForwardingDeque() {} - - @Override - protected abstract Deque delegate(); - - @Override - public void addFirst(E e) { - delegate().addFirst(e); - } - - @Override - public void addLast(E e) { - delegate().addLast(e); - } - - @Override - public Iterator descendingIterator() { - return delegate().descendingIterator(); - } - - @Override - public E getFirst() { - return delegate().getFirst(); - } - - @Override - public E getLast() { - return delegate().getLast(); - } - - @Override - public boolean offerFirst(E e) { - return delegate().offerFirst(e); - } - - @Override - public boolean offerLast(E e) { - return delegate().offerLast(e); - } - - @Override - public E peekFirst() { - return delegate().peekFirst(); - } - - @Override - public E peekLast() { - return delegate().peekLast(); - } - - @Override - public E pollFirst() { - return delegate().pollFirst(); - } - - @Override - public E pollLast() { - return delegate().pollLast(); - } - - @Override - public E pop() { - return delegate().pop(); - } - - @Override - public void push(E e) { - delegate().push(e); - } - - @Override - public E removeFirst() { - return delegate().removeFirst(); - } - - @Override - public E removeLast() { - return delegate().removeLast(); - } - - @Override - public boolean removeFirstOccurrence(Object o) { - return delegate().removeFirstOccurrence(o); - } - - @Override - public boolean removeLastOccurrence(Object o) { - return delegate().removeLastOccurrence(o); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingImmutableCollection.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingImmutableCollection.java deleted file mode 100644 index 90489a4a8ee3..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingImmutableCollection.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2010 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -/** - * Dummy class that makes the GWT serialization policy happy. It isn't used - * on the server-side. - * - * @author Hayward Chan - */ -@GwtCompatible(emulated = true) -class ForwardingImmutableCollection { - private ForwardingImmutableCollection() {} -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingImmutableList.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingImmutableList.java deleted file mode 100644 index 2b9092ea4c93..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingImmutableList.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -/** - * Unused stub class, unreferenced under Java and manually emulated under GWT. - * - * @author Chris Povirk - */ -@GwtCompatible(emulated = true) -abstract class ForwardingImmutableList { - private ForwardingImmutableList() {} -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingImmutableMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingImmutableMap.java deleted file mode 100644 index a36715743f0a..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingImmutableMap.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -/** - * Unused stub class, unreferenced under Java and manually emulated under GWT. - * - * @author Chris Povirk - */ -@GwtCompatible(emulated = true) -abstract class ForwardingImmutableMap { - private ForwardingImmutableMap() {} -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingImmutableSet.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingImmutableSet.java deleted file mode 100644 index c7d7bf6d778b..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingImmutableSet.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -/** - * Unused stub class, unreferenced under Java and manually emulated under GWT. - * - * @author Chris Povirk - */ -@GwtCompatible(emulated = true) -abstract class ForwardingImmutableSet { - private ForwardingImmutableSet() {} -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingIterator.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingIterator.java deleted file mode 100644 index 03cbc75cb0a1..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingIterator.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Iterator; - -/** - * An iterator which forwards all its method calls to another iterator. - * Subclasses should override one or more methods to modify the behavior of the - * backing iterator as desired per the decorator pattern. - * - * @author Kevin Bourrillion - * @since 2.0 - */ -@GwtCompatible -public abstract class ForwardingIterator extends ForwardingObject implements Iterator { - - /** Constructor for use by subclasses. */ - protected ForwardingIterator() {} - - @Override - protected abstract Iterator delegate(); - - @Override - public boolean hasNext() { - return delegate().hasNext(); - } - - @Override - public T next() { - return delegate().next(); - } - - @Override - public void remove() { - delegate().remove(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingList.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingList.java deleted file mode 100644 index 288340fe8271..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingList.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; - -import javax.annotation.Nullable; - -/** - * A list which forwards all its method calls to another list. Subclasses should - * override one or more methods to modify the behavior of the backing list as - * desired per the decorator pattern. - * - *

This class does not implement {@link java.util.RandomAccess}. If the - * delegate supports random access, the {@code ForwardingList} subclass should - * implement the {@code RandomAccess} interface. - * - *

Warning: The methods of {@code ForwardingList} forward - * indiscriminately to the methods of the delegate. For example, - * overriding {@link #add} alone will not change the behavior of {@link - * #addAll}, which can lead to unexpected behavior. In this case, you should - * override {@code addAll} as well, either providing your own implementation, or - * delegating to the provided {@code standardAddAll} method. - * - *

The {@code standard} methods and any collection views they return are not - * guaranteed to be thread-safe, even when all of the methods that they depend - * on are thread-safe. - * - * @author Mike Bostock - * @author Louis Wasserman - * @since 2.0 - */ -@GwtCompatible -public abstract class ForwardingList extends ForwardingCollection implements List { - // TODO(lowasser): identify places where thread safety is actually lost - - /** Constructor for use by subclasses. */ - protected ForwardingList() {} - - @Override - protected abstract List delegate(); - - @Override - public void add(int index, E element) { - delegate().add(index, element); - } - - @Override - public boolean addAll(int index, Collection elements) { - return delegate().addAll(index, elements); - } - - @Override - public E get(int index) { - return delegate().get(index); - } - - @Override - public int indexOf(Object element) { - return delegate().indexOf(element); - } - - @Override - public int lastIndexOf(Object element) { - return delegate().lastIndexOf(element); - } - - @Override - public ListIterator listIterator() { - return delegate().listIterator(); - } - - @Override - public ListIterator listIterator(int index) { - return delegate().listIterator(index); - } - - @Override - public E remove(int index) { - return delegate().remove(index); - } - - @Override - public E set(int index, E element) { - return delegate().set(index, element); - } - - @Override - public List subList(int fromIndex, int toIndex) { - return delegate().subList(fromIndex, toIndex); - } - - @Override - public boolean equals(@Nullable Object object) { - return object == this || delegate().equals(object); - } - - @Override - public int hashCode() { - return delegate().hashCode(); - } - - /** - * A sensible default implementation of {@link #add(Object)}, in terms of - * {@link #add(int, Object)}. If you override {@link #add(int, Object)}, you - * may wish to override {@link #add(Object)} to forward to this - * implementation. - * - * @since 7.0 - */ - protected boolean standardAdd(E element) { - add(size(), element); - return true; - } - - /** - * A sensible default implementation of {@link #addAll(int, Collection)}, in - * terms of the {@code add} method of {@link #listIterator(int)}. If you - * override {@link #listIterator(int)}, you may wish to override {@link - * #addAll(int, Collection)} to forward to this implementation. - * - * @since 7.0 - */ - protected boolean standardAddAll(int index, Iterable elements) { - return Lists.addAllImpl(this, index, elements); - } - - /** - * A sensible default implementation of {@link #indexOf}, in terms of {@link - * #listIterator()}. If you override {@link #listIterator()}, you may wish to - * override {@link #indexOf} to forward to this implementation. - * - * @since 7.0 - */ - protected int standardIndexOf(@Nullable Object element) { - return Lists.indexOfImpl(this, element); - } - - /** - * A sensible default implementation of {@link #lastIndexOf}, in terms of - * {@link #listIterator(int)}. If you override {@link #listIterator(int)}, you - * may wish to override {@link #lastIndexOf} to forward to this - * implementation. - * - * @since 7.0 - */ - protected int standardLastIndexOf(@Nullable Object element) { - return Lists.lastIndexOfImpl(this, element); - } - - /** - * A sensible default implementation of {@link #iterator}, in terms of - * {@link #listIterator()}. If you override {@link #listIterator()}, you may - * wish to override {@link #iterator} to forward to this implementation. - * - * @since 7.0 - */ - protected Iterator standardIterator() { - return listIterator(); - } - - /** - * A sensible default implementation of {@link #listIterator()}, in terms of - * {@link #listIterator(int)}. If you override {@link #listIterator(int)}, you - * may wish to override {@link #listIterator()} to forward to this - * implementation. - * - * @since 7.0 - */ - protected ListIterator standardListIterator() { - return listIterator(0); - } - - /** - * A sensible default implementation of {@link #listIterator(int)}, in terms - * of {@link #size}, {@link #get(int)}, {@link #set(int, Object)}, {@link - * #add(int, Object)}, and {@link #remove(int)}. If you override any of these - * methods, you may wish to override {@link #listIterator(int)} to forward to - * this implementation. - * - * @since 7.0 - */ - @Beta - protected ListIterator standardListIterator(int start) { - return Lists.listIteratorImpl(this, start); - } - - /** - * A sensible default implementation of {@link #subList(int, int)}. If you - * override any other methods, you may wish to override {@link #subList(int, - * int)} to forward to this implementation. - * - * @since 7.0 - */ - @Beta - protected List standardSubList(int fromIndex, int toIndex) { - return Lists.subListImpl(this, fromIndex, toIndex); - } - - /** - * A sensible definition of {@link #equals(Object)} in terms of {@link #size} - * and {@link #iterator}. If you override either of those methods, you may - * wish to override {@link #equals(Object)} to forward to this implementation. - * - * @since 7.0 - */ - @Beta - protected boolean standardEquals(@Nullable Object object) { - return Lists.equalsImpl(this, object); - } - - /** - * A sensible definition of {@link #hashCode} in terms of {@link #iterator}. - * If you override {@link #iterator}, you may wish to override {@link - * #hashCode} to forward to this implementation. - * - * @since 7.0 - */ - @Beta - protected int standardHashCode() { - return Lists.hashCodeImpl(this); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingListIterator.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingListIterator.java deleted file mode 100644 index b7239ba88233..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingListIterator.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.ListIterator; - -/** - * A list iterator which forwards all its method calls to another list - * iterator. Subclasses should override one or more methods to modify the - * behavior of the backing iterator as desired per the decorator pattern. - * - * @author Mike Bostock - * @since 2.0 - */ -@GwtCompatible -public abstract class ForwardingListIterator extends ForwardingIterator - implements ListIterator { - - /** Constructor for use by subclasses. */ - protected ForwardingListIterator() {} - - @Override - protected abstract ListIterator delegate(); - - @Override - public void add(E element) { - delegate().add(element); - } - - @Override - public boolean hasPrevious() { - return delegate().hasPrevious(); - } - - @Override - public int nextIndex() { - return delegate().nextIndex(); - } - - @Override - public E previous() { - return delegate().previous(); - } - - @Override - public int previousIndex() { - return delegate().previousIndex(); - } - - @Override - public void set(E element) { - delegate().set(element); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingListMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingListMultimap.java deleted file mode 100644 index 477af9922124..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingListMultimap.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2010 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.List; - -import javax.annotation.Nullable; - -/** - * A list multimap which forwards all its method calls to another list multimap. - * Subclasses should override one or more methods to modify the behavior of - * the backing multimap as desired per the decorator pattern. - * - * @author Kurt Alfred Kluever - * @since 3.0 - */ -@GwtCompatible -public abstract class ForwardingListMultimap extends ForwardingMultimap - implements ListMultimap { - - /** Constructor for use by subclasses. */ - protected ForwardingListMultimap() {} - - @Override - protected abstract ListMultimap delegate(); - - @Override - public List get(@Nullable K key) { - return delegate().get(key); - } - - @Override - public List removeAll(@Nullable Object key) { - return delegate().removeAll(key); - } - - @Override - public List replaceValues(K key, Iterable values) { - return delegate().replaceValues(key, values); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingMap.java deleted file mode 100644 index c550789fc535..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingMap.java +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Objects; - -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * A map which forwards all its method calls to another map. Subclasses should - * override one or more methods to modify the behavior of the backing map as - * desired per the decorator pattern. - * - *

Warning: The methods of {@code ForwardingMap} forward - * indiscriminately to the methods of the delegate. For example, - * overriding {@link #put} alone will not change the behavior of {@link - * #putAll}, which can lead to unexpected behavior. In this case, you should - * override {@code putAll} as well, either providing your own implementation, or - * delegating to the provided {@code standardPutAll} method. - * - *

Each of the {@code standard} methods, where appropriate, use {@link - * Objects#equal} to test equality for both keys and values. This may not be - * the desired behavior for map implementations that use non-standard notions of - * key equality, such as a {@code SortedMap} whose comparator is not consistent - * with {@code equals}. - * - *

The {@code standard} methods and the collection views they return are not - * guaranteed to be thread-safe, even when all of the methods that they depend - * on are thread-safe. - * - * @author Kevin Bourrillion - * @author Jared Levy - * @author Louis Wasserman - * @since 2.0 - */ -@GwtCompatible -public abstract class ForwardingMap extends ForwardingObject implements Map { - // TODO(lowasser): identify places where thread safety is actually lost - - /** Constructor for use by subclasses. */ - protected ForwardingMap() {} - - @Override - protected abstract Map delegate(); - - @Override - public int size() { - return delegate().size(); - } - - @Override - public boolean isEmpty() { - return delegate().isEmpty(); - } - - @Override - public V remove(Object object) { - return delegate().remove(object); - } - - @Override - public void clear() { - delegate().clear(); - } - - @Override - public boolean containsKey(@Nullable Object key) { - return delegate().containsKey(key); - } - - @Override - public boolean containsValue(@Nullable Object value) { - return delegate().containsValue(value); - } - - @Override - public V get(@Nullable Object key) { - return delegate().get(key); - } - - @Override - public V put(K key, V value) { - return delegate().put(key, value); - } - - @Override - public void putAll(Map map) { - delegate().putAll(map); - } - - @Override - public Set keySet() { - return delegate().keySet(); - } - - @Override - public Collection values() { - return delegate().values(); - } - - @Override - public Set> entrySet() { - return delegate().entrySet(); - } - - @Override - public boolean equals(@Nullable Object object) { - return object == this || delegate().equals(object); - } - - @Override - public int hashCode() { - return delegate().hashCode(); - } - - /** - * A sensible definition of {@link #putAll(Map)} in terms of {@link - * #put(Object, Object)}. If you override {@link #put(Object, Object)}, you - * may wish to override {@link #putAll(Map)} to forward to this - * implementation. - * - * @since 7.0 - */ - protected void standardPutAll(Map map) { - Maps.putAllImpl(this, map); - } - - /** - * A sensible, albeit inefficient, definition of {@link #remove} in terms of - * the {@code iterator} method of {@link #entrySet}. If you override {@link - * #entrySet}, you may wish to override {@link #remove} to forward to this - * implementation. - * - *

Alternately, you may wish to override {@link #remove} with {@code - * keySet().remove}, assuming that approach would not lead to an infinite - * loop. - * - * @since 7.0 - */ - @Beta - protected V standardRemove(@Nullable Object key) { - Iterator> entryIterator = entrySet().iterator(); - while (entryIterator.hasNext()) { - Entry entry = entryIterator.next(); - if (Objects.equal(entry.getKey(), key)) { - V value = entry.getValue(); - entryIterator.remove(); - return value; - } - } - return null; - } - - /** - * A sensible definition of {@link #clear} in terms of the {@code iterator} - * method of {@link #entrySet}. In many cases, you may wish to override - * {@link #clear} to forward to this implementation. - * - * @since 7.0 - */ - protected void standardClear() { - Iterators.clear(entrySet().iterator()); - } - - /** - * A sensible implementation of {@link Map#keySet} in terms of the following - * methods: {@link ForwardingMap#clear}, {@link ForwardingMap#containsKey}, - * {@link ForwardingMap#isEmpty}, {@link ForwardingMap#remove}, {@link - * ForwardingMap#size}, and the {@link Set#iterator} method of {@link - * ForwardingMap#entrySet}. In many cases, you may wish to override {@link - * ForwardingMap#keySet} to forward to this implementation or a subclass - * thereof. - * - * @since 10.0 - */ - @Beta - protected class StandardKeySet extends Maps.KeySet { - /** Constructor for use by subclasses. */ - public StandardKeySet() { - super(ForwardingMap.this); - } - } - - /** - * A sensible, albeit inefficient, definition of {@link #containsKey} in terms - * of the {@code iterator} method of {@link #entrySet}. If you override {@link - * #entrySet}, you may wish to override {@link #containsKey} to forward to - * this implementation. - * - * @since 7.0 - */ - @Beta - protected boolean standardContainsKey(@Nullable Object key) { - return Maps.containsKeyImpl(this, key); - } - - /** - * A sensible implementation of {@link Map#values} in terms of the following - * methods: {@link ForwardingMap#clear}, {@link ForwardingMap#containsValue}, - * {@link ForwardingMap#isEmpty}, {@link ForwardingMap#size}, and the {@link - * Set#iterator} method of {@link ForwardingMap#entrySet}. In many cases, you - * may wish to override {@link ForwardingMap#values} to forward to this - * implementation or a subclass thereof. - * - * @since 10.0 - */ - @Beta - protected class StandardValues extends Maps.Values { - /** Constructor for use by subclasses. */ - public StandardValues() { - super(ForwardingMap.this); - } - } - - /** - * A sensible definition of {@link #containsValue} in terms of the {@code - * iterator} method of {@link #entrySet}. If you override {@link #entrySet}, - * you may wish to override {@link #containsValue} to forward to this - * implementation. - * - * @since 7.0 - */ - protected boolean standardContainsValue(@Nullable Object value) { - return Maps.containsValueImpl(this, value); - } - - /** - * A sensible implementation of {@link Map#entrySet} in terms of the following - * methods: {@link ForwardingMap#clear}, {@link ForwardingMap#containsKey}, - * {@link ForwardingMap#get}, {@link ForwardingMap#isEmpty}, {@link - * ForwardingMap#remove}, and {@link ForwardingMap#size}. In many cases, you - * may wish to override {@link #entrySet} to forward to this implementation - * or a subclass thereof. - * - * @since 10.0 - */ - @Beta - protected abstract class StandardEntrySet extends Maps.EntrySet { - /** Constructor for use by subclasses. */ - public StandardEntrySet() {} - - @Override - Map map() { - return ForwardingMap.this; - } - } - - /** - * A sensible definition of {@link #isEmpty} in terms of the {@code iterator} - * method of {@link #entrySet}. If you override {@link #entrySet}, you may - * wish to override {@link #isEmpty} to forward to this implementation. - * - * @since 7.0 - */ - protected boolean standardIsEmpty() { - return !entrySet().iterator().hasNext(); - } - - /** - * A sensible definition of {@link #equals} in terms of the {@code equals} - * method of {@link #entrySet}. If you override {@link #entrySet}, you may - * wish to override {@link #equals} to forward to this implementation. - * - * @since 7.0 - */ - protected boolean standardEquals(@Nullable Object object) { - return Maps.equalsImpl(this, object); - } - - /** - * A sensible definition of {@link #hashCode} in terms of the {@code iterator} - * method of {@link #entrySet}. If you override {@link #entrySet}, you may - * wish to override {@link #hashCode} to forward to this implementation. - * - * @since 7.0 - */ - protected int standardHashCode() { - return Sets.hashCodeImpl(entrySet()); - } - - /** - * A sensible definition of {@link #toString} in terms of the {@code iterator} - * method of {@link #entrySet}. If you override {@link #entrySet}, you may - * wish to override {@link #toString} to forward to this implementation. - * - * @since 7.0 - */ - protected String standardToString() { - return Maps.toStringImpl(this); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingMapEntry.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingMapEntry.java deleted file mode 100644 index 559f0bbc6bef..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingMapEntry.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Objects; - -import java.util.Map; -import java.util.Map.Entry; - -import javax.annotation.Nullable; - -/** - * A map entry which forwards all its method calls to another map entry. - * Subclasses should override one or more methods to modify the behavior of the - * backing map entry as desired per the decorator pattern. - * - *

Warning: The methods of {@code ForwardingMapEntry} forward - * indiscriminately to the methods of the delegate. For example, - * overriding {@link #getValue} alone will not change the behavior of - * {@link #equals}, which can lead to unexpected behavior. In this case, you - * should override {@code equals} as well, either providing your own - * implementation, or delegating to the provided {@code standardEquals} method. - * - *

Each of the {@code standard} methods, where appropriate, use {@link - * Objects#equal} to test equality for both keys and values. This may not be - * the desired behavior for map implementations that use non-standard notions of - * key equality, such as the entry of a {@code SortedMap} whose comparator is - * not consistent with {@code equals}. - * - *

The {@code standard} methods are not guaranteed to be thread-safe, even - * when all of the methods that they depend on are thread-safe. - * - * @author Mike Bostock - * @author Louis Wasserman - * @since 2.0 - */ -@GwtCompatible -public abstract class ForwardingMapEntry extends ForwardingObject implements Map.Entry { - // TODO(lowasser): identify places where thread safety is actually lost - - /** Constructor for use by subclasses. */ - protected ForwardingMapEntry() {} - - @Override - protected abstract Map.Entry delegate(); - - @Override - public K getKey() { - return delegate().getKey(); - } - - @Override - public V getValue() { - return delegate().getValue(); - } - - @Override - public V setValue(V value) { - return delegate().setValue(value); - } - - @Override - public boolean equals(@Nullable Object object) { - return delegate().equals(object); - } - - @Override - public int hashCode() { - return delegate().hashCode(); - } - - /** - * A sensible definition of {@link #equals(Object)} in terms of {@link - * #getKey()} and {@link #getValue()}. If you override either of these - * methods, you may wish to override {@link #equals(Object)} to forward to - * this implementation. - * - * @since 7.0 - */ - protected boolean standardEquals(@Nullable Object object) { - if (object instanceof Entry) { - Entry that = (Entry) object; - return Objects.equal(this.getKey(), that.getKey()) - && Objects.equal(this.getValue(), that.getValue()); - } - return false; - } - - /** - * A sensible definition of {@link #hashCode()} in terms of {@link #getKey()} - * and {@link #getValue()}. If you override either of these methods, you may - * wish to override {@link #hashCode()} to forward to this implementation. - * - * @since 7.0 - */ - protected int standardHashCode() { - K k = getKey(); - V v = getValue(); - return ((k == null) ? 0 : k.hashCode()) ^ ((v == null) ? 0 : v.hashCode()); - } - - /** - * A sensible definition of {@link #toString} in terms of {@link - * #getKey} and {@link #getValue}. If you override either of these - * methods, you may wish to override {@link #equals} to forward to this - * implementation. - * - * @since 7.0 - */ - @Beta - protected String standardToString() { - return getKey() + "=" + getValue(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingMultimap.java deleted file mode 100644 index 5410a1bcd1a0..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingMultimap.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Collection; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * A multimap which forwards all its method calls to another multimap. - * Subclasses should override one or more methods to modify the behavior of - * the backing multimap as desired per the decorator pattern. - * - * @author Robert Konigsberg - * @since 2.0 - */ -@GwtCompatible -public abstract class ForwardingMultimap extends ForwardingObject implements Multimap { - - /** Constructor for use by subclasses. */ - protected ForwardingMultimap() {} - - @Override - protected abstract Multimap delegate(); - - @Override - public Map> asMap() { - return delegate().asMap(); - } - - @Override - public void clear() { - delegate().clear(); - } - - @Override - public boolean containsEntry(@Nullable Object key, @Nullable Object value) { - return delegate().containsEntry(key, value); - } - - @Override - public boolean containsKey(@Nullable Object key) { - return delegate().containsKey(key); - } - - @Override - public boolean containsValue(@Nullable Object value) { - return delegate().containsValue(value); - } - - @Override - public Collection> entries() { - return delegate().entries(); - } - - @Override - public Collection get(@Nullable K key) { - return delegate().get(key); - } - - @Override - public boolean isEmpty() { - return delegate().isEmpty(); - } - - @Override - public Multiset keys() { - return delegate().keys(); - } - - @Override - public Set keySet() { - return delegate().keySet(); - } - - @Override - public boolean put(K key, V value) { - return delegate().put(key, value); - } - - @Override - public boolean putAll(K key, Iterable values) { - return delegate().putAll(key, values); - } - - @Override - public boolean putAll(Multimap multimap) { - return delegate().putAll(multimap); - } - - @Override - public boolean remove(@Nullable Object key, @Nullable Object value) { - return delegate().remove(key, value); - } - - @Override - public Collection removeAll(@Nullable Object key) { - return delegate().removeAll(key); - } - - @Override - public Collection replaceValues(K key, Iterable values) { - return delegate().replaceValues(key, values); - } - - @Override - public int size() { - return delegate().size(); - } - - @Override - public Collection values() { - return delegate().values(); - } - - @Override - public boolean equals(@Nullable Object object) { - return object == this || delegate().equals(object); - } - - @Override - public int hashCode() { - return delegate().hashCode(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingMultiset.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingMultiset.java deleted file mode 100644 index 9d70d84f9817..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingMultiset.java +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Objects; - -import java.util.Collection; -import java.util.Iterator; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * A multiset which forwards all its method calls to another multiset. - * Subclasses should override one or more methods to modify the behavior of the - * backing multiset as desired per the decorator pattern. - * - *

Warning: The methods of {@code ForwardingMultiset} forward - * indiscriminately to the methods of the delegate. For example, - * overriding {@link #add(Object, int)} alone will not change the - * behavior of {@link #add(Object)}, which can lead to unexpected behavior. In - * this case, you should override {@code add(Object)} as well, either providing - * your own implementation, or delegating to the provided {@code standardAdd} - * method. - * - *

The {@code standard} methods and any collection views they return are not - * guaranteed to be thread-safe, even when all of the methods that they depend - * on are thread-safe. - * - * @author Kevin Bourrillion - * @author Louis Wasserman - * @since 2.0 - */ -@GwtCompatible -public abstract class ForwardingMultiset extends ForwardingCollection implements Multiset { - - /** Constructor for use by subclasses. */ - protected ForwardingMultiset() {} - - @Override - protected abstract Multiset delegate(); - - @Override - public int count(Object element) { - return delegate().count(element); - } - - @Override - public int add(E element, int occurrences) { - return delegate().add(element, occurrences); - } - - @Override - public int remove(Object element, int occurrences) { - return delegate().remove(element, occurrences); - } - - @Override - public Set elementSet() { - return delegate().elementSet(); - } - - @Override - public Set> entrySet() { - return delegate().entrySet(); - } - - @Override - public boolean equals(@Nullable Object object) { - return object == this || delegate().equals(object); - } - - @Override - public int hashCode() { - return delegate().hashCode(); - } - - @Override - public int setCount(E element, int count) { - return delegate().setCount(element, count); - } - - @Override - public boolean setCount(E element, int oldCount, int newCount) { - return delegate().setCount(element, oldCount, newCount); - } - - /** - * A sensible definition of {@link #contains} in terms of {@link #count}. If - * you override {@link #count}, you may wish to override {@link #contains} to - * forward to this implementation. - * - * @since 7.0 - */ - @Override - protected boolean standardContains(@Nullable Object object) { - return count(object) > 0; - } - - /** - * A sensible definition of {@link #clear} in terms of the {@code iterator} - * method of {@link #entrySet}. If you override {@link #entrySet}, you may - * wish to override {@link #clear} to forward to this implementation. - * - * @since 7.0 - */ - @Override - protected void standardClear() { - Iterators.clear(entrySet().iterator()); - } - - /** - * A sensible, albeit inefficient, definition of {@link #count} in terms of - * {@link #entrySet}. If you override {@link #entrySet}, you may wish to - * override {@link #count} to forward to this implementation. - * - * @since 7.0 - */ - @Beta - protected int standardCount(@Nullable Object object) { - for (Entry entry : this.entrySet()) { - if (Objects.equal(entry.getElement(), object)) { - return entry.getCount(); - } - } - return 0; - } - - /** - * A sensible definition of {@link #add(Object)} in terms of {@link - * #add(Object, int)}. If you override {@link #add(Object, int)}, you may - * wish to override {@link #add(Object)} to forward to this implementation. - * - * @since 7.0 - */ - protected boolean standardAdd(E element) { - add(element, 1); - return true; - } - - /** - * A sensible definition of {@link #addAll(Collection)} in terms of {@link - * #add(Object)} and {@link #add(Object, int)}. If you override either of - * these methods, you may wish to override {@link #addAll(Collection)} to - * forward to this implementation. - * - * @since 7.0 - */ - @Beta - @Override - protected boolean standardAddAll(Collection elementsToAdd) { - return Multisets.addAllImpl(this, elementsToAdd); - } - - /** - * A sensible definition of {@link #remove(Object)} in terms of {@link - * #remove(Object, int)}. If you override {@link #remove(Object, int)}, you - * may wish to override {@link #remove(Object)} to forward to this - * implementation. - * - * @since 7.0 - */ - @Override - protected boolean standardRemove(Object element) { - return remove(element, 1) > 0; - } - - /** - * A sensible definition of {@link #removeAll} in terms of the {@code - * removeAll} method of {@link #elementSet}. If you override {@link - * #elementSet}, you may wish to override {@link #removeAll} to forward to - * this implementation. - * - * @since 7.0 - */ - @Override - protected boolean standardRemoveAll(Collection elementsToRemove) { - return Multisets.removeAllImpl(this, elementsToRemove); - } - - /** - * A sensible definition of {@link #retainAll} in terms of the {@code - * retainAll} method of {@link #elementSet}. If you override {@link - * #elementSet}, you may wish to override {@link #retainAll} to forward to - * this implementation. - * - * @since 7.0 - */ - @Override - protected boolean standardRetainAll(Collection elementsToRetain) { - return Multisets.retainAllImpl(this, elementsToRetain); - } - - /** - * A sensible definition of {@link #setCount(Object, int)} in terms of {@link - * #count(Object)}, {@link #add(Object, int)}, and {@link #remove(Object, - * int)}. {@link #entrySet()}. If you override any of these methods, you may - * wish to override {@link #setCount(Object, int)} to forward to this - * implementation. - * - * @since 7.0 - */ - protected int standardSetCount(E element, int count) { - return Multisets.setCountImpl(this, element, count); - } - - /** - * A sensible definition of {@link #setCount(Object, int, int)} in terms of - * {@link #count(Object)} and {@link #setCount(Object, int)}. If you override - * either of these methods, you may wish to override {@link #setCount(Object, - * int, int)} to forward to this implementation. - * - * @since 7.0 - */ - protected boolean standardSetCount(E element, int oldCount, int newCount) { - return Multisets.setCountImpl(this, element, oldCount, newCount); - } - - /** - * A sensible implementation of {@link Multiset#elementSet} in terms of the - * following methods: {@link ForwardingMultiset#clear}, {@link - * ForwardingMultiset#contains}, {@link ForwardingMultiset#containsAll}, - * {@link ForwardingMultiset#count}, {@link ForwardingMultiset#isEmpty}, the - * {@link Set#size} and {@link Set#iterator} methods of {@link - * ForwardingMultiset#entrySet}, and {@link ForwardingMultiset#remove(Object, - * int)}. In many situations, you may wish to override {@link - * ForwardingMultiset#elementSet} to forward to this implementation or a - * subclass thereof. - * - * @since 10.0 - */ - @Beta - protected class StandardElementSet extends Multisets.ElementSet { - /** Constructor for use by subclasses. */ - public StandardElementSet() {} - - @Override - Multiset multiset() { - return ForwardingMultiset.this; - } - } - - /** - * A sensible definition of {@link #iterator} in terms of {@link #entrySet} - * and {@link #remove(Object)}. If you override either of these methods, you - * may wish to override {@link #iterator} to forward to this implementation. - * - * @since 7.0 - */ - protected Iterator standardIterator() { - return Multisets.iteratorImpl(this); - } - - /** - * A sensible, albeit inefficient, definition of {@link #size} in terms of - * {@link #entrySet}. If you override {@link #entrySet}, you may wish to - * override {@link #size} to forward to this implementation. - * - * @since 7.0 - */ - protected int standardSize() { - return Multisets.sizeImpl(this); - } - - /** - * A sensible, albeit inefficient, definition of {@link #size} in terms of - * {@code entrySet().size()} and {@link #count}. If you override either of - * these methods, you may wish to override {@link #size} to forward to this - * implementation. - * - * @since 7.0 - */ - protected boolean standardEquals(@Nullable Object object) { - return Multisets.equalsImpl(this, object); - } - - /** - * A sensible definition of {@link #hashCode} as {@code entrySet().hashCode()} - * . If you override {@link #entrySet}, you may wish to override {@link - * #hashCode} to forward to this implementation. - * - * @since 7.0 - */ - protected int standardHashCode() { - return entrySet().hashCode(); - } - - /** - * A sensible definition of {@link #toString} as {@code entrySet().toString()} - * . If you override {@link #entrySet}, you may wish to override {@link - * #toString} to forward to this implementation. - * - * @since 7.0 - */ - @Override - protected String standardToString() { - return entrySet().toString(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingNavigableMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingNavigableMap.java deleted file mode 100644 index b022d1a9c751..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingNavigableMap.java +++ /dev/null @@ -1,398 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.collect.CollectPreconditions.checkRemove; -import static com.google.common.collect.Maps.keyOrNull; - -import com.google.common.annotations.Beta; - -import java.util.Iterator; -import java.util.NavigableMap; -import java.util.NavigableSet; -import java.util.NoSuchElementException; -import java.util.SortedMap; - -/** - * A navigable map which forwards all its method calls to another navigable map. Subclasses should - * override one or more methods to modify the behavior of the backing map as desired per the decorator pattern. - * - *

Warning: The methods of {@code ForwardingNavigableMap} forward indiscriminately - * to the methods of the delegate. For example, overriding {@link #put} alone will not - * change the behavior of {@link #putAll}, which can lead to unexpected behavior. In this case, you - * should override {@code putAll} as well, either providing your own implementation, or delegating - * to the provided {@code standardPutAll} method. - * - *

Each of the {@code standard} methods uses the map's comparator (or the natural ordering of - * the elements, if there is no comparator) to test element equality. As a result, if the comparator - * is not consistent with equals, some of the standard implementations may violate the {@code Map} - * contract. - * - *

The {@code standard} methods and the collection views they return are not guaranteed to be - * thread-safe, even when all of the methods that they depend on are thread-safe. - * - * @author Louis Wasserman - * @since 12.0 - */ -public abstract class ForwardingNavigableMap extends ForwardingSortedMap - implements NavigableMap { - - /** Constructor for use by subclasses. */ - protected ForwardingNavigableMap() {} - - @Override - protected abstract NavigableMap delegate(); - - @Override - public Entry lowerEntry(K key) { - return delegate().lowerEntry(key); - } - - /** - * A sensible definition of {@link #lowerEntry} in terms of the {@code lastEntry()} of - * {@link #headMap(Object, boolean)}. If you override {@code headMap}, you may wish to override - * {@code lowerEntry} to forward to this implementation. - */ - protected Entry standardLowerEntry(K key) { - return headMap(key, false).lastEntry(); - } - - @Override - public K lowerKey(K key) { - return delegate().lowerKey(key); - } - - /** - * A sensible definition of {@link #lowerKey} in terms of {@code lowerEntry}. If you override - * {@link #lowerEntry}, you may wish to override {@code lowerKey} to forward to this - * implementation. - */ - protected K standardLowerKey(K key) { - return keyOrNull(lowerEntry(key)); - } - - @Override - public Entry floorEntry(K key) { - return delegate().floorEntry(key); - } - - /** - * A sensible definition of {@link #floorEntry} in terms of the {@code lastEntry()} of - * {@link #headMap(Object, boolean)}. If you override {@code headMap}, you may wish to override - * {@code floorEntry} to forward to this implementation. - */ - protected Entry standardFloorEntry(K key) { - return headMap(key, true).lastEntry(); - } - - @Override - public K floorKey(K key) { - return delegate().floorKey(key); - } - - /** - * A sensible definition of {@link #floorKey} in terms of {@code floorEntry}. If you override - * {@code floorEntry}, you may wish to override {@code floorKey} to forward to this - * implementation. - */ - protected K standardFloorKey(K key) { - return keyOrNull(floorEntry(key)); - } - - @Override - public Entry ceilingEntry(K key) { - return delegate().ceilingEntry(key); - } - - /** - * A sensible definition of {@link #ceilingEntry} in terms of the {@code firstEntry()} of - * {@link #tailMap(Object, boolean)}. If you override {@code tailMap}, you may wish to override - * {@code ceilingEntry} to forward to this implementation. - */ - protected Entry standardCeilingEntry(K key) { - return tailMap(key, true).firstEntry(); - } - - @Override - public K ceilingKey(K key) { - return delegate().ceilingKey(key); - } - - /** - * A sensible definition of {@link #ceilingKey} in terms of {@code ceilingEntry}. If you override - * {@code ceilingEntry}, you may wish to override {@code ceilingKey} to forward to this - * implementation. - */ - protected K standardCeilingKey(K key) { - return keyOrNull(ceilingEntry(key)); - } - - @Override - public Entry higherEntry(K key) { - return delegate().higherEntry(key); - } - - /** - * A sensible definition of {@link #higherEntry} in terms of the {@code firstEntry()} of - * {@link #tailMap(Object, boolean)}. If you override {@code tailMap}, you may wish to override - * {@code higherEntry} to forward to this implementation. - */ - protected Entry standardHigherEntry(K key) { - return tailMap(key, false).firstEntry(); - } - - @Override - public K higherKey(K key) { - return delegate().higherKey(key); - } - - /** - * A sensible definition of {@link #higherKey} in terms of {@code higherEntry}. If you override - * {@code higherEntry}, you may wish to override {@code higherKey} to forward to this - * implementation. - */ - protected K standardHigherKey(K key) { - return keyOrNull(higherEntry(key)); - } - - @Override - public Entry firstEntry() { - return delegate().firstEntry(); - } - - /** - * A sensible definition of {@link #firstEntry} in terms of the {@code iterator()} of - * {@link #entrySet}. If you override {@code entrySet}, you may wish to override - * {@code firstEntry} to forward to this implementation. - */ - protected Entry standardFirstEntry() { - return Iterables.getFirst(entrySet(), null); - } - - /** - * A sensible definition of {@link #firstKey} in terms of {@code firstEntry}. If you override - * {@code firstEntry}, you may wish to override {@code firstKey} to forward to this - * implementation. - */ - protected K standardFirstKey() { - Entry entry = firstEntry(); - if (entry == null) { - throw new NoSuchElementException(); - } else { - return entry.getKey(); - } - } - - @Override - public Entry lastEntry() { - return delegate().lastEntry(); - } - - /** - * A sensible definition of {@link #lastEntry} in terms of the {@code iterator()} of the - * {@link #entrySet} of {@link #descendingMap}. If you override {@code descendingMap}, you may - * wish to override {@code lastEntry} to forward to this implementation. - */ - protected Entry standardLastEntry() { - return Iterables.getFirst(descendingMap().entrySet(), null); - } - - /** - * A sensible definition of {@link #lastKey} in terms of {@code lastEntry}. If you override - * {@code lastEntry}, you may wish to override {@code lastKey} to forward to this implementation. - */ - protected K standardLastKey() { - Entry entry = lastEntry(); - if (entry == null) { - throw new NoSuchElementException(); - } else { - return entry.getKey(); - } - } - - @Override - public Entry pollFirstEntry() { - return delegate().pollFirstEntry(); - } - - /** - * A sensible definition of {@link #pollFirstEntry} in terms of the {@code iterator} of - * {@code entrySet}. If you override {@code entrySet}, you may wish to override - * {@code pollFirstEntry} to forward to this implementation. - */ - protected Entry standardPollFirstEntry() { - return Iterators.pollNext(entrySet().iterator()); - } - - @Override - public Entry pollLastEntry() { - return delegate().pollLastEntry(); - } - - /** - * A sensible definition of {@link #pollFirstEntry} in terms of the {@code iterator} of the - * {@code entrySet} of {@code descendingMap}. If you override {@code descendingMap}, you may wish - * to override {@code pollFirstEntry} to forward to this implementation. - */ - protected Entry standardPollLastEntry() { - return Iterators.pollNext(descendingMap().entrySet().iterator()); - } - - @Override - public NavigableMap descendingMap() { - return delegate().descendingMap(); - } - - /** - * A sensible implementation of {@link NavigableMap#descendingMap} in terms of the methods of - * this {@code NavigableMap}. In many cases, you may wish to override - * {@link ForwardingNavigableMap#descendingMap} to forward to this implementation or a subclass - * thereof. - * - *

In particular, this map iterates over entries with repeated calls to - * {@link NavigableMap#lowerEntry}. If a more efficient means of iteration is available, you may - * wish to override the {@code entryIterator()} method of this class. - * - * @since 12.0 - */ - @Beta - protected class StandardDescendingMap extends Maps.DescendingMap { - /** Constructor for use by subclasses. */ - public StandardDescendingMap() {} - - @Override - NavigableMap forward() { - return ForwardingNavigableMap.this; - } - - @Override - protected Iterator> entryIterator() { - return new Iterator>() { - private Entry toRemove = null; - private Entry nextOrNull = forward().lastEntry(); - - @Override - public boolean hasNext() { - return nextOrNull != null; - } - - @Override - public java.util.Map.Entry next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - try { - return nextOrNull; - } finally { - toRemove = nextOrNull; - nextOrNull = forward().lowerEntry(nextOrNull.getKey()); - } - } - - @Override - public void remove() { - checkRemove(toRemove != null); - forward().remove(toRemove.getKey()); - toRemove = null; - } - }; - } - } - - @Override - public NavigableSet navigableKeySet() { - return delegate().navigableKeySet(); - } - - /** - * A sensible implementation of {@link NavigableMap#navigableKeySet} in terms of the methods of - * this {@code NavigableMap}. In many cases, you may wish to override - * {@link ForwardingNavigableMap#navigableKeySet} to forward to this implementation or a subclass - * thereof. - * - * @since 12.0 - */ - @Beta - protected class StandardNavigableKeySet extends Maps.NavigableKeySet { - /** Constructor for use by subclasses. */ - public StandardNavigableKeySet() { - super(ForwardingNavigableMap.this); - } - } - - @Override - public NavigableSet descendingKeySet() { - return delegate().descendingKeySet(); - } - - /** - * A sensible definition of {@link #descendingKeySet} as the {@code navigableKeySet} of - * {@link #descendingMap}. (The {@link StandardDescendingMap} implementation implements - * {@code navigableKeySet} on its own, so as not to cause an infinite loop.) If you override - * {@code descendingMap}, you may wish to override {@code descendingKeySet} to forward to this - * implementation. - */ - @Beta - protected NavigableSet standardDescendingKeySet() { - return descendingMap().navigableKeySet(); - } - - /** - * A sensible definition of {@link #subMap(Object, Object)} in terms of - * {@link #subMap(Object, boolean, Object, boolean)}. If you override - * {@code subMap(K, boolean, K, boolean)}, you may wish to override {@code subMap} to forward to - * this implementation. - */ - @Override - protected SortedMap standardSubMap(K fromKey, K toKey) { - return subMap(fromKey, true, toKey, false); - } - - @Override - public NavigableMap subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { - return delegate().subMap(fromKey, fromInclusive, toKey, toInclusive); - } - - @Override - public NavigableMap headMap(K toKey, boolean inclusive) { - return delegate().headMap(toKey, inclusive); - } - - @Override - public NavigableMap tailMap(K fromKey, boolean inclusive) { - return delegate().tailMap(fromKey, inclusive); - } - - /** - * A sensible definition of {@link #headMap(Object)} in terms of - * {@link #headMap(Object, boolean)}. If you override {@code headMap(K, boolean)}, you may wish - * to override {@code headMap} to forward to this implementation. - */ - protected SortedMap standardHeadMap(K toKey) { - return headMap(toKey, false); - } - - /** - * A sensible definition of {@link #tailMap(Object)} in terms of - * {@link #tailMap(Object, boolean)}. If you override {@code tailMap(K, boolean)}, you may wish - * to override {@code tailMap} to forward to this implementation. - */ - protected SortedMap standardTailMap(K fromKey) { - return tailMap(fromKey, true); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingNavigableSet.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingNavigableSet.java deleted file mode 100644 index 447f39707773..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingNavigableSet.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.Beta; - -import java.util.Iterator; -import java.util.NavigableSet; -import java.util.SortedSet; - -/** - * A navigable set which forwards all its method calls to another navigable set. Subclasses should - * override one or more methods to modify the behavior of the backing set as desired per the decorator pattern. - * - *

Warning: The methods of {@code ForwardingNavigableSet} forward indiscriminately - * to the methods of the delegate. For example, overriding {@link #add} alone will not - * change the behavior of {@link #addAll}, which can lead to unexpected behavior. In this case, you - * should override {@code addAll} as well, either providing your own implementation, or delegating - * to the provided {@code standardAddAll} method. - * - *

Each of the {@code standard} methods uses the set's comparator (or the natural ordering of - * the elements, if there is no comparator) to test element equality. As a result, if the - * comparator is not consistent with equals, some of the standard implementations may violate the - * {@code Set} contract. - * - *

The {@code standard} methods and the collection views they return are not guaranteed to be - * thread-safe, even when all of the methods that they depend on are thread-safe. - * - * @author Louis Wasserman - * @since 12.0 - */ -public abstract class ForwardingNavigableSet extends ForwardingSortedSet - implements NavigableSet { - - /** Constructor for use by subclasses. */ - protected ForwardingNavigableSet() {} - - @Override - protected abstract NavigableSet delegate(); - - @Override - public E lower(E e) { - return delegate().lower(e); - } - - /** - * A sensible definition of {@link #lower} in terms of the {@code descendingIterator} method of - * {@link #headSet(Object, boolean)}. If you override {@link #headSet(Object, boolean)}, you may - * wish to override {@link #lower} to forward to this implementation. - */ - protected E standardLower(E e) { - return Iterators.getNext(headSet(e, false).descendingIterator(), null); - } - - @Override - public E floor(E e) { - return delegate().floor(e); - } - - /** - * A sensible definition of {@link #floor} in terms of the {@code descendingIterator} method of - * {@link #headSet(Object, boolean)}. If you override {@link #headSet(Object, boolean)}, you may - * wish to override {@link #floor} to forward to this implementation. - */ - protected E standardFloor(E e) { - return Iterators.getNext(headSet(e, true).descendingIterator(), null); - } - - @Override - public E ceiling(E e) { - return delegate().ceiling(e); - } - - /** - * A sensible definition of {@link #ceiling} in terms of the {@code iterator} method of - * {@link #tailSet(Object, boolean)}. If you override {@link #tailSet(Object, boolean)}, you may - * wish to override {@link #ceiling} to forward to this implementation. - */ - protected E standardCeiling(E e) { - return Iterators.getNext(tailSet(e, true).iterator(), null); - } - - @Override - public E higher(E e) { - return delegate().higher(e); - } - - /** - * A sensible definition of {@link #higher} in terms of the {@code iterator} method of - * {@link #tailSet(Object, boolean)}. If you override {@link #tailSet(Object, boolean)}, you may - * wish to override {@link #higher} to forward to this implementation. - */ - protected E standardHigher(E e) { - return Iterators.getNext(tailSet(e, false).iterator(), null); - } - - @Override - public E pollFirst() { - return delegate().pollFirst(); - } - - /** - * A sensible definition of {@link #pollFirst} in terms of the {@code iterator} method. If you - * override {@link #iterator} you may wish to override {@link #pollFirst} to forward to this - * implementation. - */ - protected E standardPollFirst() { - return Iterators.pollNext(iterator()); - } - - @Override - public E pollLast() { - return delegate().pollLast(); - } - - /** - * A sensible definition of {@link #pollLast} in terms of the {@code descendingIterator} method. - * If you override {@link #descendingIterator} you may wish to override {@link #pollLast} to - * forward to this implementation. - */ - protected E standardPollLast() { - return Iterators.pollNext(descendingIterator()); - } - - protected E standardFirst() { - return iterator().next(); - } - - protected E standardLast() { - return descendingIterator().next(); - } - - @Override - public NavigableSet descendingSet() { - return delegate().descendingSet(); - } - - /** - * A sensible implementation of {@link NavigableSet#descendingSet} in terms of the other methods - * of {@link NavigableSet}, notably including {@link NavigableSet#descendingIterator}. - * - *

In many cases, you may wish to override {@link ForwardingNavigableSet#descendingSet} to - * forward to this implementation or a subclass thereof. - * - * @since 12.0 - */ - @Beta - protected class StandardDescendingSet extends Sets.DescendingSet { - /** Constructor for use by subclasses. */ - public StandardDescendingSet() { - super(ForwardingNavigableSet.this); - } - } - - @Override - public Iterator descendingIterator() { - return delegate().descendingIterator(); - } - - @Override - public NavigableSet subSet( - E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { - return delegate().subSet(fromElement, fromInclusive, toElement, toInclusive); - } - - /** - * A sensible definition of {@link #subSet(Object, boolean, Object, boolean)} in terms of the - * {@code headSet} and {@code tailSet} methods. In many cases, you may wish to override - * {@link #subSet(Object, boolean, Object, boolean)} to forward to this implementation. - */ - @Beta - protected NavigableSet standardSubSet( - E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { - return tailSet(fromElement, fromInclusive).headSet(toElement, toInclusive); - } - - /** - * A sensible definition of {@link #subSet(Object, Object)} in terms of the - * {@link #subSet(Object, boolean, Object, boolean)} method. If you override - * {@link #subSet(Object, boolean, Object, boolean)}, you may wish to override - * {@link #subSet(Object, Object)} to forward to this implementation. - */ - @Override - protected SortedSet standardSubSet(E fromElement, E toElement) { - return subSet(fromElement, true, toElement, false); - } - - @Override - public NavigableSet headSet(E toElement, boolean inclusive) { - return delegate().headSet(toElement, inclusive); - } - - /** - * A sensible definition of {@link #headSet(Object)} in terms of the - * {@link #headSet(Object, boolean)} method. If you override - * {@link #headSet(Object, boolean)}, you may wish to override - * {@link #headSet(Object)} to forward to this implementation. - */ - protected SortedSet standardHeadSet(E toElement) { - return headSet(toElement, false); - } - - @Override - public NavigableSet tailSet(E fromElement, boolean inclusive) { - return delegate().tailSet(fromElement, inclusive); - } - - /** - * A sensible definition of {@link #tailSet(Object)} in terms of the - * {@link #tailSet(Object, boolean)} method. If you override - * {@link #tailSet(Object, boolean)}, you may wish to override - * {@link #tailSet(Object)} to forward to this implementation. - */ - protected SortedSet standardTailSet(E fromElement) { - return tailSet(fromElement, true); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingObject.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingObject.java deleted file mode 100644 index b25538c54d41..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingObject.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; - -/** - * An abstract base class for implementing the decorator pattern. - * The {@link #delegate()} method must be overridden to return the instance - * being decorated. - * - *

This class does not forward the {@code hashCode} and {@code equals} - * methods through to the backing object, but relies on {@code Object}'s - * implementation. This is necessary to preserve the symmetry of {@code equals}. - * Custom definitions of equality are usually based on an interface, such as - * {@code Set} or {@code List}, so that the implementation of {@code equals} can - * cast the object being tested for equality to the custom interface. {@code - * ForwardingObject} implements no such custom interfaces directly; they - * are implemented only in subclasses. Therefore, forwarding {@code equals} - * would break symmetry, as the forwarding object might consider itself equal to - * the object being tested, but the reverse could not be true. This behavior is - * consistent with the JDK's collection wrappers, such as - * {@link java.util.Collections#unmodifiableCollection}. Use an - * interface-specific subclass of {@code ForwardingObject}, such as {@link - * ForwardingList}, to preserve equality behavior, or override {@code equals} - * directly. - * - *

The {@code toString} method is forwarded to the delegate. Although this - * class does not implement {@link Serializable}, a serializable subclass may be - * created since this class has a parameter-less constructor. - * - * @author Mike Bostock - * @since 2.0 - */ -@GwtCompatible -public abstract class ForwardingObject { - - /** Constructor for use by subclasses. */ - protected ForwardingObject() {} - - /** - * Returns the backing delegate instance that methods are forwarded to. - * Abstract subclasses generally override this method with an abstract method - * that has a more specific return type, such as {@link - * ForwardingSet#delegate}. Concrete subclasses override this method to supply - * the instance being decorated. - */ - protected abstract Object delegate(); - - /** - * Returns the string representation generated by the delegate's - * {@code toString} method. - */ - @Override - public String toString() { - return delegate().toString(); - } - - /* No equals or hashCode. See class comments for details. */ -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingQueue.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingQueue.java deleted file mode 100644 index c150bdbf774e..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingQueue.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.NoSuchElementException; -import java.util.Queue; - -/** - * A queue which forwards all its method calls to another queue. Subclasses - * should override one or more methods to modify the behavior of the backing - * queue as desired per the decorator pattern. - * - *

Warning: The methods of {@code ForwardingQueue} forward - * indiscriminately to the methods of the delegate. For example, - * overriding {@link #add} alone will not change the behavior of {@link - * #offer} which can lead to unexpected behavior. In this case, you should - * override {@code offer} as well, either providing your own implementation, or - * delegating to the provided {@code standardOffer} method. - * - *

The {@code standard} methods are not guaranteed to be thread-safe, even - * when all of the methods that they depend on are thread-safe. - * - * @author Mike Bostock - * @author Louis Wasserman - * @since 2.0 - */ -@GwtCompatible -public abstract class ForwardingQueue extends ForwardingCollection implements Queue { - - /** Constructor for use by subclasses. */ - protected ForwardingQueue() {} - - @Override - protected abstract Queue delegate(); - - @Override - public boolean offer(E o) { - return delegate().offer(o); - } - - @Override - public E poll() { - return delegate().poll(); - } - - @Override - public E remove() { - return delegate().remove(); - } - - @Override - public E peek() { - return delegate().peek(); - } - - @Override - public E element() { - return delegate().element(); - } - - /** - * A sensible definition of {@link #offer} in terms of {@link #add}. If you - * override {@link #add}, you may wish to override {@link #offer} to forward - * to this implementation. - * - * @since 7.0 - */ - protected boolean standardOffer(E e) { - try { - return add(e); - } catch (IllegalStateException caught) { - return false; - } - } - - /** - * A sensible definition of {@link #peek} in terms of {@link #element}. If you - * override {@link #element}, you may wish to override {@link #peek} to - * forward to this implementation. - * - * @since 7.0 - */ - protected E standardPeek() { - try { - return element(); - } catch (NoSuchElementException caught) { - return null; - } - } - - /** - * A sensible definition of {@link #poll} in terms of {@link #remove}. If you - * override {@link #remove}, you may wish to override {@link #poll} to forward - * to this implementation. - * - * @since 7.0 - */ - protected E standardPoll() { - try { - return remove(); - } catch (NoSuchElementException caught) { - return null; - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingSet.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingSet.java deleted file mode 100644 index 0430af8297e1..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingSet.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Collection; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * A set which forwards all its method calls to another set. Subclasses should - * override one or more methods to modify the behavior of the backing set as - * desired per the decorator pattern. - * - *

Warning: The methods of {@code ForwardingSet} forward - * indiscriminately to the methods of the delegate. For example, - * overriding {@link #add} alone will not change the behavior of {@link - * #addAll}, which can lead to unexpected behavior. In this case, you should - * override {@code addAll} as well, either providing your own implementation, or - * delegating to the provided {@code standardAddAll} method. - * - *

The {@code standard} methods are not guaranteed to be thread-safe, even - * when all of the methods that they depend on are thread-safe. - * - * @author Kevin Bourrillion - * @author Louis Wasserman - * @since 2.0 - */ -@GwtCompatible -public abstract class ForwardingSet extends ForwardingCollection implements Set { - // TODO(lowasser): identify places where thread safety is actually lost - - /** Constructor for use by subclasses. */ - protected ForwardingSet() {} - - @Override - protected abstract Set delegate(); - - @Override - public boolean equals(@Nullable Object object) { - return object == this || delegate().equals(object); - } - - @Override - public int hashCode() { - return delegate().hashCode(); - } - - /** - * A sensible definition of {@link #removeAll} in terms of {@link #iterator} - * and {@link #remove}. If you override {@code iterator} or {@code remove}, - * you may wish to override {@link #removeAll} to forward to this - * implementation. - * - * @since 7.0 (this version overrides the {@code ForwardingCollection} version as of 12.0) - */ - @Override - protected boolean standardRemoveAll(Collection collection) { - return Sets.removeAllImpl(this, checkNotNull(collection)); // for GWT - } - - /** - * A sensible definition of {@link #equals} in terms of {@link #size} and - * {@link #containsAll}. If you override either of those methods, you may wish - * to override {@link #equals} to forward to this implementation. - * - * @since 7.0 - */ - protected boolean standardEquals(@Nullable Object object) { - return Sets.equalsImpl(this, object); - } - - /** - * A sensible definition of {@link #hashCode} in terms of {@link #iterator}. - * If you override {@link #iterator}, you may wish to override {@link #equals} - * to forward to this implementation. - * - * @since 7.0 - */ - protected int standardHashCode() { - return Sets.hashCodeImpl(this); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingSetMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingSetMultimap.java deleted file mode 100644 index dde1ff65c12f..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingSetMultimap.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2010 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Map.Entry; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * A set multimap which forwards all its method calls to another set multimap. - * Subclasses should override one or more methods to modify the behavior of - * the backing multimap as desired per the decorator pattern. - * - * @author Kurt Alfred Kluever - * @since 3.0 - */ -@GwtCompatible -public abstract class ForwardingSetMultimap extends ForwardingMultimap - implements SetMultimap { - - @Override - protected abstract SetMultimap delegate(); - - @Override - public Set> entries() { - return delegate().entries(); - } - - @Override - public Set get(@Nullable K key) { - return delegate().get(key); - } - - @Override - public Set removeAll(@Nullable Object key) { - return delegate().removeAll(key); - } - - @Override - public Set replaceValues(K key, Iterable values) { - return delegate().replaceValues(key, values); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingSortedMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingSortedMap.java deleted file mode 100644 index 5ccd45b2c742..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingSortedMap.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import java.util.Comparator; -import java.util.NoSuchElementException; -import java.util.SortedMap; - -import javax.annotation.Nullable; - -/** - * A sorted map which forwards all its method calls to another sorted map. - * Subclasses should override one or more methods to modify the behavior of - * the backing sorted map as desired per the decorator pattern. - * - *

Warning: The methods of {@code ForwardingSortedMap} forward - * indiscriminately to the methods of the delegate. For example, - * overriding {@link #put} alone will not change the behavior of {@link - * #putAll}, which can lead to unexpected behavior. In this case, you should - * override {@code putAll} as well, either providing your own implementation, or - * delegating to the provided {@code standardPutAll} method. - * - *

Each of the {@code standard} methods, where appropriate, use the - * comparator of the map to test equality for both keys and values, unlike - * {@code ForwardingMap}. - * - *

The {@code standard} methods and the collection views they return are not - * guaranteed to be thread-safe, even when all of the methods that they depend - * on are thread-safe. - * - * @author Mike Bostock - * @author Louis Wasserman - * @since 2.0 - */ -@GwtCompatible -public abstract class ForwardingSortedMap extends ForwardingMap - implements SortedMap { - // TODO(lowasser): identify places where thread safety is actually lost - - /** Constructor for use by subclasses. */ - protected ForwardingSortedMap() {} - - @Override - protected abstract SortedMap delegate(); - - @Override - public Comparator comparator() { - return delegate().comparator(); - } - - @Override - public K firstKey() { - return delegate().firstKey(); - } - - @Override - public SortedMap headMap(K toKey) { - return delegate().headMap(toKey); - } - - @Override - public K lastKey() { - return delegate().lastKey(); - } - - @Override - public SortedMap subMap(K fromKey, K toKey) { - return delegate().subMap(fromKey, toKey); - } - - @Override - public SortedMap tailMap(K fromKey) { - return delegate().tailMap(fromKey); - } - - /** - * A sensible implementation of {@link SortedMap#keySet} in terms of the methods of - * {@code ForwardingSortedMap}. In many cases, you may wish to override - * {@link ForwardingSortedMap#keySet} to forward to this implementation or a subclass thereof. - * - * @since 15.0 - */ - @Beta - protected class StandardKeySet extends Maps.SortedKeySet { - /** Constructor for use by subclasses. */ - public StandardKeySet() { - super(ForwardingSortedMap.this); - } - } - - // unsafe, but worst case is a CCE is thrown, which callers will be expecting - @SuppressWarnings("unchecked") - private int unsafeCompare(Object k1, Object k2) { - Comparator comparator = comparator(); - if (comparator == null) { - return ((Comparable) k1).compareTo(k2); - } else { - return ((Comparator) comparator).compare(k1, k2); - } - } - - /** - * A sensible definition of {@link #containsKey} in terms of the {@code - * firstKey()} method of {@link #tailMap}. If you override {@link #tailMap}, - * you may wish to override {@link #containsKey} to forward to this - * implementation. - * - * @since 7.0 - */ - @Override - @Beta - protected boolean standardContainsKey(@Nullable Object key) { - try { - // any CCE will be caught - @SuppressWarnings("unchecked") - SortedMap self = (SortedMap) this; - Object ceilingKey = self.tailMap(key).firstKey(); - return unsafeCompare(ceilingKey, key) == 0; - } catch (ClassCastException e) { - return false; - } catch (NoSuchElementException e) { - return false; - } catch (NullPointerException e) { - return false; - } - } - - /** - * A sensible default implementation of {@link #subMap(Object, Object)} in - * terms of {@link #headMap(Object)} and {@link #tailMap(Object)}. In some - * situations, you may wish to override {@link #subMap(Object, Object)} to - * forward to this implementation. - * - * @since 7.0 - */ - @Beta - protected SortedMap standardSubMap(K fromKey, K toKey) { - checkArgument(unsafeCompare(fromKey, toKey) <= 0, "fromKey must be <= toKey"); - return tailMap(fromKey).headMap(toKey); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingSortedMultiset.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingSortedMultiset.java deleted file mode 100644 index 2f0cbbe42fe1..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingSortedMultiset.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import java.util.Comparator; -import java.util.Iterator; -import java.util.NavigableSet; - -/** - * A sorted multiset which forwards all its method calls to another sorted multiset. Subclasses - * should override one or more methods to modify the behavior of the backing multiset as desired - * per the decorator pattern. - * - *

Warning: The methods of {@code ForwardingSortedMultiset} forward - * indiscriminately to the methods of the delegate. For example, overriding - * {@link #add(Object, int)} alone will not change the behavior of {@link #add(Object)}, - * which can lead to unexpected behavior. In this case, you should override {@code add(Object)} as - * well, either providing your own implementation, or delegating to the provided {@code - * standardAdd} method. - * - *

The {@code standard} methods and any collection views they return are not guaranteed to be - * thread-safe, even when all of the methods that they depend on are thread-safe. - * - * @author Louis Wasserman - * @since 15.0 - */ -@Beta -@GwtCompatible(emulated = true) -public abstract class ForwardingSortedMultiset extends ForwardingMultiset - implements SortedMultiset { - /** Constructor for use by subclasses. */ - protected ForwardingSortedMultiset() {} - - @Override - protected abstract SortedMultiset delegate(); - - @Override - public NavigableSet elementSet() { - return (NavigableSet) super.elementSet(); - } - - /** - * A sensible implementation of {@link SortedMultiset#elementSet} in terms of the following - * methods: {@link SortedMultiset#clear}, {@link SortedMultiset#comparator}, {@link - * SortedMultiset#contains}, {@link SortedMultiset#containsAll}, {@link SortedMultiset#count}, - * {@link SortedMultiset#firstEntry} {@link SortedMultiset#headMultiset}, {@link - * SortedMultiset#isEmpty}, {@link SortedMultiset#lastEntry}, {@link SortedMultiset#subMultiset}, - * {@link SortedMultiset#tailMultiset}, the {@code size()} and {@code iterator()} methods of - * {@link SortedMultiset#entrySet}, and {@link SortedMultiset#remove(Object, int)}. In many - * situations, you may wish to override {@link SortedMultiset#elementSet} to forward to this - * implementation or a subclass thereof. - */ - protected class StandardElementSet extends SortedMultisets.NavigableElementSet { - /** Constructor for use by subclasses. */ - public StandardElementSet() { - super(ForwardingSortedMultiset.this); - } - } - - @Override - public Comparator comparator() { - return delegate().comparator(); - } - - @Override - public SortedMultiset descendingMultiset() { - return delegate().descendingMultiset(); - } - - /** - * A skeleton implementation of a descending multiset view. Normally, - * {@link #descendingMultiset()} will not reflect any changes you make to the behavior of methods - * such as {@link #add(Object)} or {@link #pollFirstEntry}. This skeleton implementation - * correctly delegates each of its operations to the appropriate methods of this {@code - * ForwardingSortedMultiset}. - * - * In many cases, you may wish to override {@link #descendingMultiset()} to return an instance of - * a subclass of {@code StandardDescendingMultiset}. - */ - protected abstract class StandardDescendingMultiset extends DescendingMultiset { - /** Constructor for use by subclasses. */ - public StandardDescendingMultiset() {} - - @Override - SortedMultiset forwardMultiset() { - return ForwardingSortedMultiset.this; - } - } - - @Override - public Entry firstEntry() { - return delegate().firstEntry(); - } - - /** - * A sensible definition of {@link #firstEntry()} in terms of {@code entrySet().iterator()}. - * - * If you override {@link #entrySet()}, you may wish to override {@link #firstEntry()} to forward - * to this implementation. - */ - protected Entry standardFirstEntry() { - Iterator> entryIterator = entrySet().iterator(); - if (!entryIterator.hasNext()) { - return null; - } - Entry entry = entryIterator.next(); - return Multisets.immutableEntry(entry.getElement(), entry.getCount()); - } - - @Override - public Entry lastEntry() { - return delegate().lastEntry(); - } - - /** - * A sensible definition of {@link #lastEntry()} in terms of {@code - * descendingMultiset().entrySet().iterator()}. - * - * If you override {@link #descendingMultiset} or {@link #entrySet()}, you may wish to override - * {@link #firstEntry()} to forward to this implementation. - */ - protected Entry standardLastEntry() { - Iterator> entryIterator = descendingMultiset().entrySet().iterator(); - if (!entryIterator.hasNext()) { - return null; - } - Entry entry = entryIterator.next(); - return Multisets.immutableEntry(entry.getElement(), entry.getCount()); - } - - @Override - public Entry pollFirstEntry() { - return delegate().pollFirstEntry(); - } - - /** - * A sensible definition of {@link #pollFirstEntry()} in terms of {@code entrySet().iterator()}. - * - * If you override {@link #entrySet()}, you may wish to override {@link #pollFirstEntry()} to - * forward to this implementation. - */ - protected Entry standardPollFirstEntry() { - Iterator> entryIterator = entrySet().iterator(); - if (!entryIterator.hasNext()) { - return null; - } - Entry entry = entryIterator.next(); - entry = Multisets.immutableEntry(entry.getElement(), entry.getCount()); - entryIterator.remove(); - return entry; - } - - @Override - public Entry pollLastEntry() { - return delegate().pollLastEntry(); - } - - /** - * A sensible definition of {@link #pollLastEntry()} in terms of {@code - * descendingMultiset().entrySet().iterator()}. - * - * If you override {@link #descendingMultiset()} or {@link #entrySet()}, you may wish to override - * {@link #pollLastEntry()} to forward to this implementation. - */ - protected Entry standardPollLastEntry() { - Iterator> entryIterator = descendingMultiset().entrySet().iterator(); - if (!entryIterator.hasNext()) { - return null; - } - Entry entry = entryIterator.next(); - entry = Multisets.immutableEntry(entry.getElement(), entry.getCount()); - entryIterator.remove(); - return entry; - } - - @Override - public SortedMultiset headMultiset(E upperBound, BoundType boundType) { - return delegate().headMultiset(upperBound, boundType); - } - - @Override - public SortedMultiset subMultiset( - E lowerBound, BoundType lowerBoundType, E upperBound, BoundType upperBoundType) { - return delegate().subMultiset(lowerBound, lowerBoundType, upperBound, upperBoundType); - } - - /** - * A sensible definition of {@link #subMultiset(Object, BoundType, Object, BoundType)} in terms - * of {@link #headMultiset(Object, BoundType) headMultiset} and - * {@link #tailMultiset(Object, BoundType) tailMultiset}. - * - * If you override either of these methods, you may wish to override - * {@link #subMultiset(Object, BoundType, Object, BoundType)} to forward to this implementation. - */ - protected SortedMultiset standardSubMultiset( - E lowerBound, BoundType lowerBoundType, E upperBound, BoundType upperBoundType) { - return tailMultiset(lowerBound, lowerBoundType).headMultiset(upperBound, upperBoundType); - } - - @Override - public SortedMultiset tailMultiset(E lowerBound, BoundType boundType) { - return delegate().tailMultiset(lowerBound, boundType); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingSortedSet.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingSortedSet.java deleted file mode 100644 index 63ebec27d52a..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingSortedSet.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import java.util.Comparator; -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.SortedSet; - -import javax.annotation.Nullable; - -/** - * A sorted set which forwards all its method calls to another sorted set. - * Subclasses should override one or more methods to modify the behavior of the - * backing sorted set as desired per the decorator pattern. - * - *

Warning: The methods of {@code ForwardingSortedSet} forward - * indiscriminately to the methods of the delegate. For example, - * overriding {@link #add} alone will not change the behavior of {@link - * #addAll}, which can lead to unexpected behavior. In this case, you should - * override {@code addAll} as well, either providing your own implementation, or - * delegating to the provided {@code standardAddAll} method. - * - *

Each of the {@code standard} methods, where appropriate, uses the set's - * comparator (or the natural ordering of the elements, if there is no - * comparator) to test element equality. As a result, if the comparator is not - * consistent with equals, some of the standard implementations may violate the - * {@code Set} contract. - * - *

The {@code standard} methods and the collection views they return are not - * guaranteed to be thread-safe, even when all of the methods that they depend - * on are thread-safe. - * - * @author Mike Bostock - * @author Louis Wasserman - * @since 2.0 - */ -@GwtCompatible -public abstract class ForwardingSortedSet extends ForwardingSet implements SortedSet { - - /** Constructor for use by subclasses. */ - protected ForwardingSortedSet() {} - - @Override - protected abstract SortedSet delegate(); - - @Override - public Comparator comparator() { - return delegate().comparator(); - } - - @Override - public E first() { - return delegate().first(); - } - - @Override - public SortedSet headSet(E toElement) { - return delegate().headSet(toElement); - } - - @Override - public E last() { - return delegate().last(); - } - - @Override - public SortedSet subSet(E fromElement, E toElement) { - return delegate().subSet(fromElement, toElement); - } - - @Override - public SortedSet tailSet(E fromElement) { - return delegate().tailSet(fromElement); - } - - // unsafe, but worst case is a CCE is thrown, which callers will be expecting - @SuppressWarnings("unchecked") - private int unsafeCompare(Object o1, Object o2) { - Comparator comparator = comparator(); - return (comparator == null) - ? ((Comparable) o1).compareTo(o2) - : ((Comparator) comparator).compare(o1, o2); - } - - /** - * A sensible definition of {@link #contains} in terms of the {@code first()} - * method of {@link #tailSet}. If you override {@link #tailSet}, you may wish - * to override {@link #contains} to forward to this implementation. - * - * @since 7.0 - */ - @Override - @Beta - protected boolean standardContains(@Nullable Object object) { - try { - // any ClassCastExceptions are caught - @SuppressWarnings("unchecked") - SortedSet self = (SortedSet) this; - Object ceiling = self.tailSet(object).first(); - return unsafeCompare(ceiling, object) == 0; - } catch (ClassCastException e) { - return false; - } catch (NoSuchElementException e) { - return false; - } catch (NullPointerException e) { - return false; - } - } - - /** - * A sensible definition of {@link #remove} in terms of the {@code iterator()} - * method of {@link #tailSet}. If you override {@link #tailSet}, you may wish - * to override {@link #remove} to forward to this implementation. - * - * @since 7.0 - */ - @Override - @Beta - protected boolean standardRemove(@Nullable Object object) { - try { - // any ClassCastExceptions are caught - @SuppressWarnings("unchecked") - SortedSet self = (SortedSet) this; - Iterator iterator = self.tailSet(object).iterator(); - if (iterator.hasNext()) { - Object ceiling = iterator.next(); - if (unsafeCompare(ceiling, object) == 0) { - iterator.remove(); - return true; - } - } - } catch (ClassCastException e) { - return false; - } catch (NullPointerException e) { - return false; - } - return false; - } - - /** - * A sensible default implementation of {@link #subSet(Object, Object)} in - * terms of {@link #headSet(Object)} and {@link #tailSet(Object)}. In some - * situations, you may wish to override {@link #subSet(Object, Object)} to - * forward to this implementation. - * - * @since 7.0 - */ - @Beta - protected SortedSet standardSubSet(E fromElement, E toElement) { - return tailSet(fromElement).headSet(toElement); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingSortedSetMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingSortedSetMultimap.java deleted file mode 100644 index b800b7b4169c..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingSortedSetMultimap.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2010 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Comparator; -import java.util.SortedSet; - -import javax.annotation.Nullable; - -/** - * A sorted set multimap which forwards all its method calls to another sorted - * set multimap. Subclasses should override one or more methods to modify the - * behavior of the backing multimap as desired per the decorator pattern. - * - * @author Kurt Alfred Kluever - * @since 3.0 - */ -@GwtCompatible -public abstract class ForwardingSortedSetMultimap extends ForwardingSetMultimap - implements SortedSetMultimap { - - /** Constructor for use by subclasses. */ - protected ForwardingSortedSetMultimap() {} - - @Override - protected abstract SortedSetMultimap delegate(); - - @Override - public SortedSet get(@Nullable K key) { - return delegate().get(key); - } - - @Override - public SortedSet removeAll(@Nullable Object key) { - return delegate().removeAll(key); - } - - @Override - public SortedSet replaceValues(K key, Iterable values) { - return delegate().replaceValues(key, values); - } - - @Override - public Comparator valueComparator() { - return delegate().valueComparator(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingTable.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingTable.java deleted file mode 100644 index a5f1b831a945..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ForwardingTable.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Collection; -import java.util.Map; -import java.util.Set; - -/** - * A table which forwards all its method calls to another table. Subclasses - * should override one or more methods to modify the behavior of the backing - * map as desired per the decorator pattern. - * - * @author Gregory Kick - * @since 7.0 - */ -@GwtCompatible -public abstract class ForwardingTable extends ForwardingObject implements Table { - /** Constructor for use by subclasses. */ - protected ForwardingTable() {} - - @Override - protected abstract Table delegate(); - - @Override - public Set> cellSet() { - return delegate().cellSet(); - } - - @Override - public void clear() { - delegate().clear(); - } - - @Override - public Map column(C columnKey) { - return delegate().column(columnKey); - } - - @Override - public Set columnKeySet() { - return delegate().columnKeySet(); - } - - @Override - public Map> columnMap() { - return delegate().columnMap(); - } - - @Override - public boolean contains(Object rowKey, Object columnKey) { - return delegate().contains(rowKey, columnKey); - } - - @Override - public boolean containsColumn(Object columnKey) { - return delegate().containsColumn(columnKey); - } - - @Override - public boolean containsRow(Object rowKey) { - return delegate().containsRow(rowKey); - } - - @Override - public boolean containsValue(Object value) { - return delegate().containsValue(value); - } - - @Override - public V get(Object rowKey, Object columnKey) { - return delegate().get(rowKey, columnKey); - } - - @Override - public boolean isEmpty() { - return delegate().isEmpty(); - } - - @Override - public V put(R rowKey, C columnKey, V value) { - return delegate().put(rowKey, columnKey, value); - } - - @Override - public void putAll(Table table) { - delegate().putAll(table); - } - - @Override - public V remove(Object rowKey, Object columnKey) { - return delegate().remove(rowKey, columnKey); - } - - @Override - public Map row(R rowKey) { - return delegate().row(rowKey); - } - - @Override - public Set rowKeySet() { - return delegate().rowKeySet(); - } - - @Override - public Map> rowMap() { - return delegate().rowMap(); - } - - @Override - public int size() { - return delegate().size(); - } - - @Override - public Collection values() { - return delegate().values(); - } - - @Override - public boolean equals(Object obj) { - return (obj == this) || delegate().equals(obj); - } - - @Override - public int hashCode() { - return delegate().hashCode(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/GeneralRange.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/GeneralRange.java deleted file mode 100644 index 74fe62b74c96..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/GeneralRange.java +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.BoundType.CLOSED; -import static com.google.common.collect.BoundType.OPEN; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Objects; - -import java.io.Serializable; -import java.util.Comparator; - -import javax.annotation.Nullable; - -/** - * A generalized interval on any ordering, for internal use. Supports {@code null}. Unlike - * {@link Range}, this allows the use of an arbitrary comparator. This is designed for use in the - * implementation of subcollections of sorted collection types. - * - *

Whenever possible, use {@code Range} instead, which is better supported. - * - * @author Louis Wasserman - */ -@GwtCompatible(serializable = true) -final class GeneralRange implements Serializable { - /** - * Converts a Range to a GeneralRange. - */ - static GeneralRange from(Range range) { - @Nullable T lowerEndpoint = range.hasLowerBound() ? range.lowerEndpoint() : null; - BoundType lowerBoundType = range.hasLowerBound() ? range.lowerBoundType() : OPEN; - - @Nullable T upperEndpoint = range.hasUpperBound() ? range.upperEndpoint() : null; - BoundType upperBoundType = range.hasUpperBound() ? range.upperBoundType() : OPEN; - return new GeneralRange( - Ordering.natural(), - range.hasLowerBound(), - lowerEndpoint, - lowerBoundType, - range.hasUpperBound(), - upperEndpoint, - upperBoundType); - } - - /** - * Returns the whole range relative to the specified comparator. - */ - static GeneralRange all(Comparator comparator) { - return new GeneralRange(comparator, false, null, OPEN, false, null, OPEN); - } - - /** - * Returns everything above the endpoint relative to the specified comparator, with the specified - * endpoint behavior. - */ - static GeneralRange downTo( - Comparator comparator, @Nullable T endpoint, BoundType boundType) { - return new GeneralRange(comparator, true, endpoint, boundType, false, null, OPEN); - } - - /** - * Returns everything below the endpoint relative to the specified comparator, with the specified - * endpoint behavior. - */ - static GeneralRange upTo( - Comparator comparator, @Nullable T endpoint, BoundType boundType) { - return new GeneralRange(comparator, false, null, OPEN, true, endpoint, boundType); - } - - /** - * Returns everything between the endpoints relative to the specified comparator, with the - * specified endpoint behavior. - */ - static GeneralRange range( - Comparator comparator, - @Nullable T lower, - BoundType lowerType, - @Nullable T upper, - BoundType upperType) { - return new GeneralRange(comparator, true, lower, lowerType, true, upper, upperType); - } - - private final Comparator comparator; - private final boolean hasLowerBound; - @Nullable private final T lowerEndpoint; - private final BoundType lowerBoundType; - private final boolean hasUpperBound; - @Nullable private final T upperEndpoint; - private final BoundType upperBoundType; - - private GeneralRange( - Comparator comparator, - boolean hasLowerBound, - @Nullable T lowerEndpoint, - BoundType lowerBoundType, - boolean hasUpperBound, - @Nullable T upperEndpoint, - BoundType upperBoundType) { - this.comparator = checkNotNull(comparator); - this.hasLowerBound = hasLowerBound; - this.hasUpperBound = hasUpperBound; - this.lowerEndpoint = lowerEndpoint; - this.lowerBoundType = checkNotNull(lowerBoundType); - this.upperEndpoint = upperEndpoint; - this.upperBoundType = checkNotNull(upperBoundType); - - if (hasLowerBound) { - comparator.compare(lowerEndpoint, lowerEndpoint); - } - if (hasUpperBound) { - comparator.compare(upperEndpoint, upperEndpoint); - } - if (hasLowerBound && hasUpperBound) { - int cmp = comparator.compare(lowerEndpoint, upperEndpoint); - // be consistent with Range - checkArgument( - cmp <= 0, "lowerEndpoint (%s) > upperEndpoint (%s)", lowerEndpoint, upperEndpoint); - if (cmp == 0) { - checkArgument(lowerBoundType != OPEN | upperBoundType != OPEN); - } - } - } - - Comparator comparator() { - return comparator; - } - - boolean hasLowerBound() { - return hasLowerBound; - } - - boolean hasUpperBound() { - return hasUpperBound; - } - - boolean isEmpty() { - return (hasUpperBound() && tooLow(getUpperEndpoint())) - || (hasLowerBound() && tooHigh(getLowerEndpoint())); - } - - boolean tooLow(@Nullable T t) { - if (!hasLowerBound()) { - return false; - } - T lbound = getLowerEndpoint(); - int cmp = comparator.compare(t, lbound); - return cmp < 0 | (cmp == 0 & getLowerBoundType() == OPEN); - } - - boolean tooHigh(@Nullable T t) { - if (!hasUpperBound()) { - return false; - } - T ubound = getUpperEndpoint(); - int cmp = comparator.compare(t, ubound); - return cmp > 0 | (cmp == 0 & getUpperBoundType() == OPEN); - } - - boolean contains(@Nullable T t) { - return !tooLow(t) && !tooHigh(t); - } - - /** - * Returns the intersection of the two ranges, or an empty range if their intersection is empty. - */ - GeneralRange intersect(GeneralRange other) { - checkNotNull(other); - checkArgument(comparator.equals(other.comparator)); - - boolean hasLowBound = this.hasLowerBound; - @Nullable T lowEnd = getLowerEndpoint(); - BoundType lowType = getLowerBoundType(); - if (!hasLowerBound()) { - hasLowBound = other.hasLowerBound; - lowEnd = other.getLowerEndpoint(); - lowType = other.getLowerBoundType(); - } else if (other.hasLowerBound()) { - int cmp = comparator.compare(getLowerEndpoint(), other.getLowerEndpoint()); - if (cmp < 0 || (cmp == 0 && other.getLowerBoundType() == OPEN)) { - lowEnd = other.getLowerEndpoint(); - lowType = other.getLowerBoundType(); - } - } - - boolean hasUpBound = this.hasUpperBound; - @Nullable T upEnd = getUpperEndpoint(); - BoundType upType = getUpperBoundType(); - if (!hasUpperBound()) { - hasUpBound = other.hasUpperBound; - upEnd = other.getUpperEndpoint(); - upType = other.getUpperBoundType(); - } else if (other.hasUpperBound()) { - int cmp = comparator.compare(getUpperEndpoint(), other.getUpperEndpoint()); - if (cmp > 0 || (cmp == 0 && other.getUpperBoundType() == OPEN)) { - upEnd = other.getUpperEndpoint(); - upType = other.getUpperBoundType(); - } - } - - if (hasLowBound && hasUpBound) { - int cmp = comparator.compare(lowEnd, upEnd); - if (cmp > 0 || (cmp == 0 && lowType == OPEN && upType == OPEN)) { - // force allowed empty range - lowEnd = upEnd; - lowType = OPEN; - upType = CLOSED; - } - } - - return new GeneralRange(comparator, hasLowBound, lowEnd, lowType, hasUpBound, upEnd, upType); - } - - @Override - public boolean equals(@Nullable Object obj) { - if (obj instanceof GeneralRange) { - GeneralRange r = (GeneralRange) obj; - return comparator.equals(r.comparator) - && hasLowerBound == r.hasLowerBound - && hasUpperBound == r.hasUpperBound - && getLowerBoundType().equals(r.getLowerBoundType()) - && getUpperBoundType().equals(r.getUpperBoundType()) - && Objects.equal(getLowerEndpoint(), r.getLowerEndpoint()) - && Objects.equal(getUpperEndpoint(), r.getUpperEndpoint()); - } - return false; - } - - @Override - public int hashCode() { - return Objects.hashCode( - comparator, - getLowerEndpoint(), - getLowerBoundType(), - getUpperEndpoint(), - getUpperBoundType()); - } - - private transient GeneralRange reverse; - - /** - * Returns the same range relative to the reversed comparator. - */ - GeneralRange reverse() { - GeneralRange result = reverse; - if (result == null) { - result = new GeneralRange( - Ordering.from(comparator).reverse(), - hasUpperBound, - getUpperEndpoint(), - getUpperBoundType(), - hasLowerBound, - getLowerEndpoint(), - getLowerBoundType()); - result.reverse = this; - return this.reverse = result; - } - return result; - } - - @Override - public String toString() { - return new StringBuilder() - .append(comparator) - .append(":") - .append(lowerBoundType == CLOSED ? '[' : '(') - .append(hasLowerBound ? lowerEndpoint : "-\u221e") - .append(',') - .append(hasUpperBound ? upperEndpoint : "\u221e") - .append(upperBoundType == CLOSED ? ']' : ')') - .toString(); - } - - T getLowerEndpoint() { - return lowerEndpoint; - } - - BoundType getLowerBoundType() { - return lowerBoundType; - } - - T getUpperEndpoint() { - return upperEndpoint; - } - - BoundType getUpperBoundType() { - return upperBoundType; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/GenericMapMaker.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/GenericMapMaker.java deleted file mode 100644 index c951c6c36d17..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/GenericMapMaker.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2010 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS-IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.base.Equivalence; -import com.google.common.base.Function; -import com.google.common.base.MoreObjects; -import com.google.common.collect.MapMaker.RemovalListener; -import com.google.common.collect.MapMaker.RemovalNotification; - -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.TimeUnit; - -/** - * A class exactly like {@link MapMaker}, except restricted in the types of maps it can build. - * For the most part, you should probably just ignore the existence of this class. - * - * @param the base type for all key types of maps built by this map maker - * @param the base type for all value types of maps built by this map maker - * @author Kevin Bourrillion - * @since 7.0 - * @deprecated This class existed only to support the generic paramterization necessary for the - * caching functionality in {@code MapMaker}. That functionality has been moved to {@link - * com.google.common.cache.CacheBuilder}, which is a properly generified class and thus needs no - * "Generic" equivalent; simple use {@code CacheBuilder} naturally. For general migration - * instructions, see the MapMaker Migration - * Guide. - */ -@Beta -@Deprecated -@GwtCompatible(emulated = true) -abstract class GenericMapMaker { - @GwtIncompatible("To be supported") - enum NullListener implements RemovalListener { - INSTANCE; - - @Override - public void onRemoval(RemovalNotification notification) {} - } - - // Set by MapMaker, but sits in this class to preserve the type relationship - @GwtIncompatible("To be supported") - RemovalListener removalListener; - - // No subclasses but our own - GenericMapMaker() {} - - /** - * See {@link MapMaker#keyEquivalence}. - */ - @GwtIncompatible("To be supported") - abstract GenericMapMaker keyEquivalence(Equivalence equivalence); - - /** - * See {@link MapMaker#initialCapacity}. - */ - public abstract GenericMapMaker initialCapacity(int initialCapacity); - - /** - * See {@link MapMaker#maximumSize}. - */ - abstract GenericMapMaker maximumSize(int maximumSize); - - /** - * See {@link MapMaker#concurrencyLevel}. - */ - public abstract GenericMapMaker concurrencyLevel(int concurrencyLevel); - - /** - * See {@link MapMaker#weakKeys}. - */ - @GwtIncompatible("java.lang.ref.WeakReference") - public abstract GenericMapMaker weakKeys(); - - /** - * See {@link MapMaker#weakValues}. - */ - @GwtIncompatible("java.lang.ref.WeakReference") - public abstract GenericMapMaker weakValues(); - - /** - * See {@link MapMaker#softValues}. - * - * @deprecated Caching functionality in {@code MapMaker} has been moved to {@link - * com.google.common.cache.CacheBuilder}, with {@link #softValues} being replaced by {@link - * com.google.common.cache.CacheBuilder#softValues}. Note that {@code CacheBuilder} is simply - * an enhanced API for an implementation which was branched from {@code MapMaker}. - */ - @Deprecated - @GwtIncompatible("java.lang.ref.SoftReference") - abstract GenericMapMaker softValues(); - - /** - * See {@link MapMaker#expireAfterWrite}. - */ - abstract GenericMapMaker expireAfterWrite(long duration, TimeUnit unit); - - /** - * See {@link MapMaker#expireAfterAccess}. - */ - @GwtIncompatible("To be supported") - abstract GenericMapMaker expireAfterAccess(long duration, TimeUnit unit); - - /* - * Note that MapMaker's removalListener() is not here, because once you're interacting with a - * GenericMapMaker you've already called that, and shouldn't be calling it again. - */ - - @SuppressWarnings("unchecked") // safe covariant cast - @GwtIncompatible("To be supported") - RemovalListener getRemovalListener() { - return (RemovalListener) MoreObjects.firstNonNull(removalListener, NullListener.INSTANCE); - } - - /** - * See {@link MapMaker#makeMap}. - */ - public abstract ConcurrentMap makeMap(); - - /** - * See {@link MapMaker#makeCustomMap}. - */ - @GwtIncompatible("MapMakerInternalMap") - abstract MapMakerInternalMap makeCustomMap(); - - /** - * See {@link MapMaker#makeComputingMap}. - */ - @Deprecated - abstract ConcurrentMap makeComputingMap( - Function computingFunction); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/GwtTransient.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/GwtTransient.java deleted file mode 100644 index 1719456acad0..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/GwtTransient.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static java.lang.annotation.ElementType.FIELD; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import com.google.common.annotations.GwtCompatible; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -/** - * Private replacement for {@link com.google.gwt.user.client.rpc.GwtTransient} - * to work around build-system quirks. This annotation should be used - * only in {@code com.google.common.collect}. - */ -@Documented -@GwtCompatible -@Retention(RUNTIME) -@Target(FIELD) -@interface GwtTransient {} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/HashBasedTable.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/HashBasedTable.java deleted file mode 100644 index b58d60086e57..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/HashBasedTable.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.collect.CollectPreconditions.checkNonnegative; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Supplier; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; - -import javax.annotation.Nullable; - -/** - * Implementation of {@link Table} using hash tables. - * - *

The views returned by {@link #column}, {@link #columnKeySet()}, and {@link - * #columnMap()} have iterators that don't support {@code remove()}. Otherwise, - * all optional operations are supported. Null row keys, columns keys, and - * values are not supported. - * - *

Lookups by row key are often faster than lookups by column key, because - * the data is stored in a {@code Map>}. A method call like {@code - * column(columnKey).get(rowKey)} still runs quickly, since the row key is - * provided. However, {@code column(columnKey).size()} takes longer, since an - * iteration across all row keys occurs. - * - *

Note that this implementation is not synchronized. If multiple threads - * access this table concurrently and one of the threads modifies the table, it - * must be synchronized externally. - * - *

See the Guava User Guide article on - * {@code Table}. - * - * @author Jared Levy - * @since 7.0 - */ -@GwtCompatible(serializable = true) -public class HashBasedTable extends StandardTable { - private static class Factory implements Supplier>, Serializable { - final int expectedSize; - - Factory(int expectedSize) { - this.expectedSize = expectedSize; - } - - @Override - public Map get() { - return Maps.newHashMapWithExpectedSize(expectedSize); - } - - private static final long serialVersionUID = 0; - } - - /** - * Creates an empty {@code HashBasedTable}. - */ - public static HashBasedTable create() { - return new HashBasedTable(new HashMap>(), new Factory(0)); - } - - /** - * Creates an empty {@code HashBasedTable} with the specified map sizes. - * - * @param expectedRows the expected number of distinct row keys - * @param expectedCellsPerRow the expected number of column key / value - * mappings in each row - * @throws IllegalArgumentException if {@code expectedRows} or {@code - * expectedCellsPerRow} is negative - */ - public static HashBasedTable create( - int expectedRows, int expectedCellsPerRow) { - checkNonnegative(expectedCellsPerRow, "expectedCellsPerRow"); - Map> backingMap = Maps.newHashMapWithExpectedSize(expectedRows); - return new HashBasedTable(backingMap, new Factory(expectedCellsPerRow)); - } - - /** - * Creates a {@code HashBasedTable} with the same mappings as the specified - * table. - * - * @param table the table to copy - * @throws NullPointerException if any of the row keys, column keys, or values - * in {@code table} is null - */ - public static HashBasedTable create( - Table table) { - HashBasedTable result = create(); - result.putAll(table); - return result; - } - - HashBasedTable(Map> backingMap, Factory factory) { - super(backingMap, factory); - } - - // Overriding so NullPointerTester test passes. - - @Override - public boolean contains(@Nullable Object rowKey, @Nullable Object columnKey) { - return super.contains(rowKey, columnKey); - } - - @Override - public boolean containsColumn(@Nullable Object columnKey) { - return super.containsColumn(columnKey); - } - - @Override - public boolean containsRow(@Nullable Object rowKey) { - return super.containsRow(rowKey); - } - - @Override - public boolean containsValue(@Nullable Object value) { - return super.containsValue(value); - } - - @Override - public V get(@Nullable Object rowKey, @Nullable Object columnKey) { - return super.get(rowKey, columnKey); - } - - @Override - public boolean equals(@Nullable Object obj) { - return super.equals(obj); - } - - @Override - public V remove(@Nullable Object rowKey, @Nullable Object columnKey) { - return super.remove(rowKey, columnKey); - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/HashBiMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/HashBiMap.java deleted file mode 100644 index e2738fe9bc27..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/HashBiMap.java +++ /dev/null @@ -1,708 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.collect.CollectPreconditions.checkNonnegative; -import static com.google.common.collect.CollectPreconditions.checkRemove; -import static com.google.common.collect.Hashing.smearedHash; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.base.Objects; -import com.google.common.collect.Maps.IteratorBasedAbstractMap; -import com.google.j2objc.annotations.WeakOuter; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.util.AbstractMap; -import java.util.Arrays; -import java.util.ConcurrentModificationException; -import java.util.Iterator; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * A {@link BiMap} backed by two hash tables. This implementation allows null keys and values. A - * {@code HashBiMap} and its inverse are both serializable. - * - *

See the Guava User Guide article on {@code BiMap} - * . - * - * @author Louis Wasserman - * @author Mike Bostock - * @since 2.0 - */ -@GwtCompatible(emulated = true) -public final class HashBiMap extends IteratorBasedAbstractMap - implements BiMap, Serializable { - - /** - * Returns a new, empty {@code HashBiMap} with the default initial capacity (16). - */ - public static HashBiMap create() { - return create(16); - } - - /** - * Constructs a new, empty bimap with the specified expected size. - * - * @param expectedSize the expected number of entries - * @throws IllegalArgumentException if the specified expected size is negative - */ - public static HashBiMap create(int expectedSize) { - return new HashBiMap(expectedSize); - } - - /** - * Constructs a new bimap containing initial values from {@code map}. The bimap is created with an - * initial capacity sufficient to hold the mappings in the specified map. - */ - public static HashBiMap create(Map map) { - HashBiMap bimap = create(map.size()); - bimap.putAll(map); - return bimap; - } - - private static final class BiEntry extends ImmutableEntry { - final int keyHash; - final int valueHash; - - @Nullable BiEntry nextInKToVBucket; - @Nullable BiEntry nextInVToKBucket; - - @Nullable BiEntry nextInKeyInsertionOrder; - @Nullable BiEntry prevInKeyInsertionOrder; - - BiEntry(K key, int keyHash, V value, int valueHash) { - super(key, value); - this.keyHash = keyHash; - this.valueHash = valueHash; - } - } - - private static final double LOAD_FACTOR = 1.0; - - private transient BiEntry[] hashTableKToV; - private transient BiEntry[] hashTableVToK; - private transient BiEntry firstInKeyInsertionOrder; - private transient BiEntry lastInKeyInsertionOrder; - private transient int size; - private transient int mask; - private transient int modCount; - - private HashBiMap(int expectedSize) { - init(expectedSize); - } - - private void init(int expectedSize) { - checkNonnegative(expectedSize, "expectedSize"); - int tableSize = Hashing.closedTableSize(expectedSize, LOAD_FACTOR); - this.hashTableKToV = createTable(tableSize); - this.hashTableVToK = createTable(tableSize); - this.firstInKeyInsertionOrder = null; - this.lastInKeyInsertionOrder = null; - this.size = 0; - this.mask = tableSize - 1; - this.modCount = 0; - } - - /** - * Finds and removes {@code entry} from the bucket linked lists in both the - * key-to-value direction and the value-to-key direction. - */ - private void delete(BiEntry entry) { - int keyBucket = entry.keyHash & mask; - BiEntry prevBucketEntry = null; - for (BiEntry bucketEntry = hashTableKToV[keyBucket]; - true; - bucketEntry = bucketEntry.nextInKToVBucket) { - if (bucketEntry == entry) { - if (prevBucketEntry == null) { - hashTableKToV[keyBucket] = entry.nextInKToVBucket; - } else { - prevBucketEntry.nextInKToVBucket = entry.nextInKToVBucket; - } - break; - } - prevBucketEntry = bucketEntry; - } - - int valueBucket = entry.valueHash & mask; - prevBucketEntry = null; - for (BiEntry bucketEntry = hashTableVToK[valueBucket]; - true; - bucketEntry = bucketEntry.nextInVToKBucket) { - if (bucketEntry == entry) { - if (prevBucketEntry == null) { - hashTableVToK[valueBucket] = entry.nextInVToKBucket; - } else { - prevBucketEntry.nextInVToKBucket = entry.nextInVToKBucket; - } - break; - } - prevBucketEntry = bucketEntry; - } - - if (entry.prevInKeyInsertionOrder == null) { - firstInKeyInsertionOrder = entry.nextInKeyInsertionOrder; - } else { - entry.prevInKeyInsertionOrder.nextInKeyInsertionOrder = entry.nextInKeyInsertionOrder; - } - - if (entry.nextInKeyInsertionOrder == null) { - lastInKeyInsertionOrder = entry.prevInKeyInsertionOrder; - } else { - entry.nextInKeyInsertionOrder.prevInKeyInsertionOrder = entry.prevInKeyInsertionOrder; - } - - size--; - modCount++; - } - - private void insert(BiEntry entry, @Nullable BiEntry oldEntryForKey) { - int keyBucket = entry.keyHash & mask; - entry.nextInKToVBucket = hashTableKToV[keyBucket]; - hashTableKToV[keyBucket] = entry; - - int valueBucket = entry.valueHash & mask; - entry.nextInVToKBucket = hashTableVToK[valueBucket]; - hashTableVToK[valueBucket] = entry; - - if (oldEntryForKey == null) { - entry.prevInKeyInsertionOrder = lastInKeyInsertionOrder; - entry.nextInKeyInsertionOrder = null; - if (lastInKeyInsertionOrder == null) { - firstInKeyInsertionOrder = entry; - } else { - lastInKeyInsertionOrder.nextInKeyInsertionOrder = entry; - } - lastInKeyInsertionOrder = entry; - } else { - entry.prevInKeyInsertionOrder = oldEntryForKey.prevInKeyInsertionOrder; - if (entry.prevInKeyInsertionOrder == null) { - firstInKeyInsertionOrder = entry; - } else { - entry.prevInKeyInsertionOrder.nextInKeyInsertionOrder = entry; - } - entry.nextInKeyInsertionOrder = oldEntryForKey.nextInKeyInsertionOrder; - if (entry.nextInKeyInsertionOrder == null) { - lastInKeyInsertionOrder = entry; - } else { - entry.nextInKeyInsertionOrder.prevInKeyInsertionOrder = entry; - } - } - - size++; - modCount++; - } - - private BiEntry seekByKey(@Nullable Object key, int keyHash) { - for (BiEntry entry = hashTableKToV[keyHash & mask]; - entry != null; - entry = entry.nextInKToVBucket) { - if (keyHash == entry.keyHash && Objects.equal(key, entry.key)) { - return entry; - } - } - return null; - } - - private BiEntry seekByValue(@Nullable Object value, int valueHash) { - for (BiEntry entry = hashTableVToK[valueHash & mask]; - entry != null; - entry = entry.nextInVToKBucket) { - if (valueHash == entry.valueHash && Objects.equal(value, entry.value)) { - return entry; - } - } - return null; - } - - @Override - public boolean containsKey(@Nullable Object key) { - return seekByKey(key, smearedHash(key)) != null; - } - - @Override - public boolean containsValue(@Nullable Object value) { - return seekByValue(value, smearedHash(value)) != null; - } - - @Nullable - @Override - public V get(@Nullable Object key) { - return Maps.valueOrNull(seekByKey(key, smearedHash(key))); - } - - @Override - public V put(@Nullable K key, @Nullable V value) { - return put(key, value, false); - } - - @Override - public V forcePut(@Nullable K key, @Nullable V value) { - return put(key, value, true); - } - - private V put(@Nullable K key, @Nullable V value, boolean force) { - int keyHash = smearedHash(key); - int valueHash = smearedHash(value); - - BiEntry oldEntryForKey = seekByKey(key, keyHash); - if (oldEntryForKey != null - && valueHash == oldEntryForKey.valueHash - && Objects.equal(value, oldEntryForKey.value)) { - return value; - } - - BiEntry oldEntryForValue = seekByValue(value, valueHash); - if (oldEntryForValue != null) { - if (force) { - delete(oldEntryForValue); - } else { - throw new IllegalArgumentException("value already present: " + value); - } - } - - BiEntry newEntry = new BiEntry(key, keyHash, value, valueHash); - if (oldEntryForKey != null) { - delete(oldEntryForKey); - insert(newEntry, oldEntryForKey); - oldEntryForKey.prevInKeyInsertionOrder = null; - oldEntryForKey.nextInKeyInsertionOrder = null; - rehashIfNecessary(); - return oldEntryForKey.value; - } else { - insert(newEntry, null); - rehashIfNecessary(); - return null; - } - } - - @Nullable - private K putInverse(@Nullable V value, @Nullable K key, boolean force) { - int valueHash = smearedHash(value); - int keyHash = smearedHash(key); - - BiEntry oldEntryForValue = seekByValue(value, valueHash); - if (oldEntryForValue != null - && keyHash == oldEntryForValue.keyHash - && Objects.equal(key, oldEntryForValue.key)) { - return key; - } - - BiEntry oldEntryForKey = seekByKey(key, keyHash); - if (oldEntryForKey != null) { - if (force) { - delete(oldEntryForKey); - } else { - throw new IllegalArgumentException("value already present: " + key); - } - } - - if (oldEntryForValue != null) { - delete(oldEntryForValue); - } - BiEntry newEntry = new BiEntry(key, keyHash, value, valueHash); - insert(newEntry, oldEntryForKey); - if (oldEntryForKey != null) { - oldEntryForKey.prevInKeyInsertionOrder = null; - oldEntryForKey.nextInKeyInsertionOrder = null; - } - rehashIfNecessary(); - return Maps.keyOrNull(oldEntryForValue); - } - - private void rehashIfNecessary() { - BiEntry[] oldKToV = hashTableKToV; - if (Hashing.needsResizing(size, oldKToV.length, LOAD_FACTOR)) { - int newTableSize = oldKToV.length * 2; - - this.hashTableKToV = createTable(newTableSize); - this.hashTableVToK = createTable(newTableSize); - this.mask = newTableSize - 1; - this.size = 0; - - for (BiEntry entry = firstInKeyInsertionOrder; - entry != null; - entry = entry.nextInKeyInsertionOrder) { - insert(entry, entry); - } - this.modCount++; - } - } - - @SuppressWarnings("unchecked") - private BiEntry[] createTable(int length) { - return new BiEntry[length]; - } - - @Override - public V remove(@Nullable Object key) { - BiEntry entry = seekByKey(key, smearedHash(key)); - if (entry == null) { - return null; - } else { - delete(entry); - entry.prevInKeyInsertionOrder = null; - entry.nextInKeyInsertionOrder = null; - return entry.value; - } - } - - @Override - public void clear() { - size = 0; - Arrays.fill(hashTableKToV, null); - Arrays.fill(hashTableVToK, null); - firstInKeyInsertionOrder = null; - lastInKeyInsertionOrder = null; - modCount++; - } - - @Override - public int size() { - return size; - } - - abstract class Itr implements Iterator { - BiEntry next = firstInKeyInsertionOrder; - BiEntry toRemove = null; - int expectedModCount = modCount; - - @Override - public boolean hasNext() { - if (modCount != expectedModCount) { - throw new ConcurrentModificationException(); - } - return next != null; - } - - @Override - public T next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - - BiEntry entry = next; - next = entry.nextInKeyInsertionOrder; - toRemove = entry; - return output(entry); - } - - @Override - public void remove() { - if (modCount != expectedModCount) { - throw new ConcurrentModificationException(); - } - checkRemove(toRemove != null); - delete(toRemove); - expectedModCount = modCount; - toRemove = null; - } - - abstract T output(BiEntry entry); - } - - @Override - public Set keySet() { - return new KeySet(); - } - - @WeakOuter - private final class KeySet extends Maps.KeySet { - KeySet() { - super(HashBiMap.this); - } - - @Override - public Iterator iterator() { - return new Itr() { - @Override - K output(BiEntry entry) { - return entry.key; - } - }; - } - - @Override - public boolean remove(@Nullable Object o) { - BiEntry entry = seekByKey(o, smearedHash(o)); - if (entry == null) { - return false; - } else { - delete(entry); - entry.prevInKeyInsertionOrder = null; - entry.nextInKeyInsertionOrder = null; - return true; - } - } - } - - @Override - public Set values() { - return inverse().keySet(); - } - - @Override - Iterator> entryIterator() { - return new Itr>() { - @Override - Entry output(BiEntry entry) { - return new MapEntry(entry); - } - - class MapEntry extends AbstractMapEntry { - BiEntry delegate; - - MapEntry(BiEntry entry) { - this.delegate = entry; - } - - @Override - public K getKey() { - return delegate.key; - } - - @Override - public V getValue() { - return delegate.value; - } - - @Override - public V setValue(V value) { - V oldValue = delegate.value; - int valueHash = smearedHash(value); - if (valueHash == delegate.valueHash && Objects.equal(value, oldValue)) { - return value; - } - checkArgument(seekByValue(value, valueHash) == null, "value already present: %s", value); - delete(delegate); - BiEntry newEntry = - new BiEntry(delegate.key, delegate.keyHash, value, valueHash); - insert(newEntry, delegate); - delegate.prevInKeyInsertionOrder = null; - delegate.nextInKeyInsertionOrder = null; - expectedModCount = modCount; - if (toRemove == delegate) { - toRemove = newEntry; - } - delegate = newEntry; - return oldValue; - } - } - }; - } - - private transient BiMap inverse; - - @Override - public BiMap inverse() { - return (inverse == null) ? inverse = new Inverse() : inverse; - } - - private final class Inverse extends AbstractMap implements BiMap, Serializable { - BiMap forward() { - return HashBiMap.this; - } - - @Override - public int size() { - return size; - } - - @Override - public void clear() { - forward().clear(); - } - - @Override - public boolean containsKey(@Nullable Object value) { - return forward().containsValue(value); - } - - @Override - public K get(@Nullable Object value) { - return Maps.keyOrNull(seekByValue(value, smearedHash(value))); - } - - @Override - public K put(@Nullable V value, @Nullable K key) { - return putInverse(value, key, false); - } - - @Override - public K forcePut(@Nullable V value, @Nullable K key) { - return putInverse(value, key, true); - } - - @Override - public K remove(@Nullable Object value) { - BiEntry entry = seekByValue(value, smearedHash(value)); - if (entry == null) { - return null; - } else { - delete(entry); - entry.prevInKeyInsertionOrder = null; - entry.nextInKeyInsertionOrder = null; - return entry.key; - } - } - - @Override - public BiMap inverse() { - return forward(); - } - - @Override - public Set keySet() { - return new InverseKeySet(); - } - - @WeakOuter - private final class InverseKeySet extends Maps.KeySet { - InverseKeySet() { - super(Inverse.this); - } - - @Override - public boolean remove(@Nullable Object o) { - BiEntry entry = seekByValue(o, smearedHash(o)); - if (entry == null) { - return false; - } else { - delete(entry); - return true; - } - } - - @Override - public Iterator iterator() { - return new Itr() { - @Override - V output(BiEntry entry) { - return entry.value; - } - }; - } - } - - @Override - public Set values() { - return forward().keySet(); - } - - @Override - public Set> entrySet() { - return new Maps.EntrySet() { - - @Override - Map map() { - return Inverse.this; - } - - @Override - public Iterator> iterator() { - return new Itr>() { - @Override - Entry output(BiEntry entry) { - return new InverseEntry(entry); - } - - class InverseEntry extends AbstractMapEntry { - BiEntry delegate; - - InverseEntry(BiEntry entry) { - this.delegate = entry; - } - - @Override - public V getKey() { - return delegate.value; - } - - @Override - public K getValue() { - return delegate.key; - } - - @Override - public K setValue(K key) { - K oldKey = delegate.key; - int keyHash = smearedHash(key); - if (keyHash == delegate.keyHash && Objects.equal(key, oldKey)) { - return key; - } - checkArgument(seekByKey(key, keyHash) == null, "value already present: %s", key); - delete(delegate); - BiEntry newEntry = - new BiEntry(key, keyHash, delegate.value, delegate.valueHash); - delegate = newEntry; - insert(newEntry, null); - expectedModCount = modCount; - // This is safe because entries can only get bumped up to earlier in the iteration, - // so they can't get revisited. - return oldKey; - } - } - }; - } - }; - } - - Object writeReplace() { - return new InverseSerializedForm(HashBiMap.this); - } - } - - private static final class InverseSerializedForm implements Serializable { - private final HashBiMap bimap; - - InverseSerializedForm(HashBiMap bimap) { - this.bimap = bimap; - } - - Object readResolve() { - return bimap.inverse(); - } - } - - /** - * @serialData the number of entries, first key, first value, second key, second value, and so on. - */ - @GwtIncompatible("java.io.ObjectOutputStream") - private void writeObject(ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); - Serialization.writeMap(this, stream); - } - - @GwtIncompatible("java.io.ObjectInputStream") - private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - init(16); - int size = Serialization.readCount(stream); - Serialization.populateMap(this, stream, size); - } - - @GwtIncompatible("Not needed in emulated source") - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/HashMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/HashMultimap.java deleted file mode 100644 index 36dd38578bad..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/HashMultimap.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Preconditions; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -/** - * Implementation of {@link Multimap} using hash tables. - * - *

The multimap does not store duplicate key-value pairs. Adding a new - * key-value pair equal to an existing key-value pair has no effect. - * - *

Keys and values may be null. All optional multimap methods are supported, - * and all returned views are modifiable. - * - *

This class is not threadsafe when any concurrent operations update the - * multimap. Concurrent read operations will work correctly. To allow concurrent - * update operations, wrap your multimap with a call to {@link - * Multimaps#synchronizedSetMultimap}. - * - * @author Jared Levy - * @since 2.0 - */ -@GwtCompatible(serializable = true, emulated = true) -public final class HashMultimap extends AbstractSetMultimap { - private static final int DEFAULT_VALUES_PER_KEY = 2; - - @VisibleForTesting transient int expectedValuesPerKey = DEFAULT_VALUES_PER_KEY; - - /** - * Creates a new, empty {@code HashMultimap} with the default initial - * capacities. - */ - public static HashMultimap create() { - return new HashMultimap(); - } - - /** - * Constructs an empty {@code HashMultimap} with enough capacity to hold the - * specified numbers of keys and values without rehashing. - * - * @param expectedKeys the expected number of distinct keys - * @param expectedValuesPerKey the expected average number of values per key - * @throws IllegalArgumentException if {@code expectedKeys} or {@code - * expectedValuesPerKey} is negative - */ - public static HashMultimap create(int expectedKeys, int expectedValuesPerKey) { - return new HashMultimap(expectedKeys, expectedValuesPerKey); - } - - /** - * Constructs a {@code HashMultimap} with the same mappings as the specified - * multimap. If a key-value mapping appears multiple times in the input - * multimap, it only appears once in the constructed multimap. - * - * @param multimap the multimap whose contents are copied to this multimap - */ - public static HashMultimap create(Multimap multimap) { - return new HashMultimap(multimap); - } - - private HashMultimap() { - super(new HashMap>()); - } - - private HashMultimap(int expectedKeys, int expectedValuesPerKey) { - super(Maps.>newHashMapWithExpectedSize(expectedKeys)); - Preconditions.checkArgument(expectedValuesPerKey >= 0); - this.expectedValuesPerKey = expectedValuesPerKey; - } - - private HashMultimap(Multimap multimap) { - super(Maps.>newHashMapWithExpectedSize(multimap.keySet().size())); - putAll(multimap); - } - - /** - * {@inheritDoc} - * - *

Creates an empty {@code HashSet} for a collection of values for one key. - * - * @return a new {@code HashSet} containing a collection of values for one key - */ - @Override - Set createCollection() { - return Sets.newHashSetWithExpectedSize(expectedValuesPerKey); - } - - /** - * @serialData expectedValuesPerKey, number of distinct keys, and then for - * each distinct key: the key, number of values for that key, and the - * key's values - */ - @GwtIncompatible("java.io.ObjectOutputStream") - private void writeObject(ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); - Serialization.writeMultimap(this, stream); - } - - @GwtIncompatible("java.io.ObjectInputStream") - private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - expectedValuesPerKey = DEFAULT_VALUES_PER_KEY; - int distinctKeys = Serialization.readCount(stream); - Map> map = Maps.newHashMap(); - setMap(map); - Serialization.populateMultimap(this, stream, distinctKeys); - } - - @GwtIncompatible("Not needed in emulated source") - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/HashMultiset.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/HashMultiset.java deleted file mode 100644 index c2a79ffdb94d..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/HashMultiset.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.HashMap; - -/** - * Multiset implementation backed by a {@link HashMap}. - * - * @author Kevin Bourrillion - * @author Jared Levy - * @since 2.0 - */ -@GwtCompatible(serializable = true, emulated = true) -public final class HashMultiset extends AbstractMapBasedMultiset { - - /** - * Creates a new, empty {@code HashMultiset} using the default initial - * capacity. - */ - public static HashMultiset create() { - return new HashMultiset(); - } - - /** - * Creates a new, empty {@code HashMultiset} with the specified expected - * number of distinct elements. - * - * @param distinctElements the expected number of distinct elements - * @throws IllegalArgumentException if {@code distinctElements} is negative - */ - public static HashMultiset create(int distinctElements) { - return new HashMultiset(distinctElements); - } - - /** - * Creates a new {@code HashMultiset} containing the specified elements. - * - *

This implementation is highly efficient when {@code elements} is itself - * a {@link Multiset}. - * - * @param elements the elements that the multiset should contain - */ - public static HashMultiset create(Iterable elements) { - HashMultiset multiset = create(Multisets.inferDistinctElements(elements)); - Iterables.addAll(multiset, elements); - return multiset; - } - - private HashMultiset() { - super(new HashMap()); - } - - private HashMultiset(int distinctElements) { - super(Maps.newHashMapWithExpectedSize(distinctElements)); - } - - /** - * @serialData the number of distinct elements, the first element, its count, - * the second element, its count, and so on - */ - @GwtIncompatible("java.io.ObjectOutputStream") - private void writeObject(ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); - Serialization.writeMultiset(this, stream); - } - - @GwtIncompatible("java.io.ObjectInputStream") - private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - int distinctElements = Serialization.readCount(stream); - setBackingMap(Maps.newHashMap()); - Serialization.populateMultiset(this, stream, distinctElements); - } - - @GwtIncompatible("Not needed in emulated source.") - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Hashing.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Hashing.java deleted file mode 100644 index 2220007b177e..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Hashing.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.primitives.Ints; - -import javax.annotation.Nullable; - -/** - * Static methods for implementing hash-based collections. - * - * @author Kevin Bourrillion - * @author Jesse Wilson - * @author Austin Appleby - */ -@GwtCompatible -final class Hashing { - private Hashing() {} - - private static final int C1 = 0xcc9e2d51; - private static final int C2 = 0x1b873593; - - /* - * This method was rewritten in Java from an intermediate step of the Murmur hash function in - * http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp, which contained the - * following header: - * - * MurmurHash3 was written by Austin Appleby, and is placed in the public domain. The author - * hereby disclaims copyright to this source code. - */ - static int smear(int hashCode) { - return C2 * Integer.rotateLeft(hashCode * C1, 15); - } - - static int smearedHash(@Nullable Object o) { - return smear((o == null) ? 0 : o.hashCode()); - } - - private static int MAX_TABLE_SIZE = Ints.MAX_POWER_OF_TWO; - - static int closedTableSize(int expectedEntries, double loadFactor) { - // Get the recommended table size. - // Round down to the nearest power of 2. - expectedEntries = Math.max(expectedEntries, 2); - int tableSize = Integer.highestOneBit(expectedEntries); - // Check to make sure that we will not exceed the maximum load factor. - if (expectedEntries > (int) (loadFactor * tableSize)) { - tableSize <<= 1; - return (tableSize > 0) ? tableSize : MAX_TABLE_SIZE; - } - return tableSize; - } - - static boolean needsResizing(int size, int tableSize, double loadFactor) { - return size > loadFactor * tableSize && tableSize < MAX_TABLE_SIZE; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableAsList.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableAsList.java deleted file mode 100644 index ff123e56fe64..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableAsList.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; - -import java.io.InvalidObjectException; -import java.io.ObjectInputStream; -import java.io.Serializable; - -/** - * List returned by {@link ImmutableCollection#asList} that delegates {@code contains} checks - * to the backing collection. - * - * @author Jared Levy - * @author Louis Wasserman - */ -@GwtCompatible(serializable = true, emulated = true) -@SuppressWarnings("serial") -abstract class ImmutableAsList extends ImmutableList { - abstract ImmutableCollection delegateCollection(); - - @Override - public boolean contains(Object target) { - // The collection's contains() is at least as fast as ImmutableList's - // and is often faster. - return delegateCollection().contains(target); - } - - @Override - public int size() { - return delegateCollection().size(); - } - - @Override - public boolean isEmpty() { - return delegateCollection().isEmpty(); - } - - @Override - boolean isPartialView() { - return delegateCollection().isPartialView(); - } - - /** - * Serialized form that leads to the same performance as the original list. - */ - @GwtIncompatible("serialization") - static class SerializedForm implements Serializable { - final ImmutableCollection collection; - - SerializedForm(ImmutableCollection collection) { - this.collection = collection; - } - - Object readResolve() { - return collection.asList(); - } - - private static final long serialVersionUID = 0; - } - - @GwtIncompatible("serialization") - private void readObject(ObjectInputStream stream) throws InvalidObjectException { - throw new InvalidObjectException("Use SerializedForm"); - } - - @GwtIncompatible("serialization") - @Override - Object writeReplace() { - return new SerializedForm(delegateCollection()); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableBiMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableBiMap.java deleted file mode 100644 index 2c531b396b32..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableBiMap.java +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import java.util.Arrays; -import java.util.Comparator; -import java.util.Map; - -/** - * A {@link BiMap} whose contents will never change, with many other important properties detailed - * at {@link ImmutableCollection}. - * - * @author Jared Levy - * @since 2.0 - */ -@GwtCompatible(serializable = true, emulated = true) -public abstract class ImmutableBiMap extends ImmutableMap implements BiMap { - - /** - * Returns the empty bimap. - */ - // Casting to any type is safe because the set will never hold any elements. - @SuppressWarnings("unchecked") - public static ImmutableBiMap of() { - return (ImmutableBiMap) RegularImmutableBiMap.EMPTY; - } - - /** - * Returns an immutable bimap containing a single entry. - */ - public static ImmutableBiMap of(K k1, V v1) { - return new SingletonImmutableBiMap(k1, v1); - } - - /** - * Returns an immutable map containing the given entries, in order. - * - * @throws IllegalArgumentException if duplicate keys or values are added - */ - public static ImmutableBiMap of(K k1, V v1, K k2, V v2) { - return RegularImmutableBiMap.fromEntries(entryOf(k1, v1), entryOf(k2, v2)); - } - - /** - * Returns an immutable map containing the given entries, in order. - * - * @throws IllegalArgumentException if duplicate keys or values are added - */ - public static ImmutableBiMap of(K k1, V v1, K k2, V v2, K k3, V v3) { - return RegularImmutableBiMap.fromEntries(entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3)); - } - - /** - * Returns an immutable map containing the given entries, in order. - * - * @throws IllegalArgumentException if duplicate keys or values are added - */ - public static ImmutableBiMap of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { - return RegularImmutableBiMap.fromEntries( - entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3), entryOf(k4, v4)); - } - - /** - * Returns an immutable map containing the given entries, in order. - * - * @throws IllegalArgumentException if duplicate keys or values are added - */ - public static ImmutableBiMap of( - K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { - return RegularImmutableBiMap.fromEntries( - entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3), entryOf(k4, v4), entryOf(k5, v5)); - } - - // looking for of() with > 5 entries? Use the builder instead. - - /** - * Returns a new builder. The generated builder is equivalent to the builder - * created by the {@link Builder} constructor. - */ - public static Builder builder() { - return new Builder(); - } - - /** - * A builder for creating immutable bimap instances, especially {@code public - * static final} bimaps ("constant bimaps"). Example:

   {@code
-   *
-   *   static final ImmutableBiMap WORD_TO_INT =
-   *       new ImmutableBiMap.Builder()
-   *           .put("one", 1)
-   *           .put("two", 2)
-   *           .put("three", 3)
-   *           .build();}
- * - *

For small immutable bimaps, the {@code ImmutableBiMap.of()} methods - * are even more convenient. - * - *

Builder instances can be reused - it is safe to call {@link #build} - * multiple times to build multiple bimaps in series. Each bimap is a superset - * of the bimaps created before it. - * - * @since 2.0 - */ - public static final class Builder extends ImmutableMap.Builder { - - /** - * Creates a new builder. The returned builder is equivalent to the builder - * generated by {@link ImmutableBiMap#builder}. - */ - public Builder() {} - - Builder(int size) { - super(size); - } - - /** - * Associates {@code key} with {@code value} in the built bimap. Duplicate - * keys or values are not allowed, and will cause {@link #build} to fail. - */ - @Override - public Builder put(K key, V value) { - super.put(key, value); - return this; - } - - /** - * Adds the given {@code entry} to the bimap. Duplicate keys or values - * are not allowed, and will cause {@link #build} to fail. - * - * @since 19.0 - */ - @Override - public Builder put(Entry entry) { - super.put(entry); - return this; - } - - /** - * Associates all of the given map's keys and values in the built bimap. - * Duplicate keys or values are not allowed, and will cause {@link #build} - * to fail. - * - * @throws NullPointerException if any key or value in {@code map} is null - */ - @Override - public Builder putAll(Map map) { - super.putAll(map); - return this; - } - - /** - * Adds all of the given entries to the built bimap. Duplicate keys or - * values are not allowed, and will cause {@link #build} to fail. - * - * @throws NullPointerException if any key, value, or entry is null - * @since 19.0 - */ - @Beta - @Override - public Builder putAll(Iterable> entries) { - super.putAll(entries); - return this; - } - - /** - * Configures this {@code Builder} to order entries by value according to the specified - * comparator. - * - *

The sort order is stable, that is, if two entries have values that compare - * as equivalent, the entry that was inserted first will be first in the built map's - * iteration order. - * - * @throws IllegalStateException if this method was already called - * @since 19.0 - */ - @Beta - @Override - public Builder orderEntriesByValue(Comparator valueComparator) { - super.orderEntriesByValue(valueComparator); - return this; - } - - /** - * Returns a newly-created immutable bimap. - * - * @throws IllegalArgumentException if duplicate keys or values were added - */ - @Override - public ImmutableBiMap build() { - switch (size) { - case 0: - return of(); - case 1: - return of(entries[0].getKey(), entries[0].getValue()); - default: - /* - * If entries is full, then this implementation may end up using the entries array - * directly and writing over the entry objects with non-terminal entries, but this is - * safe; if this Builder is used further, it will grow the entries array (so it can't - * affect the original array), and future build() calls will always copy any entry - * objects that cannot be safely reused. - */ - if (valueComparator != null) { - if (entriesUsed) { - entries = ObjectArrays.arraysCopyOf(entries, size); - } - Arrays.sort( - entries, - 0, - size, - Ordering.from(valueComparator).onResultOf(Maps.valueFunction())); - } - entriesUsed = size == entries.length; - return RegularImmutableBiMap.fromEntryArray(size, entries); - } - } - } - - /** - * Returns an immutable bimap containing the same entries as {@code map}. If - * {@code map} somehow contains entries with duplicate keys (for example, if - * it is a {@code SortedMap} whose comparator is not consistent with - * equals), the results of this method are undefined. - * - *

Despite the method name, this method attempts to avoid actually copying - * the data when it is safe to do so. The exact circumstances under which a - * copy will or will not be performed are undocumented and subject to change. - * - * @throws IllegalArgumentException if two keys have the same value - * @throws NullPointerException if any key or value in {@code map} is null - */ - public static ImmutableBiMap copyOf(Map map) { - if (map instanceof ImmutableBiMap) { - @SuppressWarnings("unchecked") // safe since map is not writable - ImmutableBiMap bimap = (ImmutableBiMap) map; - // TODO(lowasser): if we need to make a copy of a BiMap because the - // forward map is a view, don't make a copy of the non-view delegate map - if (!bimap.isPartialView()) { - return bimap; - } - } - return copyOf(map.entrySet()); - } - - /** - * Returns an immutable bimap containing the given entries. - * - * @throws IllegalArgumentException if two keys have the same value or two - * values have the same key - * @throws NullPointerException if any key, value, or entry is null - * @since 19.0 - */ - @Beta - public static ImmutableBiMap copyOf( - Iterable> entries) { - @SuppressWarnings("unchecked") // we'll only be using getKey and getValue, which are covariant - Entry[] entryArray = (Entry[]) Iterables.toArray(entries, EMPTY_ENTRY_ARRAY); - switch (entryArray.length) { - case 0: - return of(); - case 1: - Entry entry = entryArray[0]; - return of(entry.getKey(), entry.getValue()); - default: - /* - * The current implementation will end up using entryArray directly, though it will write - * over the (arbitrary, potentially mutable) Entry objects actually stored in entryArray. - */ - return RegularImmutableBiMap.fromEntries(entryArray); - } - } - - ImmutableBiMap() {} - - /** - * {@inheritDoc} - * - *

The inverse of an {@code ImmutableBiMap} is another - * {@code ImmutableBiMap}. - */ - @Override - public abstract ImmutableBiMap inverse(); - - /** - * Returns an immutable set of the values in this map. The values are in the - * same order as the parameters used to build this map. - */ - @Override - public ImmutableSet values() { - return inverse().keySet(); - } - - /** - * Guaranteed to throw an exception and leave the bimap unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public V forcePut(K key, V value) { - throw new UnsupportedOperationException(); - } - - /** - * Serialized type for all ImmutableBiMap instances. It captures the logical - * contents and they are reconstructed using public factory methods. This - * ensures that the implementation types remain as implementation details. - * - * Since the bimap is immutable, ImmutableBiMap doesn't require special logic - * for keeping the bimap and its inverse in sync during serialization, the way - * AbstractBiMap does. - */ - private static class SerializedForm extends ImmutableMap.SerializedForm { - SerializedForm(ImmutableBiMap bimap) { - super(bimap); - } - - @Override - Object readResolve() { - Builder builder = new Builder(); - return createMap(builder); - } - - private static final long serialVersionUID = 0; - } - - @Override - Object writeReplace() { - return new SerializedForm(this); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableClassToInstanceMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableClassToInstanceMap.java deleted file mode 100644 index a74ae5fd8d49..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableClassToInstanceMap.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.primitives.Primitives; - -import java.io.Serializable; -import java.util.Map; - -import javax.annotation.Nullable; - -/** - * A {@link ClassToInstanceMap} whose contents will never change, with many - * other important properties detailed at {@link ImmutableCollection}. - * - * @author Kevin Bourrillion - * @since 2.0 - */ -public final class ImmutableClassToInstanceMap extends ForwardingMap, B> - implements ClassToInstanceMap, Serializable { - - private static final ImmutableClassToInstanceMap EMPTY = - new ImmutableClassToInstanceMap(ImmutableMap., Object>of()); - - /** - * Returns an empty {@code ImmutableClassToInstanceMap}. - * - * @since 19.0 - */ - @SuppressWarnings("unchecked") - public static ImmutableClassToInstanceMap of() { - return (ImmutableClassToInstanceMap) EMPTY; - } - - /** - * Returns an {@code ImmutableClassToInstanceMap} containing a single entry. - * - * @since 19.0 - */ - public static ImmutableClassToInstanceMap of(Class type, T value) { - ImmutableMap, B> map = ImmutableMap., B>of(type, value); - return new ImmutableClassToInstanceMap(map); - } - - /** - * Returns a new builder. The generated builder is equivalent to the builder - * created by the {@link Builder} constructor. - */ - public static Builder builder() { - return new Builder(); - } - - /** - * A builder for creating immutable class-to-instance maps. Example: - *
   {@code
-   *
-   *   static final ImmutableClassToInstanceMap HANDLERS =
-   *       new ImmutableClassToInstanceMap.Builder()
-   *           .put(FooHandler.class, new FooHandler())
-   *           .put(BarHandler.class, new SubBarHandler())
-   *           .put(Handler.class, new QuuxHandler())
-   *           .build();}
- * - *

After invoking {@link #build()} it is still possible to add more entries - * and build again. Thus each map generated by this builder will be a superset - * of any map generated before it. - * - * @since 2.0 - */ - public static final class Builder { - private final ImmutableMap.Builder, B> mapBuilder = ImmutableMap.builder(); - - /** - * Associates {@code key} with {@code value} in the built map. Duplicate - * keys are not allowed, and will cause {@link #build} to fail. - */ - public Builder put(Class key, T value) { - mapBuilder.put(key, value); - return this; - } - - /** - * Associates all of {@code map's} keys and values in the built map. - * Duplicate keys are not allowed, and will cause {@link #build} to fail. - * - * @throws NullPointerException if any key or value in {@code map} is null - * @throws ClassCastException if any value is not an instance of the type - * specified by its key - */ - public Builder putAll(Map, ? extends T> map) { - for (Entry, ? extends T> entry : map.entrySet()) { - Class type = entry.getKey(); - T value = entry.getValue(); - mapBuilder.put(type, cast(type, value)); - } - return this; - } - - private static T cast(Class type, B value) { - return Primitives.wrap(type).cast(value); - } - - /** - * Returns a new immutable class-to-instance map containing the entries - * provided to this builder. - * - * @throws IllegalArgumentException if duplicate keys were added - */ - public ImmutableClassToInstanceMap build() { - ImmutableMap, B> map = mapBuilder.build(); - if (map.isEmpty()) { - return of(); - } else { - return new ImmutableClassToInstanceMap(map); - } - } - } - - /** - * Returns an immutable map containing the same entries as {@code map}. If - * {@code map} somehow contains entries with duplicate keys (for example, if - * it is a {@code SortedMap} whose comparator is not consistent with - * equals), the results of this method are undefined. - * - *

Note: Despite what the method name suggests, if {@code map} is - * an {@code ImmutableClassToInstanceMap}, no copy will actually be performed. - * - * @throws NullPointerException if any key or value in {@code map} is null - * @throws ClassCastException if any value is not an instance of the type - * specified by its key - */ - public static ImmutableClassToInstanceMap copyOf( - Map, ? extends S> map) { - if (map instanceof ImmutableClassToInstanceMap) { - @SuppressWarnings("unchecked") // covariant casts safe (unmodifiable) - // Eclipse won't compile if we cast to the parameterized type. - ImmutableClassToInstanceMap cast = (ImmutableClassToInstanceMap) map; - return cast; - } - return new Builder().putAll(map).build(); - } - - private final ImmutableMap, B> delegate; - - private ImmutableClassToInstanceMap(ImmutableMap, B> delegate) { - this.delegate = delegate; - } - - @Override - protected Map, B> delegate() { - return delegate; - } - - @Override - @SuppressWarnings("unchecked") // value could not get in if not a T - @Nullable - public T getInstance(Class type) { - return (T) delegate.get(checkNotNull(type)); - } - - /** - * Guaranteed to throw an exception and leave the map unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public T putInstance(Class type, T value) { - throw new UnsupportedOperationException(); - } - - Object readResolve() { - return isEmpty() ? of() : this; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableCollection.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableCollection.java deleted file mode 100644 index 606629f98935..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableCollection.java +++ /dev/null @@ -1,474 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.CollectPreconditions.checkNonnegative; -import static com.google.common.collect.ObjectArrays.checkElementsNotNull; - -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; -import java.util.AbstractCollection; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import javax.annotation.Nullable; - -/** - * A {@link Collection} whose contents will never change, and which offers a few additional - * guarantees detailed below. - * - *

Warning: avoid direct usage of {@link ImmutableCollection} as a type (just as - * with {@link Collection} itself). Prefer subtypes such as {@link ImmutableSet} or {@link - * ImmutableList}, which have well-defined {@link #equals} semantics, thus avoiding a common source - * of bugs and confusion. - * - *

About all {@code Immutable-} collections

- * - *

The remainder of this documentation applies to every public {@code Immutable-} type in this - * package, whether it is a subtype of {@code ImmutableCollection} or not. - * - *

Guarantees

- * - *

Each makes the following guarantees: - * - *

    - *
  • Shallow immutability. Elements can never be added, removed or replaced in this - * collection. This is a stronger guarantee than that of - * {@link Collections#unmodifiableCollection}, whose contents change whenever the wrapped - * collection is modified. - *
  • Null-hostility. This collection will never contain a null element. - *
  • Deterministic iteration. The iteration order is always well-defined, depending on how - * the collection was created (see the appropriate factory method for details). View collections - * such as {@link ImmutableMultiset#elementSet} iterate in the same order as the parent, except - * as noted. - *
  • Thread safety. It is safe to access this collection concurrently from multiple - * threads. - *
  • Integrity. This type cannot be subclassed outside this package (which would allow - * these guarantees to be violated). - *
- * - *

"Interfaces", not implementations

- * - *

Each public class, such as {@link ImmutableSet}, is a type offering meaningful - * behavioral guarantees -- not merely a specific implementation as in the case of, say, - * {@link ArrayList}. You should treat them as interfaces in every important sense of the word. - * - *

For field types and method return types, you should generally use the immutable type (such as - * {@link ImmutableList}) instead of the general collection interface type (such as {@link List}). - * This communicates to your callers all of the semantic guarantees listed above, which is almost - * always very useful information. - * - *

On the other hand, a parameter type of {@link ImmutableList} is generally a nuisance to - * callers. Instead, accept {@link Iterable} and have your method or constructor body pass it to the - * appropriate {@code copyOf} method itself. - * - *

Creation

- * - *

Except for logically "abstract" types like {@code ImmutableCollection} itself, each {@code - * Immutable} type provides the static operations you need to obtain instances of that type. These - * usually include: - * - *

    - *
  • Static methods named {@code of}, accepting an explicit list of elements or entries. - *
  • Static methods named {@code copyOf} (or {@code copyOfSorted}), accepting an existing - * collection whose contents should be copied. - *
  • A static nested {@code Builder} class which can be used to populate a new immutable instance. - *
- * - *

Warnings

- * - *
    - *
  • Warning: as with any collection, it is almost always a bad idea to modify an element - * (in a way that affects its {@link Object#equals} behavior) while it is contained in a - * collection. Undefined behavior and bugs will result. It's generally best to avoid using - * mutable objects as elements at all, as many users may expect your "immutable" object to be - * deeply immutable. - *
- * - *

Performance notes

- * - *
    - *
  • Implementations can be generally assumed to prioritize memory efficiency, then speed of - * access, and lastly speed of creation. - *
  • The {@code copyOf} methods will sometimes recognize that the actual copy operation is - * unnecessary; for example, {@code copyOf(copyOf(anArrayList))} should copy the data only once. - * This reduces the expense of habitually making defensive copies at API boundaries. However, - * the precise conditions for skipping the copy operation are undefined. - *
  • Warning: a view collection such as {@link ImmutableMap#keySet} or {@link - * ImmutableList#subList} may retain a reference to the entire data set, preventing it from - * being garbage collected. If some of the data is no longer reachable through other means, this - * constitutes a memory leak. Pass the view collection to the appropriate {@code copyOf} method - * to obtain a correctly-sized copy. - *
  • The performance of using the associated {@code Builder} class can be assumed to be - * no worse, and possibly better, than creating a mutable collection and copying it. - *
  • Implementations generally do not cache hash codes. If your element or key type has a slow - * {@code hashCode} implementation, it should cache it itself. - *
- * - *

Example usage

- * - *
   {@code
- *
- *   class Foo {
- *     private static final ImmutableSet RESERVED_CODES =
- *         ImmutableSet.of("AZ", "CQ", "ZX");
- *
- *     private final ImmutableSet codes;
- *
- *     public Foo(Iterable codes) {
- *       this.codes = ImmutableSet.copyOf(codes);
- *       checkArgument(Collections.disjoint(this.codes, RESERVED_CODES));
- *     }
- *   }}
- * - *

See also

- * - *

See the Guava User Guide article on - * immutable collections. - * - * @since 2.0 - */ -@GwtCompatible(emulated = true) -@SuppressWarnings("serial") // we're overriding default serialization -// TODO(kevinb): I think we should push everything down to "BaseImmutableCollection" or something, -// just to do everything we can to emphasize the "practically an interface" nature of this class. -public abstract class ImmutableCollection extends AbstractCollection implements Serializable { - - ImmutableCollection() {} - - /** - * Returns an unmodifiable iterator across the elements in this collection. - */ - @Override - public abstract UnmodifiableIterator iterator(); - - @Override - public final Object[] toArray() { - int size = size(); - if (size == 0) { - return ObjectArrays.EMPTY_ARRAY; - } - Object[] result = new Object[size]; - copyIntoArray(result, 0); - return result; - } - - @Override - public final T[] toArray(T[] other) { - checkNotNull(other); - int size = size(); - if (other.length < size) { - other = ObjectArrays.newArray(other, size); - } else if (other.length > size) { - other[size] = null; - } - copyIntoArray(other, 0); - return other; - } - - @Override - public abstract boolean contains(@Nullable Object object); - - /** - * Guaranteed to throw an exception and leave the collection unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final boolean add(E e) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the collection unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final boolean remove(Object object) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the collection unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final boolean addAll(Collection newElements) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the collection unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final boolean removeAll(Collection oldElements) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the collection unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final boolean retainAll(Collection elementsToKeep) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the collection unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final void clear() { - throw new UnsupportedOperationException(); - } - - /* - * TODO(kevinb): Restructure code so ImmutableList doesn't contain this - * variable, which it doesn't use. - */ - private transient ImmutableList asList; - - /** - * Returns an {@code ImmutableList} containing the same elements, in the same order, as this - * collection. - * - *

Performance note: in most cases this method can return quickly without actually - * copying anything. The exact circumstances under which the copy is performed are undefined and - * subject to change. - * - * @since 2.0 - */ - public ImmutableList asList() { - ImmutableList list = asList; - return (list == null) ? (asList = createAsList()) : list; - } - - ImmutableList createAsList() { - switch (size()) { - case 0: - return ImmutableList.of(); - case 1: - return ImmutableList.of(iterator().next()); - default: - return new RegularImmutableAsList(this, toArray()); - } - } - - /** - * Returns {@code true} if this immutable collection's implementation contains references to - * user-created objects that aren't accessible via this collection's methods. This is generally - * used to determine whether {@code copyOf} implementations should make an explicit copy to avoid - * memory leaks. - */ - abstract boolean isPartialView(); - - /** - * Copies the contents of this immutable collection into the specified array at the specified - * offset. Returns {@code offset + size()}. - */ - int copyIntoArray(Object[] dst, int offset) { - for (E e : this) { - dst[offset++] = e; - } - return offset; - } - - Object writeReplace() { - // We serialize by default to ImmutableList, the simplest thing that works. - return new ImmutableList.SerializedForm(toArray()); - } - - /** - * Abstract base class for builders of {@link ImmutableCollection} types. - * - * @since 10.0 - */ - public abstract static class Builder { - static final int DEFAULT_INITIAL_CAPACITY = 4; - - static int expandedCapacity(int oldCapacity, int minCapacity) { - if (minCapacity < 0) { - throw new AssertionError("cannot store more than MAX_VALUE elements"); - } - // careful of overflow! - int newCapacity = oldCapacity + (oldCapacity >> 1) + 1; - if (newCapacity < minCapacity) { - newCapacity = Integer.highestOneBit(minCapacity - 1) << 1; - } - if (newCapacity < 0) { - newCapacity = Integer.MAX_VALUE; - // guaranteed to be >= newCapacity - } - return newCapacity; - } - - Builder() {} - - /** - * Adds {@code element} to the {@code ImmutableCollection} being built. - * - *

Note that each builder class covariantly returns its own type from - * this method. - * - * @param element the element to add - * @return this {@code Builder} instance - * @throws NullPointerException if {@code element} is null - */ - public abstract Builder add(E element); - - /** - * Adds each element of {@code elements} to the {@code ImmutableCollection} - * being built. - * - *

Note that each builder class overrides this method in order to - * covariantly return its own type. - * - * @param elements the elements to add - * @return this {@code Builder} instance - * @throws NullPointerException if {@code elements} is null or contains a - * null element - */ - public Builder add(E... elements) { - for (E element : elements) { - add(element); - } - return this; - } - - /** - * Adds each element of {@code elements} to the {@code ImmutableCollection} - * being built. - * - *

Note that each builder class overrides this method in order to - * covariantly return its own type. - * - * @param elements the elements to add - * @return this {@code Builder} instance - * @throws NullPointerException if {@code elements} is null or contains a - * null element - */ - public Builder addAll(Iterable elements) { - for (E element : elements) { - add(element); - } - return this; - } - - /** - * Adds each element of {@code elements} to the {@code ImmutableCollection} - * being built. - * - *

Note that each builder class overrides this method in order to - * covariantly return its own type. - * - * @param elements the elements to add - * @return this {@code Builder} instance - * @throws NullPointerException if {@code elements} is null or contains a - * null element - */ - public Builder addAll(Iterator elements) { - while (elements.hasNext()) { - add(elements.next()); - } - return this; - } - - /** - * Returns a newly-created {@code ImmutableCollection} of the appropriate - * type, containing the elements provided to this builder. - * - *

Note that each builder class covariantly returns the appropriate type - * of {@code ImmutableCollection} from this method. - */ - public abstract ImmutableCollection build(); - } - - abstract static class ArrayBasedBuilder extends ImmutableCollection.Builder { - Object[] contents; - int size; - - ArrayBasedBuilder(int initialCapacity) { - checkNonnegative(initialCapacity, "initialCapacity"); - this.contents = new Object[initialCapacity]; - this.size = 0; - } - - /** - * Expand the absolute capacity of the builder so it can accept at least - * the specified number of elements without being resized. - */ - private void ensureCapacity(int minCapacity) { - if (contents.length < minCapacity) { - this.contents = - ObjectArrays.arraysCopyOf( - this.contents, expandedCapacity(contents.length, minCapacity)); - } - } - - @Override - public ArrayBasedBuilder add(E element) { - checkNotNull(element); - ensureCapacity(size + 1); - contents[size++] = element; - return this; - } - - @Override - public Builder add(E... elements) { - checkElementsNotNull(elements); - ensureCapacity(size + elements.length); - System.arraycopy(elements, 0, contents, size, elements.length); - size += elements.length; - return this; - } - - @Override - public Builder addAll(Iterable elements) { - if (elements instanceof Collection) { - Collection collection = (Collection) elements; - ensureCapacity(size + collection.size()); - } - super.addAll(elements); - return this; - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableEntry.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableEntry.java deleted file mode 100644 index b17d5cbb3886..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableEntry.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; - -import javax.annotation.Nullable; - -/** - * @see com.google.common.collect.Maps#immutableEntry(Object, Object) - */ -@GwtCompatible(serializable = true) -class ImmutableEntry extends AbstractMapEntry implements Serializable { - final K key; - final V value; - - ImmutableEntry(@Nullable K key, @Nullable V value) { - this.key = key; - this.value = value; - } - - @Nullable - @Override - public final K getKey() { - return key; - } - - @Nullable - @Override - public final V getValue() { - return value; - } - - @Override - public final V setValue(V value) { - throw new UnsupportedOperationException(); - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableEnumMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableEnumMap.java deleted file mode 100644 index c361fa52c518..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableEnumMap.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.collect.ImmutableMap.IteratorBasedImmutableMap; - -import java.io.Serializable; -import java.util.EnumMap; - -import javax.annotation.Nullable; - -/** - * Implementation of {@link ImmutableMap} backed by a non-empty {@link - * java.util.EnumMap}. - * - * @author Louis Wasserman - */ -@GwtCompatible(serializable = true, emulated = true) -@SuppressWarnings("serial") // we're overriding default serialization -final class ImmutableEnumMap, V> extends IteratorBasedImmutableMap { - static , V> ImmutableMap asImmutable(EnumMap map) { - switch (map.size()) { - case 0: - return ImmutableMap.of(); - case 1: - Entry entry = Iterables.getOnlyElement(map.entrySet()); - return ImmutableMap.of(entry.getKey(), entry.getValue()); - default: - return new ImmutableEnumMap(map); - } - } - - private transient final EnumMap delegate; - - private ImmutableEnumMap(EnumMap delegate) { - this.delegate = delegate; - checkArgument(!delegate.isEmpty()); - } - - @Override - UnmodifiableIterator keyIterator() { - return Iterators.unmodifiableIterator(delegate.keySet().iterator()); - } - - @Override - public int size() { - return delegate.size(); - } - - @Override - public boolean containsKey(@Nullable Object key) { - return delegate.containsKey(key); - } - - @Override - public V get(Object key) { - return delegate.get(key); - } - - @Override - public boolean equals(Object object) { - if (object == this) { - return true; - } - if (object instanceof ImmutableEnumMap) { - object = ((ImmutableEnumMap) object).delegate; - } - return delegate.equals(object); - } - - @Override - UnmodifiableIterator> entryIterator() { - return Maps.unmodifiableEntryIterator(delegate.entrySet().iterator()); - } - - @Override - boolean isPartialView() { - return false; - } - - // All callers of the constructor are restricted to >. - @Override - Object writeReplace() { - return new EnumSerializedForm(delegate); - } - - /* - * This class is used to serialize ImmutableEnumMap instances. - */ - private static class EnumSerializedForm, V> implements Serializable { - final EnumMap delegate; - - EnumSerializedForm(EnumMap delegate) { - this.delegate = delegate; - } - - Object readResolve() { - return new ImmutableEnumMap(delegate); - } - - private static final long serialVersionUID = 0; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableEnumSet.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableEnumSet.java deleted file mode 100644 index 67e82454ab4b..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableEnumSet.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; -import java.util.Collection; -import java.util.EnumSet; - -/** - * Implementation of {@link ImmutableSet} backed by a non-empty {@link - * java.util.EnumSet}. - * - * @author Jared Levy - */ -@GwtCompatible(serializable = true, emulated = true) -@SuppressWarnings("serial") // we're overriding default serialization -final class ImmutableEnumSet> extends ImmutableSet { - @SuppressWarnings("rawtypes") // necessary to compile against Java 8 - static ImmutableSet asImmutable(EnumSet set) { - switch (set.size()) { - case 0: - return ImmutableSet.of(); - case 1: - return ImmutableSet.of(Iterables.getOnlyElement(set)); - default: - return new ImmutableEnumSet(set); - } - } - - /* - * Notes on EnumSet and >: - * - * This class isn't an arbitrary ForwardingImmutableSet because we need to - * know that calling {@code clone()} during deserialization will return an - * object that no one else has a reference to, allowing us to guarantee - * immutability. Hence, we support only {@link EnumSet}. - */ - private final transient EnumSet delegate; - - private ImmutableEnumSet(EnumSet delegate) { - this.delegate = delegate; - } - - @Override - boolean isPartialView() { - return false; - } - - @Override - public UnmodifiableIterator iterator() { - return Iterators.unmodifiableIterator(delegate.iterator()); - } - - @Override - public int size() { - return delegate.size(); - } - - @Override - public boolean contains(Object object) { - return delegate.contains(object); - } - - @Override - public boolean containsAll(Collection collection) { - if (collection instanceof ImmutableEnumSet) { - collection = ((ImmutableEnumSet) collection).delegate; - } - return delegate.containsAll(collection); - } - - @Override - public boolean isEmpty() { - return delegate.isEmpty(); - } - - @Override - public boolean equals(Object object) { - if (object == this) { - return true; - } - if (object instanceof ImmutableEnumSet) { - object = ((ImmutableEnumSet) object).delegate; - } - return delegate.equals(object); - } - - @Override - boolean isHashCodeFast() { - return true; - } - - private transient int hashCode; - - @Override - public int hashCode() { - int result = hashCode; - return (result == 0) ? hashCode = delegate.hashCode() : result; - } - - @Override - public String toString() { - return delegate.toString(); - } - - // All callers of the constructor are restricted to >. - @Override - Object writeReplace() { - return new EnumSerializedForm(delegate); - } - - /* - * This class is used to serialize ImmutableEnumSet instances. - */ - private static class EnumSerializedForm> implements Serializable { - final EnumSet delegate; - - EnumSerializedForm(EnumSet delegate) { - this.delegate = delegate; - } - - Object readResolve() { - // EJ2 #76: Write readObject() methods defensively. - return new ImmutableEnumSet(delegate.clone()); - } - - private static final long serialVersionUID = 0; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableList.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableList.java deleted file mode 100644 index 273772e3887a..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableList.java +++ /dev/null @@ -1,705 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkElementIndex; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkPositionIndexes; -import static com.google.common.collect.ObjectArrays.arraysCopyOf; -import static com.google.common.collect.ObjectArrays.checkElementsNotNull; -import static com.google.common.collect.RegularImmutableList.EMPTY; - -import com.google.common.annotations.GwtCompatible; - -import java.io.InvalidObjectException; -import java.io.ObjectInputStream; -import java.io.Serializable; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.RandomAccess; - -import javax.annotation.Nullable; - -/** - * A {@link List} whose contents will never change, with many other important properties detailed at - * {@link ImmutableCollection}. - * - *

See the Guava User Guide article on - * immutable collections. - * - * @see ImmutableMap - * @see ImmutableSet - * @author Kevin Bourrillion - * @since 2.0 - */ -@GwtCompatible(serializable = true, emulated = true) -@SuppressWarnings("serial") // we're overriding default serialization -public abstract class ImmutableList extends ImmutableCollection - implements List, RandomAccess { - /** - * Returns the empty immutable list. This set behaves and performs comparably - * to {@link Collections#emptyList}, and is preferable mainly for consistency - * and maintainability of your code. - */ - // Casting to any type is safe because the list will never hold any elements. - @SuppressWarnings("unchecked") - public static ImmutableList of() { - return (ImmutableList) EMPTY; - } - - /** - * Returns an immutable list containing a single element. This list behaves - * and performs comparably to {@link Collections#singleton}, but will not - * accept a null element. It is preferable mainly for consistency and - * maintainability of your code. - * - * @throws NullPointerException if {@code element} is null - */ - public static ImmutableList of(E element) { - return new SingletonImmutableList(element); - } - - /** - * Returns an immutable list containing the given elements, in order. - * - * @throws NullPointerException if any element is null - */ - public static ImmutableList of(E e1, E e2) { - return construct(e1, e2); - } - - /** - * Returns an immutable list containing the given elements, in order. - * - * @throws NullPointerException if any element is null - */ - public static ImmutableList of(E e1, E e2, E e3) { - return construct(e1, e2, e3); - } - - /** - * Returns an immutable list containing the given elements, in order. - * - * @throws NullPointerException if any element is null - */ - public static ImmutableList of(E e1, E e2, E e3, E e4) { - return construct(e1, e2, e3, e4); - } - - /** - * Returns an immutable list containing the given elements, in order. - * - * @throws NullPointerException if any element is null - */ - public static ImmutableList of(E e1, E e2, E e3, E e4, E e5) { - return construct(e1, e2, e3, e4, e5); - } - - /** - * Returns an immutable list containing the given elements, in order. - * - * @throws NullPointerException if any element is null - */ - public static ImmutableList of(E e1, E e2, E e3, E e4, E e5, E e6) { - return construct(e1, e2, e3, e4, e5, e6); - } - - /** - * Returns an immutable list containing the given elements, in order. - * - * @throws NullPointerException if any element is null - */ - public static ImmutableList of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) { - return construct(e1, e2, e3, e4, e5, e6, e7); - } - - /** - * Returns an immutable list containing the given elements, in order. - * - * @throws NullPointerException if any element is null - */ - public static ImmutableList of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) { - return construct(e1, e2, e3, e4, e5, e6, e7, e8); - } - - /** - * Returns an immutable list containing the given elements, in order. - * - * @throws NullPointerException if any element is null - */ - public static ImmutableList of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) { - return construct(e1, e2, e3, e4, e5, e6, e7, e8, e9); - } - - /** - * Returns an immutable list containing the given elements, in order. - * - * @throws NullPointerException if any element is null - */ - public static ImmutableList of( - E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) { - return construct(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10); - } - - /** - * Returns an immutable list containing the given elements, in order. - * - * @throws NullPointerException if any element is null - */ - public static ImmutableList of( - E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11) { - return construct(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11); - } - - // These go up to eleven. After that, you just get the varargs form, and - // whatever warnings might come along with it. :( - - /** - * Returns an immutable list containing the given elements, in order. - * - * @throws NullPointerException if any element is null - * @since 3.0 (source-compatible since 2.0) - */ - public static ImmutableList of( - E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11, E e12, E... others) { - Object[] array = new Object[12 + others.length]; - array[0] = e1; - array[1] = e2; - array[2] = e3; - array[3] = e4; - array[4] = e5; - array[5] = e6; - array[6] = e7; - array[7] = e8; - array[8] = e9; - array[9] = e10; - array[10] = e11; - array[11] = e12; - System.arraycopy(others, 0, array, 12, others.length); - return construct(array); - } - - /** - * Returns an immutable list containing the given elements, in order. If - * {@code elements} is a {@link Collection}, this method behaves exactly as - * {@link #copyOf(Collection)}; otherwise, it behaves exactly as {@code - * copyOf(elements.iterator()}. - * - * @throws NullPointerException if any of {@code elements} is null - */ - public static ImmutableList copyOf(Iterable elements) { - checkNotNull(elements); // TODO(kevinb): is this here only for GWT? - return (elements instanceof Collection) - ? copyOf((Collection) elements) - : copyOf(elements.iterator()); - } - - /** - * Returns an immutable list containing the given elements, in order. - * - *

Despite the method name, this method attempts to avoid actually copying - * the data when it is safe to do so. The exact circumstances under which a - * copy will or will not be performed are undocumented and subject to change. - * - *

Note that if {@code list} is a {@code List}, then {@code - * ImmutableList.copyOf(list)} returns an {@code ImmutableList} - * containing each of the strings in {@code list}, while - * ImmutableList.of(list)} returns an {@code ImmutableList>} - * containing one element (the given list itself). - * - *

This method is safe to use even when {@code elements} is a synchronized - * or concurrent collection that is currently being modified by another - * thread. - * - * @throws NullPointerException if any of {@code elements} is null - */ - public static ImmutableList copyOf(Collection elements) { - if (elements instanceof ImmutableCollection) { - @SuppressWarnings("unchecked") // all supported methods are covariant - ImmutableList list = ((ImmutableCollection) elements).asList(); - return list.isPartialView() ? ImmutableList.asImmutableList(list.toArray()) : list; - } - return construct(elements.toArray()); - } - - /** - * Returns an immutable list containing the given elements, in order. - * - * @throws NullPointerException if any of {@code elements} is null - */ - public static ImmutableList copyOf(Iterator elements) { - // We special-case for 0 or 1 elements, but going further is madness. - if (!elements.hasNext()) { - return of(); - } - E first = elements.next(); - if (!elements.hasNext()) { - return of(first); - } else { - return new ImmutableList.Builder().add(first).addAll(elements).build(); - } - } - - /** - * Returns an immutable list containing the given elements, in order. - * - * @throws NullPointerException if any of {@code elements} is null - * @since 3.0 - */ - public static ImmutableList copyOf(E[] elements) { - switch (elements.length) { - case 0: - return ImmutableList.of(); - case 1: - return new SingletonImmutableList(elements[0]); - default: - return new RegularImmutableList(checkElementsNotNull(elements.clone())); - } - } - - /** - * Views the array as an immutable list. Checks for nulls; does not copy. - */ - private static ImmutableList construct(Object... elements) { - return asImmutableList(checkElementsNotNull(elements)); - } - - /** - * Views the array as an immutable list. Does not check for nulls; does not copy. - * - *

The array must be internally created. - */ - static ImmutableList asImmutableList(Object[] elements) { - return asImmutableList(elements, elements.length); - } - - /** - * Views the array as an immutable list. Copies if the specified range does not cover the complete - * array. Does not check for nulls. - */ - static ImmutableList asImmutableList(Object[] elements, int length) { - switch (length) { - case 0: - return of(); - case 1: - @SuppressWarnings("unchecked") // collection had only Es in it - ImmutableList list = new SingletonImmutableList((E) elements[0]); - return list; - default: - if (length < elements.length) { - elements = arraysCopyOf(elements, length); - } - return new RegularImmutableList(elements); - } - } - - ImmutableList() {} - - // This declaration is needed to make List.iterator() and - // ImmutableCollection.iterator() consistent. - @Override - public UnmodifiableIterator iterator() { - return listIterator(); - } - - @Override - public UnmodifiableListIterator listIterator() { - return listIterator(0); - } - - @Override - public UnmodifiableListIterator listIterator(int index) { - return new AbstractIndexedListIterator(size(), index) { - @Override - protected E get(int index) { - return ImmutableList.this.get(index); - } - }; - } - - @Override - public int indexOf(@Nullable Object object) { - return (object == null) ? -1 : Lists.indexOfImpl(this, object); - } - - @Override - public int lastIndexOf(@Nullable Object object) { - return (object == null) ? -1 : Lists.lastIndexOfImpl(this, object); - } - - @Override - public boolean contains(@Nullable Object object) { - return indexOf(object) >= 0; - } - - // constrain the return type to ImmutableList - - /** - * Returns an immutable list of the elements between the specified {@code - * fromIndex}, inclusive, and {@code toIndex}, exclusive. (If {@code - * fromIndex} and {@code toIndex} are equal, the empty immutable list is - * returned.) - */ - @Override - public ImmutableList subList(int fromIndex, int toIndex) { - checkPositionIndexes(fromIndex, toIndex, size()); - int length = toIndex - fromIndex; - if (length == size()) { - return this; - } - switch (length) { - case 0: - return of(); - case 1: - return of(get(fromIndex)); - default: - return subListUnchecked(fromIndex, toIndex); - } - } - - /** - * Called by the default implementation of {@link #subList} when {@code - * toIndex - fromIndex > 1}, after index validation has already been - * performed. - */ - ImmutableList subListUnchecked(int fromIndex, int toIndex) { - return new SubList(fromIndex, toIndex - fromIndex); - } - - class SubList extends ImmutableList { - final transient int offset; - final transient int length; - - SubList(int offset, int length) { - this.offset = offset; - this.length = length; - } - - @Override - public int size() { - return length; - } - - @Override - public E get(int index) { - checkElementIndex(index, length); - return ImmutableList.this.get(index + offset); - } - - @Override - public ImmutableList subList(int fromIndex, int toIndex) { - checkPositionIndexes(fromIndex, toIndex, length); - return ImmutableList.this.subList(fromIndex + offset, toIndex + offset); - } - - @Override - boolean isPartialView() { - return true; - } - } - - /** - * Guaranteed to throw an exception and leave the list unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final boolean addAll(int index, Collection newElements) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the list unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final E set(int index, E element) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the list unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final void add(int index, E element) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the list unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final E remove(int index) { - throw new UnsupportedOperationException(); - } - - /** - * Returns this list instance. - * - * @since 2.0 - */ - @Override - public final ImmutableList asList() { - return this; - } - - @Override - int copyIntoArray(Object[] dst, int offset) { - // this loop is faster for RandomAccess instances, which ImmutableLists are - int size = size(); - for (int i = 0; i < size; i++) { - dst[offset + i] = get(i); - } - return offset + size; - } - - /** - * Returns a view of this immutable list in reverse order. For example, {@code - * ImmutableList.of(1, 2, 3).reverse()} is equivalent to {@code - * ImmutableList.of(3, 2, 1)}. - * - * @return a view of this immutable list in reverse order - * @since 7.0 - */ - public ImmutableList reverse() { - return (size() <= 1) ? this : new ReverseImmutableList(this); - } - - private static class ReverseImmutableList extends ImmutableList { - private final transient ImmutableList forwardList; - - ReverseImmutableList(ImmutableList backingList) { - this.forwardList = backingList; - } - - private int reverseIndex(int index) { - return (size() - 1) - index; - } - - private int reversePosition(int index) { - return size() - index; - } - - @Override - public ImmutableList reverse() { - return forwardList; - } - - @Override - public boolean contains(@Nullable Object object) { - return forwardList.contains(object); - } - - @Override - public int indexOf(@Nullable Object object) { - int index = forwardList.lastIndexOf(object); - return (index >= 0) ? reverseIndex(index) : -1; - } - - @Override - public int lastIndexOf(@Nullable Object object) { - int index = forwardList.indexOf(object); - return (index >= 0) ? reverseIndex(index) : -1; - } - - @Override - public ImmutableList subList(int fromIndex, int toIndex) { - checkPositionIndexes(fromIndex, toIndex, size()); - return forwardList.subList(reversePosition(toIndex), reversePosition(fromIndex)).reverse(); - } - - @Override - public E get(int index) { - checkElementIndex(index, size()); - return forwardList.get(reverseIndex(index)); - } - - @Override - public int size() { - return forwardList.size(); - } - - @Override - boolean isPartialView() { - return forwardList.isPartialView(); - } - } - - @Override - public boolean equals(@Nullable Object obj) { - return Lists.equalsImpl(this, obj); - } - - @Override - public int hashCode() { - int hashCode = 1; - int n = size(); - for (int i = 0; i < n; i++) { - hashCode = 31 * hashCode + get(i).hashCode(); - - hashCode = ~~hashCode; - // needed to deal with GWT integer overflow - } - return hashCode; - } - - /* - * Serializes ImmutableLists as their logical contents. This ensures that - * implementation types do not leak into the serialized representation. - */ - static class SerializedForm implements Serializable { - final Object[] elements; - - SerializedForm(Object[] elements) { - this.elements = elements; - } - - Object readResolve() { - return copyOf(elements); - } - - private static final long serialVersionUID = 0; - } - - private void readObject(ObjectInputStream stream) throws InvalidObjectException { - throw new InvalidObjectException("Use SerializedForm"); - } - - @Override - Object writeReplace() { - return new SerializedForm(toArray()); - } - - /** - * Returns a new builder. The generated builder is equivalent to the builder - * created by the {@link Builder} constructor. - */ - public static Builder builder() { - return new Builder(); - } - - /** - * A builder for creating immutable list instances, especially {@code public - * static final} lists ("constant lists"). Example:

   {@code
-   *
-   *   public static final ImmutableList GOOGLE_COLORS
-   *       = new ImmutableList.Builder()
-   *           .addAll(WEBSAFE_COLORS)
-   *           .add(new Color(0, 191, 255))
-   *           .build();}
- * - *

Builder instances can be reused; it is safe to call {@link #build} multiple - * times to build multiple lists in series. Each new list contains all the - * elements of the ones created before it. - * - * @since 2.0 - */ - public static final class Builder extends ImmutableCollection.ArrayBasedBuilder { - /** - * Creates a new builder. The returned builder is equivalent to the builder - * generated by {@link ImmutableList#builder}. - */ - public Builder() { - this(DEFAULT_INITIAL_CAPACITY); - } - - // TODO(lowasser): consider exposing this - Builder(int capacity) { - super(capacity); - } - - /** - * Adds {@code element} to the {@code ImmutableList}. - * - * @param element the element to add - * @return this {@code Builder} object - * @throws NullPointerException if {@code element} is null - */ - @Override - public Builder add(E element) { - super.add(element); - return this; - } - - /** - * Adds each element of {@code elements} to the {@code ImmutableList}. - * - * @param elements the {@code Iterable} to add to the {@code ImmutableList} - * @return this {@code Builder} object - * @throws NullPointerException if {@code elements} is null or contains a - * null element - */ - @Override - public Builder addAll(Iterable elements) { - super.addAll(elements); - return this; - } - - /** - * Adds each element of {@code elements} to the {@code ImmutableList}. - * - * @param elements the {@code Iterable} to add to the {@code ImmutableList} - * @return this {@code Builder} object - * @throws NullPointerException if {@code elements} is null or contains a - * null element - */ - @Override - public Builder add(E... elements) { - super.add(elements); - return this; - } - - /** - * Adds each element of {@code elements} to the {@code ImmutableList}. - * - * @param elements the {@code Iterable} to add to the {@code ImmutableList} - * @return this {@code Builder} object - * @throws NullPointerException if {@code elements} is null or contains a - * null element - */ - @Override - public Builder addAll(Iterator elements) { - super.addAll(elements); - return this; - } - - /** - * Returns a newly-created {@code ImmutableList} based on the contents of - * the {@code Builder}. - */ - @Override - public ImmutableList build() { - return asImmutableList(contents, size); - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableListMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableListMultimap.java deleted file mode 100644 index f70cc527c8ea..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableListMultimap.java +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; - -import java.io.IOException; -import java.io.InvalidObjectException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.Collection; -import java.util.Comparator; -import java.util.Map.Entry; - -import javax.annotation.Nullable; - -/** - * A {@link ListMultimap} whose contents will never change, with many other important properties - * detailed at {@link ImmutableCollection}. - * - *

See the Guava User Guide article on - * immutable collections. - * - * @author Jared Levy - * @since 2.0 - */ -@GwtCompatible(serializable = true, emulated = true) -public class ImmutableListMultimap extends ImmutableMultimap - implements ListMultimap { - - /** Returns the empty multimap. */ - // Casting is safe because the multimap will never hold any elements. - @SuppressWarnings("unchecked") - public static ImmutableListMultimap of() { - return (ImmutableListMultimap) EmptyImmutableListMultimap.INSTANCE; - } - - /** - * Returns an immutable multimap containing a single entry. - */ - public static ImmutableListMultimap of(K k1, V v1) { - ImmutableListMultimap.Builder builder = ImmutableListMultimap.builder(); - builder.put(k1, v1); - return builder.build(); - } - - /** - * Returns an immutable multimap containing the given entries, in order. - */ - public static ImmutableListMultimap of(K k1, V v1, K k2, V v2) { - ImmutableListMultimap.Builder builder = ImmutableListMultimap.builder(); - builder.put(k1, v1); - builder.put(k2, v2); - return builder.build(); - } - - /** - * Returns an immutable multimap containing the given entries, in order. - */ - public static ImmutableListMultimap of(K k1, V v1, K k2, V v2, K k3, V v3) { - ImmutableListMultimap.Builder builder = ImmutableListMultimap.builder(); - builder.put(k1, v1); - builder.put(k2, v2); - builder.put(k3, v3); - return builder.build(); - } - - /** - * Returns an immutable multimap containing the given entries, in order. - */ - public static ImmutableListMultimap of( - K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { - ImmutableListMultimap.Builder builder = ImmutableListMultimap.builder(); - builder.put(k1, v1); - builder.put(k2, v2); - builder.put(k3, v3); - builder.put(k4, v4); - return builder.build(); - } - - /** - * Returns an immutable multimap containing the given entries, in order. - */ - public static ImmutableListMultimap of( - K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { - ImmutableListMultimap.Builder builder = ImmutableListMultimap.builder(); - builder.put(k1, v1); - builder.put(k2, v2); - builder.put(k3, v3); - builder.put(k4, v4); - builder.put(k5, v5); - return builder.build(); - } - - // looking for of() with > 5 entries? Use the builder instead. - - /** - * Returns a new builder. The generated builder is equivalent to the builder - * created by the {@link Builder} constructor. - */ - public static Builder builder() { - return new Builder(); - } - - /** - * A builder for creating immutable {@code ListMultimap} instances, especially - * {@code public static final} multimaps ("constant multimaps"). Example: - *

   {@code
-   *
-   *   static final Multimap STRING_TO_INTEGER_MULTIMAP =
-   *       new ImmutableListMultimap.Builder()
-   *           .put("one", 1)
-   *           .putAll("several", 1, 2, 3)
-   *           .putAll("many", 1, 2, 3, 4, 5)
-   *           .build();}
- * - *

Builder instances can be reused; it is safe to call {@link #build} multiple - * times to build multiple multimaps in series. Each multimap contains the - * key-value mappings in the previously created multimaps. - * - * @since 2.0 - */ - public static final class Builder extends ImmutableMultimap.Builder { - /** - * Creates a new builder. The returned builder is equivalent to the builder - * generated by {@link ImmutableListMultimap#builder}. - */ - public Builder() {} - - @Override - public Builder put(K key, V value) { - super.put(key, value); - return this; - } - - /** - * {@inheritDoc} - * - * @since 11.0 - */ - @Override - public Builder put(Entry entry) { - super.put(entry); - return this; - } - - /** - * {@inheritDoc} - * - * @since 19.0 - */ - @Beta - @Override - public Builder putAll(Iterable> entries) { - super.putAll(entries); - return this; - } - - @Override - public Builder putAll(K key, Iterable values) { - super.putAll(key, values); - return this; - } - - @Override - public Builder putAll(K key, V... values) { - super.putAll(key, values); - return this; - } - - @Override - public Builder putAll(Multimap multimap) { - super.putAll(multimap); - return this; - } - - /** - * {@inheritDoc} - * - * @since 8.0 - */ - @Override - public Builder orderKeysBy(Comparator keyComparator) { - super.orderKeysBy(keyComparator); - return this; - } - - /** - * {@inheritDoc} - * - * @since 8.0 - */ - @Override - public Builder orderValuesBy(Comparator valueComparator) { - super.orderValuesBy(valueComparator); - return this; - } - - /** - * Returns a newly-created immutable list multimap. - */ - @Override - public ImmutableListMultimap build() { - return (ImmutableListMultimap) super.build(); - } - } - - /** - * Returns an immutable multimap containing the same mappings as {@code - * multimap}. The generated multimap's key and value orderings correspond to - * the iteration ordering of the {@code multimap.asMap()} view. - * - *

Despite the method name, this method attempts to avoid actually copying - * the data when it is safe to do so. The exact circumstances under which a - * copy will or will not be performed are undocumented and subject to change. - * - * @throws NullPointerException if any key or value in {@code multimap} is - * null - */ - public static ImmutableListMultimap copyOf( - Multimap multimap) { - if (multimap.isEmpty()) { - return of(); - } - - // TODO(lowasser): copy ImmutableSetMultimap by using asList() on the sets - if (multimap instanceof ImmutableListMultimap) { - @SuppressWarnings("unchecked") // safe since multimap is not writable - ImmutableListMultimap kvMultimap = (ImmutableListMultimap) multimap; - if (!kvMultimap.isPartialView()) { - return kvMultimap; - } - } - - ImmutableMap.Builder> builder = - new ImmutableMap.Builder>(multimap.asMap().size()); - int size = 0; - - for (Entry> entry : - multimap.asMap().entrySet()) { - ImmutableList list = ImmutableList.copyOf(entry.getValue()); - if (!list.isEmpty()) { - builder.put(entry.getKey(), list); - size += list.size(); - } - } - - return new ImmutableListMultimap(builder.build(), size); - } - - /** - * Returns an immutable multimap containing the specified entries. The - * returned multimap iterates over keys in the order they were first - * encountered in the input, and the values for each key are iterated in the - * order they were encountered. - * - * @throws NullPointerException if any key, value, or entry is null - * @since 19.0 - */ - @Beta - public static ImmutableListMultimap copyOf( - Iterable> entries) { - return new Builder().putAll(entries).build(); - } - - ImmutableListMultimap(ImmutableMap> map, int size) { - super(map, size); - } - - // views - - /** - * Returns an immutable list of the values for the given key. If no mappings - * in the multimap have the provided key, an empty immutable list is - * returned. The values are in the same order as the parameters used to build - * this multimap. - */ - @Override - public ImmutableList get(@Nullable K key) { - // This cast is safe as its type is known in constructor. - ImmutableList list = (ImmutableList) map.get(key); - return (list == null) ? ImmutableList.of() : list; - } - - private transient ImmutableListMultimap inverse; - - /** - * {@inheritDoc} - * - *

Because an inverse of a list multimap can contain multiple pairs with - * the same key and value, this method returns an {@code - * ImmutableListMultimap} rather than the {@code ImmutableMultimap} specified - * in the {@code ImmutableMultimap} class. - * - * @since 11.0 - */ - @Override - public ImmutableListMultimap inverse() { - ImmutableListMultimap result = inverse; - return (result == null) ? (inverse = invert()) : result; - } - - private ImmutableListMultimap invert() { - Builder builder = builder(); - for (Entry entry : entries()) { - builder.put(entry.getValue(), entry.getKey()); - } - ImmutableListMultimap invertedMultimap = builder.build(); - invertedMultimap.inverse = this; - return invertedMultimap; - } - - /** - * Guaranteed to throw an exception and leave the multimap unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public ImmutableList removeAll(Object key) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the multimap unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public ImmutableList replaceValues(K key, Iterable values) { - throw new UnsupportedOperationException(); - } - - /** - * @serialData number of distinct keys, and then for each distinct key: the - * key, the number of values for that key, and the key's values - */ - @GwtIncompatible("java.io.ObjectOutputStream") - private void writeObject(ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); - Serialization.writeMultimap(this, stream); - } - - @GwtIncompatible("java.io.ObjectInputStream") - private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - int keyCount = stream.readInt(); - if (keyCount < 0) { - throw new InvalidObjectException("Invalid key count " + keyCount); - } - ImmutableMap.Builder> builder = ImmutableMap.builder(); - int tmpSize = 0; - - for (int i = 0; i < keyCount; i++) { - Object key = stream.readObject(); - int valueCount = stream.readInt(); - if (valueCount <= 0) { - throw new InvalidObjectException("Invalid value count " + valueCount); - } - - ImmutableList.Builder valuesBuilder = ImmutableList.builder(); - for (int j = 0; j < valueCount; j++) { - valuesBuilder.add(stream.readObject()); - } - builder.put(key, valuesBuilder.build()); - tmpSize += valueCount; - } - - ImmutableMap> tmpMap; - try { - tmpMap = builder.build(); - } catch (IllegalArgumentException e) { - throw (InvalidObjectException) new InvalidObjectException(e.getMessage()).initCause(e); - } - - FieldSettersHolder.MAP_FIELD_SETTER.set(this, tmpMap); - FieldSettersHolder.SIZE_FIELD_SETTER.set(this, tmpSize); - } - - @GwtIncompatible("Not needed in emulated source") - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableMap.java deleted file mode 100644 index 3fe475c92520..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableMap.java +++ /dev/null @@ -1,664 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; -import static com.google.common.collect.CollectPreconditions.checkEntryNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.j2objc.annotations.WeakOuter; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.EnumMap; -import java.util.Iterator; -import java.util.Map; - -import javax.annotation.Nullable; - -/** - * A {@link Map} whose contents will never change, with many other important properties detailed at - * {@link ImmutableCollection}. - * - *

See the Guava User Guide article on - * immutable collections. - * - * @author Jesse Wilson - * @author Kevin Bourrillion - * @since 2.0 - */ -@GwtCompatible(serializable = true, emulated = true) -@SuppressWarnings("serial") // we're overriding default serialization -public abstract class ImmutableMap implements Map, Serializable { - - /** - * Returns the empty map. This map behaves and performs comparably to - * {@link Collections#emptyMap}, and is preferable mainly for consistency - * and maintainability of your code. - */ - public static ImmutableMap of() { - return ImmutableBiMap.of(); - } - - /** - * Returns an immutable map containing a single entry. This map behaves and - * performs comparably to {@link Collections#singletonMap} but will not accept - * a null key or value. It is preferable mainly for consistency and - * maintainability of your code. - */ - public static ImmutableMap of(K k1, V v1) { - return ImmutableBiMap.of(k1, v1); - } - - /** - * Returns an immutable map containing the given entries, in order. - * - * @throws IllegalArgumentException if duplicate keys are provided - */ - public static ImmutableMap of(K k1, V v1, K k2, V v2) { - return RegularImmutableMap.fromEntries(entryOf(k1, v1), entryOf(k2, v2)); - } - - /** - * Returns an immutable map containing the given entries, in order. - * - * @throws IllegalArgumentException if duplicate keys are provided - */ - public static ImmutableMap of(K k1, V v1, K k2, V v2, K k3, V v3) { - return RegularImmutableMap.fromEntries(entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3)); - } - - /** - * Returns an immutable map containing the given entries, in order. - * - * @throws IllegalArgumentException if duplicate keys are provided - */ - public static ImmutableMap of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { - return RegularImmutableMap.fromEntries( - entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3), entryOf(k4, v4)); - } - - /** - * Returns an immutable map containing the given entries, in order. - * - * @throws IllegalArgumentException if duplicate keys are provided - */ - public static ImmutableMap of( - K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { - return RegularImmutableMap.fromEntries( - entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3), entryOf(k4, v4), entryOf(k5, v5)); - } - - // looking for of() with > 5 entries? Use the builder instead. - - /** - * Verifies that {@code key} and {@code value} are non-null, and returns a new - * immutable entry with those values. - * - *

A call to {@link Map.Entry#setValue} on the returned entry will always - * throw {@link UnsupportedOperationException}. - */ - static ImmutableMapEntry entryOf(K key, V value) { - return new ImmutableMapEntry(key, value); - } - - /** - * Returns a new builder. The generated builder is equivalent to the builder - * created by the {@link Builder} constructor. - */ - public static Builder builder() { - return new Builder(); - } - - static void checkNoConflict( - boolean safe, String conflictDescription, Entry entry1, Entry entry2) { - if (!safe) { - throw new IllegalArgumentException( - "Multiple entries with same " + conflictDescription + ": " + entry1 + " and " + entry2); - } - } - - /** - * A builder for creating immutable map instances, especially {@code public - * static final} maps ("constant maps"). Example:

   {@code
-   *
-   *   static final ImmutableMap WORD_TO_INT =
-   *       new ImmutableMap.Builder()
-   *           .put("one", 1)
-   *           .put("two", 2)
-   *           .put("three", 3)
-   *           .build();}
- * - *

For small immutable maps, the {@code ImmutableMap.of()} methods are - * even more convenient. - * - *

Builder instances can be reused - it is safe to call {@link #build} - * multiple times to build multiple maps in series. Each map is a superset of - * the maps created before it. - * - * @since 2.0 - */ - public static class Builder { - Comparator valueComparator; - ImmutableMapEntry[] entries; - int size; - boolean entriesUsed; - - /** - * Creates a new builder. The returned builder is equivalent to the builder - * generated by {@link ImmutableMap#builder}. - */ - public Builder() { - this(ImmutableCollection.Builder.DEFAULT_INITIAL_CAPACITY); - } - - @SuppressWarnings("unchecked") - Builder(int initialCapacity) { - this.entries = new ImmutableMapEntry[initialCapacity]; - this.size = 0; - this.entriesUsed = false; - } - - private void ensureCapacity(int minCapacity) { - if (minCapacity > entries.length) { - entries = - ObjectArrays.arraysCopyOf( - entries, ImmutableCollection.Builder.expandedCapacity(entries.length, minCapacity)); - entriesUsed = false; - } - } - - /** - * Associates {@code key} with {@code value} in the built map. Duplicate - * keys are not allowed, and will cause {@link #build} to fail. - */ - public Builder put(K key, V value) { - ensureCapacity(size + 1); - ImmutableMapEntry entry = entryOf(key, value); - // don't inline this: we want to fail atomically if key or value is null - entries[size++] = entry; - return this; - } - - /** - * Adds the given {@code entry} to the map, making it immutable if - * necessary. Duplicate keys are not allowed, and will cause {@link #build} - * to fail. - * - * @since 11.0 - */ - public Builder put(Entry entry) { - return put(entry.getKey(), entry.getValue()); - } - - /** - * Associates all of the given map's keys and values in the built map. - * Duplicate keys are not allowed, and will cause {@link #build} to fail. - * - * @throws NullPointerException if any key or value in {@code map} is null - */ - public Builder putAll(Map map) { - return putAll(map.entrySet()); - } - - /** - * Adds all of the given entries to the built map. Duplicate keys are not - * allowed, and will cause {@link #build} to fail. - * - * @throws NullPointerException if any key, value, or entry is null - * @since 19.0 - */ - @Beta - public Builder putAll(Iterable> entries) { - if (entries instanceof Collection) { - ensureCapacity(size + ((Collection) entries).size()); - } - for (Entry entry : entries) { - put(entry); - } - return this; - } - - /** - * Configures this {@code Builder} to order entries by value according to the specified - * comparator. - * - *

The sort order is stable, that is, if two entries have values that compare - * as equivalent, the entry that was inserted first will be first in the built map's - * iteration order. - * - * @throws IllegalStateException if this method was already called - * @since 19.0 - */ - @Beta - public Builder orderEntriesByValue(Comparator valueComparator) { - checkState(this.valueComparator == null, "valueComparator was already set"); - this.valueComparator = checkNotNull(valueComparator, "valueComparator"); - return this; - } - - /* - * TODO(kevinb): Should build() and the ImmutableBiMap & ImmutableSortedMap - * versions throw an IllegalStateException instead? - */ - - /** - * Returns a newly-created immutable map. - * - * @throws IllegalArgumentException if duplicate keys were added - */ - public ImmutableMap build() { - switch (size) { - case 0: - return of(); - case 1: - return of(entries[0].getKey(), entries[0].getValue()); - default: - /* - * If entries is full, then this implementation may end up using the entries array - * directly and writing over the entry objects with non-terminal entries, but this is - * safe; if this Builder is used further, it will grow the entries array (so it can't - * affect the original array), and future build() calls will always copy any entry - * objects that cannot be safely reused. - */ - if (valueComparator != null) { - if (entriesUsed) { - entries = ObjectArrays.arraysCopyOf(entries, size); - } - Arrays.sort( - entries, - 0, - size, - Ordering.from(valueComparator).onResultOf(Maps.valueFunction())); - } - entriesUsed = size == entries.length; - return RegularImmutableMap.fromEntryArray(size, entries); - } - } - } - - /** - * Returns an immutable map containing the same entries as {@code map}. If - * {@code map} somehow contains entries with duplicate keys (for example, if - * it is a {@code SortedMap} whose comparator is not consistent with - * equals), the results of this method are undefined. - * - *

Despite the method name, this method attempts to avoid actually copying - * the data when it is safe to do so. The exact circumstances under which a - * copy will or will not be performed are undocumented and subject to change. - * - * @throws NullPointerException if any key or value in {@code map} is null - */ - public static ImmutableMap copyOf(Map map) { - if ((map instanceof ImmutableMap) && !(map instanceof ImmutableSortedMap)) { - // TODO(lowasser): Make ImmutableMap.copyOf(immutableBiMap) call copyOf() - // on the ImmutableMap delegate(), rather than the bimap itself - - @SuppressWarnings("unchecked") // safe since map is not writable - ImmutableMap kvMap = (ImmutableMap) map; - if (!kvMap.isPartialView()) { - return kvMap; - } - } else if (map instanceof EnumMap) { - @SuppressWarnings("unchecked") // safe since map is not writable - ImmutableMap kvMap = (ImmutableMap) copyOfEnumMap((EnumMap) map); - return kvMap; - } - return copyOf(map.entrySet()); - } - - /** - * Returns an immutable map containing the specified entries. The returned - * map iterates over entries in the same order as the original iterable. - * - * @throws NullPointerException if any key, value, or entry is null - * @throws IllegalArgumentException if two entries have the same key - * @since 19.0 - */ - @Beta - public static ImmutableMap copyOf( - Iterable> entries) { - @SuppressWarnings("unchecked") // we'll only be using getKey and getValue, which are covariant - Entry[] entryArray = (Entry[]) Iterables.toArray(entries, EMPTY_ENTRY_ARRAY); - switch (entryArray.length) { - case 0: - return of(); - case 1: - Entry onlyEntry = entryArray[0]; - return of(onlyEntry.getKey(), onlyEntry.getValue()); - default: - /* - * The current implementation will end up using entryArray directly, though it will write - * over the (arbitrary, potentially mutable) Entry objects actually stored in entryArray. - */ - return RegularImmutableMap.fromEntries(entryArray); - } - } - - private static , V> ImmutableMap copyOfEnumMap( - EnumMap original) { - EnumMap copy = new EnumMap(original); - for (Map.Entry entry : copy.entrySet()) { - checkEntryNotNull(entry.getKey(), entry.getValue()); - } - return ImmutableEnumMap.asImmutable(copy); - } - - static final Entry[] EMPTY_ENTRY_ARRAY = new Entry[0]; - - abstract static class IteratorBasedImmutableMap extends ImmutableMap { - abstract UnmodifiableIterator> entryIterator(); - - @Override - ImmutableSet> createEntrySet() { - @WeakOuter - class EntrySetImpl extends ImmutableMapEntrySet { - @Override - ImmutableMap map() { - return IteratorBasedImmutableMap.this; - } - - @Override - public UnmodifiableIterator> iterator() { - return entryIterator(); - } - } - return new EntrySetImpl(); - } - } - - ImmutableMap() {} - - /** - * Guaranteed to throw an exception and leave the map unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final V put(K k, V v) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the map unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final V remove(Object o) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the map unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final void putAll(Map map) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the map unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final void clear() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isEmpty() { - return size() == 0; - } - - @Override - public boolean containsKey(@Nullable Object key) { - return get(key) != null; - } - - @Override - public boolean containsValue(@Nullable Object value) { - return values().contains(value); - } - - // Overriding to mark it Nullable - @Override - public abstract V get(@Nullable Object key); - - private transient ImmutableSet> entrySet; - - /** - * Returns an immutable set of the mappings in this map. The entries are in - * the same order as the parameters used to build this map. - */ - @Override - public ImmutableSet> entrySet() { - ImmutableSet> result = entrySet; - return (result == null) ? entrySet = createEntrySet() : result; - } - - abstract ImmutableSet> createEntrySet(); - - private transient ImmutableSet keySet; - - /** - * Returns an immutable set of the keys in this map. These keys are in - * the same order as the parameters used to build this map. - */ - @Override - public ImmutableSet keySet() { - ImmutableSet result = keySet; - return (result == null) ? keySet = createKeySet() : result; - } - - ImmutableSet createKeySet() { - return isEmpty() ? ImmutableSet.of() : new ImmutableMapKeySet(this); - } - - UnmodifiableIterator keyIterator() { - final UnmodifiableIterator> entryIterator = entrySet().iterator(); - return new UnmodifiableIterator() { - @Override - public boolean hasNext() { - return entryIterator.hasNext(); - } - - @Override - public K next() { - return entryIterator.next().getKey(); - } - }; - } - - private transient ImmutableCollection values; - - /** - * Returns an immutable collection of the values in this map. The values are - * in the same order as the parameters used to build this map. - */ - @Override - public ImmutableCollection values() { - ImmutableCollection result = values; - return (result == null) ? values = new ImmutableMapValues(this) : result; - } - - // cached so that this.multimapView().inverse() only computes inverse once - private transient ImmutableSetMultimap multimapView; - - /** - * Returns a multimap view of the map. - * - * @since 14.0 - */ - @Beta - public ImmutableSetMultimap asMultimap() { - if (isEmpty()) { - return ImmutableSetMultimap.of(); - } - ImmutableSetMultimap result = multimapView; - return (result == null) - ? (multimapView = - new ImmutableSetMultimap(new MapViewOfValuesAsSingletonSets(), size(), null)) - : result; - } - - @WeakOuter - private final class MapViewOfValuesAsSingletonSets - extends IteratorBasedImmutableMap> { - - @Override - public int size() { - return ImmutableMap.this.size(); - } - - @Override - public ImmutableSet keySet() { - return ImmutableMap.this.keySet(); - } - - @Override - public boolean containsKey(@Nullable Object key) { - return ImmutableMap.this.containsKey(key); - } - - @Override - public ImmutableSet get(@Nullable Object key) { - V outerValue = ImmutableMap.this.get(key); - return (outerValue == null) ? null : ImmutableSet.of(outerValue); - } - - @Override - boolean isPartialView() { - return ImmutableMap.this.isPartialView(); - } - - @Override - public int hashCode() { - // ImmutableSet.of(value).hashCode() == value.hashCode(), so the hashes are the same - return ImmutableMap.this.hashCode(); - } - - @Override - boolean isHashCodeFast() { - return ImmutableMap.this.isHashCodeFast(); - } - - @Override - UnmodifiableIterator>> entryIterator() { - final Iterator> backingIterator = ImmutableMap.this.entrySet().iterator(); - return new UnmodifiableIterator>>() { - @Override - public boolean hasNext() { - return backingIterator.hasNext(); - } - - @Override - public Entry> next() { - final Entry backingEntry = backingIterator.next(); - return new AbstractMapEntry>() { - @Override - public K getKey() { - return backingEntry.getKey(); - } - - @Override - public ImmutableSet getValue() { - return ImmutableSet.of(backingEntry.getValue()); - } - }; - } - }; - } - } - - @Override - public boolean equals(@Nullable Object object) { - return Maps.equalsImpl(this, object); - } - - abstract boolean isPartialView(); - - @Override - public int hashCode() { - return Sets.hashCodeImpl(entrySet()); - } - - boolean isHashCodeFast() { - return false; - } - - @Override - public String toString() { - return Maps.toStringImpl(this); - } - - /** - * Serialized type for all ImmutableMap instances. It captures the logical - * contents and they are reconstructed using public factory methods. This - * ensures that the implementation types remain as implementation details. - */ - static class SerializedForm implements Serializable { - private final Object[] keys; - private final Object[] values; - - SerializedForm(ImmutableMap map) { - keys = new Object[map.size()]; - values = new Object[map.size()]; - int i = 0; - for (Entry entry : map.entrySet()) { - keys[i] = entry.getKey(); - values[i] = entry.getValue(); - i++; - } - } - - Object readResolve() { - Builder builder = new Builder(keys.length); - return createMap(builder); - } - - Object createMap(Builder builder) { - for (int i = 0; i < keys.length; i++) { - builder.put(keys[i], values[i]); - } - return builder.build(); - } - - private static final long serialVersionUID = 0; - } - - Object writeReplace() { - return new SerializedForm(this); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableMapEntry.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableMapEntry.java deleted file mode 100644 index 6487aee181c8..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableMapEntry.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2013 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.collect.CollectPreconditions.checkEntryNotNull; - -import com.google.common.annotations.GwtIncompatible; - -import javax.annotation.Nullable; - -/** - * Implementation of {@code Map.Entry} for {@link ImmutableMap} that adds extra methods to traverse - * hash buckets for the key and the value. This allows reuse in {@link RegularImmutableMap} and - * {@link RegularImmutableBiMap}, which don't have to recopy the entries created by their - * {@code Builder} implementations. - * - *

This base implementation has no key or value pointers, so instances of ImmutableMapEntry - * (but not its subclasses) can be reused when copied from one ImmutableMap to another. - * - * @author Louis Wasserman - */ -@GwtIncompatible("unnecessary") -class ImmutableMapEntry extends ImmutableEntry { - /** - * Creates an {@code ImmutableMapEntry} array to hold parameterized entries. The - * result must never be upcast back to ImmutableMapEntry[] (or Object[], etc.), or - * allowed to escape the class. - */ - @SuppressWarnings("unchecked") // Safe as long as the javadocs are followed - static ImmutableMapEntry[] createEntryArray(int size) { - return new ImmutableMapEntry[size]; - } - - ImmutableMapEntry(K key, V value) { - super(key, value); - checkEntryNotNull(key, value); - } - - ImmutableMapEntry(ImmutableMapEntry contents) { - super(contents.getKey(), contents.getValue()); - // null check would be redundant - } - - @Nullable - ImmutableMapEntry getNextInKeyBucket() { - return null; - } - - @Nullable - ImmutableMapEntry getNextInValueBucket() { - return null; - } - - /** - * Returns true if this entry has no bucket links and can safely be reused as a terminal - * entry in a bucket in another map. - */ - boolean isReusable() { - return true; - } - - static class NonTerminalImmutableMapEntry extends ImmutableMapEntry { - private final transient ImmutableMapEntry nextInKeyBucket; - - NonTerminalImmutableMapEntry(K key, V value, ImmutableMapEntry nextInKeyBucket) { - super(key, value); - this.nextInKeyBucket = nextInKeyBucket; - } - - @Override - @Nullable - final ImmutableMapEntry getNextInKeyBucket() { - return nextInKeyBucket; - } - - @Override - final boolean isReusable() { - return false; - } - } - - static final class NonTerminalImmutableBiMapEntry - extends NonTerminalImmutableMapEntry { - private final transient ImmutableMapEntry nextInValueBucket; - - NonTerminalImmutableBiMapEntry( - K key, - V value, - ImmutableMapEntry nextInKeyBucket, - ImmutableMapEntry nextInValueBucket) { - super(key, value, nextInKeyBucket); - this.nextInValueBucket = nextInValueBucket; - } - - @Override - @Nullable - ImmutableMapEntry getNextInValueBucket() { - return nextInValueBucket; - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableMapEntrySet.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableMapEntrySet.java deleted file mode 100644 index 0329c0595535..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableMapEntrySet.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.j2objc.annotations.Weak; - -import java.io.Serializable; -import java.util.Map.Entry; - -import javax.annotation.Nullable; - -/** - * {@code entrySet()} implementation for {@link ImmutableMap}. - * - * @author Jesse Wilson - * @author Kevin Bourrillion - */ -@GwtCompatible(emulated = true) -abstract class ImmutableMapEntrySet extends ImmutableSet> { - static final class RegularEntrySet extends ImmutableMapEntrySet { - @Weak private final transient ImmutableMap map; - private final transient Entry[] entries; - - RegularEntrySet(ImmutableMap map, Entry[] entries) { - this.map = map; - this.entries = entries; - } - - @Override - ImmutableMap map() { - return map; - } - - @Override - public UnmodifiableIterator> iterator() { - return asList().iterator(); - } - - @Override - ImmutableList> createAsList() { - return new RegularImmutableAsList>(this, entries); - } - } - - ImmutableMapEntrySet() {} - - abstract ImmutableMap map(); - - @Override - public int size() { - return map().size(); - } - - @Override - public boolean contains(@Nullable Object object) { - if (object instanceof Entry) { - Entry entry = (Entry) object; - V value = map().get(entry.getKey()); - return value != null && value.equals(entry.getValue()); - } - return false; - } - - @Override - boolean isPartialView() { - return map().isPartialView(); - } - - @Override - @GwtIncompatible("not used in GWT") - boolean isHashCodeFast() { - return map().isHashCodeFast(); - } - - @Override - public int hashCode() { - return map().hashCode(); - } - - @GwtIncompatible("serialization") - @Override - Object writeReplace() { - return new EntrySetSerializedForm(map()); - } - - @GwtIncompatible("serialization") - private static class EntrySetSerializedForm implements Serializable { - final ImmutableMap map; - - EntrySetSerializedForm(ImmutableMap map) { - this.map = map; - } - - Object readResolve() { - return map.entrySet(); - } - - private static final long serialVersionUID = 0; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableMapKeySet.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableMapKeySet.java deleted file mode 100644 index b97560b6d391..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableMapKeySet.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.j2objc.annotations.Weak; - -import java.io.Serializable; - -import javax.annotation.Nullable; - -/** - * {@code keySet()} implementation for {@link ImmutableMap}. - * - * @author Jesse Wilson - * @author Kevin Bourrillion - */ -@GwtCompatible(emulated = true) -final class ImmutableMapKeySet extends ImmutableSet.Indexed { - @Weak private final ImmutableMap map; - - ImmutableMapKeySet(ImmutableMap map) { - this.map = map; - } - - @Override - public int size() { - return map.size(); - } - - @Override - public UnmodifiableIterator iterator() { - return map.keyIterator(); - } - - @Override - public boolean contains(@Nullable Object object) { - return map.containsKey(object); - } - - @Override - K get(int index) { - return map.entrySet().asList().get(index).getKey(); - } - - @Override - boolean isPartialView() { - return true; - } - - @GwtIncompatible("serialization") - @Override - Object writeReplace() { - return new KeySetSerializedForm(map); - } - - @GwtIncompatible("serialization") - private static class KeySetSerializedForm implements Serializable { - final ImmutableMap map; - - KeySetSerializedForm(ImmutableMap map) { - this.map = map; - } - - Object readResolve() { - return map.keySet(); - } - - private static final long serialVersionUID = 0; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableMapValues.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableMapValues.java deleted file mode 100644 index be291fb935e6..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableMapValues.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.j2objc.annotations.Weak; - -import java.io.Serializable; -import java.util.Map.Entry; - -import javax.annotation.Nullable; - -/** - * {@code values()} implementation for {@link ImmutableMap}. - * - * @author Jesse Wilson - * @author Kevin Bourrillion - */ -@GwtCompatible(emulated = true) -final class ImmutableMapValues extends ImmutableCollection { - @Weak private final ImmutableMap map; - - ImmutableMapValues(ImmutableMap map) { - this.map = map; - } - - @Override - public int size() { - return map.size(); - } - - @Override - public UnmodifiableIterator iterator() { - return new UnmodifiableIterator() { - final UnmodifiableIterator> entryItr = map.entrySet().iterator(); - - @Override - public boolean hasNext() { - return entryItr.hasNext(); - } - - @Override - public V next() { - return entryItr.next().getValue(); - } - }; - } - - @Override - public boolean contains(@Nullable Object object) { - return object != null && Iterators.contains(iterator(), object); - } - - @Override - boolean isPartialView() { - return true; - } - - @Override - ImmutableList createAsList() { - final ImmutableList> entryList = map.entrySet().asList(); - return new ImmutableAsList() { - @Override - public V get(int index) { - return entryList.get(index).getValue(); - } - - @Override - ImmutableCollection delegateCollection() { - return ImmutableMapValues.this; - } - }; - } - - @GwtIncompatible("serialization") - @Override - Object writeReplace() { - return new SerializedForm(map); - } - - @GwtIncompatible("serialization") - private static class SerializedForm implements Serializable { - final ImmutableMap map; - - SerializedForm(ImmutableMap map) { - this.map = map; - } - - Object readResolve() { - return map.values(); - } - - private static final long serialVersionUID = 0; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableMultimap.java deleted file mode 100644 index 5790218bd057..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableMultimap.java +++ /dev/null @@ -1,699 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.CollectPreconditions.checkEntryNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.j2objc.annotations.Weak; -import com.google.j2objc.annotations.WeakOuter; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * A {@link Multimap} whose contents will never change, with many other important properties - * detailed at {@link ImmutableCollection}. - * - *

Warning: avoid direct usage of {@link ImmutableMultimap} as a type (as with - * {@link Multimap} itself). Prefer subtypes such as {@link ImmutableSetMultimap} or {@link - * ImmutableListMultimap}, which have well-defined {@link #equals} semantics, thus avoiding a common - * source of bugs and confusion. - * - *

Note: every {@link ImmutableMultimap} offers an {@link #inverse} view, so there is no - * need for a distinct {@code ImmutableBiMultimap} type. - * - * - *

Key-grouped iteration. All view collections follow the same iteration order. In all - * current implementations, the iteration order always keeps multiple entries with the same key - * together. Any creation method that would customarily respect insertion order (such as {@link - * #copyOf(Multimap)}) instead preserves key-grouped order by inserting entries for an existing key - * immediately after the last entry having that key. - * - *

See the Guava User Guide article on - * immutable collections. - * - * @author Jared Levy - * @since 2.0 - */ -@GwtCompatible(emulated = true) -public abstract class ImmutableMultimap extends AbstractMultimap - implements Serializable { - - /** Returns an empty multimap. */ - public static ImmutableMultimap of() { - return ImmutableListMultimap.of(); - } - - /** - * Returns an immutable multimap containing a single entry. - */ - public static ImmutableMultimap of(K k1, V v1) { - return ImmutableListMultimap.of(k1, v1); - } - - /** - * Returns an immutable multimap containing the given entries, in order. - */ - public static ImmutableMultimap of(K k1, V v1, K k2, V v2) { - return ImmutableListMultimap.of(k1, v1, k2, v2); - } - - /** - * Returns an immutable multimap containing the given entries, in the - * "key-grouped" insertion order described in the - * class documentation. - */ - public static ImmutableMultimap of(K k1, V v1, K k2, V v2, K k3, V v3) { - return ImmutableListMultimap.of(k1, v1, k2, v2, k3, v3); - } - - /** - * Returns an immutable multimap containing the given entries, in the - * "key-grouped" insertion order described in the - * class documentation. - */ - public static ImmutableMultimap of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { - return ImmutableListMultimap.of(k1, v1, k2, v2, k3, v3, k4, v4); - } - - /** - * Returns an immutable multimap containing the given entries, in the - * "key-grouped" insertion order described in the - * class documentation. - */ - public static ImmutableMultimap of( - K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { - return ImmutableListMultimap.of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5); - } - - // looking for of() with > 5 entries? Use the builder instead. - - /** - * Returns a new builder. The generated builder is equivalent to the builder - * created by the {@link Builder} constructor. - */ - public static Builder builder() { - return new Builder(); - } - - /** - * A builder for creating immutable multimap instances, especially - * {@code public static final} multimaps ("constant multimaps"). Example: - *

   {@code
-   *
-   *   static final Multimap STRING_TO_INTEGER_MULTIMAP =
-   *       new ImmutableMultimap.Builder()
-   *           .put("one", 1)
-   *           .putAll("several", 1, 2, 3)
-   *           .putAll("many", 1, 2, 3, 4, 5)
-   *           .build();}
- * - *

Builder instances can be reused; it is safe to call {@link #build} multiple - * times to build multiple multimaps in series. Each multimap contains the - * key-value mappings in the previously created multimaps. - * - * @since 2.0 - */ - public static class Builder { - Multimap builderMultimap; - Comparator keyComparator; - Comparator valueComparator; - - /** - * Creates a new builder. The returned builder is equivalent to the builder - * generated by {@link ImmutableMultimap#builder}. - */ - public Builder() { - this(MultimapBuilder.linkedHashKeys().arrayListValues().build()); - } - - Builder(Multimap builderMultimap) { - this.builderMultimap = builderMultimap; - } - - /** - * Adds a key-value mapping to the built multimap. - */ - public Builder put(K key, V value) { - checkEntryNotNull(key, value); - builderMultimap.put(key, value); - return this; - } - - /** - * Adds an entry to the built multimap. - * - * @since 11.0 - */ - public Builder put(Entry entry) { - return put(entry.getKey(), entry.getValue()); - } - - /** - * Adds entries to the built multimap. - * - * @since 19.0 - */ - @Beta - public Builder putAll(Iterable> entries) { - for (Entry entry : entries) { - put(entry); - } - return this; - } - - /** - * Stores a collection of values with the same key in the built multimap. - * - * @throws NullPointerException if {@code key}, {@code values}, or any - * element in {@code values} is null. The builder is left in an invalid - * state. - */ - public Builder putAll(K key, Iterable values) { - if (key == null) { - throw new NullPointerException("null key in entry: null=" + Iterables.toString(values)); - } - Collection valueList = builderMultimap.get(key); - for (V value : values) { - checkEntryNotNull(key, value); - valueList.add(value); - } - return this; - } - - /** - * Stores an array of values with the same key in the built multimap. - * - * @throws NullPointerException if the key or any value is null. The builder - * is left in an invalid state. - */ - public Builder putAll(K key, V... values) { - return putAll(key, Arrays.asList(values)); - } - - /** - * Stores another multimap's entries in the built multimap. The generated - * multimap's key and value orderings correspond to the iteration ordering - * of the {@code multimap.asMap()} view, with new keys and values following - * any existing keys and values. - * - * @throws NullPointerException if any key or value in {@code multimap} is - * null. The builder is left in an invalid state. - */ - public Builder putAll(Multimap multimap) { - for (Entry> entry : - multimap.asMap().entrySet()) { - putAll(entry.getKey(), entry.getValue()); - } - return this; - } - - /** - * Specifies the ordering of the generated multimap's keys. - * - * @since 8.0 - */ - public Builder orderKeysBy(Comparator keyComparator) { - this.keyComparator = checkNotNull(keyComparator); - return this; - } - - /** - * Specifies the ordering of the generated multimap's values for each key. - * - * @since 8.0 - */ - public Builder orderValuesBy(Comparator valueComparator) { - this.valueComparator = checkNotNull(valueComparator); - return this; - } - - /** - * Returns a newly-created immutable multimap. - */ - public ImmutableMultimap build() { - if (valueComparator != null) { - for (Collection values : builderMultimap.asMap().values()) { - List list = (List) values; - Collections.sort(list, valueComparator); - } - } - if (keyComparator != null) { - Multimap sortedCopy = - MultimapBuilder.linkedHashKeys().arrayListValues().build(); - List>> entries = - Ordering.from(keyComparator) - .onKeys() - .immutableSortedCopy(builderMultimap.asMap().entrySet()); - for (Map.Entry> entry : entries) { - sortedCopy.putAll(entry.getKey(), entry.getValue()); - } - builderMultimap = sortedCopy; - } - return copyOf(builderMultimap); - } - } - - /** - * Returns an immutable multimap containing the same mappings as {@code - * multimap}, in the "key-grouped" iteration order described in the class - * documentation. - * - *

Despite the method name, this method attempts to avoid actually copying - * the data when it is safe to do so. The exact circumstances under which a - * copy will or will not be performed are undocumented and subject to change. - * - * @throws NullPointerException if any key or value in {@code multimap} is - * null - */ - public static ImmutableMultimap copyOf(Multimap multimap) { - if (multimap instanceof ImmutableMultimap) { - @SuppressWarnings("unchecked") // safe since multimap is not writable - ImmutableMultimap kvMultimap = (ImmutableMultimap) multimap; - if (!kvMultimap.isPartialView()) { - return kvMultimap; - } - } - return ImmutableListMultimap.copyOf(multimap); - } - - /** - * Returns an immutable multimap containing the specified entries. The - * returned multimap iterates over keys in the order they were first - * encountered in the input, and the values for each key are iterated in the - * order they were encountered. - * - * @throws NullPointerException if any key, value, or entry is null - * @since 19.0 - */ - @Beta - public static ImmutableMultimap copyOf( - Iterable> entries) { - return ImmutableListMultimap.copyOf(entries); - } - - final transient ImmutableMap> map; - final transient int size; - - // These constants allow the deserialization code to set final fields. This - // holder class makes sure they are not initialized unless an instance is - // deserialized. - @GwtIncompatible("java serialization is not supported") - static class FieldSettersHolder { - static final Serialization.FieldSetter MAP_FIELD_SETTER = - Serialization.getFieldSetter(ImmutableMultimap.class, "map"); - static final Serialization.FieldSetter SIZE_FIELD_SETTER = - Serialization.getFieldSetter(ImmutableMultimap.class, "size"); - static final Serialization.FieldSetter EMPTY_SET_FIELD_SETTER = - Serialization.getFieldSetter(ImmutableSetMultimap.class, "emptySet"); - } - - ImmutableMultimap(ImmutableMap> map, int size) { - this.map = map; - this.size = size; - } - - // mutators (not supported) - - /** - * Guaranteed to throw an exception and leave the multimap unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public ImmutableCollection removeAll(Object key) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the multimap unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public ImmutableCollection replaceValues(K key, Iterable values) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the multimap unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public void clear() { - throw new UnsupportedOperationException(); - } - - /** - * Returns an immutable collection of the values for the given key. If no - * mappings in the multimap have the provided key, an empty immutable - * collection is returned. The values are in the same order as the parameters - * used to build this multimap. - */ - @Override - public abstract ImmutableCollection get(K key); - - /** - * Returns an immutable multimap which is the inverse of this one. For every - * key-value mapping in the original, the result will have a mapping with - * key and value reversed. - * - * @since 11.0 - */ - public abstract ImmutableMultimap inverse(); - - /** - * Guaranteed to throw an exception and leave the multimap unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public boolean put(K key, V value) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the multimap unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public boolean putAll(K key, Iterable values) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the multimap unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public boolean putAll(Multimap multimap) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the multimap unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public boolean remove(Object key, Object value) { - throw new UnsupportedOperationException(); - } - - /** - * Returns {@code true} if this immutable multimap's implementation contains references to - * user-created objects that aren't accessible via this multimap's methods. This is generally - * used to determine whether {@code copyOf} implementations should make an explicit copy to avoid - * memory leaks. - */ - boolean isPartialView() { - return map.isPartialView(); - } - - // accessors - - @Override - public boolean containsKey(@Nullable Object key) { - return map.containsKey(key); - } - - @Override - public boolean containsValue(@Nullable Object value) { - return value != null && super.containsValue(value); - } - - @Override - public int size() { - return size; - } - - // views - - /** - * Returns an immutable set of the distinct keys in this multimap, in the same - * order as they appear in this multimap. - */ - @Override - public ImmutableSet keySet() { - return map.keySet(); - } - - /** - * Returns an immutable map that associates each key with its corresponding - * values in the multimap. Keys and values appear in the same order as in this - * multimap. - */ - @Override - @SuppressWarnings("unchecked") // a widening cast - public ImmutableMap> asMap() { - return (ImmutableMap) map; - } - - @Override - Map> createAsMap() { - throw new AssertionError("should never be called"); - } - - /** - * Returns an immutable collection of all key-value pairs in the multimap. - */ - @Override - public ImmutableCollection> entries() { - return (ImmutableCollection>) super.entries(); - } - - @Override - ImmutableCollection> createEntries() { - return new EntryCollection(this); - } - - private static class EntryCollection extends ImmutableCollection> { - @Weak final ImmutableMultimap multimap; - - EntryCollection(ImmutableMultimap multimap) { - this.multimap = multimap; - } - - @Override - public UnmodifiableIterator> iterator() { - return multimap.entryIterator(); - } - - @Override - boolean isPartialView() { - return multimap.isPartialView(); - } - - @Override - public int size() { - return multimap.size(); - } - - @Override - public boolean contains(Object object) { - if (object instanceof Entry) { - Entry entry = (Entry) object; - return multimap.containsEntry(entry.getKey(), entry.getValue()); - } - return false; - } - - private static final long serialVersionUID = 0; - } - - private abstract class Itr extends UnmodifiableIterator { - final Iterator>> mapIterator = asMap().entrySet().iterator(); - K key = null; - Iterator valueIterator = Iterators.emptyIterator(); - - abstract T output(K key, V value); - - @Override - public boolean hasNext() { - return mapIterator.hasNext() || valueIterator.hasNext(); - } - - @Override - public T next() { - if (!valueIterator.hasNext()) { - Entry> mapEntry = mapIterator.next(); - key = mapEntry.getKey(); - valueIterator = mapEntry.getValue().iterator(); - } - return output(key, valueIterator.next()); - } - } - - @Override - UnmodifiableIterator> entryIterator() { - return new Itr>() { - @Override - Entry output(K key, V value) { - return Maps.immutableEntry(key, value); - } - }; - } - - /** - * Returns an immutable multiset containing all the keys in this multimap, in - * the same order and with the same frequencies as they appear in this - * multimap; to get only a single occurrence of each key, use {@link #keySet}. - */ - @Override - public ImmutableMultiset keys() { - return (ImmutableMultiset) super.keys(); - } - - @Override - ImmutableMultiset createKeys() { - return new Keys(); - } - - @SuppressWarnings("serial") // Uses writeReplace, not default serialization - @WeakOuter - class Keys extends ImmutableMultiset { - @Override - public boolean contains(@Nullable Object object) { - return containsKey(object); - } - - @Override - public int count(@Nullable Object element) { - Collection values = map.get(element); - return (values == null) ? 0 : values.size(); - } - - @Override - public Set elementSet() { - return keySet(); - } - - @Override - public int size() { - return ImmutableMultimap.this.size(); - } - - @Override - Multiset.Entry getEntry(int index) { - Map.Entry> entry = map.entrySet().asList().get(index); - return Multisets.immutableEntry(entry.getKey(), entry.getValue().size()); - } - - @Override - boolean isPartialView() { - return true; - } - } - - /** - * Returns an immutable collection of the values in this multimap. Its - * iterator traverses the values for the first key, the values for the second - * key, and so on. - */ - @Override - public ImmutableCollection values() { - return (ImmutableCollection) super.values(); - } - - @Override - ImmutableCollection createValues() { - return new Values(this); - } - - @Override - UnmodifiableIterator valueIterator() { - return new Itr() { - @Override - V output(K key, V value) { - return value; - } - }; - } - - private static final class Values extends ImmutableCollection { - @Weak private final transient ImmutableMultimap multimap; - - Values(ImmutableMultimap multimap) { - this.multimap = multimap; - } - - @Override - public boolean contains(@Nullable Object object) { - return multimap.containsValue(object); - } - - @Override - public UnmodifiableIterator iterator() { - return multimap.valueIterator(); - } - - @GwtIncompatible("not present in emulated superclass") - @Override - int copyIntoArray(Object[] dst, int offset) { - for (ImmutableCollection valueCollection : multimap.map.values()) { - offset = valueCollection.copyIntoArray(dst, offset); - } - return offset; - } - - @Override - public int size() { - return multimap.size(); - } - - @Override - boolean isPartialView() { - return true; - } - - private static final long serialVersionUID = 0; - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableMultiset.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableMultiset.java deleted file mode 100644 index 02c51ca43ab7..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableMultiset.java +++ /dev/null @@ -1,556 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.collect.Multiset.Entry; -import com.google.j2objc.annotations.WeakOuter; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; - -import javax.annotation.Nullable; - -/** - * A {@link Multiset} whose contents will never change, with many other important properties - * detailed at {@link ImmutableCollection}. - * - *

Grouped iteration. In all current implementations, duplicate elements always appear - * consecutively when iterating. Elements iterate in order by the first appearance of - * that element when the multiset was created. - * - *

See the Guava User Guide article on - * immutable collections. - * - * @author Jared Levy - * @author Louis Wasserman - * @since 2.0 - */ -@GwtCompatible(serializable = true, emulated = true) -@SuppressWarnings("serial") // we're overriding default serialization -// TODO(lowasser): write an efficient asList() implementation -public abstract class ImmutableMultiset extends ImmutableCollection implements Multiset { - /** - * Returns the empty immutable multiset. - */ - @SuppressWarnings("unchecked") // all supported methods are covariant - public static ImmutableMultiset of() { - return (ImmutableMultiset) RegularImmutableMultiset.EMPTY; - } - - /** - * Returns an immutable multiset containing a single element. - * - * @throws NullPointerException if {@code element} is null - * @since 6.0 (source-compatible since 2.0) - */ - @SuppressWarnings("unchecked") // generic array created but never written - public static ImmutableMultiset of(E element) { - return copyFromElements(element); - } - - /** - * Returns an immutable multiset containing the given elements, in order. - * - * @throws NullPointerException if any element is null - * @since 6.0 (source-compatible since 2.0) - */ - @SuppressWarnings("unchecked") // - public static ImmutableMultiset of(E e1, E e2) { - return copyFromElements(e1, e2); - } - - /** - * Returns an immutable multiset containing the given elements, in the "grouped iteration order" - * described in the class documentation. - * - * @throws NullPointerException if any element is null - * @since 6.0 (source-compatible since 2.0) - */ - @SuppressWarnings("unchecked") // - public static ImmutableMultiset of(E e1, E e2, E e3) { - return copyFromElements(e1, e2, e3); - } - - /** - * Returns an immutable multiset containing the given elements, in the "grouped iteration order" - * described in the class documentation. - * - * @throws NullPointerException if any element is null - * @since 6.0 (source-compatible since 2.0) - */ - @SuppressWarnings("unchecked") // - public static ImmutableMultiset of(E e1, E e2, E e3, E e4) { - return copyFromElements(e1, e2, e3, e4); - } - - /** - * Returns an immutable multiset containing the given elements, in the "grouped iteration order" - * described in the class documentation. - * - * @throws NullPointerException if any element is null - * @since 6.0 (source-compatible since 2.0) - */ - @SuppressWarnings("unchecked") // - public static ImmutableMultiset of(E e1, E e2, E e3, E e4, E e5) { - return copyFromElements(e1, e2, e3, e4, e5); - } - - /** - * Returns an immutable multiset containing the given elements, in the "grouped iteration order" - * described in the class documentation. - * - * @throws NullPointerException if any element is null - * @since 6.0 (source-compatible since 2.0) - */ - @SuppressWarnings("unchecked") // - public static ImmutableMultiset of(E e1, E e2, E e3, E e4, E e5, E e6, E... others) { - return new Builder() - .add(e1) - .add(e2) - .add(e3) - .add(e4) - .add(e5) - .add(e6) - .add(others) - .build(); - } - - /** - * Returns an immutable multiset containing the given elements, in the "grouped iteration order" - * described in the class documentation. - * - * @throws NullPointerException if any of {@code elements} is null - * @since 6.0 - */ - public static ImmutableMultiset copyOf(E[] elements) { - return copyFromElements(elements); - } - - /** - * Returns an immutable multiset containing the given elements, in the "grouped iteration order" - * described in the class documentation. - * - * @throws NullPointerException if any of {@code elements} is null - */ - public static ImmutableMultiset copyOf(Iterable elements) { - if (elements instanceof ImmutableMultiset) { - @SuppressWarnings("unchecked") // all supported methods are covariant - ImmutableMultiset result = (ImmutableMultiset) elements; - if (!result.isPartialView()) { - return result; - } - } - - Multiset multiset = - (elements instanceof Multiset) - ? Multisets.cast(elements) - : LinkedHashMultiset.create(elements); - - return copyFromEntries(multiset.entrySet()); - } - - private static ImmutableMultiset copyFromElements(E... elements) { - Multiset multiset = LinkedHashMultiset.create(); - Collections.addAll(multiset, elements); - return copyFromEntries(multiset.entrySet()); - } - - static ImmutableMultiset copyFromEntries( - Collection> entries) { - if (entries.isEmpty()) { - return of(); - } else { - return new RegularImmutableMultiset(entries); - } - } - - /** - * Returns an immutable multiset containing the given elements, in the "grouped iteration order" - * described in the class documentation. - * - * @throws NullPointerException if any of {@code elements} is null - */ - public static ImmutableMultiset copyOf(Iterator elements) { - Multiset multiset = LinkedHashMultiset.create(); - Iterators.addAll(multiset, elements); - return copyFromEntries(multiset.entrySet()); - } - - ImmutableMultiset() {} - - @Override - public UnmodifiableIterator iterator() { - final Iterator> entryIterator = entrySet().iterator(); - return new UnmodifiableIterator() { - int remaining; - E element; - - @Override - public boolean hasNext() { - return (remaining > 0) || entryIterator.hasNext(); - } - - @Override - public E next() { - if (remaining <= 0) { - Entry entry = entryIterator.next(); - element = entry.getElement(); - remaining = entry.getCount(); - } - remaining--; - return element; - } - }; - } - - @Override - public boolean contains(@Nullable Object object) { - return count(object) > 0; - } - - /** - * Guaranteed to throw an exception and leave the collection unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final int add(E element, int occurrences) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the collection unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final int remove(Object element, int occurrences) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the collection unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final int setCount(E element, int count) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the collection unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final boolean setCount(E element, int oldCount, int newCount) { - throw new UnsupportedOperationException(); - } - - @GwtIncompatible("not present in emulated superclass") - @Override - int copyIntoArray(Object[] dst, int offset) { - for (Multiset.Entry entry : entrySet()) { - Arrays.fill(dst, offset, offset + entry.getCount(), entry.getElement()); - offset += entry.getCount(); - } - return offset; - } - - @Override - public boolean equals(@Nullable Object object) { - return Multisets.equalsImpl(this, object); - } - - @Override - public int hashCode() { - return Sets.hashCodeImpl(entrySet()); - } - - @Override - public String toString() { - return entrySet().toString(); - } - - private transient ImmutableSet> entrySet; - - @Override - public ImmutableSet> entrySet() { - ImmutableSet> es = entrySet; - return (es == null) ? (entrySet = createEntrySet()) : es; - } - - private final ImmutableSet> createEntrySet() { - return isEmpty() ? ImmutableSet.>of() : new EntrySet(); - } - - abstract Entry getEntry(int index); - - @WeakOuter - private final class EntrySet extends ImmutableSet.Indexed> { - @Override - boolean isPartialView() { - return ImmutableMultiset.this.isPartialView(); - } - - @Override - Entry get(int index) { - return getEntry(index); - } - - @Override - public int size() { - return elementSet().size(); - } - - @Override - public boolean contains(Object o) { - if (o instanceof Entry) { - Entry entry = (Entry) o; - if (entry.getCount() <= 0) { - return false; - } - int count = count(entry.getElement()); - return count == entry.getCount(); - } - return false; - } - - @Override - public int hashCode() { - return ImmutableMultiset.this.hashCode(); - } - - // We can't label this with @Override, because it doesn't override anything - // in the GWT emulated version. - // TODO(cpovirk): try making all copies of this method @GwtIncompatible instead - Object writeReplace() { - return new EntrySetSerializedForm(ImmutableMultiset.this); - } - - private static final long serialVersionUID = 0; - } - - static class EntrySetSerializedForm implements Serializable { - final ImmutableMultiset multiset; - - EntrySetSerializedForm(ImmutableMultiset multiset) { - this.multiset = multiset; - } - - Object readResolve() { - return multiset.entrySet(); - } - } - - private static class SerializedForm implements Serializable { - final Object[] elements; - final int[] counts; - - SerializedForm(Multiset multiset) { - int distinct = multiset.entrySet().size(); - elements = new Object[distinct]; - counts = new int[distinct]; - int i = 0; - for (Entry entry : multiset.entrySet()) { - elements[i] = entry.getElement(); - counts[i] = entry.getCount(); - i++; - } - } - - Object readResolve() { - LinkedHashMultiset multiset = LinkedHashMultiset.create(elements.length); - for (int i = 0; i < elements.length; i++) { - multiset.add(elements[i], counts[i]); - } - return ImmutableMultiset.copyOf(multiset); - } - - private static final long serialVersionUID = 0; - } - - // We can't label this with @Override, because it doesn't override anything - // in the GWT emulated version. - Object writeReplace() { - return new SerializedForm(this); - } - - /** - * Returns a new builder. The generated builder is equivalent to the builder - * created by the {@link Builder} constructor. - */ - public static Builder builder() { - return new Builder(); - } - - /** - * A builder for creating immutable multiset instances, especially {@code - * public static final} multisets ("constant multisets"). Example: - *
 {@code
-   *
-   *   public static final ImmutableMultiset BEANS =
-   *       new ImmutableMultiset.Builder()
-   *           .addCopies(Bean.COCOA, 4)
-   *           .addCopies(Bean.GARDEN, 6)
-   *           .addCopies(Bean.RED, 8)
-   *           .addCopies(Bean.BLACK_EYED, 10)
-   *           .build();}
- * - *

Builder instances can be reused; it is safe to call {@link #build} multiple - * times to build multiple multisets in series. - * - * @since 2.0 - */ - public static class Builder extends ImmutableCollection.Builder { - final Multiset contents; - - /** - * Creates a new builder. The returned builder is equivalent to the builder - * generated by {@link ImmutableMultiset#builder}. - */ - public Builder() { - this(LinkedHashMultiset.create()); - } - - Builder(Multiset contents) { - this.contents = contents; - } - - /** - * Adds {@code element} to the {@code ImmutableMultiset}. - * - * @param element the element to add - * @return this {@code Builder} object - * @throws NullPointerException if {@code element} is null - */ - @Override - public Builder add(E element) { - contents.add(checkNotNull(element)); - return this; - } - - /** - * Adds a number of occurrences of an element to this {@code - * ImmutableMultiset}. - * - * @param element the element to add - * @param occurrences the number of occurrences of the element to add. May - * be zero, in which case no change will be made. - * @return this {@code Builder} object - * @throws NullPointerException if {@code element} is null - * @throws IllegalArgumentException if {@code occurrences} is negative, or - * if this operation would result in more than {@link Integer#MAX_VALUE} - * occurrences of the element - */ - public Builder addCopies(E element, int occurrences) { - contents.add(checkNotNull(element), occurrences); - return this; - } - - /** - * Adds or removes the necessary occurrences of an element such that the - * element attains the desired count. - * - * @param element the element to add or remove occurrences of - * @param count the desired count of the element in this multiset - * @return this {@code Builder} object - * @throws NullPointerException if {@code element} is null - * @throws IllegalArgumentException if {@code count} is negative - */ - public Builder setCount(E element, int count) { - contents.setCount(checkNotNull(element), count); - return this; - } - - /** - * Adds each element of {@code elements} to the {@code ImmutableMultiset}. - * - * @param elements the elements to add - * @return this {@code Builder} object - * @throws NullPointerException if {@code elements} is null or contains a - * null element - */ - @Override - public Builder add(E... elements) { - super.add(elements); - return this; - } - - /** - * Adds each element of {@code elements} to the {@code ImmutableMultiset}. - * - * @param elements the {@code Iterable} to add to the {@code - * ImmutableMultiset} - * @return this {@code Builder} object - * @throws NullPointerException if {@code elements} is null or contains a - * null element - */ - @Override - public Builder addAll(Iterable elements) { - if (elements instanceof Multiset) { - Multiset multiset = Multisets.cast(elements); - for (Entry entry : multiset.entrySet()) { - addCopies(entry.getElement(), entry.getCount()); - } - } else { - super.addAll(elements); - } - return this; - } - - /** - * Adds each element of {@code elements} to the {@code ImmutableMultiset}. - * - * @param elements the elements to add to the {@code ImmutableMultiset} - * @return this {@code Builder} object - * @throws NullPointerException if {@code elements} is null or contains a - * null element - */ - @Override - public Builder addAll(Iterator elements) { - super.addAll(elements); - return this; - } - - /** - * Returns a newly-created {@code ImmutableMultiset} based on the contents - * of the {@code Builder}. - */ - @Override - public ImmutableMultiset build() { - return copyOf(contents); - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableRangeMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableRangeMap.java deleted file mode 100644 index a96b857094d3..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableRangeMap.java +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkElementIndex; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.collect.SortedLists.KeyAbsentBehavior; -import com.google.common.collect.SortedLists.KeyPresentBehavior; - -import java.io.Serializable; -import java.util.Map; -import java.util.Map.Entry; -import java.util.NoSuchElementException; - -import javax.annotation.Nullable; - -/** - * A {@link RangeMap} whose contents will never change, with many other important properties - * detailed at {@link ImmutableCollection}. - * - * @author Louis Wasserman - * @since 14.0 - */ -@Beta -@GwtIncompatible("NavigableMap") -public class ImmutableRangeMap, V> implements RangeMap, Serializable { - - private static final ImmutableRangeMap, Object> EMPTY = - new ImmutableRangeMap, Object>( - ImmutableList.>>of(), ImmutableList.of()); - - /** - * Returns an empty immutable range map. - */ - @SuppressWarnings("unchecked") - public static , V> ImmutableRangeMap of() { - return (ImmutableRangeMap) EMPTY; - } - - /** - * Returns an immutable range map mapping a single range to a single value. - */ - public static , V> ImmutableRangeMap of(Range range, V value) { - return new ImmutableRangeMap(ImmutableList.of(range), ImmutableList.of(value)); - } - - @SuppressWarnings("unchecked") - public static , V> ImmutableRangeMap copyOf( - RangeMap rangeMap) { - if (rangeMap instanceof ImmutableRangeMap) { - return (ImmutableRangeMap) rangeMap; - } - Map, ? extends V> map = rangeMap.asMapOfRanges(); - ImmutableList.Builder> rangesBuilder = new ImmutableList.Builder>(map.size()); - ImmutableList.Builder valuesBuilder = new ImmutableList.Builder(map.size()); - for (Entry, ? extends V> entry : map.entrySet()) { - rangesBuilder.add(entry.getKey()); - valuesBuilder.add(entry.getValue()); - } - return new ImmutableRangeMap(rangesBuilder.build(), valuesBuilder.build()); - } - - /** - * Returns a new builder for an immutable range map. - */ - public static , V> Builder builder() { - return new Builder(); - } - - /** - * A builder for immutable range maps. Overlapping ranges are prohibited. - */ - public static final class Builder, V> { - private final RangeSet keyRanges; - private final RangeMap rangeMap; - - public Builder() { - this.keyRanges = TreeRangeSet.create(); - this.rangeMap = TreeRangeMap.create(); - } - - /** - * Associates the specified range with the specified value. - * - * @throws IllegalArgumentException if {@code range} overlaps with any other ranges inserted - * into this builder, or if {@code range} is empty - */ - public Builder put(Range range, V value) { - checkNotNull(range); - checkNotNull(value); - checkArgument(!range.isEmpty(), "Range must not be empty, but was %s", range); - if (!keyRanges.complement().encloses(range)) { - // it's an error case; we can afford an expensive lookup - for (Entry, V> entry : rangeMap.asMapOfRanges().entrySet()) { - Range key = entry.getKey(); - if (key.isConnected(range) && !key.intersection(range).isEmpty()) { - throw new IllegalArgumentException( - "Overlapping ranges: range " + range + " overlaps with entry " + entry); - } - } - } - keyRanges.add(range); - rangeMap.put(range, value); - return this; - } - - /** - * Copies all associations from the specified range map into this builder. - * - * @throws IllegalArgumentException if any of the ranges in {@code rangeMap} overlap with ranges - * already in this builder - */ - public Builder putAll(RangeMap rangeMap) { - for (Entry, ? extends V> entry : rangeMap.asMapOfRanges().entrySet()) { - put(entry.getKey(), entry.getValue()); - } - return this; - } - - /** - * Returns an {@code ImmutableRangeMap} containing the associations previously added to this - * builder. - */ - public ImmutableRangeMap build() { - Map, V> map = rangeMap.asMapOfRanges(); - ImmutableList.Builder> rangesBuilder = - new ImmutableList.Builder>(map.size()); - ImmutableList.Builder valuesBuilder = new ImmutableList.Builder(map.size()); - for (Entry, V> entry : map.entrySet()) { - rangesBuilder.add(entry.getKey()); - valuesBuilder.add(entry.getValue()); - } - return new ImmutableRangeMap(rangesBuilder.build(), valuesBuilder.build()); - } - } - - private final transient ImmutableList> ranges; - private final transient ImmutableList values; - - ImmutableRangeMap(ImmutableList> ranges, ImmutableList values) { - this.ranges = ranges; - this.values = values; - } - - @Override - @Nullable - public V get(K key) { - int index = - SortedLists.binarySearch( - ranges, - Range.lowerBoundFn(), - Cut.belowValue(key), - KeyPresentBehavior.ANY_PRESENT, - KeyAbsentBehavior.NEXT_LOWER); - if (index == -1) { - return null; - } else { - Range range = ranges.get(index); - return range.contains(key) ? values.get(index) : null; - } - } - - @Override - @Nullable - public Map.Entry, V> getEntry(K key) { - int index = - SortedLists.binarySearch( - ranges, - Range.lowerBoundFn(), - Cut.belowValue(key), - KeyPresentBehavior.ANY_PRESENT, - KeyAbsentBehavior.NEXT_LOWER); - if (index == -1) { - return null; - } else { - Range range = ranges.get(index); - return range.contains(key) ? Maps.immutableEntry(range, values.get(index)) : null; - } - } - - @Override - public Range span() { - if (ranges.isEmpty()) { - throw new NoSuchElementException(); - } - Range firstRange = ranges.get(0); - Range lastRange = ranges.get(ranges.size() - 1); - return Range.create(firstRange.lowerBound, lastRange.upperBound); - } - - @Override - public void put(Range range, V value) { - throw new UnsupportedOperationException(); - } - - @Override - public void putAll(RangeMap rangeMap) { - throw new UnsupportedOperationException(); - } - - @Override - public void clear() { - throw new UnsupportedOperationException(); - } - - @Override - public void remove(Range range) { - throw new UnsupportedOperationException(); - } - - @Override - public ImmutableMap, V> asMapOfRanges() { - if (ranges.isEmpty()) { - return ImmutableMap.of(); - } - RegularImmutableSortedSet> rangeSet = - new RegularImmutableSortedSet>(ranges, Range.RANGE_LEX_ORDERING); - return new ImmutableSortedMap, V>(rangeSet, values); - } - - @Override - public ImmutableMap, V> asDescendingMapOfRanges() { - if (ranges.isEmpty()) { - return ImmutableMap.of(); - } - RegularImmutableSortedSet> rangeSet = - new RegularImmutableSortedSet>( - ranges.reverse(), Range.RANGE_LEX_ORDERING.reverse()); - return new ImmutableSortedMap, V>(rangeSet, values.reverse()); - } - - @Override - public ImmutableRangeMap subRangeMap(final Range range) { - if (checkNotNull(range).isEmpty()) { - return ImmutableRangeMap.of(); - } else if (ranges.isEmpty() || range.encloses(span())) { - return this; - } - int lowerIndex = - SortedLists.binarySearch( - ranges, - Range.upperBoundFn(), - range.lowerBound, - KeyPresentBehavior.FIRST_AFTER, - KeyAbsentBehavior.NEXT_HIGHER); - int upperIndex = - SortedLists.binarySearch( - ranges, - Range.lowerBoundFn(), - range.upperBound, - KeyPresentBehavior.ANY_PRESENT, - KeyAbsentBehavior.NEXT_HIGHER); - if (lowerIndex >= upperIndex) { - return ImmutableRangeMap.of(); - } - final int off = lowerIndex; - final int len = upperIndex - lowerIndex; - ImmutableList> subRanges = - new ImmutableList>() { - @Override - public int size() { - return len; - } - - @Override - public Range get(int index) { - checkElementIndex(index, len); - if (index == 0 || index == len - 1) { - return ranges.get(index + off).intersection(range); - } else { - return ranges.get(index + off); - } - } - - @Override - boolean isPartialView() { - return true; - } - }; - final ImmutableRangeMap outer = this; - return new ImmutableRangeMap(subRanges, values.subList(lowerIndex, upperIndex)) { - @Override - public ImmutableRangeMap subRangeMap(Range subRange) { - if (range.isConnected(subRange)) { - return outer.subRangeMap(subRange.intersection(range)); - } else { - return ImmutableRangeMap.of(); - } - } - }; - } - - @Override - public int hashCode() { - return asMapOfRanges().hashCode(); - } - - @Override - public boolean equals(@Nullable Object o) { - if (o instanceof RangeMap) { - RangeMap rangeMap = (RangeMap) o; - return asMapOfRanges().equals(rangeMap.asMapOfRanges()); - } - return false; - } - - @Override - public String toString() { - return asMapOfRanges().toString(); - } - - /** - * This class is used to serialize ImmutableRangeMap instances. - * Serializes the {@link #asMapOfRanges()} form. - */ - private static class SerializedForm, V> implements Serializable { - - private final ImmutableMap, V> mapOfRanges; - - SerializedForm(ImmutableMap, V> mapOfRanges) { - this.mapOfRanges = mapOfRanges; - } - - Object readResolve() { - if (mapOfRanges.isEmpty()) { - return of(); - } else { - return createRangeMap(); - } - } - - Object createRangeMap() { - Builder builder = new Builder(); - for (Entry, V> entry : mapOfRanges.entrySet()) { - builder.put(entry.getKey(), entry.getValue()); - } - return builder.build(); - } - - private static final long serialVersionUID = 0; - } - - Object writeReplace() { - return new SerializedForm(asMapOfRanges()); - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableRangeSet.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableRangeSet.java deleted file mode 100644 index 6345e93ef97a..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableRangeSet.java +++ /dev/null @@ -1,637 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkElementIndex; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.SortedLists.KeyAbsentBehavior.NEXT_LOWER; -import static com.google.common.collect.SortedLists.KeyPresentBehavior.ANY_PRESENT; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.collect.SortedLists.KeyAbsentBehavior; -import com.google.common.collect.SortedLists.KeyPresentBehavior; -import com.google.common.primitives.Ints; - -import java.io.Serializable; -import java.util.Collections; -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * A {@link RangeSet} whose contents will never change, with many other important properties - * detailed at {@link ImmutableCollection}. - * - * @author Louis Wasserman - * @since 14.0 - */ -@Beta -public final class ImmutableRangeSet extends AbstractRangeSet - implements Serializable { - - private static final ImmutableRangeSet> EMPTY = - new ImmutableRangeSet>(ImmutableList.>>of()); - - private static final ImmutableRangeSet> ALL = - new ImmutableRangeSet>(ImmutableList.of(Range.>all())); - - /** - * Returns an empty immutable range set. - */ - @SuppressWarnings("unchecked") - public static ImmutableRangeSet of() { - return (ImmutableRangeSet) EMPTY; - } - - /** - * Returns an immutable range set containing the single range {@link Range#all()}. - */ - @SuppressWarnings("unchecked") - static ImmutableRangeSet all() { - return (ImmutableRangeSet) ALL; - } - - /** - * Returns an immutable range set containing the specified single range. If {@link Range#isEmpty() - * range.isEmpty()}, this is equivalent to {@link ImmutableRangeSet#of()}. - */ - public static ImmutableRangeSet of(Range range) { - checkNotNull(range); - if (range.isEmpty()) { - return of(); - } else if (range.equals(Range.all())) { - return all(); - } else { - return new ImmutableRangeSet(ImmutableList.of(range)); - } - } - - /** - * Returns an immutable copy of the specified {@code RangeSet}. - */ - public static ImmutableRangeSet copyOf(RangeSet rangeSet) { - checkNotNull(rangeSet); - if (rangeSet.isEmpty()) { - return of(); - } else if (rangeSet.encloses(Range.all())) { - return all(); - } - - if (rangeSet instanceof ImmutableRangeSet) { - ImmutableRangeSet immutableRangeSet = (ImmutableRangeSet) rangeSet; - if (!immutableRangeSet.isPartialView()) { - return immutableRangeSet; - } - } - return new ImmutableRangeSet(ImmutableList.copyOf(rangeSet.asRanges())); - } - - ImmutableRangeSet(ImmutableList> ranges) { - this.ranges = ranges; - } - - private ImmutableRangeSet(ImmutableList> ranges, ImmutableRangeSet complement) { - this.ranges = ranges; - this.complement = complement; - } - - private transient final ImmutableList> ranges; - - @Override - public boolean encloses(Range otherRange) { - int index = - SortedLists.binarySearch( - ranges, - Range.lowerBoundFn(), - otherRange.lowerBound, - Ordering.natural(), - ANY_PRESENT, - NEXT_LOWER); - return index != -1 && ranges.get(index).encloses(otherRange); - } - - @Override - public Range rangeContaining(C value) { - int index = - SortedLists.binarySearch( - ranges, - Range.lowerBoundFn(), - Cut.belowValue(value), - Ordering.natural(), - ANY_PRESENT, - NEXT_LOWER); - if (index != -1) { - Range range = ranges.get(index); - return range.contains(value) ? range : null; - } - return null; - } - - @Override - public Range span() { - if (ranges.isEmpty()) { - throw new NoSuchElementException(); - } - return Range.create(ranges.get(0).lowerBound, ranges.get(ranges.size() - 1).upperBound); - } - - @Override - public boolean isEmpty() { - return ranges.isEmpty(); - } - - @Override - public void add(Range range) { - throw new UnsupportedOperationException(); - } - - @Override - public void addAll(RangeSet other) { - throw new UnsupportedOperationException(); - } - - @Override - public void remove(Range range) { - throw new UnsupportedOperationException(); - } - - @Override - public void removeAll(RangeSet other) { - throw new UnsupportedOperationException(); - } - - @Override - public ImmutableSet> asRanges() { - if (ranges.isEmpty()) { - return ImmutableSet.of(); - } - return new RegularImmutableSortedSet>(ranges, Range.RANGE_LEX_ORDERING); - } - - @Override - public ImmutableSet> asDescendingSetOfRanges() { - if (ranges.isEmpty()) { - return ImmutableSet.of(); - } - return new RegularImmutableSortedSet>( - ranges.reverse(), Range.RANGE_LEX_ORDERING.reverse()); - } - - private transient ImmutableRangeSet complement; - - private final class ComplementRanges extends ImmutableList> { - // True if the "positive" range set is empty or bounded below. - private final boolean positiveBoundedBelow; - - // True if the "positive" range set is empty or bounded above. - private final boolean positiveBoundedAbove; - - private final int size; - - ComplementRanges() { - this.positiveBoundedBelow = ranges.get(0).hasLowerBound(); - this.positiveBoundedAbove = Iterables.getLast(ranges).hasUpperBound(); - - int size = ranges.size() - 1; - if (positiveBoundedBelow) { - size++; - } - if (positiveBoundedAbove) { - size++; - } - this.size = size; - } - - @Override - public int size() { - return size; - } - - @Override - public Range get(int index) { - checkElementIndex(index, size); - - Cut lowerBound; - if (positiveBoundedBelow) { - lowerBound = (index == 0) ? Cut.belowAll() : ranges.get(index - 1).upperBound; - } else { - lowerBound = ranges.get(index).upperBound; - } - - Cut upperBound; - if (positiveBoundedAbove && index == size - 1) { - upperBound = Cut.aboveAll(); - } else { - upperBound = ranges.get(index + (positiveBoundedBelow ? 0 : 1)).lowerBound; - } - - return Range.create(lowerBound, upperBound); - } - - @Override - boolean isPartialView() { - return true; - } - } - - @Override - public ImmutableRangeSet complement() { - ImmutableRangeSet result = complement; - if (result != null) { - return result; - } else if (ranges.isEmpty()) { - return complement = all(); - } else if (ranges.size() == 1 && ranges.get(0).equals(Range.all())) { - return complement = of(); - } else { - ImmutableList> complementRanges = new ComplementRanges(); - result = complement = new ImmutableRangeSet(complementRanges, this); - } - return result; - } - - /** - * Returns a list containing the nonempty intersections of {@code range} - * with the ranges in this range set. - */ - private ImmutableList> intersectRanges(final Range range) { - if (ranges.isEmpty() || range.isEmpty()) { - return ImmutableList.of(); - } else if (range.encloses(span())) { - return ranges; - } - - final int fromIndex; - if (range.hasLowerBound()) { - fromIndex = - SortedLists.binarySearch( - ranges, - Range.upperBoundFn(), - range.lowerBound, - KeyPresentBehavior.FIRST_AFTER, - KeyAbsentBehavior.NEXT_HIGHER); - } else { - fromIndex = 0; - } - - int toIndex; - if (range.hasUpperBound()) { - toIndex = - SortedLists.binarySearch( - ranges, - Range.lowerBoundFn(), - range.upperBound, - KeyPresentBehavior.FIRST_PRESENT, - KeyAbsentBehavior.NEXT_HIGHER); - } else { - toIndex = ranges.size(); - } - final int length = toIndex - fromIndex; - if (length == 0) { - return ImmutableList.of(); - } else { - return new ImmutableList>() { - @Override - public int size() { - return length; - } - - @Override - public Range get(int index) { - checkElementIndex(index, length); - if (index == 0 || index == length - 1) { - return ranges.get(index + fromIndex).intersection(range); - } else { - return ranges.get(index + fromIndex); - } - } - - @Override - boolean isPartialView() { - return true; - } - }; - } - } - - /** - * Returns a view of the intersection of this range set with the given range. - */ - @Override - public ImmutableRangeSet subRangeSet(Range range) { - if (!isEmpty()) { - Range span = span(); - if (range.encloses(span)) { - return this; - } else if (range.isConnected(span)) { - return new ImmutableRangeSet(intersectRanges(range)); - } - } - return of(); - } - - /** - * Returns an {@link ImmutableSortedSet} containing the same values in the given domain - * {@linkplain RangeSet#contains contained} by this range set. - * - *

Note: {@code a.asSet(d).equals(b.asSet(d))} does not imply {@code a.equals(b)}! For - * example, {@code a} and {@code b} could be {@code [2..4]} and {@code (1..5)}, or the empty - * ranges {@code [3..3)} and {@code [4..4)}. - * - *

Warning: Be extremely careful what you do with the {@code asSet} view of a large - * range set (such as {@code ImmutableRangeSet.of(Range.greaterThan(0))}). Certain operations on - * such a set can be performed efficiently, but others (such as {@link Set#hashCode} or - * {@link Collections#frequency}) can cause major performance problems. - * - *

The returned set's {@link Object#toString} method returns a short-hand form of the set's - * contents, such as {@code "[1..100]}"}. - * - * @throws IllegalArgumentException if neither this range nor the domain has a lower bound, or if - * neither has an upper bound - */ - public ImmutableSortedSet asSet(DiscreteDomain domain) { - checkNotNull(domain); - if (isEmpty()) { - return ImmutableSortedSet.of(); - } - Range span = span().canonical(domain); - if (!span.hasLowerBound()) { - // according to the spec of canonical, neither this ImmutableRangeSet nor - // the range have a lower bound - throw new IllegalArgumentException( - "Neither the DiscreteDomain nor this range set are bounded below"); - } else if (!span.hasUpperBound()) { - try { - domain.maxValue(); - } catch (NoSuchElementException e) { - throw new IllegalArgumentException( - "Neither the DiscreteDomain nor this range set are bounded above"); - } - } - - return new AsSet(domain); - } - - private final class AsSet extends ImmutableSortedSet { - private final DiscreteDomain domain; - - AsSet(DiscreteDomain domain) { - super(Ordering.natural()); - this.domain = domain; - } - - private transient Integer size; - - @Override - public int size() { - // racy single-check idiom - Integer result = size; - if (result == null) { - long total = 0; - for (Range range : ranges) { - total += ContiguousSet.create(range, domain).size(); - if (total >= Integer.MAX_VALUE) { - break; - } - } - result = size = Ints.saturatedCast(total); - } - return result.intValue(); - } - - @Override - public UnmodifiableIterator iterator() { - return new AbstractIterator() { - final Iterator> rangeItr = ranges.iterator(); - Iterator elemItr = Iterators.emptyIterator(); - - @Override - protected C computeNext() { - while (!elemItr.hasNext()) { - if (rangeItr.hasNext()) { - elemItr = ContiguousSet.create(rangeItr.next(), domain).iterator(); - } else { - return endOfData(); - } - } - return elemItr.next(); - } - }; - } - - @Override - @GwtIncompatible("NavigableSet") - public UnmodifiableIterator descendingIterator() { - return new AbstractIterator() { - final Iterator> rangeItr = ranges.reverse().iterator(); - Iterator elemItr = Iterators.emptyIterator(); - - @Override - protected C computeNext() { - while (!elemItr.hasNext()) { - if (rangeItr.hasNext()) { - elemItr = ContiguousSet.create(rangeItr.next(), domain).descendingIterator(); - } else { - return endOfData(); - } - } - return elemItr.next(); - } - }; - } - - ImmutableSortedSet subSet(Range range) { - return subRangeSet(range).asSet(domain); - } - - @Override - ImmutableSortedSet headSetImpl(C toElement, boolean inclusive) { - return subSet(Range.upTo(toElement, BoundType.forBoolean(inclusive))); - } - - @Override - ImmutableSortedSet subSetImpl( - C fromElement, boolean fromInclusive, C toElement, boolean toInclusive) { - if (!fromInclusive && !toInclusive && Range.compareOrThrow(fromElement, toElement) == 0) { - return ImmutableSortedSet.of(); - } - return subSet( - Range.range( - fromElement, BoundType.forBoolean(fromInclusive), - toElement, BoundType.forBoolean(toInclusive))); - } - - @Override - ImmutableSortedSet tailSetImpl(C fromElement, boolean inclusive) { - return subSet(Range.downTo(fromElement, BoundType.forBoolean(inclusive))); - } - - @Override - public boolean contains(@Nullable Object o) { - if (o == null) { - return false; - } - try { - @SuppressWarnings("unchecked") // we catch CCE's - C c = (C) o; - return ImmutableRangeSet.this.contains(c); - } catch (ClassCastException e) { - return false; - } - } - - @Override - int indexOf(Object target) { - if (contains(target)) { - @SuppressWarnings("unchecked") // if it's contained, it's definitely a C - C c = (C) target; - long total = 0; - for (Range range : ranges) { - if (range.contains(c)) { - return Ints.saturatedCast(total + ContiguousSet.create(range, domain).indexOf(c)); - } else { - total += ContiguousSet.create(range, domain).size(); - } - } - throw new AssertionError("impossible"); - } - return -1; - } - - @Override - boolean isPartialView() { - return ranges.isPartialView(); - } - - @Override - public String toString() { - return ranges.toString(); - } - - @Override - Object writeReplace() { - return new AsSetSerializedForm(ranges, domain); - } - } - - private static class AsSetSerializedForm implements Serializable { - private final ImmutableList> ranges; - private final DiscreteDomain domain; - - AsSetSerializedForm(ImmutableList> ranges, DiscreteDomain domain) { - this.ranges = ranges; - this.domain = domain; - } - - Object readResolve() { - return new ImmutableRangeSet(ranges).asSet(domain); - } - } - - /** - * Returns {@code true} if this immutable range set's implementation contains references to - * user-created objects that aren't accessible via this range set's methods. This is generally - * used to determine whether {@code copyOf} implementations should make an explicit copy to avoid - * memory leaks. - */ - boolean isPartialView() { - return ranges.isPartialView(); - } - - /** - * Returns a new builder for an immutable range set. - */ - public static > Builder builder() { - return new Builder(); - } - - /** - * A builder for immutable range sets. - */ - public static class Builder> { - private final RangeSet rangeSet; - - public Builder() { - this.rangeSet = TreeRangeSet.create(); - } - - /** - * Add the specified range to this builder. Adjacent/abutting ranges are permitted, but - * empty ranges, or ranges with nonempty overlap, are forbidden. - * - * @throws IllegalArgumentException if {@code range} is empty or has nonempty intersection with - * any ranges already added to the builder - */ - public Builder add(Range range) { - if (range.isEmpty()) { - throw new IllegalArgumentException("range must not be empty, but was " + range); - } else if (!rangeSet.complement().encloses(range)) { - for (Range currentRange : rangeSet.asRanges()) { - checkArgument( - !currentRange.isConnected(range) || currentRange.intersection(range).isEmpty(), - "Ranges may not overlap, but received %s and %s", - currentRange, - range); - } - throw new AssertionError("should have thrown an IAE above"); - } - rangeSet.add(range); - return this; - } - - /** - * Add all ranges from the specified range set to this builder. Duplicate or connected ranges - * are permitted, and will be merged in the resulting immutable range set. - */ - public Builder addAll(RangeSet ranges) { - for (Range range : ranges.asRanges()) { - add(range); - } - return this; - } - - /** - * Returns an {@code ImmutableRangeSet} containing the ranges added to this builder. - */ - public ImmutableRangeSet build() { - return copyOf(rangeSet); - } - } - - private static final class SerializedForm implements Serializable { - private final ImmutableList> ranges; - - SerializedForm(ImmutableList> ranges) { - this.ranges = ranges; - } - - Object readResolve() { - if (ranges.isEmpty()) { - return of(); - } else if (ranges.equals(ImmutableList.of(Range.all()))) { - return all(); - } else { - return new ImmutableRangeSet(ranges); - } - } - } - - Object writeReplace() { - return new SerializedForm(ranges); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSet.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSet.java deleted file mode 100644 index ea5b691ddf91..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSet.java +++ /dev/null @@ -1,502 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.collect.ObjectArrays.checkElementNotNull; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.primitives.Ints; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.EnumSet; -import java.util.Iterator; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * A {@link Set} whose contents will never change, with many other important properties detailed at - * {@link ImmutableCollection}. - * - * @since 2.0 - */ -@GwtCompatible(serializable = true, emulated = true) -@SuppressWarnings("serial") // we're overriding default serialization -public abstract class ImmutableSet extends ImmutableCollection implements Set { - /** - * Returns the empty immutable set. Preferred over {@link Collections#emptySet} for code - * consistency, and because the return type conveys the immutability guarantee. - */ - @SuppressWarnings({"unchecked"}) // fully variant implementation (never actually produces any Es) - public static ImmutableSet of() { - return (ImmutableSet) RegularImmutableSet.EMPTY; - } - - /** - * Returns an immutable set containing {@code element}. Preferred over {@link - * Collections#singleton} for code consistency, {@code null} rejection, and because the return - * type conveys the immutability guarantee. - */ - public static ImmutableSet of(E element) { - return new SingletonImmutableSet(element); - } - - /** - * Returns an immutable set containing the given elements, minus duplicates, in the order each was - * first specified. That is, if multiple elements are {@linkplain Object#equals equal}, all except - * the first are ignored. - */ - public static ImmutableSet of(E e1, E e2) { - return construct(2, e1, e2); - } - - /** - * Returns an immutable set containing the given elements, minus duplicates, in the order each was - * first specified. That is, if multiple elements are {@linkplain Object#equals equal}, all except - * the first are ignored. - */ - public static ImmutableSet of(E e1, E e2, E e3) { - return construct(3, e1, e2, e3); - } - - /** - * Returns an immutable set containing the given elements, minus duplicates, in the order each was - * first specified. That is, if multiple elements are {@linkplain Object#equals equal}, all except - * the first are ignored. - */ - public static ImmutableSet of(E e1, E e2, E e3, E e4) { - return construct(4, e1, e2, e3, e4); - } - - /** - * Returns an immutable set containing the given elements, minus duplicates, in the order each was - * first specified. That is, if multiple elements are {@linkplain Object#equals equal}, all except - * the first are ignored. - */ - public static ImmutableSet of(E e1, E e2, E e3, E e4, E e5) { - return construct(5, e1, e2, e3, e4, e5); - } - - /** - * Returns an immutable set containing the given elements, minus duplicates, in the order each was - * first specified. That is, if multiple elements are {@linkplain Object#equals equal}, all except - * the first are ignored. - * - * @since 3.0 (source-compatible since 2.0) - */ - public static ImmutableSet of(E e1, E e2, E e3, E e4, E e5, E e6, E... others) { - final int paramCount = 6; - Object[] elements = new Object[paramCount + others.length]; - elements[0] = e1; - elements[1] = e2; - elements[2] = e3; - elements[3] = e4; - elements[4] = e5; - elements[5] = e6; - System.arraycopy(others, 0, elements, paramCount, others.length); - return construct(elements.length, elements); - } - - /** - * Constructs an {@code ImmutableSet} from the first {@code n} elements of the specified array. - * If {@code k} is the size of the returned {@code ImmutableSet}, then the unique elements of - * {@code elements} will be in the first {@code k} positions, and {@code elements[i] == null} for - * {@code k <= i < n}. - * - *

This may modify {@code elements}. Additionally, if {@code n == elements.length} and - * {@code elements} contains no duplicates, {@code elements} may be used without copying in the - * returned {@code ImmutableSet}, in which case it may no longer be modified. - * - *

{@code elements} may contain only values of type {@code E}. - * - * @throws NullPointerException if any of the first {@code n} elements of {@code elements} is - * null - */ - private static ImmutableSet construct(int n, Object... elements) { - switch (n) { - case 0: - return of(); - case 1: - @SuppressWarnings("unchecked") // safe; elements contains only E's - E elem = (E) elements[0]; - return of(elem); - default: - // continue below to handle the general case - } - int tableSize = chooseTableSize(n); - Object[] table = new Object[tableSize]; - int mask = tableSize - 1; - int hashCode = 0; - int uniques = 0; - for (int i = 0; i < n; i++) { - Object element = checkElementNotNull(elements[i], i); - int hash = element.hashCode(); - for (int j = Hashing.smear(hash); ; j++) { - int index = j & mask; - Object value = table[index]; - if (value == null) { - // Came to an empty slot. Put the element here. - elements[uniques++] = element; - table[index] = element; - hashCode += hash; - break; - } else if (value.equals(element)) { - break; - } - } - } - Arrays.fill(elements, uniques, n, null); - if (uniques == 1) { - // There is only one element or elements are all duplicates - @SuppressWarnings("unchecked") // we are careful to only pass in E - E element = (E) elements[0]; - return new SingletonImmutableSet(element, hashCode); - } else if (tableSize != chooseTableSize(uniques)) { - // Resize the table when the array includes too many duplicates. - // when this happens, we have already made a copy - return construct(uniques, elements); - } else { - Object[] uniqueElements = - (uniques < elements.length) - ? ObjectArrays.arraysCopyOf(elements, uniques) - : elements; - return new RegularImmutableSet(uniqueElements, hashCode, table, mask); - } - } - - // We use power-of-2 tables, and this is the highest int that's a power of 2 - static final int MAX_TABLE_SIZE = Ints.MAX_POWER_OF_TWO; - - // Represents how tightly we can pack things, as a maximum. - private static final double DESIRED_LOAD_FACTOR = 0.7; - - // If the set has this many elements, it will "max out" the table size - private static final int CUTOFF = (int) (MAX_TABLE_SIZE * DESIRED_LOAD_FACTOR); - - /** - * Returns an array size suitable for the backing array of a hash table that - * uses open addressing with linear probing in its implementation. The - * returned size is the smallest power of two that can hold setSize elements - * with the desired load factor. - * - *

Do not call this method with setSize < 2. - */ - @VisibleForTesting - static int chooseTableSize(int setSize) { - // Correct the size for open addressing to match desired load factor. - if (setSize < CUTOFF) { - // Round up to the next highest power of 2. - int tableSize = Integer.highestOneBit(setSize - 1) << 1; - while (tableSize * DESIRED_LOAD_FACTOR < setSize) { - tableSize <<= 1; - } - return tableSize; - } - - // The table can't be completely full or we'll get infinite reprobes - checkArgument(setSize < MAX_TABLE_SIZE, "collection too large"); - return MAX_TABLE_SIZE; - } - - /** - * Returns an immutable set containing each of {@code elements}, minus duplicates, in the order - * each appears first in the source collection. - * - *

Performance note: This method will sometimes recognize that the actual copy operation - * is unnecessary; for example, {@code copyOf(copyOf(anArrayList))} will copy the data only once. - * This reduces the expense of habitually making defensive copies at API boundaries. However, the - * the precise conditions for skipping the copy operation are undefined. - * - * @throws NullPointerException if any of {@code elements} is null - * @since 7.0 (source-compatible since 2.0) - */ - public static ImmutableSet copyOf(Collection elements) { - /* - * TODO(lowasser): consider checking for ImmutableAsList here - * TODO(lowasser): consider checking for Multiset here - */ - if (elements instanceof ImmutableSet && !(elements instanceof ImmutableSortedSet)) { - @SuppressWarnings("unchecked") // all supported methods are covariant - ImmutableSet set = (ImmutableSet) elements; - if (!set.isPartialView()) { - return set; - } - } else if (elements instanceof EnumSet) { - return copyOfEnumSet((EnumSet) elements); - } - Object[] array = elements.toArray(); - return construct(array.length, array); - } - - /** - * Returns an immutable set containing each of {@code elements}, minus duplicates, in the order - * each appears first in the source iterable. This method iterates over {@code elements} only - * once. - * - *

Performance note: This method will sometimes recognize that the actual copy operation - * is unnecessary; for example, {@code copyOf(copyOf(anArrayList))} should copy the data only - * once. This reduces the expense of habitually making defensive copies at API boundaries. - * However, the precise conditions for skipping the copy operation are undefined. - * - * @throws NullPointerException if any of {@code elements} is null - */ - public static ImmutableSet copyOf(Iterable elements) { - return (elements instanceof Collection) - ? copyOf((Collection) elements) - : copyOf(elements.iterator()); - } - - /** - * Returns an immutable set containing each of {@code elements}, minus duplicates, in the order - * each appears first in the source iterator. - * - * @throws NullPointerException if any of {@code elements} is null - */ - public static ImmutableSet copyOf(Iterator elements) { - // We special-case for 0 or 1 elements, but anything further is madness. - if (!elements.hasNext()) { - return of(); - } - E first = elements.next(); - if (!elements.hasNext()) { - return of(first); - } else { - return new ImmutableSet.Builder() - .add(first) - .addAll(elements) - .build(); - } - } - - /** - * Returns an immutable set containing each of {@code elements}, minus duplicates, in the order - * each appears first in the source array. - * - * @throws NullPointerException if any of {@code elements} is null - * @since 3.0 - */ - public static ImmutableSet copyOf(E[] elements) { - switch (elements.length) { - case 0: - return of(); - case 1: - return of(elements[0]); - default: - return construct(elements.length, elements.clone()); - } - } - - @SuppressWarnings("rawtypes") // necessary to compile against Java 8 - private static ImmutableSet copyOfEnumSet(EnumSet enumSet) { - return ImmutableEnumSet.asImmutable(EnumSet.copyOf(enumSet)); - } - - ImmutableSet() {} - - /** Returns {@code true} if the {@code hashCode()} method runs quickly. */ - boolean isHashCodeFast() { - return false; - } - - @Override - public boolean equals(@Nullable Object object) { - if (object == this) { - return true; - } else if (object instanceof ImmutableSet - && isHashCodeFast() - && ((ImmutableSet) object).isHashCodeFast() - && hashCode() != object.hashCode()) { - return false; - } - return Sets.equalsImpl(this, object); - } - - @Override - public int hashCode() { - return Sets.hashCodeImpl(this); - } - - // This declaration is needed to make Set.iterator() and - // ImmutableCollection.iterator() consistent. - @Override - public abstract UnmodifiableIterator iterator(); - - abstract static class Indexed extends ImmutableSet { - abstract E get(int index); - - @Override - public UnmodifiableIterator iterator() { - return asList().iterator(); - } - - @Override - ImmutableList createAsList() { - return new ImmutableAsList() { - @Override - public E get(int index) { - return Indexed.this.get(index); - } - - @Override - Indexed delegateCollection() { - return Indexed.this; - } - }; - } - } - - /* - * This class is used to serialize all ImmutableSet instances, except for - * ImmutableEnumSet/ImmutableSortedSet, regardless of implementation type. It - * captures their "logical contents" and they are reconstructed using public - * static factories. This is necessary to ensure that the existence of a - * particular implementation type is an implementation detail. - */ - private static class SerializedForm implements Serializable { - final Object[] elements; - - SerializedForm(Object[] elements) { - this.elements = elements; - } - - Object readResolve() { - return copyOf(elements); - } - - private static final long serialVersionUID = 0; - } - - @Override - Object writeReplace() { - return new SerializedForm(toArray()); - } - - /** - * Returns a new builder. The generated builder is equivalent to the builder - * created by the {@link Builder} constructor. - */ - public static Builder builder() { - return new Builder(); - } - - /** - * A builder for creating {@code ImmutableSet} instances. Example:

   {@code
-   *
-   *   static final ImmutableSet GOOGLE_COLORS =
-   *       ImmutableSet.builder()
-   *           .addAll(WEBSAFE_COLORS)
-   *           .add(new Color(0, 191, 255))
-   *           .build();}
- * - *

Building does not change the state of the builder, so it is still possible to add more - * elements and to build again. - * - * @since 2.0 - */ - public static class Builder extends ImmutableCollection.ArrayBasedBuilder { - - /** - * Creates a new builder. The returned builder is equivalent to the builder - * generated by {@link ImmutableSet#builder}. - */ - public Builder() { - this(DEFAULT_INITIAL_CAPACITY); - } - - Builder(int capacity) { - super(capacity); - } - - /** - * Adds {@code element} to the {@code ImmutableSet}. If the {@code - * ImmutableSet} already contains {@code element}, then {@code add} has no - * effect (only the previously added element is retained). - * - * @param element the element to add - * @return this {@code Builder} object - * @throws NullPointerException if {@code element} is null - */ - @Override - public Builder add(E element) { - super.add(element); - return this; - } - - /** - * Adds each element of {@code elements} to the {@code ImmutableSet}, - * ignoring duplicate elements (only the first duplicate element is added). - * - * @param elements the elements to add - * @return this {@code Builder} object - * @throws NullPointerException if {@code elements} is null or contains a - * null element - */ - @Override - public Builder add(E... elements) { - super.add(elements); - return this; - } - - /** - * Adds each element of {@code elements} to the {@code ImmutableSet}, - * ignoring duplicate elements (only the first duplicate element is added). - * - * @param elements the {@code Iterable} to add to the {@code ImmutableSet} - * @return this {@code Builder} object - * @throws NullPointerException if {@code elements} is null or contains a - * null element - */ - @Override - public Builder addAll(Iterable elements) { - super.addAll(elements); - return this; - } - - /** - * Adds each element of {@code elements} to the {@code ImmutableSet}, - * ignoring duplicate elements (only the first duplicate element is added). - * - * @param elements the elements to add to the {@code ImmutableSet} - * @return this {@code Builder} object - * @throws NullPointerException if {@code elements} is null or contains a - * null element - */ - @Override - public Builder addAll(Iterator elements) { - super.addAll(elements); - return this; - } - - /** - * Returns a newly-created {@code ImmutableSet} based on the contents of - * the {@code Builder}. - */ - @Override - public ImmutableSet build() { - ImmutableSet result = construct(size, contents); - // construct has the side effect of deduping contents, so we update size - // accordingly. - size = result.size(); - return result; - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSetMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSetMultimap.java deleted file mode 100644 index 5cad0104f2d0..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSetMultimap.java +++ /dev/null @@ -1,548 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.base.MoreObjects; -import com.google.j2objc.annotations.Weak; - -import java.io.IOException; -import java.io.InvalidObjectException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.Arrays; -import java.util.Collection; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import javax.annotation.Nullable; - -/** - * A {@link SetMultimap} whose contents will never change, with many other important properties - * detailed at {@link ImmutableCollection}. - * - *

See the Guava User Guide article on - * immutable collections. - * - * @author Mike Ward - * @since 2.0 - */ -@GwtCompatible(serializable = true, emulated = true) -public class ImmutableSetMultimap extends ImmutableMultimap - implements SetMultimap { - - /** Returns the empty multimap. */ - // Casting is safe because the multimap will never hold any elements. - @SuppressWarnings("unchecked") - public static ImmutableSetMultimap of() { - return (ImmutableSetMultimap) EmptyImmutableSetMultimap.INSTANCE; - } - - /** - * Returns an immutable multimap containing a single entry. - */ - public static ImmutableSetMultimap of(K k1, V v1) { - ImmutableSetMultimap.Builder builder = ImmutableSetMultimap.builder(); - builder.put(k1, v1); - return builder.build(); - } - - /** - * Returns an immutable multimap containing the given entries, in order. - * Repeated occurrences of an entry (according to {@link Object#equals}) after - * the first are ignored. - */ - public static ImmutableSetMultimap of(K k1, V v1, K k2, V v2) { - ImmutableSetMultimap.Builder builder = ImmutableSetMultimap.builder(); - builder.put(k1, v1); - builder.put(k2, v2); - return builder.build(); - } - - /** - * Returns an immutable multimap containing the given entries, in order. - * Repeated occurrences of an entry (according to {@link Object#equals}) after - * the first are ignored. - */ - public static ImmutableSetMultimap of(K k1, V v1, K k2, V v2, K k3, V v3) { - ImmutableSetMultimap.Builder builder = ImmutableSetMultimap.builder(); - builder.put(k1, v1); - builder.put(k2, v2); - builder.put(k3, v3); - return builder.build(); - } - - /** - * Returns an immutable multimap containing the given entries, in order. - * Repeated occurrences of an entry (according to {@link Object#equals}) after - * the first are ignored. - */ - public static ImmutableSetMultimap of( - K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { - ImmutableSetMultimap.Builder builder = ImmutableSetMultimap.builder(); - builder.put(k1, v1); - builder.put(k2, v2); - builder.put(k3, v3); - builder.put(k4, v4); - return builder.build(); - } - - /** - * Returns an immutable multimap containing the given entries, in order. - * Repeated occurrences of an entry (according to {@link Object#equals}) after - * the first are ignored. - */ - public static ImmutableSetMultimap of( - K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { - ImmutableSetMultimap.Builder builder = ImmutableSetMultimap.builder(); - builder.put(k1, v1); - builder.put(k2, v2); - builder.put(k3, v3); - builder.put(k4, v4); - builder.put(k5, v5); - return builder.build(); - } - - // looking for of() with > 5 entries? Use the builder instead. - - /** - * Returns a new {@link Builder}. - */ - public static Builder builder() { - return new Builder(); - } - - /** - * A builder for creating immutable {@code SetMultimap} instances, especially - * {@code public static final} multimaps ("constant multimaps"). Example: - *

   {@code
-   *
-   *   static final Multimap STRING_TO_INTEGER_MULTIMAP =
-   *       new ImmutableSetMultimap.Builder()
-   *           .put("one", 1)
-   *           .putAll("several", 1, 2, 3)
-   *           .putAll("many", 1, 2, 3, 4, 5)
-   *           .build();}
- * - *

Builder instances can be reused; it is safe to call {@link #build} multiple - * times to build multiple multimaps in series. Each multimap contains the - * key-value mappings in the previously created multimaps. - * - * @since 2.0 - */ - public static final class Builder extends ImmutableMultimap.Builder { - /** - * Creates a new builder. The returned builder is equivalent to the builder - * generated by {@link ImmutableSetMultimap#builder}. - */ - public Builder() { - super(MultimapBuilder.linkedHashKeys().linkedHashSetValues().build()); - } - - /** - * Adds a key-value mapping to the built multimap if it is not already - * present. - */ - @Override - public Builder put(K key, V value) { - builderMultimap.put(checkNotNull(key), checkNotNull(value)); - return this; - } - - /** - * Adds an entry to the built multimap if it is not already present. - * - * @since 11.0 - */ - @Override - public Builder put(Entry entry) { - builderMultimap.put(checkNotNull(entry.getKey()), checkNotNull(entry.getValue())); - return this; - } - - /** - * {@inheritDoc} - * - * @since 19.0 - */ - @Beta - @Override - public Builder putAll(Iterable> entries) { - super.putAll(entries); - return this; - } - - @Override - public Builder putAll(K key, Iterable values) { - Collection collection = builderMultimap.get(checkNotNull(key)); - for (V value : values) { - collection.add(checkNotNull(value)); - } - return this; - } - - @Override - public Builder putAll(K key, V... values) { - return putAll(key, Arrays.asList(values)); - } - - @Override - public Builder putAll(Multimap multimap) { - for (Entry> entry : - multimap.asMap().entrySet()) { - putAll(entry.getKey(), entry.getValue()); - } - return this; - } - - /** - * {@inheritDoc} - * - * @since 8.0 - */ - @Override - public Builder orderKeysBy(Comparator keyComparator) { - this.keyComparator = checkNotNull(keyComparator); - return this; - } - - /** - * Specifies the ordering of the generated multimap's values for each key. - * - *

If this method is called, the sets returned by the {@code get()} - * method of the generated multimap and its {@link Multimap#asMap()} view - * are {@link ImmutableSortedSet} instances. However, serialization does not - * preserve that property, though it does maintain the key and value - * ordering. - * - * @since 8.0 - */ - // TODO: Make serialization behavior consistent. - @Override - public Builder orderValuesBy(Comparator valueComparator) { - super.orderValuesBy(valueComparator); - return this; - } - - /** - * Returns a newly-created immutable set multimap. - */ - @Override - public ImmutableSetMultimap build() { - if (keyComparator != null) { - Multimap sortedCopy = - MultimapBuilder.linkedHashKeys().linkedHashSetValues().build(); - List>> entries = - Ordering.from(keyComparator) - .onKeys() - .immutableSortedCopy(builderMultimap.asMap().entrySet()); - for (Map.Entry> entry : entries) { - sortedCopy.putAll(entry.getKey(), entry.getValue()); - } - builderMultimap = sortedCopy; - } - return copyOf(builderMultimap, valueComparator); - } - } - - /** - * Returns an immutable set multimap containing the same mappings as - * {@code multimap}. The generated multimap's key and value orderings - * correspond to the iteration ordering of the {@code multimap.asMap()} view. - * Repeated occurrences of an entry in the multimap after the first are - * ignored. - * - *

Despite the method name, this method attempts to avoid actually copying - * the data when it is safe to do so. The exact circumstances under which a - * copy will or will not be performed are undocumented and subject to change. - * - * @throws NullPointerException if any key or value in {@code multimap} is - * null - */ - public static ImmutableSetMultimap copyOf( - Multimap multimap) { - return copyOf(multimap, null); - } - - private static ImmutableSetMultimap copyOf( - Multimap multimap, Comparator valueComparator) { - checkNotNull(multimap); // eager for GWT - if (multimap.isEmpty() && valueComparator == null) { - return of(); - } - - if (multimap instanceof ImmutableSetMultimap) { - @SuppressWarnings("unchecked") // safe since multimap is not writable - ImmutableSetMultimap kvMultimap = (ImmutableSetMultimap) multimap; - if (!kvMultimap.isPartialView()) { - return kvMultimap; - } - } - - ImmutableMap.Builder> builder = - new ImmutableMap.Builder>(multimap.asMap().size()); - int size = 0; - - for (Entry> entry : - multimap.asMap().entrySet()) { - K key = entry.getKey(); - Collection values = entry.getValue(); - ImmutableSet set = valueSet(valueComparator, values); - if (!set.isEmpty()) { - builder.put(key, set); - size += set.size(); - } - } - - return new ImmutableSetMultimap(builder.build(), size, valueComparator); - } - - /** - * Returns an immutable multimap containing the specified entries. The - * returned multimap iterates over keys in the order they were first - * encountered in the input, and the values for each key are iterated in the - * order they were encountered. If two values for the same key are - * {@linkplain Object#equals equal}, the first value encountered is used. - * - * @throws NullPointerException if any key, value, or entry is null - * @since 19.0 - */ - @Beta - public static ImmutableSetMultimap copyOf( - Iterable> entries) { - return new Builder().putAll(entries).build(); - } - - /** - * Returned by get() when a missing key is provided. Also holds the - * comparator, if any, used for values. - */ - private final transient ImmutableSet emptySet; - - ImmutableSetMultimap( - ImmutableMap> map, - int size, - @Nullable Comparator valueComparator) { - super(map, size); - this.emptySet = emptySet(valueComparator); - } - - // views - - /** - * Returns an immutable set of the values for the given key. If no mappings - * in the multimap have the provided key, an empty immutable set is returned. - * The values are in the same order as the parameters used to build this - * multimap. - */ - @Override - public ImmutableSet get(@Nullable K key) { - // This cast is safe as its type is known in constructor. - ImmutableSet set = (ImmutableSet) map.get(key); - return MoreObjects.firstNonNull(set, emptySet); - } - - private transient ImmutableSetMultimap inverse; - - /** - * {@inheritDoc} - * - *

Because an inverse of a set multimap cannot contain multiple pairs with - * the same key and value, this method returns an {@code ImmutableSetMultimap} - * rather than the {@code ImmutableMultimap} specified in the {@code - * ImmutableMultimap} class. - * - * @since 11.0 - */ - public ImmutableSetMultimap inverse() { - ImmutableSetMultimap result = inverse; - return (result == null) ? (inverse = invert()) : result; - } - - private ImmutableSetMultimap invert() { - Builder builder = builder(); - for (Entry entry : entries()) { - builder.put(entry.getValue(), entry.getKey()); - } - ImmutableSetMultimap invertedMultimap = builder.build(); - invertedMultimap.inverse = this; - return invertedMultimap; - } - - /** - * Guaranteed to throw an exception and leave the multimap unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public ImmutableSet removeAll(Object key) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the multimap unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public ImmutableSet replaceValues(K key, Iterable values) { - throw new UnsupportedOperationException(); - } - - private transient ImmutableSet> entries; - - /** - * Returns an immutable collection of all key-value pairs in the multimap. - * Its iterator traverses the values for the first key, the values for the - * second key, and so on. - */ - @Override - public ImmutableSet> entries() { - ImmutableSet> result = entries; - return result == null - ? (entries = new EntrySet(this)) - : result; - } - - private static final class EntrySet extends ImmutableSet> { - @Weak private final transient ImmutableSetMultimap multimap; - - EntrySet(ImmutableSetMultimap multimap) { - this.multimap = multimap; - } - - @Override - public boolean contains(@Nullable Object object) { - if (object instanceof Entry) { - Entry entry = (Entry) object; - return multimap.containsEntry(entry.getKey(), entry.getValue()); - } - return false; - } - - @Override - public int size() { - return multimap.size(); - } - - @Override - public UnmodifiableIterator> iterator() { - return multimap.entryIterator(); - } - - @Override - boolean isPartialView() { - return false; - } - } - - private static ImmutableSet valueSet( - @Nullable Comparator valueComparator, Collection values) { - return (valueComparator == null) - ? ImmutableSet.copyOf(values) - : ImmutableSortedSet.copyOf(valueComparator, values); - } - - private static ImmutableSet emptySet(@Nullable Comparator valueComparator) { - return (valueComparator == null) - ? ImmutableSet.of() - : ImmutableSortedSet.emptySet(valueComparator); - } - - private static ImmutableSet.Builder valuesBuilder( - @Nullable Comparator valueComparator) { - return (valueComparator == null) - ? new ImmutableSet.Builder() - : new ImmutableSortedSet.Builder(valueComparator); - } - - /** - * @serialData number of distinct keys, and then for each distinct key: the - * key, the number of values for that key, and the key's values - */ - @GwtIncompatible("java.io.ObjectOutputStream") - private void writeObject(ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); - stream.writeObject(valueComparator()); - Serialization.writeMultimap(this, stream); - } - - @Nullable - Comparator valueComparator() { - return emptySet instanceof ImmutableSortedSet - ? ((ImmutableSortedSet) emptySet).comparator() - : null; - } - - @GwtIncompatible("java.io.ObjectInputStream") - // Serialization type safety is at the caller's mercy. - @SuppressWarnings("unchecked") - private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - Comparator valueComparator = (Comparator) stream.readObject(); - int keyCount = stream.readInt(); - if (keyCount < 0) { - throw new InvalidObjectException("Invalid key count " + keyCount); - } - ImmutableMap.Builder> builder = ImmutableMap.builder(); - int tmpSize = 0; - - for (int i = 0; i < keyCount; i++) { - Object key = stream.readObject(); - int valueCount = stream.readInt(); - if (valueCount <= 0) { - throw new InvalidObjectException("Invalid value count " + valueCount); - } - - ImmutableSet.Builder valuesBuilder = valuesBuilder(valueComparator); - for (int j = 0; j < valueCount; j++) { - valuesBuilder.add(stream.readObject()); - } - ImmutableSet valueSet = valuesBuilder.build(); - if (valueSet.size() != valueCount) { - throw new InvalidObjectException("Duplicate key-value pairs exist for key " + key); - } - builder.put(key, valueSet); - tmpSize += valueCount; - } - - ImmutableMap> tmpMap; - try { - tmpMap = builder.build(); - } catch (IllegalArgumentException e) { - throw (InvalidObjectException) new InvalidObjectException(e.getMessage()).initCause(e); - } - - FieldSettersHolder.MAP_FIELD_SETTER.set(this, tmpMap); - FieldSettersHolder.SIZE_FIELD_SETTER.set(this, tmpSize); - FieldSettersHolder.EMPTY_SET_FIELD_SETTER.set(this, emptySet(valueComparator)); - } - - @GwtIncompatible("not needed in emulated source.") - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSortedAsList.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSortedAsList.java deleted file mode 100644 index 43aa976a1db3..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSortedAsList.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; - -import java.util.Comparator; - -import javax.annotation.Nullable; - -/** - * List returned by {@code ImmutableSortedSet.asList()} when the set isn't empty. - * - * @author Jared Levy - * @author Louis Wasserman - */ -@GwtCompatible(emulated = true) -@SuppressWarnings("serial") -final class ImmutableSortedAsList extends RegularImmutableAsList - implements SortedIterable { - ImmutableSortedAsList(ImmutableSortedSet backingSet, ImmutableList backingList) { - super(backingSet, backingList); - } - - @Override - ImmutableSortedSet delegateCollection() { - return (ImmutableSortedSet) super.delegateCollection(); - } - - @Override - public Comparator comparator() { - return delegateCollection().comparator(); - } - - // Override indexOf() and lastIndexOf() to be O(log N) instead of O(N). - - @GwtIncompatible("ImmutableSortedSet.indexOf") - // TODO(cpovirk): consider manual binary search under GWT to preserve O(log N) lookup - @Override - public int indexOf(@Nullable Object target) { - int index = delegateCollection().indexOf(target); - - // TODO(kevinb): reconsider if it's really worth making feeble attempts at - // sanity for inconsistent comparators. - - // The equals() check is needed when the comparator isn't compatible with - // equals(). - return (index >= 0 && get(index).equals(target)) ? index : -1; - } - - @GwtIncompatible("ImmutableSortedSet.indexOf") - @Override - public int lastIndexOf(@Nullable Object target) { - return indexOf(target); - } - - @Override - public boolean contains(Object target) { - // Necessary for ISS's with comparators inconsistent with equals. - return indexOf(target) >= 0; - } - - @GwtIncompatible("super.subListUnchecked does not exist; inherited subList is valid if slow") - /* - * TODO(cpovirk): if we start to override indexOf/lastIndexOf under GWT, we'll want some way to - * override subList to return an ImmutableSortedAsList for better performance. Right now, I'm not - * sure there's any performance hit from our failure to override subListUnchecked under GWT - */ - @Override - ImmutableList subListUnchecked(int fromIndex, int toIndex) { - ImmutableList parentSubList = super.subListUnchecked(fromIndex, toIndex); - return new RegularImmutableSortedSet(parentSubList, comparator()).asList(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSortedMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSortedMap.java deleted file mode 100644 index 84dc1fc9177d..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSortedMap.java +++ /dev/null @@ -1,871 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.CollectPreconditions.checkEntryNotNull; -import static com.google.common.collect.Maps.keyOrNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.j2objc.annotations.WeakOuter; - -import java.util.Arrays; -import java.util.Comparator; -import java.util.Map; -import java.util.NavigableMap; -import java.util.SortedMap; -import java.util.TreeMap; - -import javax.annotation.Nullable; - -/** - * A {@link NavigableMap} whose contents will never change, with many other important properties - * detailed at {@link ImmutableCollection}. - * - *

Warning: as with any sorted collection, you are strongly advised not to use a {@link - * Comparator} or {@link Comparable} type whose comparison behavior is inconsistent with - * equals. That is, {@code a.compareTo(b)} or {@code comparator.compare(a, b)} should equal zero - * if and only if {@code a.equals(b)}. If this advice is not followed, the resulting map will - * not correctly obey its specification. - * - *

See the Guava User Guide article on - * immutable collections. - * - * @author Jared Levy - * @author Louis Wasserman - * @since 2.0 (implements {@code NavigableMap} since 12.0) - */ -@GwtCompatible(serializable = true, emulated = true) -public final class ImmutableSortedMap extends ImmutableSortedMapFauxverideShim - implements NavigableMap { - - /* - * TODO(kevinb): Confirm that ImmutableSortedMap is faster to construct and - * uses less memory than TreeMap; then say so in the class Javadoc. - */ - private static final Comparator NATURAL_ORDER = Ordering.natural(); - - private static final ImmutableSortedMap NATURAL_EMPTY_MAP = - new ImmutableSortedMap( - ImmutableSortedSet.emptySet(Ordering.natural()), ImmutableList.of()); - - static ImmutableSortedMap emptyMap(Comparator comparator) { - if (Ordering.natural().equals(comparator)) { - return of(); - } else { - return new ImmutableSortedMap( - ImmutableSortedSet.emptySet(comparator), ImmutableList.of()); - } - } - - /** - * Returns the empty sorted map. - */ - @SuppressWarnings("unchecked") - // unsafe, comparator() returns a comparator on the specified type - // TODO(kevinb): evaluate whether or not of().comparator() should return null - public static ImmutableSortedMap of() { - return (ImmutableSortedMap) NATURAL_EMPTY_MAP; - } - - /** - * Returns an immutable map containing a single entry. - */ - public static , V> ImmutableSortedMap of(K k1, V v1) { - return of(Ordering.natural(), k1, v1); - } - - /** - * Returns an immutable map containing a single entry. - */ - private static ImmutableSortedMap of(Comparator comparator, K k1, V v1) { - return new ImmutableSortedMap( - new RegularImmutableSortedSet(ImmutableList.of(k1), checkNotNull(comparator)), - ImmutableList.of(v1)); - } - - private static , V> ImmutableSortedMap ofEntries( - ImmutableMapEntry... entries) { - return fromEntries(Ordering.natural(), false, entries, entries.length); - } - - /** - * Returns an immutable sorted map containing the given entries, sorted by the - * natural ordering of their keys. - * - * @throws IllegalArgumentException if the two keys are equal according to - * their natural ordering - */ - @SuppressWarnings("unchecked") - public static , V> ImmutableSortedMap of( - K k1, V v1, K k2, V v2) { - return ofEntries(entryOf(k1, v1), entryOf(k2, v2)); - } - - /** - * Returns an immutable sorted map containing the given entries, sorted by the - * natural ordering of their keys. - * - * @throws IllegalArgumentException if any two keys are equal according to - * their natural ordering - */ - @SuppressWarnings("unchecked") - public static , V> ImmutableSortedMap of( - K k1, V v1, K k2, V v2, K k3, V v3) { - return ofEntries(entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3)); - } - - /** - * Returns an immutable sorted map containing the given entries, sorted by the - * natural ordering of their keys. - * - * @throws IllegalArgumentException if any two keys are equal according to - * their natural ordering - */ - @SuppressWarnings("unchecked") - public static , V> ImmutableSortedMap of( - K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { - return ofEntries(entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3), entryOf(k4, v4)); - } - - /** - * Returns an immutable sorted map containing the given entries, sorted by the - * natural ordering of their keys. - * - * @throws IllegalArgumentException if any two keys are equal according to - * their natural ordering - */ - @SuppressWarnings("unchecked") - public static , V> ImmutableSortedMap of( - K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { - return ofEntries( - entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3), entryOf(k4, v4), entryOf(k5, v5)); - } - - /** - * Returns an immutable map containing the same entries as {@code map}, sorted - * by the natural ordering of the keys. - * - *

Despite the method name, this method attempts to avoid actually copying - * the data when it is safe to do so. The exact circumstances under which a - * copy will or will not be performed are undocumented and subject to change. - * - *

This method is not type-safe, as it may be called on a map with keys - * that are not mutually comparable. - * - * @throws ClassCastException if the keys in {@code map} are not mutually - * comparable - * @throws NullPointerException if any key or value in {@code map} is null - * @throws IllegalArgumentException if any two keys are equal according to - * their natural ordering - */ - public static ImmutableSortedMap copyOf(Map map) { - // Hack around K not being a subtype of Comparable. - // Unsafe, see ImmutableSortedSetFauxverideShim. - @SuppressWarnings("unchecked") - Ordering naturalOrder = (Ordering) NATURAL_ORDER; - return copyOfInternal(map, naturalOrder); - } - - /** - * Returns an immutable map containing the same entries as {@code map}, with - * keys sorted by the provided comparator. - * - *

Despite the method name, this method attempts to avoid actually copying - * the data when it is safe to do so. The exact circumstances under which a - * copy will or will not be performed are undocumented and subject to change. - * - * @throws NullPointerException if any key or value in {@code map} is null - * @throws IllegalArgumentException if any two keys are equal according to the - * comparator - */ - public static ImmutableSortedMap copyOf( - Map map, Comparator comparator) { - return copyOfInternal(map, checkNotNull(comparator)); - } - - /** - * Returns an immutable map containing the given entries, with keys sorted - * by the provided comparator. - * - *

This method is not type-safe, as it may be called on a map with keys - * that are not mutually comparable. - * - * @throws NullPointerException if any key or value in {@code map} is null - * @throws IllegalArgumentException if any two keys are equal according to the - * comparator - * @since 19.0 - */ - @Beta - public static ImmutableSortedMap copyOf( - Iterable> entries) { - // Hack around K not being a subtype of Comparable. - // Unsafe, see ImmutableSortedSetFauxverideShim. - @SuppressWarnings("unchecked") - Ordering naturalOrder = (Ordering) NATURAL_ORDER; - return copyOf(entries, naturalOrder); - } - - /** - * Returns an immutable map containing the given entries, with keys sorted - * by the provided comparator. - * - * @throws NullPointerException if any key or value in {@code map} is null - * @throws IllegalArgumentException if any two keys are equal according to the - * comparator - * @since 19.0 - */ - @Beta - public static ImmutableSortedMap copyOf( - Iterable> entries, - Comparator comparator) { - return fromEntries(checkNotNull(comparator), false, entries); - } - - /** - * Returns an immutable map containing the same entries as the provided sorted - * map, with the same ordering. - * - *

Despite the method name, this method attempts to avoid actually copying - * the data when it is safe to do so. The exact circumstances under which a - * copy will or will not be performed are undocumented and subject to change. - * - * @throws NullPointerException if any key or value in {@code map} is null - */ - @SuppressWarnings("unchecked") - public static ImmutableSortedMap copyOfSorted(SortedMap map) { - Comparator comparator = map.comparator(); - if (comparator == null) { - // If map has a null comparator, the keys should have a natural ordering, - // even though K doesn't explicitly implement Comparable. - comparator = (Comparator) NATURAL_ORDER; - } - if (map instanceof ImmutableSortedMap) { - // TODO(kevinb): Prove that this cast is safe, even though - // Collections.unmodifiableSortedMap requires the same key type. - @SuppressWarnings("unchecked") - ImmutableSortedMap kvMap = (ImmutableSortedMap) map; - if (!kvMap.isPartialView()) { - return kvMap; - } - } - return fromEntries(comparator, true, map.entrySet()); - } - - private static ImmutableSortedMap copyOfInternal( - Map map, Comparator comparator) { - boolean sameComparator = false; - if (map instanceof SortedMap) { - SortedMap sortedMap = (SortedMap) map; - Comparator comparator2 = sortedMap.comparator(); - sameComparator = - (comparator2 == null) - ? comparator == NATURAL_ORDER - : comparator.equals(comparator2); - } - - if (sameComparator && (map instanceof ImmutableSortedMap)) { - // TODO(kevinb): Prove that this cast is safe, even though - // Collections.unmodifiableSortedMap requires the same key type. - @SuppressWarnings("unchecked") - ImmutableSortedMap kvMap = (ImmutableSortedMap) map; - if (!kvMap.isPartialView()) { - return kvMap; - } - } - return fromEntries(comparator, sameComparator, map.entrySet()); - } - - /** - * Accepts a collection of possibly-null entries. If {@code sameComparator}, then it is assumed - * that they do not need to be sorted or checked for dupes. - */ - private static ImmutableSortedMap fromEntries( - Comparator comparator, - boolean sameComparator, - Iterable> entries) { - // "adding" type params to an array of a raw type should be safe as - // long as no one can ever cast that same array instance back to a - // raw type. - @SuppressWarnings("unchecked") - Entry[] entryArray = (Entry[]) Iterables.toArray(entries, EMPTY_ENTRY_ARRAY); - return fromEntries(comparator, sameComparator, entryArray, entryArray.length); - } - - private static ImmutableSortedMap fromEntries( - Comparator comparator, - boolean sameComparator, - Entry[] entryArray, - int size) { - switch (size) { - case 0: - return emptyMap(comparator); - case 1: - return ImmutableSortedMap.of( - comparator, entryArray[0].getKey(), entryArray[0].getValue()); - default: - Object[] keys = new Object[size]; - Object[] values = new Object[size]; - if (sameComparator) { - // Need to check for nulls, but don't need to sort or validate. - for (int i = 0; i < size; i++) { - Object key = entryArray[i].getKey(); - Object value = entryArray[i].getValue(); - checkEntryNotNull(key, value); - keys[i] = key; - values[i] = value; - } - } else { - // Need to sort and check for nulls and dupes. - Arrays.sort(entryArray, 0, size, Ordering.from(comparator).onKeys()); - K prevKey = entryArray[0].getKey(); - keys[0] = prevKey; - values[0] = entryArray[0].getValue(); - for (int i = 1; i < size; i++) { - K key = entryArray[i].getKey(); - V value = entryArray[i].getValue(); - checkEntryNotNull(key, value); - keys[i] = key; - values[i] = value; - checkNoConflict( - comparator.compare(prevKey, key) != 0, "key", entryArray[i - 1], entryArray[i]); - prevKey = key; - } - } - return new ImmutableSortedMap( - new RegularImmutableSortedSet(new RegularImmutableList(keys), comparator), - new RegularImmutableList(values)); - } - } - - /** - * Returns a builder that creates immutable sorted maps whose keys are - * ordered by their natural ordering. The sorted maps use {@link - * Ordering#natural()} as the comparator. - */ - public static , V> Builder naturalOrder() { - return new Builder(Ordering.natural()); - } - - /** - * Returns a builder that creates immutable sorted maps with an explicit - * comparator. If the comparator has a more general type than the map's keys, - * such as creating a {@code SortedMap} with a {@code - * Comparator}, use the {@link Builder} constructor instead. - * - * @throws NullPointerException if {@code comparator} is null - */ - public static Builder orderedBy(Comparator comparator) { - return new Builder(comparator); - } - - /** - * Returns a builder that creates immutable sorted maps whose keys are - * ordered by the reverse of their natural ordering. - */ - public static , V> Builder reverseOrder() { - return new Builder(Ordering.natural().reverse()); - } - - /** - * A builder for creating immutable sorted map instances, especially {@code - * public static final} maps ("constant maps"). Example:

   {@code
-   *
-   *   static final ImmutableSortedMap INT_TO_WORD =
-   *       new ImmutableSortedMap.Builder(Ordering.natural())
-   *           .put(1, "one")
-   *           .put(2, "two")
-   *           .put(3, "three")
-   *           .build();}
- * - *

For small immutable sorted maps, the {@code ImmutableSortedMap.of()} - * methods are even more convenient. - * - *

Builder instances can be reused - it is safe to call {@link #build} - * multiple times to build multiple maps in series. Each map is a superset of - * the maps created before it. - * - * @since 2.0 - */ - public static class Builder extends ImmutableMap.Builder { - private final Comparator comparator; - - /** - * Creates a new builder. The returned builder is equivalent to the builder - * generated by {@link ImmutableSortedMap#orderedBy}. - */ - @SuppressWarnings("unchecked") - public Builder(Comparator comparator) { - this.comparator = checkNotNull(comparator); - } - - /** - * Associates {@code key} with {@code value} in the built map. Duplicate - * keys, according to the comparator (which might be the keys' natural - * order), are not allowed, and will cause {@link #build} to fail. - */ - @Override - public Builder put(K key, V value) { - super.put(key, value); - return this; - } - - /** - * Adds the given {@code entry} to the map, making it immutable if - * necessary. Duplicate keys, according to the comparator (which might be - * the keys' natural order), are not allowed, and will cause {@link #build} - * to fail. - * - * @since 11.0 - */ - @Override - public Builder put(Entry entry) { - super.put(entry); - return this; - } - - /** - * Associates all of the given map's keys and values in the built map. - * Duplicate keys, according to the comparator (which might be the keys' - * natural order), are not allowed, and will cause {@link #build} to fail. - * - * @throws NullPointerException if any key or value in {@code map} is null - */ - @Override - public Builder putAll(Map map) { - super.putAll(map); - return this; - } - - /** - * Adds all the given entries to the built map. Duplicate keys, according - * to the comparator (which might be the keys' natural order), are not - * allowed, and will cause {@link #build} to fail. - * - * @throws NullPointerException if any key, value, or entry is null - * @since 19.0 - */ - @Beta - @Override - public Builder putAll(Iterable> entries) { - super.putAll(entries); - return this; - } - - /** - * Throws an {@code UnsupportedOperationException}. - * - * @since 19.0 - * @deprecated Unsupported by ImmutableSortedMap.Builder. - */ - @Beta - @Override - @Deprecated - public Builder orderEntriesByValue(Comparator valueComparator) { - throw new UnsupportedOperationException("Not available on ImmutableSortedMap.Builder"); - } - - /** - * Returns a newly-created immutable sorted map. - * - * @throws IllegalArgumentException if any two keys are equal according to - * the comparator (which might be the keys' natural order) - */ - @Override - public ImmutableSortedMap build() { - switch (size) { - case 0: - return emptyMap(comparator); - case 1: - return of(comparator, entries[0].getKey(), entries[0].getValue()); - default: - return fromEntries(comparator, false, entries, size); - } - } - } - - private final transient RegularImmutableSortedSet keySet; - private final transient ImmutableList valueList; - private transient ImmutableSortedMap descendingMap; - - ImmutableSortedMap(RegularImmutableSortedSet keySet, ImmutableList valueList) { - this(keySet, valueList, null); - } - - ImmutableSortedMap( - RegularImmutableSortedSet keySet, - ImmutableList valueList, - ImmutableSortedMap descendingMap) { - this.keySet = keySet; - this.valueList = valueList; - this.descendingMap = descendingMap; - } - - @Override - public int size() { - return valueList.size(); - } - - @Override - public V get(@Nullable Object key) { - int index = keySet.indexOf(key); - return (index == -1) ? null : valueList.get(index); - } - - @Override - boolean isPartialView() { - return keySet.isPartialView() || valueList.isPartialView(); - } - - /** - * Returns an immutable set of the mappings in this map, sorted by the key - * ordering. - */ - @Override - public ImmutableSet> entrySet() { - return super.entrySet(); - } - - @Override - ImmutableSet> createEntrySet() { - @WeakOuter - class EntrySet extends ImmutableMapEntrySet { - @Override - public UnmodifiableIterator> iterator() { - return asList().iterator(); - } - - @Override - ImmutableList> createAsList() { - return new ImmutableAsList>() { - @Override - public Entry get(int index) { - return Maps.immutableEntry(keySet.asList().get(index), valueList.get(index)); - } - - @Override - ImmutableCollection> delegateCollection() { - return EntrySet.this; - } - }; - } - - @Override - ImmutableMap map() { - return ImmutableSortedMap.this; - } - } - return isEmpty() ? ImmutableSet.>of() : new EntrySet(); - } - - /** - * Returns an immutable sorted set of the keys in this map. - */ - @Override - public ImmutableSortedSet keySet() { - return keySet; - } - - /** - * Returns an immutable collection of the values in this map, sorted by the - * ordering of the corresponding keys. - */ - @Override - public ImmutableCollection values() { - return valueList; - } - - /** - * Returns the comparator that orders the keys, which is - * {@link Ordering#natural()} when the natural ordering of the keys is used. - * Note that its behavior is not consistent with {@link TreeMap#comparator()}, - * which returns {@code null} to indicate natural ordering. - */ - @Override - public Comparator comparator() { - return keySet().comparator(); - } - - @Override - public K firstKey() { - return keySet().first(); - } - - @Override - public K lastKey() { - return keySet().last(); - } - - private ImmutableSortedMap getSubMap(int fromIndex, int toIndex) { - if (fromIndex == 0 && toIndex == size()) { - return this; - } else if (fromIndex == toIndex) { - return emptyMap(comparator()); - } else { - return new ImmutableSortedMap( - keySet.getSubSet(fromIndex, toIndex), valueList.subList(fromIndex, toIndex)); - } - } - - /** - * This method returns a {@code ImmutableSortedMap}, consisting of the entries - * whose keys are less than {@code toKey}. - * - *

The {@link SortedMap#headMap} documentation states that a submap of a - * submap throws an {@link IllegalArgumentException} if passed a {@code toKey} - * greater than an earlier {@code toKey}. However, this method doesn't throw - * an exception in that situation, but instead keeps the original {@code - * toKey}. - */ - @Override - public ImmutableSortedMap headMap(K toKey) { - return headMap(toKey, false); - } - - /** - * This method returns a {@code ImmutableSortedMap}, consisting of the entries - * whose keys are less than (or equal to, if {@code inclusive}) {@code toKey}. - * - *

The {@link SortedMap#headMap} documentation states that a submap of a - * submap throws an {@link IllegalArgumentException} if passed a {@code toKey} - * greater than an earlier {@code toKey}. However, this method doesn't throw - * an exception in that situation, but instead keeps the original {@code - * toKey}. - * - * @since 12.0 - */ - @Override - public ImmutableSortedMap headMap(K toKey, boolean inclusive) { - return getSubMap(0, keySet.headIndex(checkNotNull(toKey), inclusive)); - } - - /** - * This method returns a {@code ImmutableSortedMap}, consisting of the entries - * whose keys ranges from {@code fromKey}, inclusive, to {@code toKey}, - * exclusive. - * - *

The {@link SortedMap#subMap} documentation states that a submap of a - * submap throws an {@link IllegalArgumentException} if passed a {@code - * fromKey} less than an earlier {@code fromKey}. However, this method doesn't - * throw an exception in that situation, but instead keeps the original {@code - * fromKey}. Similarly, this method keeps the original {@code toKey}, instead - * of throwing an exception, if passed a {@code toKey} greater than an earlier - * {@code toKey}. - */ - @Override - public ImmutableSortedMap subMap(K fromKey, K toKey) { - return subMap(fromKey, true, toKey, false); - } - - /** - * This method returns a {@code ImmutableSortedMap}, consisting of the entries - * whose keys ranges from {@code fromKey} to {@code toKey}, inclusive or - * exclusive as indicated by the boolean flags. - * - *

The {@link SortedMap#subMap} documentation states that a submap of a - * submap throws an {@link IllegalArgumentException} if passed a {@code - * fromKey} less than an earlier {@code fromKey}. However, this method doesn't - * throw an exception in that situation, but instead keeps the original {@code - * fromKey}. Similarly, this method keeps the original {@code toKey}, instead - * of throwing an exception, if passed a {@code toKey} greater than an earlier - * {@code toKey}. - * - * @since 12.0 - */ - @Override - public ImmutableSortedMap subMap( - K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { - checkNotNull(fromKey); - checkNotNull(toKey); - checkArgument( - comparator().compare(fromKey, toKey) <= 0, - "expected fromKey <= toKey but %s > %s", - fromKey, - toKey); - return headMap(toKey, toInclusive).tailMap(fromKey, fromInclusive); - } - - /** - * This method returns a {@code ImmutableSortedMap}, consisting of the entries - * whose keys are greater than or equals to {@code fromKey}. - * - *

The {@link SortedMap#tailMap} documentation states that a submap of a - * submap throws an {@link IllegalArgumentException} if passed a {@code - * fromKey} less than an earlier {@code fromKey}. However, this method doesn't - * throw an exception in that situation, but instead keeps the original {@code - * fromKey}. - */ - @Override - public ImmutableSortedMap tailMap(K fromKey) { - return tailMap(fromKey, true); - } - - /** - * This method returns a {@code ImmutableSortedMap}, consisting of the entries - * whose keys are greater than (or equal to, if {@code inclusive}) - * {@code fromKey}. - * - *

The {@link SortedMap#tailMap} documentation states that a submap of a - * submap throws an {@link IllegalArgumentException} if passed a {@code - * fromKey} less than an earlier {@code fromKey}. However, this method doesn't - * throw an exception in that situation, but instead keeps the original {@code - * fromKey}. - * - * @since 12.0 - */ - @Override - public ImmutableSortedMap tailMap(K fromKey, boolean inclusive) { - return getSubMap(keySet.tailIndex(checkNotNull(fromKey), inclusive), size()); - } - - @Override - public Entry lowerEntry(K key) { - return headMap(key, false).lastEntry(); - } - - @Override - public K lowerKey(K key) { - return keyOrNull(lowerEntry(key)); - } - - @Override - public Entry floorEntry(K key) { - return headMap(key, true).lastEntry(); - } - - @Override - public K floorKey(K key) { - return keyOrNull(floorEntry(key)); - } - - @Override - public Entry ceilingEntry(K key) { - return tailMap(key, true).firstEntry(); - } - - @Override - public K ceilingKey(K key) { - return keyOrNull(ceilingEntry(key)); - } - - @Override - public Entry higherEntry(K key) { - return tailMap(key, false).firstEntry(); - } - - @Override - public K higherKey(K key) { - return keyOrNull(higherEntry(key)); - } - - @Override - public Entry firstEntry() { - return isEmpty() ? null : entrySet().asList().get(0); - } - - @Override - public Entry lastEntry() { - return isEmpty() ? null : entrySet().asList().get(size() - 1); - } - - /** - * Guaranteed to throw an exception and leave the map unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final Entry pollFirstEntry() { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the map unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final Entry pollLastEntry() { - throw new UnsupportedOperationException(); - } - - @Override - public ImmutableSortedMap descendingMap() { - // TODO(kevinb): the descendingMap is never actually cached at all. Either it should be or the - // code below simplified. - ImmutableSortedMap result = descendingMap; - if (result == null) { - if (isEmpty()) { - return result = emptyMap(Ordering.from(comparator()).reverse()); - } else { - return result = - new ImmutableSortedMap( - (RegularImmutableSortedSet) keySet.descendingSet(), valueList.reverse(), this); - } - } - return result; - } - - @Override - public ImmutableSortedSet navigableKeySet() { - return keySet; - } - - @Override - public ImmutableSortedSet descendingKeySet() { - return keySet.descendingSet(); - } - - /** - * Serialized type for all ImmutableSortedMap instances. It captures the - * logical contents and they are reconstructed using public factory methods. - * This ensures that the implementation types remain as implementation - * details. - */ - private static class SerializedForm extends ImmutableMap.SerializedForm { - private final Comparator comparator; - - @SuppressWarnings("unchecked") - SerializedForm(ImmutableSortedMap sortedMap) { - super(sortedMap); - comparator = (Comparator) sortedMap.comparator(); - } - - @Override - Object readResolve() { - Builder builder = new Builder(comparator); - return createMap(builder); - } - - private static final long serialVersionUID = 0; - } - - @Override - Object writeReplace() { - return new SerializedForm(this); - } - - // This class is never actually serialized directly, but we have to make the - // warning go away (and suppressing would suppress for all nested classes too) - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSortedMapFauxverideShim.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSortedMapFauxverideShim.java deleted file mode 100644 index 13ce60d16b76..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSortedMapFauxverideShim.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -/** - * "Overrides" the {@link ImmutableMap} static methods that lack - * {@link ImmutableSortedMap} equivalents with deprecated, exception-throwing - * versions. See {@link ImmutableSortedSetFauxverideShim} for details. - * - * @author Chris Povirk - */ -abstract class ImmutableSortedMapFauxverideShim extends ImmutableMap { - /** - * Not supported. Use {@link ImmutableSortedMap#naturalOrder}, which offers - * better type-safety, instead. This method exists only to hide - * {@link ImmutableMap#builder} from consumers of {@code ImmutableSortedMap}. - * - * @throws UnsupportedOperationException always - * @deprecated Use {@link ImmutableSortedMap#naturalOrder}, which offers - * better type-safety. - */ - @Deprecated - public static ImmutableSortedMap.Builder builder() { - throw new UnsupportedOperationException(); - } - - /** - * Not supported. You are attempting to create a map that may contain a - * non-{@code Comparable} key. Proper calls will resolve to the version in - * {@code ImmutableSortedMap}, not this dummy version. - * - * @throws UnsupportedOperationException always - * @deprecated Pass a key of type {@code Comparable} to use {@link - * ImmutableSortedMap#of(Comparable, Object)}. - */ - @Deprecated - public static ImmutableSortedMap of(K k1, V v1) { - throw new UnsupportedOperationException(); - } - - /** - * Not supported. You are attempting to create a map that may contain - * non-{@code Comparable} keys. Proper calls will resolve to the version - * in {@code ImmutableSortedMap}, not this dummy version. - * - * @throws UnsupportedOperationException always - * @deprecated Pass keys of type {@code Comparable} to use {@link - * ImmutableSortedMap#of(Comparable, Object, Comparable, Object)}. - */ - @Deprecated - public static ImmutableSortedMap of(K k1, V v1, K k2, V v2) { - throw new UnsupportedOperationException(); - } - - /** - * Not supported. You are attempting to create a map that may contain - * non-{@code Comparable} keys. Proper calls to will resolve to the - * version in {@code ImmutableSortedMap}, not this dummy version. - * - * @throws UnsupportedOperationException always - * @deprecated Pass keys of type {@code Comparable} to use {@link - * ImmutableSortedMap#of(Comparable, Object, Comparable, Object, - * Comparable, Object)}. - */ - @Deprecated - public static ImmutableSortedMap of(K k1, V v1, K k2, V v2, K k3, V v3) { - throw new UnsupportedOperationException(); - } - - /** - * Not supported. You are attempting to create a map that may contain - * non-{@code Comparable} keys. Proper calls will resolve to the version - * in {@code ImmutableSortedMap}, not this dummy version. - * - * @throws UnsupportedOperationException always - * @deprecated Pass keys of type {@code Comparable} to use {@link - * ImmutableSortedMap#of(Comparable, Object, Comparable, Object, - * Comparable, Object, Comparable, Object)}. - */ - @Deprecated - public static ImmutableSortedMap of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { - throw new UnsupportedOperationException(); - } - - /** - * Not supported. You are attempting to create a map that may contain - * non-{@code Comparable} keys. Proper calls will resolve to the version - * in {@code ImmutableSortedMap}, not this dummy version. - * - * @throws UnsupportedOperationException always - * @deprecated Pass keys of type {@code Comparable} to use {@link - * ImmutableSortedMap#of(Comparable, Object, Comparable, Object, - * Comparable, Object, Comparable, Object, Comparable, Object)}. - */ - @Deprecated - public static ImmutableSortedMap of( - K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { - throw new UnsupportedOperationException(); - } - - // No copyOf() fauxveride; see ImmutableSortedSetFauxverideShim. -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSortedMultiset.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSortedMultiset.java deleted file mode 100644 index 6d6bb5f1dfce..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSortedMultiset.java +++ /dev/null @@ -1,549 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtIncompatible; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; - -/** - * A {@link SortedMultiset} whose contents will never change, with many other important properties - * detailed at {@link ImmutableCollection}. - * - *

Warning: as with any sorted collection, you are strongly advised not to use a {@link - * Comparator} or {@link Comparable} type whose comparison behavior is inconsistent with - * equals. That is, {@code a.compareTo(b)} or {@code comparator.compare(a, b)} should equal zero - * if and only if {@code a.equals(b)}. If this advice is not followed, the resulting - * collection will not correctly obey its specification. - * - *

See the Guava User Guide article on - * immutable collections. - * - * @author Louis Wasserman - * @since 12.0 - */ -@Beta -@GwtIncompatible("hasn't been tested yet") -public abstract class ImmutableSortedMultiset extends ImmutableSortedMultisetFauxverideShim - implements SortedMultiset { - // TODO(lowasser): GWT compatibility - - private static final Comparator NATURAL_ORDER = Ordering.natural(); - - private static final ImmutableSortedMultiset NATURAL_EMPTY_MULTISET = - new RegularImmutableSortedMultiset(NATURAL_ORDER); - - /** - * Returns the empty immutable sorted multiset. - */ - @SuppressWarnings("unchecked") - public static ImmutableSortedMultiset of() { - return (ImmutableSortedMultiset) NATURAL_EMPTY_MULTISET; - } - - /** - * Returns an immutable sorted multiset containing a single element. - */ - public static > ImmutableSortedMultiset of(E element) { - RegularImmutableSortedSet elementSet = - (RegularImmutableSortedSet) ImmutableSortedSet.of(element); - long[] cumulativeCounts = {0, 1}; - return new RegularImmutableSortedMultiset(elementSet, cumulativeCounts, 0, 1); - } - - /** - * Returns an immutable sorted multiset containing the given elements sorted by their natural - * ordering. - * - * @throws NullPointerException if any element is null - */ - @SuppressWarnings("unchecked") - public static > ImmutableSortedMultiset of(E e1, E e2) { - return copyOf(Ordering.natural(), Arrays.asList(e1, e2)); - } - - /** - * Returns an immutable sorted multiset containing the given elements sorted by their natural - * ordering. - * - * @throws NullPointerException if any element is null - */ - @SuppressWarnings("unchecked") - public static > ImmutableSortedMultiset of(E e1, E e2, E e3) { - return copyOf(Ordering.natural(), Arrays.asList(e1, e2, e3)); - } - - /** - * Returns an immutable sorted multiset containing the given elements sorted by their natural - * ordering. - * - * @throws NullPointerException if any element is null - */ - @SuppressWarnings("unchecked") - public static > ImmutableSortedMultiset of( - E e1, E e2, E e3, E e4) { - return copyOf(Ordering.natural(), Arrays.asList(e1, e2, e3, e4)); - } - - /** - * Returns an immutable sorted multiset containing the given elements sorted by their natural - * ordering. - * - * @throws NullPointerException if any element is null - */ - @SuppressWarnings("unchecked") - public static > ImmutableSortedMultiset of( - E e1, E e2, E e3, E e4, E e5) { - return copyOf(Ordering.natural(), Arrays.asList(e1, e2, e3, e4, e5)); - } - - /** - * Returns an immutable sorted multiset containing the given elements sorted by their natural - * ordering. - * - * @throws NullPointerException if any element is null - */ - @SuppressWarnings("unchecked") - public static > ImmutableSortedMultiset of( - E e1, E e2, E e3, E e4, E e5, E e6, E... remaining) { - int size = remaining.length + 6; - List all = Lists.newArrayListWithCapacity(size); - Collections.addAll(all, e1, e2, e3, e4, e5, e6); - Collections.addAll(all, remaining); - return copyOf(Ordering.natural(), all); - } - - /** - * Returns an immutable sorted multiset containing the given elements sorted by their natural - * ordering. - * - * @throws NullPointerException if any of {@code elements} is null - */ - public static > ImmutableSortedMultiset copyOf(E[] elements) { - return copyOf(Ordering.natural(), Arrays.asList(elements)); - } - - /** - * Returns an immutable sorted multiset containing the given elements sorted by their natural - * ordering. To create a copy of a {@code SortedMultiset} that preserves the - * comparator, call {@link #copyOfSorted} instead. This method iterates over {@code elements} at - * most once. - * - *

Note that if {@code s} is a {@code multiset}, then {@code - * ImmutableSortedMultiset.copyOf(s)} returns an {@code ImmutableSortedMultiset} - * containing each of the strings in {@code s}, while {@code ImmutableSortedMultiset.of(s)} - * returns an {@code ImmutableSortedMultiset>} containing one element (the given - * multiset itself). - * - *

Despite the method name, this method attempts to avoid actually copying the data when it is - * safe to do so. The exact circumstances under which a copy will or will not be performed are - * undocumented and subject to change. - * - *

This method is not type-safe, as it may be called on elements that are not mutually - * comparable. - * - * @throws ClassCastException if the elements are not mutually comparable - * @throws NullPointerException if any of {@code elements} is null - */ - public static ImmutableSortedMultiset copyOf(Iterable elements) { - // Hack around E not being a subtype of Comparable. - // Unsafe, see ImmutableSortedMultisetFauxverideShim. - @SuppressWarnings("unchecked") - Ordering naturalOrder = (Ordering) Ordering.natural(); - return copyOf(naturalOrder, elements); - } - - /** - * Returns an immutable sorted multiset containing the given elements sorted by their natural - * ordering. - * - *

This method is not type-safe, as it may be called on elements that are not mutually - * comparable. - * - * @throws ClassCastException if the elements are not mutually comparable - * @throws NullPointerException if any of {@code elements} is null - */ - public static ImmutableSortedMultiset copyOf(Iterator elements) { - // Hack around E not being a subtype of Comparable. - // Unsafe, see ImmutableSortedMultisetFauxverideShim. - @SuppressWarnings("unchecked") - Ordering naturalOrder = (Ordering) Ordering.natural(); - return copyOf(naturalOrder, elements); - } - - /** - * Returns an immutable sorted multiset containing the given elements sorted by the given {@code - * Comparator}. - * - * @throws NullPointerException if {@code comparator} or any of {@code elements} is null - */ - public static ImmutableSortedMultiset copyOf( - Comparator comparator, Iterator elements) { - checkNotNull(comparator); - return new Builder(comparator).addAll(elements).build(); - } - - /** - * Returns an immutable sorted multiset containing the given elements sorted by the given {@code - * Comparator}. This method iterates over {@code elements} at most once. - * - *

Despite the method name, this method attempts to avoid actually copying the data when it is - * safe to do so. The exact circumstances under which a copy will or will not be performed are - * undocumented and subject to change. - * - * @throws NullPointerException if {@code comparator} or any of {@code elements} is null - */ - public static ImmutableSortedMultiset copyOf( - Comparator comparator, Iterable elements) { - if (elements instanceof ImmutableSortedMultiset) { - @SuppressWarnings("unchecked") // immutable collections are always safe for covariant casts - ImmutableSortedMultiset multiset = (ImmutableSortedMultiset) elements; - if (comparator.equals(multiset.comparator())) { - if (multiset.isPartialView()) { - return copyOfSortedEntries(comparator, multiset.entrySet().asList()); - } else { - return multiset; - } - } - } - elements = Lists.newArrayList(elements); // defensive copy - TreeMultiset sortedCopy = TreeMultiset.create(checkNotNull(comparator)); - Iterables.addAll(sortedCopy, elements); - return copyOfSortedEntries(comparator, sortedCopy.entrySet()); - } - - /** - * Returns an immutable sorted multiset containing the elements of a sorted multiset, sorted by - * the same {@code Comparator}. That behavior differs from {@link #copyOf(Iterable)}, which - * always uses the natural ordering of the elements. - * - *

Despite the method name, this method attempts to avoid actually copying the data when it is - * safe to do so. The exact circumstances under which a copy will or will not be performed are - * undocumented and subject to change. - * - *

This method is safe to use even when {@code sortedMultiset} is a synchronized or concurrent - * collection that is currently being modified by another thread. - * - * @throws NullPointerException if {@code sortedMultiset} or any of its elements is null - */ - public static ImmutableSortedMultiset copyOfSorted(SortedMultiset sortedMultiset) { - return copyOfSortedEntries( - sortedMultiset.comparator(), Lists.newArrayList(sortedMultiset.entrySet())); - } - - private static ImmutableSortedMultiset copyOfSortedEntries( - Comparator comparator, Collection> entries) { - if (entries.isEmpty()) { - return emptyMultiset(comparator); - } - ImmutableList.Builder elementsBuilder = new ImmutableList.Builder(entries.size()); - long[] cumulativeCounts = new long[entries.size() + 1]; - int i = 0; - for (Entry entry : entries) { - elementsBuilder.add(entry.getElement()); - cumulativeCounts[i + 1] = cumulativeCounts[i] + entry.getCount(); - i++; - } - return new RegularImmutableSortedMultiset( - new RegularImmutableSortedSet(elementsBuilder.build(), comparator), - cumulativeCounts, - 0, - entries.size()); - } - - @SuppressWarnings("unchecked") - static ImmutableSortedMultiset emptyMultiset(Comparator comparator) { - if (NATURAL_ORDER.equals(comparator)) { - return (ImmutableSortedMultiset) NATURAL_EMPTY_MULTISET; - } else { - return new RegularImmutableSortedMultiset(comparator); - } - } - - ImmutableSortedMultiset() {} - - @Override - public final Comparator comparator() { - return elementSet().comparator(); - } - - @Override - public abstract ImmutableSortedSet elementSet(); - - transient ImmutableSortedMultiset descendingMultiset; - - @Override - public ImmutableSortedMultiset descendingMultiset() { - ImmutableSortedMultiset result = descendingMultiset; - if (result == null) { - return descendingMultiset = - this.isEmpty() - ? emptyMultiset(Ordering.from(comparator()).reverse()) - : new DescendingImmutableSortedMultiset(this); - } - return result; - } - - /** - * {@inheritDoc} - * - *

This implementation is guaranteed to throw an {@link UnsupportedOperationException}. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final Entry pollFirstEntry() { - throw new UnsupportedOperationException(); - } - - /** - * {@inheritDoc} - * - *

This implementation is guaranteed to throw an {@link UnsupportedOperationException}. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final Entry pollLastEntry() { - throw new UnsupportedOperationException(); - } - - @Override - public abstract ImmutableSortedMultiset headMultiset(E upperBound, BoundType boundType); - - @Override - public ImmutableSortedMultiset subMultiset( - E lowerBound, BoundType lowerBoundType, E upperBound, BoundType upperBoundType) { - checkArgument( - comparator().compare(lowerBound, upperBound) <= 0, - "Expected lowerBound <= upperBound but %s > %s", - lowerBound, - upperBound); - return tailMultiset(lowerBound, lowerBoundType).headMultiset(upperBound, upperBoundType); - } - - @Override - public abstract ImmutableSortedMultiset tailMultiset(E lowerBound, BoundType boundType); - - /** - * Returns a builder that creates immutable sorted multisets with an explicit comparator. If the - * comparator has a more general type than the set being generated, such as creating a {@code - * SortedMultiset} with a {@code Comparator}, use the {@link Builder} - * constructor instead. - * - * @throws NullPointerException if {@code comparator} is null - */ - public static Builder orderedBy(Comparator comparator) { - return new Builder(comparator); - } - - /** - * Returns a builder that creates immutable sorted multisets whose elements are ordered by the - * reverse of their natural ordering. - * - *

Note: the type parameter {@code E} extends {@code Comparable} rather than {@code - * Comparable} as a workaround for javac bug 6468354. - */ - public static > Builder reverseOrder() { - return new Builder(Ordering.natural().reverse()); - } - - /** - * Returns a builder that creates immutable sorted multisets whose elements are ordered by their - * natural ordering. The sorted multisets use {@link Ordering#natural()} as the comparator. This - * method provides more type-safety than {@link #builder}, as it can be called only for classes - * that implement {@link Comparable}. - * - *

Note: the type parameter {@code E} extends {@code Comparable} rather than {@code - * Comparable} as a workaround for javac bug 6468354. - */ - public static > Builder naturalOrder() { - return new Builder(Ordering.natural()); - } - - /** - * A builder for creating immutable multiset instances, especially {@code public static final} - * multisets ("constant multisets"). Example: - * - *

 {@code
-   *
-   *   public static final ImmutableSortedMultiset BEANS =
-   *       new ImmutableSortedMultiset.Builder()
-   *           .addCopies(Bean.COCOA, 4)
-   *           .addCopies(Bean.GARDEN, 6)
-   *           .addCopies(Bean.RED, 8)
-   *           .addCopies(Bean.BLACK_EYED, 10)
-   *           .build();}
- * - *

Builder instances can be reused; it is safe to call {@link #build} multiple times to build - * multiple multisets in series. - * - * @since 12.0 - */ - public static class Builder extends ImmutableMultiset.Builder { - /** - * Creates a new builder. The returned builder is equivalent to the builder generated by - * {@link ImmutableSortedMultiset#orderedBy(Comparator)}. - */ - public Builder(Comparator comparator) { - super(TreeMultiset.create(checkNotNull(comparator))); - } - - /** - * Adds {@code element} to the {@code ImmutableSortedMultiset}. - * - * @param element the element to add - * @return this {@code Builder} object - * @throws NullPointerException if {@code element} is null - */ - @Override - public Builder add(E element) { - super.add(element); - return this; - } - - /** - * Adds a number of occurrences of an element to this {@code ImmutableSortedMultiset}. - * - * @param element the element to add - * @param occurrences the number of occurrences of the element to add. May be zero, in which - * case no change will be made. - * @return this {@code Builder} object - * @throws NullPointerException if {@code element} is null - * @throws IllegalArgumentException if {@code occurrences} is negative, or if this operation - * would result in more than {@link Integer#MAX_VALUE} occurrences of the element - */ - @Override - public Builder addCopies(E element, int occurrences) { - super.addCopies(element, occurrences); - return this; - } - - /** - * Adds or removes the necessary occurrences of an element such that the element attains the - * desired count. - * - * @param element the element to add or remove occurrences of - * @param count the desired count of the element in this multiset - * @return this {@code Builder} object - * @throws NullPointerException if {@code element} is null - * @throws IllegalArgumentException if {@code count} is negative - */ - @Override - public Builder setCount(E element, int count) { - super.setCount(element, count); - return this; - } - - /** - * Adds each element of {@code elements} to the {@code ImmutableSortedMultiset}. - * - * @param elements the elements to add - * @return this {@code Builder} object - * @throws NullPointerException if {@code elements} is null or contains a null element - */ - @Override - public Builder add(E... elements) { - super.add(elements); - return this; - } - - /** - * Adds each element of {@code elements} to the {@code ImmutableSortedMultiset}. - * - * @param elements the {@code Iterable} to add to the {@code ImmutableSortedMultiset} - * @return this {@code Builder} object - * @throws NullPointerException if {@code elements} is null or contains a null element - */ - @Override - public Builder addAll(Iterable elements) { - super.addAll(elements); - return this; - } - - /** - * Adds each element of {@code elements} to the {@code ImmutableSortedMultiset}. - * - * @param elements the elements to add to the {@code ImmutableSortedMultiset} - * @return this {@code Builder} object - * @throws NullPointerException if {@code elements} is null or contains a null element - */ - @Override - public Builder addAll(Iterator elements) { - super.addAll(elements); - return this; - } - - /** - * Returns a newly-created {@code ImmutableSortedMultiset} based on the contents of the {@code - * Builder}. - */ - @Override - public ImmutableSortedMultiset build() { - return copyOfSorted((SortedMultiset) contents); - } - } - - private static final class SerializedForm implements Serializable { - Comparator comparator; - E[] elements; - int[] counts; - - @SuppressWarnings("unchecked") - SerializedForm(SortedMultiset multiset) { - this.comparator = multiset.comparator(); - int n = multiset.entrySet().size(); - elements = (E[]) new Object[n]; - counts = new int[n]; - int i = 0; - for (Entry entry : multiset.entrySet()) { - elements[i] = entry.getElement(); - counts[i] = entry.getCount(); - i++; - } - } - - Object readResolve() { - int n = elements.length; - Builder builder = new Builder(comparator); - for (int i = 0; i < n; i++) { - builder.addCopies(elements[i], counts[i]); - } - return builder.build(); - } - } - - @Override - Object writeReplace() { - return new SerializedForm(this); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSortedMultisetFauxverideShim.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSortedMultisetFauxverideShim.java deleted file mode 100644 index 8f133413d105..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSortedMultisetFauxverideShim.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -/** - * "Overrides" the {@link ImmutableMultiset} static methods that lack - * {@link ImmutableSortedMultiset} equivalents with deprecated, exception-throwing versions. This - * prevents accidents like the following: - * - *

   {@code
- *
- *   List objects = ...;
- *   // Sort them:
- *   Set sorted = ImmutableSortedMultiset.copyOf(objects);
- *   // BAD CODE! The returned multiset is actually an unsorted ImmutableMultiset!}
- *
- * 

While we could put the overrides in {@link ImmutableSortedMultiset} itself, it seems clearer - * to separate these "do not call" methods from those intended for normal use. - * - * @author Louis Wasserman - */ -abstract class ImmutableSortedMultisetFauxverideShim extends ImmutableMultiset { - /** - * Not supported. Use {@link ImmutableSortedMultiset#naturalOrder}, which offers better - * type-safety, instead. This method exists only to hide {@link ImmutableMultiset#builder} from - * consumers of {@code ImmutableSortedMultiset}. - * - * @throws UnsupportedOperationException always - * @deprecated Use {@link ImmutableSortedMultiset#naturalOrder}, which offers better type-safety. - */ - @Deprecated - public static ImmutableSortedMultiset.Builder builder() { - throw new UnsupportedOperationException(); - } - - /** - * Not supported. You are attempting to create a multiset that may contain a non-{@code - * Comparable} element. Proper calls will resolve to the version in {@code - * ImmutableSortedMultiset}, not this dummy version. - * - * @throws UnsupportedOperationException always - * @deprecated Pass a parameter of type {@code Comparable} to use - * {@link ImmutableSortedMultiset#of(Comparable)}. - */ - @Deprecated - public static ImmutableSortedMultiset of(E element) { - throw new UnsupportedOperationException(); - } - - /** - * Not supported. You are attempting to create a multiset that may contain a non-{@code - * Comparable} element. Proper calls will resolve to the version in {@code - * ImmutableSortedMultiset}, not this dummy version. - * - * @throws UnsupportedOperationException always - * @deprecated Pass the parameters of type {@code Comparable} to use - * {@link ImmutableSortedMultiset#of(Comparable, Comparable)}. - */ - @Deprecated - public static ImmutableSortedMultiset of(E e1, E e2) { - throw new UnsupportedOperationException(); - } - - /** - * Not supported. You are attempting to create a multiset that may contain a non-{@code - * Comparable} element. Proper calls will resolve to the version in {@code - * ImmutableSortedMultiset}, not this dummy version. - * - * @throws UnsupportedOperationException always - * @deprecated Pass the parameters of type {@code Comparable} to use - * {@link ImmutableSortedMultiset#of(Comparable, Comparable, Comparable)}. - */ - @Deprecated - public static ImmutableSortedMultiset of(E e1, E e2, E e3) { - throw new UnsupportedOperationException(); - } - - /** - * Not supported. You are attempting to create a multiset that may contain a non-{@code - * Comparable} element. Proper calls will resolve to the version in {@code - * ImmutableSortedMultiset}, not this dummy version. - * - * @throws UnsupportedOperationException always - * @deprecated Pass the parameters of type {@code Comparable} to use {@link - * ImmutableSortedMultiset#of(Comparable, Comparable, Comparable, Comparable)}. - */ - @Deprecated - public static ImmutableSortedMultiset of(E e1, E e2, E e3, E e4) { - throw new UnsupportedOperationException(); - } - - /** - * Not supported. You are attempting to create a multiset that may contain a non-{@code - * Comparable} element. Proper calls will resolve to the version in {@code - * ImmutableSortedMultiset}, not this dummy version. - * - * @throws UnsupportedOperationException always - * @deprecated Pass the parameters of type {@code Comparable} to use {@link - * ImmutableSortedMultiset#of(Comparable, Comparable, Comparable, Comparable, - * Comparable)} . - */ - @Deprecated - public static ImmutableSortedMultiset of(E e1, E e2, E e3, E e4, E e5) { - throw new UnsupportedOperationException(); - } - - /** - * Not supported. You are attempting to create a multiset that may contain a non-{@code - * Comparable} element. Proper calls will resolve to the version in {@code - * ImmutableSortedMultiset}, not this dummy version. - * - * @throws UnsupportedOperationException always - * @deprecated Pass the parameters of type {@code Comparable} to use {@link - * ImmutableSortedMultiset#of(Comparable, Comparable, Comparable, Comparable, - * Comparable, Comparable, Comparable...)} . - */ - @Deprecated - public static ImmutableSortedMultiset of( - E e1, E e2, E e3, E e4, E e5, E e6, E... remaining) { - throw new UnsupportedOperationException(); - } - - /** - * Not supported. You are attempting to create a multiset that may contain non-{@code - * Comparable} elements. Proper calls will resolve to the version in {@code - * ImmutableSortedMultiset}, not this dummy version. - * - * @throws UnsupportedOperationException always - * @deprecated Pass parameters of type {@code Comparable} to use - * {@link ImmutableSortedMultiset#copyOf(Comparable[])}. - */ - @Deprecated - public static ImmutableSortedMultiset copyOf(E[] elements) { - throw new UnsupportedOperationException(); - } - - /* - * We would like to include an unsupported " copyOf(Iterable)" here, providing only the - * properly typed "> copyOf(Iterable)" in ImmutableSortedMultiset (and - * likewise for the Iterator equivalent). However, due to a change in Sun's interpretation of the - * JLS (as described at http://bugs.sun.com/view_bug.do?bug_id=6182950), the OpenJDK 7 compiler - * available as of this writing rejects our attempts. To maintain compatibility with that version - * and with any other compilers that interpret the JLS similarly, there is no definition of - * copyOf() here, and the definition in ImmutableSortedMultiset matches that in - * ImmutableMultiset. - * - * The result is that ImmutableSortedMultiset.copyOf() may be called on non-Comparable elements. - * We have not discovered a better solution. In retrospect, the static factory methods should - * have gone in a separate class so that ImmutableSortedMultiset wouldn't "inherit" - * too-permissive factory methods from ImmutableMultiset. - */ -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSortedSet.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSortedSet.java deleted file mode 100644 index 4a7a94b67df2..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSortedSet.java +++ /dev/null @@ -1,787 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.ObjectArrays.checkElementsNotNull; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; - -import java.io.InvalidObjectException; -import java.io.ObjectInputStream; -import java.io.Serializable; -import java.util.Arrays; -import java.util.Collection; -import java.util.Comparator; -import java.util.Iterator; -import java.util.NavigableSet; -import java.util.SortedSet; - -import javax.annotation.Nullable; - -/** - * A {@link NavigableSet} whose contents will never change, with many other important properties - * detailed at {@link ImmutableCollection}. - * - *

Warning: as with any sorted collection, you are strongly advised not to use a {@link - * Comparator} or {@link Comparable} type whose comparison behavior is inconsistent with - * equals. That is, {@code a.compareTo(b)} or {@code comparator.compare(a, b)} should equal zero - * if and only if {@code a.equals(b)}. If this advice is not followed, the resulting - * collection will not correctly obey its specification. - * - *

See the Guava User Guide article on - * immutable collections. - * - * @author Jared Levy - * @author Louis Wasserman - * @since 2.0 (implements {@code NavigableSet} since 12.0) - */ -// TODO(benyu): benchmark and optimize all creation paths, which are a mess now -@GwtCompatible(serializable = true, emulated = true) -@SuppressWarnings("serial") // we're overriding default serialization -public abstract class ImmutableSortedSet extends ImmutableSortedSetFauxverideShim - implements NavigableSet, SortedIterable { - - private static final Comparator NATURAL_ORDER = Ordering.natural(); - - private static final RegularImmutableSortedSet NATURAL_EMPTY_SET = - new RegularImmutableSortedSet(ImmutableList.of(), NATURAL_ORDER); - - static RegularImmutableSortedSet emptySet(Comparator comparator) { - if (NATURAL_ORDER.equals(comparator)) { - return (RegularImmutableSortedSet) NATURAL_EMPTY_SET; - } else { - return new RegularImmutableSortedSet(ImmutableList.of(), comparator); - } - } - - /** - * Returns the empty immutable sorted set. - */ - public static ImmutableSortedSet of() { - return (ImmutableSortedSet) NATURAL_EMPTY_SET; - } - - /** - * Returns an immutable sorted set containing a single element. - */ - public static > ImmutableSortedSet of(E element) { - return new RegularImmutableSortedSet(ImmutableList.of(element), Ordering.natural()); - } - - /** - * Returns an immutable sorted set containing the given elements sorted by - * their natural ordering. When multiple elements are equivalent according to - * {@link Comparable#compareTo}, only the first one specified is included. - * - * @throws NullPointerException if any element is null - */ - @SuppressWarnings("unchecked") - public static > ImmutableSortedSet of(E e1, E e2) { - return construct(Ordering.natural(), 2, e1, e2); - } - - /** - * Returns an immutable sorted set containing the given elements sorted by - * their natural ordering. When multiple elements are equivalent according to - * {@link Comparable#compareTo}, only the first one specified is included. - * - * @throws NullPointerException if any element is null - */ - @SuppressWarnings("unchecked") - public static > ImmutableSortedSet of(E e1, E e2, E e3) { - return construct(Ordering.natural(), 3, e1, e2, e3); - } - - /** - * Returns an immutable sorted set containing the given elements sorted by - * their natural ordering. When multiple elements are equivalent according to - * {@link Comparable#compareTo}, only the first one specified is included. - * - * @throws NullPointerException if any element is null - */ - @SuppressWarnings("unchecked") - public static > ImmutableSortedSet of(E e1, E e2, E e3, E e4) { - return construct(Ordering.natural(), 4, e1, e2, e3, e4); - } - - /** - * Returns an immutable sorted set containing the given elements sorted by - * their natural ordering. When multiple elements are equivalent according to - * {@link Comparable#compareTo}, only the first one specified is included. - * - * @throws NullPointerException if any element is null - */ - @SuppressWarnings("unchecked") - public static > ImmutableSortedSet of( - E e1, E e2, E e3, E e4, E e5) { - return construct(Ordering.natural(), 5, e1, e2, e3, e4, e5); - } - - /** - * Returns an immutable sorted set containing the given elements sorted by - * their natural ordering. When multiple elements are equivalent according to - * {@link Comparable#compareTo}, only the first one specified is included. - * - * @throws NullPointerException if any element is null - * @since 3.0 (source-compatible since 2.0) - */ - @SuppressWarnings("unchecked") - public static > ImmutableSortedSet of( - E e1, E e2, E e3, E e4, E e5, E e6, E... remaining) { - Comparable[] contents = new Comparable[6 + remaining.length]; - contents[0] = e1; - contents[1] = e2; - contents[2] = e3; - contents[3] = e4; - contents[4] = e5; - contents[5] = e6; - System.arraycopy(remaining, 0, contents, 6, remaining.length); - return construct(Ordering.natural(), contents.length, (E[]) contents); - } - - // TODO(kevinb): Consider factory methods that reject duplicates - - /** - * Returns an immutable sorted set containing the given elements sorted by - * their natural ordering. When multiple elements are equivalent according to - * {@link Comparable#compareTo}, only the first one specified is included. - * - * @throws NullPointerException if any of {@code elements} is null - * @since 3.0 - */ - public static > ImmutableSortedSet copyOf(E[] elements) { - return construct(Ordering.natural(), elements.length, elements.clone()); - } - - /** - * Returns an immutable sorted set containing the given elements sorted by - * their natural ordering. When multiple elements are equivalent according to - * {@code compareTo()}, only the first one specified is included. To create a - * copy of a {@code SortedSet} that preserves the comparator, call {@link - * #copyOfSorted} instead. This method iterates over {@code elements} at most - * once. - - * - *

Note that if {@code s} is a {@code Set}, then {@code - * ImmutableSortedSet.copyOf(s)} returns an {@code ImmutableSortedSet} - * containing each of the strings in {@code s}, while {@code - * ImmutableSortedSet.of(s)} returns an {@code - * ImmutableSortedSet>} containing one element (the given set - * itself). - * - *

Despite the method name, this method attempts to avoid actually copying - * the data when it is safe to do so. The exact circumstances under which a - * copy will or will not be performed are undocumented and subject to change. - * - *

This method is not type-safe, as it may be called on elements that are - * not mutually comparable. - * - * @throws ClassCastException if the elements are not mutually comparable - * @throws NullPointerException if any of {@code elements} is null - */ - public static ImmutableSortedSet copyOf(Iterable elements) { - // Hack around E not being a subtype of Comparable. - // Unsafe, see ImmutableSortedSetFauxverideShim. - @SuppressWarnings("unchecked") - Ordering naturalOrder = (Ordering) Ordering.natural(); - return copyOf(naturalOrder, elements); - } - - /** - * Returns an immutable sorted set containing the given elements sorted by - * their natural ordering. When multiple elements are equivalent according to - * {@code compareTo()}, only the first one specified is included. To create a - * copy of a {@code SortedSet} that preserves the comparator, call - * {@link #copyOfSorted} instead. This method iterates over {@code elements} - * at most once. - * - *

Note that if {@code s} is a {@code Set}, then - * {@code ImmutableSortedSet.copyOf(s)} returns an - * {@code ImmutableSortedSet} containing each of the strings in - * {@code s}, while {@code ImmutableSortedSet.of(s)} returns an - * {@code ImmutableSortedSet>} containing one element (the given - * set itself). - * - *

Note: Despite what the method name suggests, if {@code elements} - * is an {@code ImmutableSortedSet}, it may be returned instead of a copy. - * - *

This method is not type-safe, as it may be called on elements that are - * not mutually comparable. - * - *

This method is safe to use even when {@code elements} is a synchronized - * or concurrent collection that is currently being modified by another - * thread. - * - * @throws ClassCastException if the elements are not mutually comparable - * @throws NullPointerException if any of {@code elements} is null - * @since 7.0 (source-compatible since 2.0) - */ - public static ImmutableSortedSet copyOf(Collection elements) { - // Hack around E not being a subtype of Comparable. - // Unsafe, see ImmutableSortedSetFauxverideShim. - @SuppressWarnings("unchecked") - Ordering naturalOrder = (Ordering) Ordering.natural(); - return copyOf(naturalOrder, elements); - } - - /** - * Returns an immutable sorted set containing the given elements sorted by - * their natural ordering. When multiple elements are equivalent according to - * {@code compareTo()}, only the first one specified is included. - * - *

This method is not type-safe, as it may be called on elements that are - * not mutually comparable. - * - * @throws ClassCastException if the elements are not mutually comparable - * @throws NullPointerException if any of {@code elements} is null - */ - public static ImmutableSortedSet copyOf(Iterator elements) { - // Hack around E not being a subtype of Comparable. - // Unsafe, see ImmutableSortedSetFauxverideShim. - @SuppressWarnings("unchecked") - Ordering naturalOrder = (Ordering) Ordering.natural(); - return copyOf(naturalOrder, elements); - } - - /** - * Returns an immutable sorted set containing the given elements sorted by - * the given {@code Comparator}. When multiple elements are equivalent - * according to {@code compareTo()}, only the first one specified is - * included. - * - * @throws NullPointerException if {@code comparator} or any of - * {@code elements} is null - */ - public static ImmutableSortedSet copyOf( - Comparator comparator, Iterator elements) { - return new Builder(comparator).addAll(elements).build(); - } - - /** - * Returns an immutable sorted set containing the given elements sorted by - * the given {@code Comparator}. When multiple elements are equivalent - * according to {@code compare()}, only the first one specified is - * included. This method iterates over {@code elements} at most once. - * - *

Despite the method name, this method attempts to avoid actually copying - * the data when it is safe to do so. The exact circumstances under which a - * copy will or will not be performed are undocumented and subject to change. - * - * @throws NullPointerException if {@code comparator} or any of {@code - * elements} is null - */ - public static ImmutableSortedSet copyOf( - Comparator comparator, Iterable elements) { - checkNotNull(comparator); - boolean hasSameComparator = SortedIterables.hasSameComparator(comparator, elements); - - if (hasSameComparator && (elements instanceof ImmutableSortedSet)) { - @SuppressWarnings("unchecked") - ImmutableSortedSet original = (ImmutableSortedSet) elements; - if (!original.isPartialView()) { - return original; - } - } - @SuppressWarnings("unchecked") // elements only contains E's; it's safe. - E[] array = (E[]) Iterables.toArray(elements); - return construct(comparator, array.length, array); - } - - /** - * Returns an immutable sorted set containing the given elements sorted by - * the given {@code Comparator}. When multiple elements are equivalent - * according to {@code compareTo()}, only the first one specified is - * included. - * - *

Despite the method name, this method attempts to avoid actually copying - * the data when it is safe to do so. The exact circumstances under which a - * copy will or will not be performed are undocumented and subject to change. - * - *

This method is safe to use even when {@code elements} is a synchronized - * or concurrent collection that is currently being modified by another - * thread. - * - * @throws NullPointerException if {@code comparator} or any of - * {@code elements} is null - * @since 7.0 (source-compatible since 2.0) - */ - public static ImmutableSortedSet copyOf( - Comparator comparator, Collection elements) { - return copyOf(comparator, (Iterable) elements); - } - - /** - * Returns an immutable sorted set containing the elements of a sorted set, - * sorted by the same {@code Comparator}. That behavior differs from {@link - * #copyOf(Iterable)}, which always uses the natural ordering of the - * elements. - * - *

Despite the method name, this method attempts to avoid actually copying - * the data when it is safe to do so. The exact circumstances under which a - * copy will or will not be performed are undocumented and subject to change. - * - *

This method is safe to use even when {@code sortedSet} is a synchronized - * or concurrent collection that is currently being modified by another - * thread. - * - * @throws NullPointerException if {@code sortedSet} or any of its elements - * is null - */ - public static ImmutableSortedSet copyOfSorted(SortedSet sortedSet) { - Comparator comparator = SortedIterables.comparator(sortedSet); - ImmutableList list = ImmutableList.copyOf(sortedSet); - if (list.isEmpty()) { - return emptySet(comparator); - } else { - return new RegularImmutableSortedSet(list, comparator); - } - } - - /** - * Constructs an {@code ImmutableSortedSet} from the first {@code n} elements of - * {@code contents}. If {@code k} is the size of the returned {@code ImmutableSortedSet}, then - * the sorted unique elements are in the first {@code k} positions of {@code contents}, and - * {@code contents[i] == null} for {@code k <= i < n}. - * - *

If {@code k == contents.length}, then {@code contents} may no longer be safe for - * modification. - * - * @throws NullPointerException if any of the first {@code n} elements of {@code contents} is - * null - */ - static ImmutableSortedSet construct( - Comparator comparator, int n, E... contents) { - if (n == 0) { - return emptySet(comparator); - } - checkElementsNotNull(contents, n); - Arrays.sort(contents, 0, n, comparator); - int uniques = 1; - for (int i = 1; i < n; i++) { - E cur = contents[i]; - E prev = contents[uniques - 1]; - if (comparator.compare(cur, prev) != 0) { - contents[uniques++] = cur; - } - } - Arrays.fill(contents, uniques, n, null); - return new RegularImmutableSortedSet( - ImmutableList.asImmutableList(contents, uniques), comparator); - } - - /** - * Returns a builder that creates immutable sorted sets with an explicit - * comparator. If the comparator has a more general type than the set being - * generated, such as creating a {@code SortedSet} with a - * {@code Comparator}, use the {@link Builder} constructor instead. - * - * @throws NullPointerException if {@code comparator} is null - */ - public static Builder orderedBy(Comparator comparator) { - return new Builder(comparator); - } - - /** - * Returns a builder that creates immutable sorted sets whose elements are - * ordered by the reverse of their natural ordering. - */ - public static > Builder reverseOrder() { - return new Builder(Ordering.natural().reverse()); - } - - /** - * Returns a builder that creates immutable sorted sets whose elements are - * ordered by their natural ordering. The sorted sets use {@link - * Ordering#natural()} as the comparator. This method provides more - * type-safety than {@link #builder}, as it can be called only for classes - * that implement {@link Comparable}. - */ - public static > Builder naturalOrder() { - return new Builder(Ordering.natural()); - } - - /** - * A builder for creating immutable sorted set instances, especially {@code - * public static final} sets ("constant sets"), with a given comparator. - * Example:

   {@code
-   *
-   *   public static final ImmutableSortedSet LUCKY_NUMBERS =
-   *       new ImmutableSortedSet.Builder(ODDS_FIRST_COMPARATOR)
-   *           .addAll(SINGLE_DIGIT_PRIMES)
-   *           .add(42)
-   *           .build();}
- * - *

Builder instances can be reused; it is safe to call {@link #build} multiple - * times to build multiple sets in series. Each set is a superset of the set - * created before it. - * - * @since 2.0 - */ - public static final class Builder extends ImmutableSet.Builder { - private final Comparator comparator; - - /** - * Creates a new builder. The returned builder is equivalent to the builder - * generated by {@link ImmutableSortedSet#orderedBy}. - */ - public Builder(Comparator comparator) { - this.comparator = checkNotNull(comparator); - } - - /** - * Adds {@code element} to the {@code ImmutableSortedSet}. If the - * {@code ImmutableSortedSet} already contains {@code element}, then - * {@code add} has no effect. (only the previously added element - * is retained). - * - * @param element the element to add - * @return this {@code Builder} object - * @throws NullPointerException if {@code element} is null - */ - @Override - public Builder add(E element) { - super.add(element); - return this; - } - - /** - * Adds each element of {@code elements} to the {@code ImmutableSortedSet}, - * ignoring duplicate elements (only the first duplicate element is added). - * - * @param elements the elements to add - * @return this {@code Builder} object - * @throws NullPointerException if {@code elements} contains a null element - */ - @Override - public Builder add(E... elements) { - super.add(elements); - return this; - } - - /** - * Adds each element of {@code elements} to the {@code ImmutableSortedSet}, - * ignoring duplicate elements (only the first duplicate element is added). - * - * @param elements the elements to add to the {@code ImmutableSortedSet} - * @return this {@code Builder} object - * @throws NullPointerException if {@code elements} contains a null element - */ - @Override - public Builder addAll(Iterable elements) { - super.addAll(elements); - return this; - } - - /** - * Adds each element of {@code elements} to the {@code ImmutableSortedSet}, - * ignoring duplicate elements (only the first duplicate element is added). - * - * @param elements the elements to add to the {@code ImmutableSortedSet} - * @return this {@code Builder} object - * @throws NullPointerException if {@code elements} contains a null element - */ - @Override - public Builder addAll(Iterator elements) { - super.addAll(elements); - return this; - } - - /** - * Returns a newly-created {@code ImmutableSortedSet} based on the contents - * of the {@code Builder} and its comparator. - */ - @Override - public ImmutableSortedSet build() { - @SuppressWarnings("unchecked") // we're careful to put only E's in here - E[] contentsArray = (E[]) contents; - ImmutableSortedSet result = construct(comparator, size, contentsArray); - this.size = result.size(); // we eliminated duplicates in-place in contentsArray - return result; - } - } - - int unsafeCompare(Object a, Object b) { - return unsafeCompare(comparator, a, b); - } - - static int unsafeCompare(Comparator comparator, Object a, Object b) { - // Pretend the comparator can compare anything. If it turns out it can't - // compare a and b, we should get a CCE on the subsequent line. Only methods - // that are spec'd to throw CCE should call this. - @SuppressWarnings("unchecked") - Comparator unsafeComparator = (Comparator) comparator; - return unsafeComparator.compare(a, b); - } - - final transient Comparator comparator; - - ImmutableSortedSet(Comparator comparator) { - this.comparator = comparator; - } - - /** - * Returns the comparator that orders the elements, which is - * {@link Ordering#natural()} when the natural ordering of the - * elements is used. Note that its behavior is not consistent with - * {@link SortedSet#comparator()}, which returns {@code null} to indicate - * natural ordering. - */ - @Override - public Comparator comparator() { - return comparator; - } - - @Override // needed to unify the iterator() methods in Collection and SortedIterable - public abstract UnmodifiableIterator iterator(); - - /** - * {@inheritDoc} - * - *

This method returns a serializable {@code ImmutableSortedSet}. - * - *

The {@link SortedSet#headSet} documentation states that a subset of a - * subset throws an {@link IllegalArgumentException} if passed a - * {@code toElement} greater than an earlier {@code toElement}. However, this - * method doesn't throw an exception in that situation, but instead keeps the - * original {@code toElement}. - */ - @Override - public ImmutableSortedSet headSet(E toElement) { - return headSet(toElement, false); - } - - /** - * @since 12.0 - */ - @GwtIncompatible("NavigableSet") - @Override - public ImmutableSortedSet headSet(E toElement, boolean inclusive) { - return headSetImpl(checkNotNull(toElement), inclusive); - } - - /** - * {@inheritDoc} - * - *

This method returns a serializable {@code ImmutableSortedSet}. - * - *

The {@link SortedSet#subSet} documentation states that a subset of a - * subset throws an {@link IllegalArgumentException} if passed a - * {@code fromElement} smaller than an earlier {@code fromElement}. However, - * this method doesn't throw an exception in that situation, but instead keeps - * the original {@code fromElement}. Similarly, this method keeps the - * original {@code toElement}, instead of throwing an exception, if passed a - * {@code toElement} greater than an earlier {@code toElement}. - */ - @Override - public ImmutableSortedSet subSet(E fromElement, E toElement) { - return subSet(fromElement, true, toElement, false); - } - - /** - * @since 12.0 - */ - @GwtIncompatible("NavigableSet") - @Override - public ImmutableSortedSet subSet( - E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { - checkNotNull(fromElement); - checkNotNull(toElement); - checkArgument(comparator.compare(fromElement, toElement) <= 0); - return subSetImpl(fromElement, fromInclusive, toElement, toInclusive); - } - - /** - * {@inheritDoc} - * - *

This method returns a serializable {@code ImmutableSortedSet}. - * - *

The {@link SortedSet#tailSet} documentation states that a subset of a - * subset throws an {@link IllegalArgumentException} if passed a - * {@code fromElement} smaller than an earlier {@code fromElement}. However, - * this method doesn't throw an exception in that situation, but instead keeps - * the original {@code fromElement}. - */ - @Override - public ImmutableSortedSet tailSet(E fromElement) { - return tailSet(fromElement, true); - } - - /** - * @since 12.0 - */ - @GwtIncompatible("NavigableSet") - @Override - public ImmutableSortedSet tailSet(E fromElement, boolean inclusive) { - return tailSetImpl(checkNotNull(fromElement), inclusive); - } - - /* - * These methods perform most headSet, subSet, and tailSet logic, besides - * parameter validation. - */ - abstract ImmutableSortedSet headSetImpl(E toElement, boolean inclusive); - - abstract ImmutableSortedSet subSetImpl( - E fromElement, boolean fromInclusive, E toElement, boolean toInclusive); - - abstract ImmutableSortedSet tailSetImpl(E fromElement, boolean inclusive); - - /** - * @since 12.0 - */ - @GwtIncompatible("NavigableSet") - @Override - public E lower(E e) { - return Iterators.getNext(headSet(e, false).descendingIterator(), null); - } - - /** - * @since 12.0 - */ - @GwtIncompatible("NavigableSet") - @Override - public E floor(E e) { - return Iterators.getNext(headSet(e, true).descendingIterator(), null); - } - - /** - * @since 12.0 - */ - @GwtIncompatible("NavigableSet") - @Override - public E ceiling(E e) { - return Iterables.getFirst(tailSet(e, true), null); - } - - /** - * @since 12.0 - */ - @GwtIncompatible("NavigableSet") - @Override - public E higher(E e) { - return Iterables.getFirst(tailSet(e, false), null); - } - - @Override - public E first() { - return iterator().next(); - } - - @Override - public E last() { - return descendingIterator().next(); - } - - /** - * Guaranteed to throw an exception and leave the set unmodified. - * - * @since 12.0 - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @GwtIncompatible("NavigableSet") - @Override - public final E pollFirst() { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the set unmodified. - * - * @since 12.0 - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @GwtIncompatible("NavigableSet") - @Override - public final E pollLast() { - throw new UnsupportedOperationException(); - } - - @GwtIncompatible("NavigableSet") - transient ImmutableSortedSet descendingSet; - - /** - * @since 12.0 - */ - @GwtIncompatible("NavigableSet") - @Override - public ImmutableSortedSet descendingSet() { - // racy single-check idiom - ImmutableSortedSet result = descendingSet; - if (result == null) { - result = descendingSet = createDescendingSet(); - result.descendingSet = this; - } - return result; - } - - @GwtIncompatible("NavigableSet") - ImmutableSortedSet createDescendingSet() { - return new DescendingImmutableSortedSet(this); - } - - /** - * @since 12.0 - */ - @GwtIncompatible("NavigableSet") - @Override - public abstract UnmodifiableIterator descendingIterator(); - - /** - * Returns the position of an element within the set, or -1 if not present. - */ - abstract int indexOf(@Nullable Object target); - - /* - * This class is used to serialize all ImmutableSortedSet instances, - * regardless of implementation type. It captures their "logical contents" - * only. This is necessary to ensure that the existence of a particular - * implementation type is an implementation detail. - */ - private static class SerializedForm implements Serializable { - final Comparator comparator; - final Object[] elements; - - public SerializedForm(Comparator comparator, Object[] elements) { - this.comparator = comparator; - this.elements = elements; - } - - @SuppressWarnings("unchecked") - Object readResolve() { - return new Builder(comparator).add((E[]) elements).build(); - } - - private static final long serialVersionUID = 0; - } - - private void readObject(ObjectInputStream stream) throws InvalidObjectException { - throw new InvalidObjectException("Use SerializedForm"); - } - - @Override - Object writeReplace() { - return new SerializedForm(comparator, toArray()); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSortedSetFauxverideShim.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSortedSetFauxverideShim.java deleted file mode 100644 index 1ed865c411e8..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableSortedSetFauxverideShim.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -/** - * "Overrides" the {@link ImmutableSet} static methods that lack - * {@link ImmutableSortedSet} equivalents with deprecated, exception-throwing - * versions. This prevents accidents like the following:

   {@code
- *
- *   List objects = ...;
- *   // Sort them:
- *   Set sorted = ImmutableSortedSet.copyOf(objects);
- *   // BAD CODE! The returned set is actually an unsorted ImmutableSet!}
- *
- * 

While we could put the overrides in {@link ImmutableSortedSet} itself, it - * seems clearer to separate these "do not call" methods from those intended for - * normal use. - * - * @author Chris Povirk - */ -abstract class ImmutableSortedSetFauxverideShim extends ImmutableSet { - /** - * Not supported. Use {@link ImmutableSortedSet#naturalOrder}, which offers - * better type-safety, instead. This method exists only to hide - * {@link ImmutableSet#builder} from consumers of {@code ImmutableSortedSet}. - * - * @throws UnsupportedOperationException always - * @deprecated Use {@link ImmutableSortedSet#naturalOrder}, which offers - * better type-safety. - */ - @Deprecated - public static ImmutableSortedSet.Builder builder() { - throw new UnsupportedOperationException(); - } - - /** - * Not supported. You are attempting to create a set that may contain a - * non-{@code Comparable} element. Proper calls will resolve to the - * version in {@code ImmutableSortedSet}, not this dummy version. - * - * @throws UnsupportedOperationException always - * @deprecated Pass a parameter of type {@code Comparable} to use {@link - * ImmutableSortedSet#of(Comparable)}. - */ - @Deprecated - public static ImmutableSortedSet of(E element) { - throw new UnsupportedOperationException(); - } - - /** - * Not supported. You are attempting to create a set that may contain a - * non-{@code Comparable} element. Proper calls will resolve to the - * version in {@code ImmutableSortedSet}, not this dummy version. - * - * @throws UnsupportedOperationException always - * @deprecated Pass the parameters of type {@code Comparable} to use {@link - * ImmutableSortedSet#of(Comparable, Comparable)}. - */ - @Deprecated - public static ImmutableSortedSet of(E e1, E e2) { - throw new UnsupportedOperationException(); - } - - /** - * Not supported. You are attempting to create a set that may contain a - * non-{@code Comparable} element. Proper calls will resolve to the - * version in {@code ImmutableSortedSet}, not this dummy version. - * - * @throws UnsupportedOperationException always - * @deprecated Pass the parameters of type {@code Comparable} to use {@link - * ImmutableSortedSet#of(Comparable, Comparable, Comparable)}. - */ - @Deprecated - public static ImmutableSortedSet of(E e1, E e2, E e3) { - throw new UnsupportedOperationException(); - } - - /** - * Not supported. You are attempting to create a set that may contain a - * non-{@code Comparable} element. Proper calls will resolve to the - * version in {@code ImmutableSortedSet}, not this dummy version. - * - * @throws UnsupportedOperationException always - * @deprecated Pass the parameters of type {@code Comparable} to use {@link - * ImmutableSortedSet#of(Comparable, Comparable, Comparable, Comparable)}. - * - */ - @Deprecated - public static ImmutableSortedSet of(E e1, E e2, E e3, E e4) { - throw new UnsupportedOperationException(); - } - - /** - * Not supported. You are attempting to create a set that may contain a - * non-{@code Comparable} element. Proper calls will resolve to the - * version in {@code ImmutableSortedSet}, not this dummy version. - * - * @throws UnsupportedOperationException always - * @deprecated Pass the parameters of type {@code Comparable} to use {@link - * ImmutableSortedSet#of( - * Comparable, Comparable, Comparable, Comparable, Comparable)}. - */ - @Deprecated - public static ImmutableSortedSet of(E e1, E e2, E e3, E e4, E e5) { - throw new UnsupportedOperationException(); - } - - /** - * Not supported. You are attempting to create a set that may contain a - * non-{@code Comparable} element. Proper calls will resolve to the - * version in {@code ImmutableSortedSet}, not this dummy version. - * - * @throws UnsupportedOperationException always - * @deprecated Pass the parameters of type {@code Comparable} to use {@link - * ImmutableSortedSet#of(Comparable, Comparable, Comparable, Comparable, - * Comparable, Comparable, Comparable...)}. - */ - @Deprecated - public static ImmutableSortedSet of(E e1, E e2, E e3, E e4, E e5, E e6, E... remaining) { - throw new UnsupportedOperationException(); - } - - /** - * Not supported. You are attempting to create a set that may contain - * non-{@code Comparable} elements. Proper calls will resolve to the - * version in {@code ImmutableSortedSet}, not this dummy version. - * - * @throws UnsupportedOperationException always - * @deprecated Pass parameters of type {@code Comparable} to use {@link - * ImmutableSortedSet#copyOf(Comparable[])}. - */ - @Deprecated - public static ImmutableSortedSet copyOf(E[] elements) { - throw new UnsupportedOperationException(); - } - - /* - * We would like to include an unsupported " copyOf(Iterable)" here, - * providing only the properly typed - * "> copyOf(Iterable)" in ImmutableSortedSet (and - * likewise for the Iterator equivalent). However, due to a change in Sun's - * interpretation of the JLS (as described at - * http://bugs.sun.com/view_bug.do?bug_id=6182950), the OpenJDK 7 compiler - * available as of this writing rejects our attempts. To maintain - * compatibility with that version and with any other compilers that interpret - * the JLS similarly, there is no definition of copyOf() here, and the - * definition in ImmutableSortedSet matches that in ImmutableSet. - * - * The result is that ImmutableSortedSet.copyOf() may be called on - * non-Comparable elements. We have not discovered a better solution. In - * retrospect, the static factory methods should have gone in a separate class - * so that ImmutableSortedSet wouldn't "inherit" too-permissive factory - * methods from ImmutableSet. - */ -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableTable.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableTable.java deleted file mode 100644 index 354b299abfd5..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ImmutableTable.java +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.MoreObjects; - -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nullable; - -/** - * A {@link Table} whose contents will never change, with many other important - * properties detailed at {@link ImmutableCollection}. - * - *

See the Guava User Guide article on - * immutable collections. - * - * @author Gregory Kick - * @since 11.0 - */ -@GwtCompatible -// TODO(gak): make serializable -public abstract class ImmutableTable extends AbstractTable { - private static final ImmutableTable EMPTY = - new SparseImmutableTable( - ImmutableList.>of(), - ImmutableSet.of(), - ImmutableSet.of()); - - /** Returns an empty immutable table. */ - @SuppressWarnings("unchecked") - public static ImmutableTable of() { - return (ImmutableTable) EMPTY; - } - - /** Returns an immutable table containing a single cell. */ - public static ImmutableTable of(R rowKey, C columnKey, V value) { - return new SingletonImmutableTable(rowKey, columnKey, value); - } - - /** - * Returns an immutable copy of the provided table. - * - *

The {@link Table#cellSet()} iteration order of the provided table - * determines the iteration ordering of all views in the returned table. Note - * that some views of the original table and the copied table may have - * different iteration orders. For more control over the ordering, create a - * {@link Builder} and call {@link Builder#orderRowsBy}, - * {@link Builder#orderColumnsBy}, and {@link Builder#putAll} - * - *

Despite the method name, this method attempts to avoid actually copying - * the data when it is safe to do so. The exact circumstances under which a - * copy will or will not be performed are undocumented and subject to change. - */ - public static ImmutableTable copyOf( - Table table) { - if (table instanceof ImmutableTable) { - @SuppressWarnings("unchecked") - ImmutableTable parameterizedTable = (ImmutableTable) table; - return parameterizedTable; - } else { - int size = table.size(); - switch (size) { - case 0: - return of(); - case 1: - Cell onlyCell = - Iterables.getOnlyElement(table.cellSet()); - return ImmutableTable.of( - onlyCell.getRowKey(), onlyCell.getColumnKey(), onlyCell.getValue()); - default: - ImmutableSet.Builder> cellSetBuilder = - new ImmutableSet.Builder>(size); - for (Cell cell : table.cellSet()) { - /* - * Must cast to be able to create a Cell rather than a - * Cell - */ - cellSetBuilder.add( - cellOf((R) cell.getRowKey(), (C) cell.getColumnKey(), (V) cell.getValue())); - } - return RegularImmutableTable.forCells(cellSetBuilder.build()); - } - } - } - - /** - * Returns a new builder. The generated builder is equivalent to the builder - * created by the {@link Builder#ImmutableTable.Builder()} constructor. - */ - public static Builder builder() { - return new Builder(); - } - - /** - * Verifies that {@code rowKey}, {@code columnKey} and {@code value} are - * non-null, and returns a new entry with those values. - */ - static Cell cellOf(R rowKey, C columnKey, V value) { - return Tables.immutableCell(checkNotNull(rowKey), checkNotNull(columnKey), checkNotNull(value)); - } - - /** - * A builder for creating immutable table instances, especially {@code public - * static final} tables ("constant tables"). Example:

   {@code
-   *
-   *   static final ImmutableTable SPREADSHEET =
-   *       new ImmutableTable.Builder()
-   *           .put(1, 'A', "foo")
-   *           .put(1, 'B', "bar")
-   *           .put(2, 'A', "baz")
-   *           .build();}
- * - *

By default, the order in which cells are added to the builder determines - * the iteration ordering of all views in the returned table, with {@link - * #putAll} following the {@link Table#cellSet()} iteration order. However, if - * {@link #orderRowsBy} or {@link #orderColumnsBy} is called, the views are - * sorted by the supplied comparators. - * - * For empty or single-cell immutable tables, {@link #of()} and - * {@link #of(Object, Object, Object)} are even more convenient. - * - *

Builder instances can be reused - it is safe to call {@link #build} - * multiple times to build multiple tables in series. Each table is a superset - * of the tables created before it. - * - * @since 11.0 - */ - public static final class Builder { - private final List> cells = Lists.newArrayList(); - private Comparator rowComparator; - private Comparator columnComparator; - - /** - * Creates a new builder. The returned builder is equivalent to the builder - * generated by {@link ImmutableTable#builder}. - */ - public Builder() {} - - /** - * Specifies the ordering of the generated table's rows. - */ - public Builder orderRowsBy(Comparator rowComparator) { - this.rowComparator = checkNotNull(rowComparator); - return this; - } - - /** - * Specifies the ordering of the generated table's columns. - */ - public Builder orderColumnsBy(Comparator columnComparator) { - this.columnComparator = checkNotNull(columnComparator); - return this; - } - - /** - * Associates the ({@code rowKey}, {@code columnKey}) pair with {@code - * value} in the built table. Duplicate key pairs are not allowed and will - * cause {@link #build} to fail. - */ - public Builder put(R rowKey, C columnKey, V value) { - cells.add(cellOf(rowKey, columnKey, value)); - return this; - } - - /** - * Adds the given {@code cell} to the table, making it immutable if - * necessary. Duplicate key pairs are not allowed and will cause {@link - * #build} to fail. - */ - public Builder put(Cell cell) { - if (cell instanceof Tables.ImmutableCell) { - checkNotNull(cell.getRowKey()); - checkNotNull(cell.getColumnKey()); - checkNotNull(cell.getValue()); - @SuppressWarnings("unchecked") // all supported methods are covariant - Cell immutableCell = (Cell) cell; - cells.add(immutableCell); - } else { - put(cell.getRowKey(), cell.getColumnKey(), cell.getValue()); - } - return this; - } - - /** - * Associates all of the given table's keys and values in the built table. - * Duplicate row key column key pairs are not allowed, and will cause - * {@link #build} to fail. - * - * @throws NullPointerException if any key or value in {@code table} is null - */ - public Builder putAll(Table table) { - for (Cell cell : table.cellSet()) { - put(cell); - } - return this; - } - - /** - * Returns a newly-created immutable table. - * - * @throws IllegalArgumentException if duplicate key pairs were added - */ - public ImmutableTable build() { - int size = cells.size(); - switch (size) { - case 0: - return of(); - case 1: - return new SingletonImmutableTable(Iterables.getOnlyElement(cells)); - default: - return RegularImmutableTable.forCells(cells, rowComparator, columnComparator); - } - } - } - - ImmutableTable() {} - - @Override - public ImmutableSet> cellSet() { - return (ImmutableSet>) super.cellSet(); - } - - @Override - abstract ImmutableSet> createCellSet(); - - @Override - final UnmodifiableIterator> cellIterator() { - throw new AssertionError("should never be called"); - } - - @Override - public ImmutableCollection values() { - return (ImmutableCollection) super.values(); - } - - @Override - abstract ImmutableCollection createValues(); - - @Override - final Iterator valuesIterator() { - throw new AssertionError("should never be called"); - } - - /** - * {@inheritDoc} - * - * @throws NullPointerException if {@code columnKey} is {@code null} - */ - @Override - public ImmutableMap column(C columnKey) { - checkNotNull(columnKey); - return MoreObjects.firstNonNull( - (ImmutableMap) columnMap().get(columnKey), - ImmutableMap.of()); - } - - @Override - public ImmutableSet columnKeySet() { - return columnMap().keySet(); - } - - /** - * {@inheritDoc} - * - *

The value {@code Map} instances in the returned map are - * {@link ImmutableMap} instances as well. - */ - @Override - public abstract ImmutableMap> columnMap(); - - /** - * {@inheritDoc} - * - * @throws NullPointerException if {@code rowKey} is {@code null} - */ - @Override - public ImmutableMap row(R rowKey) { - checkNotNull(rowKey); - return MoreObjects.firstNonNull( - (ImmutableMap) rowMap().get(rowKey), - ImmutableMap.of()); - } - - @Override - public ImmutableSet rowKeySet() { - return rowMap().keySet(); - } - - /** - * {@inheritDoc} - * - *

The value {@code Map} instances in the returned map are - * {@link ImmutableMap} instances as well. - */ - @Override - public abstract ImmutableMap> rowMap(); - - @Override - public boolean contains(@Nullable Object rowKey, @Nullable Object columnKey) { - return get(rowKey, columnKey) != null; - } - - @Override - public boolean containsValue(@Nullable Object value) { - return values().contains(value); - } - - /** - * Guaranteed to throw an exception and leave the table unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final void clear() { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the table unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final V put(R rowKey, C columnKey, V value) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the table unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final void putAll(Table table) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the table unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final V remove(Object rowKey, Object columnKey) { - throw new UnsupportedOperationException(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Interner.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Interner.java deleted file mode 100644 index cd5e930dccb5..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Interner.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.Beta; - -/** - * Provides equivalent behavior to {@link String#intern} for other immutable - * types. - * - * @author Kevin Bourrillion - * @since 3.0 - */ -@Beta -public interface Interner { - /** - * Chooses and returns the representative instance for any of a collection of - * instances that are equal to each other. If two {@linkplain Object#equals - * equal} inputs are given to this method, both calls will return the same - * instance. That is, {@code intern(a).equals(a)} always holds, and {@code - * intern(a) == intern(b)} if and only if {@code a.equals(b)}. Note that - * {@code intern(a)} is permitted to return one instance now and a different - * instance later if the original interned instance was garbage-collected. - * - *

Warning: do not use with mutable objects. - * - * @throws NullPointerException if {@code sample} is null - */ - E intern(E sample); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Interners.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Interners.java deleted file mode 100644 index 94531dfa02bd..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Interners.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.base.Equivalence; -import com.google.common.base.Function; -import com.google.common.collect.MapMakerInternalMap.ReferenceEntry; - -import java.util.concurrent.ConcurrentMap; - -/** - * Contains static methods pertaining to instances of {@link Interner}. - * - * @author Kevin Bourrillion - * @since 3.0 - */ -@Beta -public final class Interners { - private Interners() {} - - /** - * Returns a new thread-safe interner which retains a strong reference to each instance it has - * interned, thus preventing these instances from being garbage-collected. If this retention is - * acceptable, this implementation may perform better than {@link #newWeakInterner}. Note that - * unlike {@link String#intern}, using this interner does not consume memory in the permanent - * generation. - */ - public static Interner newStrongInterner() { - final ConcurrentMap map = new MapMaker().makeMap(); - return new Interner() { - @Override - public E intern(E sample) { - E canonical = map.putIfAbsent(checkNotNull(sample), sample); - return (canonical == null) ? sample : canonical; - } - }; - } - - /** - * Returns a new thread-safe interner which retains a weak reference to each instance it has - * interned, and so does not prevent these instances from being garbage-collected. This most - * likely does not perform as well as {@link #newStrongInterner}, but is the best alternative - * when the memory usage of that implementation is unacceptable. Note that unlike {@link - * String#intern}, using this interner does not consume memory in the permanent generation. - */ - @GwtIncompatible("java.lang.ref.WeakReference") - public static Interner newWeakInterner() { - return new WeakInterner(); - } - - private static class WeakInterner implements Interner { - // MapMaker is our friend, we know about this type - private final MapMakerInternalMap map = - new MapMaker() - .weakKeys() - .keyEquivalence(Equivalence.equals()) - .makeCustomMap(); - - @Override - public E intern(E sample) { - while (true) { - // trying to read the canonical... - ReferenceEntry entry = map.getEntry(sample); - if (entry != null) { - E canonical = entry.getKey(); - if (canonical != null) { // only matters if weak/soft keys are used - return canonical; - } - } - - // didn't see it, trying to put it instead... - Dummy sneaky = map.putIfAbsent(sample, Dummy.VALUE); - if (sneaky == null) { - return sample; - } else { - /* Someone beat us to it! Trying again... - * - * Technically this loop not guaranteed to terminate, so theoretically (extremely - * unlikely) this thread might starve, but even then, there is always going to be another - * thread doing progress here. - */ - } - } - } - - private enum Dummy { - VALUE - } - } - - /** - * Returns a function that delegates to the {@link Interner#intern} method of the given interner. - * - * @since 8.0 - */ - public static Function asFunction(Interner interner) { - return new InternerFunction(checkNotNull(interner)); - } - - private static class InternerFunction implements Function { - - private final Interner interner; - - public InternerFunction(Interner interner) { - this.interner = interner; - } - - @Override - public E apply(E input) { - return interner.intern(input); - } - - @Override - public int hashCode() { - return interner.hashCode(); - } - - @Override - public boolean equals(Object other) { - if (other instanceof InternerFunction) { - InternerFunction that = (InternerFunction) other; - return interner.equals(that.interner); - } - - return false; - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Iterables.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Iterables.java deleted file mode 100644 index a1421a055632..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Iterables.java +++ /dev/null @@ -1,1021 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.CollectPreconditions.checkRemove; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.base.Function; -import com.google.common.base.Optional; -import com.google.common.base.Predicate; - -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.Queue; -import java.util.RandomAccess; -import java.util.Set; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * This class contains static utility methods that operate on or return objects - * of type {@code Iterable}. Except as noted, each method has a corresponding - * {@link Iterator}-based method in the {@link Iterators} class. - * - *

Performance notes: Unless otherwise noted, all of the iterables - * produced in this class are lazy, which means that their iterators - * only advance the backing iteration when absolutely necessary. - * - *

See the Guava User Guide article on - * {@code Iterables}. - * - * @author Kevin Bourrillion - * @author Jared Levy - * @since 2.0 - */ -@GwtCompatible(emulated = true) -public final class Iterables { - private Iterables() {} - - /** Returns an unmodifiable view of {@code iterable}. */ - public static Iterable unmodifiableIterable(final Iterable iterable) { - checkNotNull(iterable); - if (iterable instanceof UnmodifiableIterable || iterable instanceof ImmutableCollection) { - return iterable; - } - return new UnmodifiableIterable(iterable); - } - - /** - * Simply returns its argument. - * - * @deprecated no need to use this - * @since 10.0 - */ - @Deprecated - public static Iterable unmodifiableIterable(ImmutableCollection iterable) { - return checkNotNull(iterable); - } - - private static final class UnmodifiableIterable extends FluentIterable { - private final Iterable iterable; - - private UnmodifiableIterable(Iterable iterable) { - this.iterable = iterable; - } - - @Override - public Iterator iterator() { - return Iterators.unmodifiableIterator(iterable.iterator()); - } - - @Override - public String toString() { - return iterable.toString(); - } - // no equals and hashCode; it would break the contract! - } - - /** - * Returns the number of elements in {@code iterable}. - */ - public static int size(Iterable iterable) { - return (iterable instanceof Collection) - ? ((Collection) iterable).size() - : Iterators.size(iterable.iterator()); - } - - /** - * Returns {@code true} if {@code iterable} contains any object for which {@code equals(element)} - * is true. - */ - public static boolean contains(Iterable iterable, @Nullable Object element) { - if (iterable instanceof Collection) { - Collection collection = (Collection) iterable; - return Collections2.safeContains(collection, element); - } - return Iterators.contains(iterable.iterator(), element); - } - - /** - * Removes, from an iterable, every element that belongs to the provided - * collection. - * - *

This method calls {@link Collection#removeAll} if {@code iterable} is a - * collection, and {@link Iterators#removeAll} otherwise. - * - * @param removeFrom the iterable to (potentially) remove elements from - * @param elementsToRemove the elements to remove - * @return {@code true} if any element was removed from {@code iterable} - */ - public static boolean removeAll(Iterable removeFrom, Collection elementsToRemove) { - return (removeFrom instanceof Collection) - ? ((Collection) removeFrom).removeAll(checkNotNull(elementsToRemove)) - : Iterators.removeAll(removeFrom.iterator(), elementsToRemove); - } - - /** - * Removes, from an iterable, every element that does not belong to the - * provided collection. - * - *

This method calls {@link Collection#retainAll} if {@code iterable} is a - * collection, and {@link Iterators#retainAll} otherwise. - * - * @param removeFrom the iterable to (potentially) remove elements from - * @param elementsToRetain the elements to retain - * @return {@code true} if any element was removed from {@code iterable} - */ - public static boolean retainAll(Iterable removeFrom, Collection elementsToRetain) { - return (removeFrom instanceof Collection) - ? ((Collection) removeFrom).retainAll(checkNotNull(elementsToRetain)) - : Iterators.retainAll(removeFrom.iterator(), elementsToRetain); - } - - /** - * Removes, from an iterable, every element that satisfies the provided - * predicate. - * - * @param removeFrom the iterable to (potentially) remove elements from - * @param predicate a predicate that determines whether an element should - * be removed - * @return {@code true} if any elements were removed from the iterable - * - * @throws UnsupportedOperationException if the iterable does not support - * {@code remove()}. - * @since 2.0 - */ - public static boolean removeIf(Iterable removeFrom, Predicate predicate) { - if (removeFrom instanceof RandomAccess && removeFrom instanceof List) { - return removeIfFromRandomAccessList((List) removeFrom, checkNotNull(predicate)); - } - return Iterators.removeIf(removeFrom.iterator(), predicate); - } - - private static boolean removeIfFromRandomAccessList( - List list, Predicate predicate) { - // Note: Not all random access lists support set() so we need to deal with - // those that don't and attempt the slower remove() based solution. - int from = 0; - int to = 0; - - for (; from < list.size(); from++) { - T element = list.get(from); - if (!predicate.apply(element)) { - if (from > to) { - try { - list.set(to, element); - } catch (UnsupportedOperationException e) { - slowRemoveIfForRemainingElements(list, predicate, to, from); - return true; - } - } - to++; - } - } - - // Clear the tail of any remaining items - list.subList(to, list.size()).clear(); - return from != to; - } - - private static void slowRemoveIfForRemainingElements( - List list, Predicate predicate, int to, int from) { - // Here we know that: - // * (to < from) and that both are valid indices. - // * Everything with (index < to) should be kept. - // * Everything with (to <= index < from) should be removed. - // * The element with (index == from) should be kept. - // * Everything with (index > from) has not been checked yet. - - // Check from the end of the list backwards (minimize expected cost of - // moving elements when remove() is called). Stop before 'from' because - // we already know that should be kept. - for (int n = list.size() - 1; n > from; n--) { - if (predicate.apply(list.get(n))) { - list.remove(n); - } - } - // And now remove everything in the range [to, from) (going backwards). - for (int n = from - 1; n >= to; n--) { - list.remove(n); - } - } - - /** - * Removes and returns the first matching element, or returns {@code null} if there is none. - */ - @Nullable - static T removeFirstMatching(Iterable removeFrom, Predicate predicate) { - checkNotNull(predicate); - Iterator iterator = removeFrom.iterator(); - while (iterator.hasNext()) { - T next = iterator.next(); - if (predicate.apply(next)) { - iterator.remove(); - return next; - } - } - return null; - } - - /** - * Determines whether two iterables contain equal elements in the same order. - * More specifically, this method returns {@code true} if {@code iterable1} - * and {@code iterable2} contain the same number of elements and every element - * of {@code iterable1} is equal to the corresponding element of - * {@code iterable2}. - */ - @CheckReturnValue - public static boolean elementsEqual(Iterable iterable1, Iterable iterable2) { - if (iterable1 instanceof Collection && iterable2 instanceof Collection) { - Collection collection1 = (Collection) iterable1; - Collection collection2 = (Collection) iterable2; - if (collection1.size() != collection2.size()) { - return false; - } - } - return Iterators.elementsEqual(iterable1.iterator(), iterable2.iterator()); - } - - /** - * Returns a string representation of {@code iterable}, with the format {@code - * [e1, e2, ..., en]} (that is, identical to {@link java.util.Arrays - * Arrays}{@code .toString(Iterables.toArray(iterable))}). Note that for - * most implementations of {@link Collection}, {@code - * collection.toString()} also gives the same result, but that behavior is not - * generally guaranteed. - */ - public static String toString(Iterable iterable) { - return Iterators.toString(iterable.iterator()); - } - - /** - * Returns the single element contained in {@code iterable}. - * - * @throws NoSuchElementException if the iterable is empty - * @throws IllegalArgumentException if the iterable contains multiple - * elements - */ - public static T getOnlyElement(Iterable iterable) { - return Iterators.getOnlyElement(iterable.iterator()); - } - - /** - * Returns the single element contained in {@code iterable}, or {@code - * defaultValue} if the iterable is empty. - * - * @throws IllegalArgumentException if the iterator contains multiple - * elements - */ - @Nullable - public static T getOnlyElement(Iterable iterable, @Nullable T defaultValue) { - return Iterators.getOnlyElement(iterable.iterator(), defaultValue); - } - - /** - * Copies an iterable's elements into an array. - * - * @param iterable the iterable to copy - * @param type the type of the elements - * @return a newly-allocated array into which all the elements of the iterable - * have been copied - */ - @GwtIncompatible("Array.newInstance(Class, int)") - public static T[] toArray(Iterable iterable, Class type) { - Collection collection = toCollection(iterable); - T[] array = ObjectArrays.newArray(type, collection.size()); - return collection.toArray(array); - } - - static T[] toArray(Iterable iterable, T[] array) { - Collection collection = toCollection(iterable); - return collection.toArray(array); - } - - /** - * Copies an iterable's elements into an array. - * - * @param iterable the iterable to copy - * @return a newly-allocated array into which all the elements of the iterable - * have been copied - */ - static Object[] toArray(Iterable iterable) { - return toCollection(iterable).toArray(); - } - - /** - * Converts an iterable into a collection. If the iterable is already a - * collection, it is returned. Otherwise, an {@link java.util.ArrayList} is - * created with the contents of the iterable in the same iteration order. - */ - private static Collection toCollection(Iterable iterable) { - return (iterable instanceof Collection) - ? (Collection) iterable - : Lists.newArrayList(iterable.iterator()); - } - - /** - * Adds all elements in {@code iterable} to {@code collection}. - * - * @return {@code true} if {@code collection} was modified as a result of this - * operation. - */ - public static boolean addAll(Collection addTo, Iterable elementsToAdd) { - if (elementsToAdd instanceof Collection) { - Collection c = Collections2.cast(elementsToAdd); - return addTo.addAll(c); - } - return Iterators.addAll(addTo, checkNotNull(elementsToAdd).iterator()); - } - - /** - * Returns the number of elements in the specified iterable that equal the - * specified object. This implementation avoids a full iteration when the - * iterable is a {@link Multiset} or {@link Set}. - * - * @see Collections#frequency - */ - public static int frequency(Iterable iterable, @Nullable Object element) { - if ((iterable instanceof Multiset)) { - return ((Multiset) iterable).count(element); - } else if ((iterable instanceof Set)) { - return ((Set) iterable).contains(element) ? 1 : 0; - } - return Iterators.frequency(iterable.iterator(), element); - } - - /** - * Returns an iterable whose iterators cycle indefinitely over the elements of - * {@code iterable}. - * - *

That iterator supports {@code remove()} if {@code iterable.iterator()} - * does. After {@code remove()} is called, subsequent cycles omit the removed - * element, which is no longer in {@code iterable}. The iterator's - * {@code hasNext()} method returns {@code true} until {@code iterable} is - * empty. - * - *

Warning: Typical uses of the resulting iterator may produce an - * infinite loop. You should use an explicit {@code break} or be certain that - * you will eventually remove all the elements. - * - *

To cycle over the iterable {@code n} times, use the following: - * {@code Iterables.concat(Collections.nCopies(n, iterable))} - */ - public static Iterable cycle(final Iterable iterable) { - checkNotNull(iterable); - return new FluentIterable() { - @Override - public Iterator iterator() { - return Iterators.cycle(iterable); - } - - @Override - public String toString() { - return iterable.toString() + " (cycled)"; - } - }; - } - - /** - * Returns an iterable whose iterators cycle indefinitely over the provided - * elements. - * - *

After {@code remove} is invoked on a generated iterator, the removed - * element will no longer appear in either that iterator or any other iterator - * created from the same source iterable. That is, this method behaves exactly - * as {@code Iterables.cycle(Lists.newArrayList(elements))}. The iterator's - * {@code hasNext} method returns {@code true} until all of the original - * elements have been removed. - * - *

Warning: Typical uses of the resulting iterator may produce an - * infinite loop. You should use an explicit {@code break} or be certain that - * you will eventually remove all the elements. - * - *

To cycle over the elements {@code n} times, use the following: - * {@code Iterables.concat(Collections.nCopies(n, Arrays.asList(elements)))} - */ - public static Iterable cycle(T... elements) { - return cycle(Lists.newArrayList(elements)); - } - - /** - * Combines two iterables into a single iterable. The returned iterable has an - * iterator that traverses the elements in {@code a}, followed by the elements - * in {@code b}. The source iterators are not polled until necessary. - * - *

The returned iterable's iterator supports {@code remove()} when the - * corresponding input iterator supports it. - */ - public static Iterable concat(Iterable a, Iterable b) { - return concat(ImmutableList.of(a, b)); - } - - /** - * Combines three iterables into a single iterable. The returned iterable has - * an iterator that traverses the elements in {@code a}, followed by the - * elements in {@code b}, followed by the elements in {@code c}. The source - * iterators are not polled until necessary. - * - *

The returned iterable's iterator supports {@code remove()} when the - * corresponding input iterator supports it. - */ - public static Iterable concat( - Iterable a, Iterable b, Iterable c) { - return concat(ImmutableList.of(a, b, c)); - } - - /** - * Combines four iterables into a single iterable. The returned iterable has - * an iterator that traverses the elements in {@code a}, followed by the - * elements in {@code b}, followed by the elements in {@code c}, followed by - * the elements in {@code d}. The source iterators are not polled until - * necessary. - * - *

The returned iterable's iterator supports {@code remove()} when the - * corresponding input iterator supports it. - */ - public static Iterable concat( - Iterable a, - Iterable b, - Iterable c, - Iterable d) { - return concat(ImmutableList.of(a, b, c, d)); - } - - /** - * Combines multiple iterables into a single iterable. The returned iterable - * has an iterator that traverses the elements of each iterable in - * {@code inputs}. The input iterators are not polled until necessary. - * - *

The returned iterable's iterator supports {@code remove()} when the - * corresponding input iterator supports it. - * - * @throws NullPointerException if any of the provided iterables is null - */ - public static Iterable concat(Iterable... inputs) { - return concat(ImmutableList.copyOf(inputs)); - } - - /** - * Combines multiple iterables into a single iterable. The returned iterable - * has an iterator that traverses the elements of each iterable in - * {@code inputs}. The input iterators are not polled until necessary. - * - *

The returned iterable's iterator supports {@code remove()} when the - * corresponding input iterator supports it. The methods of the returned - * iterable may throw {@code NullPointerException} if any of the input - * iterators is null. - */ - public static Iterable concat(final Iterable> inputs) { - checkNotNull(inputs); - return new FluentIterable() { - @Override - public Iterator iterator() { - return Iterators.concat(iterators(inputs)); - } - }; - } - - /** - * Returns an iterator over the iterators of the given iterables. - */ - private static Iterator> iterators( - Iterable> iterables) { - return new TransformedIterator, Iterator>( - iterables.iterator()) { - @Override - Iterator transform(Iterable from) { - return from.iterator(); - } - }; - } - - /** - * Divides an iterable into unmodifiable sublists of the given size (the final - * iterable may be smaller). For example, partitioning an iterable containing - * {@code [a, b, c, d, e]} with a partition size of 3 yields {@code - * [[a, b, c], [d, e]]} -- an outer iterable containing two inner lists of - * three and two elements, all in the original order. - * - *

Iterators returned by the returned iterable do not support the {@link - * Iterator#remove()} method. The returned lists implement {@link - * RandomAccess}, whether or not the input list does. - * - *

Note: if {@code iterable} is a {@link List}, use {@link - * Lists#partition(List, int)} instead. - * - * @param iterable the iterable to return a partitioned view of - * @param size the desired size of each partition (the last may be smaller) - * @return an iterable of unmodifiable lists containing the elements of {@code - * iterable} divided into partitions - * @throws IllegalArgumentException if {@code size} is nonpositive - */ - public static Iterable> partition(final Iterable iterable, final int size) { - checkNotNull(iterable); - checkArgument(size > 0); - return new FluentIterable>() { - @Override - public Iterator> iterator() { - return Iterators.partition(iterable.iterator(), size); - } - }; - } - - /** - * Divides an iterable into unmodifiable sublists of the given size, padding - * the final iterable with null values if necessary. For example, partitioning - * an iterable containing {@code [a, b, c, d, e]} with a partition size of 3 - * yields {@code [[a, b, c], [d, e, null]]} -- an outer iterable containing - * two inner lists of three elements each, all in the original order. - * - *

Iterators returned by the returned iterable do not support the {@link - * Iterator#remove()} method. - * - * @param iterable the iterable to return a partitioned view of - * @param size the desired size of each partition - * @return an iterable of unmodifiable lists containing the elements of {@code - * iterable} divided into partitions (the final iterable may have - * trailing null elements) - * @throws IllegalArgumentException if {@code size} is nonpositive - */ - public static Iterable> paddedPartition(final Iterable iterable, final int size) { - checkNotNull(iterable); - checkArgument(size > 0); - return new FluentIterable>() { - @Override - public Iterator> iterator() { - return Iterators.paddedPartition(iterable.iterator(), size); - } - }; - } - - /** - * Returns the elements of {@code unfiltered} that satisfy a predicate. The - * resulting iterable's iterator does not support {@code remove()}. - */ - @CheckReturnValue - public static Iterable filter( - final Iterable unfiltered, final Predicate predicate) { - checkNotNull(unfiltered); - checkNotNull(predicate); - return new FluentIterable() { - @Override - public Iterator iterator() { - return Iterators.filter(unfiltered.iterator(), predicate); - } - }; - } - - /** - * Returns all instances of class {@code type} in {@code unfiltered}. The - * returned iterable has elements whose class is {@code type} or a subclass of - * {@code type}. The returned iterable's iterator does not support - * {@code remove()}. - * - * @param unfiltered an iterable containing objects of any type - * @param type the type of elements desired - * @return an unmodifiable iterable containing all elements of the original - * iterable that were of the requested type - */ - @GwtIncompatible("Class.isInstance") - @CheckReturnValue - public static Iterable filter(final Iterable unfiltered, final Class type) { - checkNotNull(unfiltered); - checkNotNull(type); - return new FluentIterable() { - @Override - public Iterator iterator() { - return Iterators.filter(unfiltered.iterator(), type); - } - }; - } - - /** - * Returns {@code true} if any element in {@code iterable} satisfies the predicate. - */ - public static boolean any(Iterable iterable, Predicate predicate) { - return Iterators.any(iterable.iterator(), predicate); - } - - /** - * Returns {@code true} if every element in {@code iterable} satisfies the - * predicate. If {@code iterable} is empty, {@code true} is returned. - */ - public static boolean all(Iterable iterable, Predicate predicate) { - return Iterators.all(iterable.iterator(), predicate); - } - - /** - * Returns the first element in {@code iterable} that satisfies the given - * predicate; use this method only when such an element is known to exist. If - * it is possible that no element will match, use {@link #tryFind} or - * {@link #find(Iterable, Predicate, Object)} instead. - * - * @throws NoSuchElementException if no element in {@code iterable} matches - * the given predicate - */ - public static T find(Iterable iterable, Predicate predicate) { - return Iterators.find(iterable.iterator(), predicate); - } - - /** - * Returns the first element in {@code iterable} that satisfies the given - * predicate, or {@code defaultValue} if none found. Note that this can - * usually be handled more naturally using {@code - * tryFind(iterable, predicate).or(defaultValue)}. - * - * @since 7.0 - */ - @Nullable - public static T find( - Iterable iterable, Predicate predicate, @Nullable T defaultValue) { - return Iterators.find(iterable.iterator(), predicate, defaultValue); - } - - /** - * Returns an {@link Optional} containing the first element in {@code - * iterable} that satisfies the given predicate, if such an element exists. - * - *

Warning: avoid using a {@code predicate} that matches {@code - * null}. If {@code null} is matched in {@code iterable}, a - * NullPointerException will be thrown. - * - * @since 11.0 - */ - public static Optional tryFind(Iterable iterable, Predicate predicate) { - return Iterators.tryFind(iterable.iterator(), predicate); - } - - /** - * Returns the index in {@code iterable} of the first element that satisfies - * the provided {@code predicate}, or {@code -1} if the Iterable has no such - * elements. - * - *

More formally, returns the lowest index {@code i} such that - * {@code predicate.apply(Iterables.get(iterable, i))} returns {@code true}, - * or {@code -1} if there is no such index. - * - * @since 2.0 - */ - public static int indexOf(Iterable iterable, Predicate predicate) { - return Iterators.indexOf(iterable.iterator(), predicate); - } - - /** - * Returns an iterable that applies {@code function} to each element of {@code - * fromIterable}. - * - *

The returned iterable's iterator supports {@code remove()} if the - * provided iterator does. After a successful {@code remove()} call, - * {@code fromIterable} no longer contains the corresponding element. - * - *

If the input {@code Iterable} is known to be a {@code List} or other - * {@code Collection}, consider {@link Lists#transform} and {@link - * Collections2#transform}. - */ - @CheckReturnValue - public static Iterable transform( - final Iterable fromIterable, final Function function) { - checkNotNull(fromIterable); - checkNotNull(function); - return new FluentIterable() { - @Override - public Iterator iterator() { - return Iterators.transform(fromIterable.iterator(), function); - } - }; - } - - /** - * Returns the element at the specified position in an iterable. - * - * @param position position of the element to return - * @return the element at the specified position in {@code iterable} - * @throws IndexOutOfBoundsException if {@code position} is negative or - * greater than or equal to the size of {@code iterable} - */ - public static T get(Iterable iterable, int position) { - checkNotNull(iterable); - return (iterable instanceof List) - ? ((List) iterable).get(position) - : Iterators.get(iterable.iterator(), position); - } - - /** - * Returns the element at the specified position in an iterable or a default - * value otherwise. - * - * @param position position of the element to return - * @param defaultValue the default value to return if {@code position} is - * greater than or equal to the size of the iterable - * @return the element at the specified position in {@code iterable} or - * {@code defaultValue} if {@code iterable} contains fewer than - * {@code position + 1} elements. - * @throws IndexOutOfBoundsException if {@code position} is negative - * @since 4.0 - */ - @Nullable - public static T get(Iterable iterable, int position, @Nullable T defaultValue) { - checkNotNull(iterable); - Iterators.checkNonnegative(position); - if (iterable instanceof List) { - List list = Lists.cast(iterable); - return (position < list.size()) ? list.get(position) : defaultValue; - } else { - Iterator iterator = iterable.iterator(); - Iterators.advance(iterator, position); - return Iterators.getNext(iterator, defaultValue); - } - } - - /** - * Returns the first element in {@code iterable} or {@code defaultValue} if - * the iterable is empty. The {@link Iterators} analog to this method is - * {@link Iterators#getNext}. - * - *

If no default value is desired (and the caller instead wants a - * {@link NoSuchElementException} to be thrown), it is recommended that - * {@code iterable.iterator().next()} is used instead. - * - * @param defaultValue the default value to return if the iterable is empty - * @return the first element of {@code iterable} or the default value - * @since 7.0 - */ - @Nullable - public static T getFirst(Iterable iterable, @Nullable T defaultValue) { - return Iterators.getNext(iterable.iterator(), defaultValue); - } - - /** - * Returns the last element of {@code iterable}. - * - * @return the last element of {@code iterable} - * @throws NoSuchElementException if the iterable is empty - */ - public static T getLast(Iterable iterable) { - // TODO(kevinb): Support a concurrently modified collection? - if (iterable instanceof List) { - List list = (List) iterable; - if (list.isEmpty()) { - throw new NoSuchElementException(); - } - return getLastInNonemptyList(list); - } - - return Iterators.getLast(iterable.iterator()); - } - - /** - * Returns the last element of {@code iterable} or {@code defaultValue} if - * the iterable is empty. - * - * @param defaultValue the value to return if {@code iterable} is empty - * @return the last element of {@code iterable} or the default value - * @since 3.0 - */ - @Nullable - public static T getLast(Iterable iterable, @Nullable T defaultValue) { - if (iterable instanceof Collection) { - Collection c = Collections2.cast(iterable); - if (c.isEmpty()) { - return defaultValue; - } else if (iterable instanceof List) { - return getLastInNonemptyList(Lists.cast(iterable)); - } - } - - return Iterators.getLast(iterable.iterator(), defaultValue); - } - - private static T getLastInNonemptyList(List list) { - return list.get(list.size() - 1); - } - - /** - * Returns a view of {@code iterable} that skips its first - * {@code numberToSkip} elements. If {@code iterable} contains fewer than - * {@code numberToSkip} elements, the returned iterable skips all of its - * elements. - * - *

Modifications to the underlying {@link Iterable} before a call to - * {@code iterator()} are reflected in the returned iterator. That is, the - * iterator skips the first {@code numberToSkip} elements that exist when the - * {@code Iterator} is created, not when {@code skip()} is called. - * - *

The returned iterable's iterator supports {@code remove()} if the - * iterator of the underlying iterable supports it. Note that it is - * not possible to delete the last skipped element by immediately - * calling {@code remove()} on that iterator, as the {@code Iterator} - * contract states that a call to {@code remove()} before a call to - * {@code next()} will throw an {@link IllegalStateException}. - * - * @since 3.0 - */ - public static Iterable skip(final Iterable iterable, final int numberToSkip) { - checkNotNull(iterable); - checkArgument(numberToSkip >= 0, "number to skip cannot be negative"); - - if (iterable instanceof List) { - final List list = (List) iterable; - return new FluentIterable() { - @Override - public Iterator iterator() { - // TODO(kevinb): Support a concurrently modified collection? - int toSkip = Math.min(list.size(), numberToSkip); - return list.subList(toSkip, list.size()).iterator(); - } - }; - } - - return new FluentIterable() { - @Override - public Iterator iterator() { - final Iterator iterator = iterable.iterator(); - - Iterators.advance(iterator, numberToSkip); - - /* - * We can't just return the iterator because an immediate call to its - * remove() method would remove one of the skipped elements instead of - * throwing an IllegalStateException. - */ - return new Iterator() { - boolean atStart = true; - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public T next() { - T result = iterator.next(); - atStart = false; // not called if next() fails - return result; - } - - @Override - public void remove() { - checkRemove(!atStart); - iterator.remove(); - } - }; - } - }; - } - - /** - * Creates an iterable with the first {@code limitSize} elements of the given - * iterable. If the original iterable does not contain that many elements, the - * returned iterable will have the same behavior as the original iterable. The - * returned iterable's iterator supports {@code remove()} if the original - * iterator does. - * - * @param iterable the iterable to limit - * @param limitSize the maximum number of elements in the returned iterable - * @throws IllegalArgumentException if {@code limitSize} is negative - * @since 3.0 - */ - public static Iterable limit(final Iterable iterable, final int limitSize) { - checkNotNull(iterable); - checkArgument(limitSize >= 0, "limit is negative"); - return new FluentIterable() { - @Override - public Iterator iterator() { - return Iterators.limit(iterable.iterator(), limitSize); - } - }; - } - - /** - * Returns a view of the supplied iterable that wraps each generated - * {@link Iterator} through {@link Iterators#consumingIterator(Iterator)}. - * - *

Note: If {@code iterable} is a {@link Queue}, the returned iterable will - * get entries from {@link Queue#remove()} since {@link Queue}'s iteration - * order is undefined. Calling {@link Iterator#hasNext()} on a generated - * iterator from the returned iterable may cause an item to be immediately - * dequeued for return on a subsequent call to {@link Iterator#next()}. - * - * @param iterable the iterable to wrap - * @return a view of the supplied iterable that wraps each generated iterator - * through {@link Iterators#consumingIterator(Iterator)}; for queues, - * an iterable that generates iterators that return and consume the - * queue's elements in queue order - * - * @see Iterators#consumingIterator(Iterator) - * @since 2.0 - */ - public static Iterable consumingIterable(final Iterable iterable) { - if (iterable instanceof Queue) { - return new FluentIterable() { - @Override - public Iterator iterator() { - return new ConsumingQueueIterator((Queue) iterable); - } - - @Override - public String toString() { - return "Iterables.consumingIterable(...)"; - } - }; - } - - checkNotNull(iterable); - - return new FluentIterable() { - @Override - public Iterator iterator() { - return Iterators.consumingIterator(iterable.iterator()); - } - - @Override - public String toString() { - return "Iterables.consumingIterable(...)"; - } - }; - } - - // Methods only in Iterables, not in Iterators - - /** - * Determines if the given iterable contains no elements. - * - *

There is no precise {@link Iterator} equivalent to this method, since - * one can only ask an iterator whether it has any elements remaining - * (which one does using {@link Iterator#hasNext}). - * - * @return {@code true} if the iterable contains no elements - */ - public static boolean isEmpty(Iterable iterable) { - if (iterable instanceof Collection) { - return ((Collection) iterable).isEmpty(); - } - return !iterable.iterator().hasNext(); - } - - /** - * Returns an iterable over the merged contents of all given - * {@code iterables}. Equivalent entries will not be de-duplicated. - * - *

Callers must ensure that the source {@code iterables} are in - * non-descending order as this method does not sort its input. - * - *

For any equivalent elements across all {@code iterables}, it is - * undefined which element is returned first. - * - * @since 11.0 - */ - @Beta - public static Iterable mergeSorted( - final Iterable> iterables, - final Comparator comparator) { - checkNotNull(iterables, "iterables"); - checkNotNull(comparator, "comparator"); - Iterable iterable = - new FluentIterable() { - @Override - public Iterator iterator() { - return Iterators.mergeSorted( - Iterables.transform(iterables, Iterables.toIterator()), - comparator); - } - }; - return new UnmodifiableIterable(iterable); - } - - // TODO(user): Is this the best place for this? Move to fluent functions? - // Useful as a public method? - private static Function, Iterator> toIterator() { - return new Function, Iterator>() { - @Override - public Iterator apply(Iterable iterable) { - return iterable.iterator(); - } - }; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Iterators.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Iterators.java deleted file mode 100644 index c94b1e89e9ec..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Iterators.java +++ /dev/null @@ -1,1339 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; -import static com.google.common.base.Predicates.equalTo; -import static com.google.common.base.Predicates.in; -import static com.google.common.base.Predicates.instanceOf; -import static com.google.common.base.Predicates.not; -import static com.google.common.collect.CollectPreconditions.checkRemove; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.base.Function; -import com.google.common.base.Objects; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.base.Predicate; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.NoSuchElementException; -import java.util.PriorityQueue; -import java.util.Queue; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * This class contains static utility methods that operate on or return objects - * of type {@link Iterator}. Except as noted, each method has a corresponding - * {@link Iterable}-based method in the {@link Iterables} class. - * - *

Performance notes: Unless otherwise noted, all of the iterators - * produced in this class are lazy, which means that they only advance - * the backing iteration when absolutely necessary. - * - *

See the Guava User Guide section on - * {@code Iterators}. - * - * @author Kevin Bourrillion - * @author Jared Levy - * @since 2.0 - */ -@GwtCompatible(emulated = true) -public final class Iterators { - private Iterators() {} - - static final UnmodifiableListIterator EMPTY_LIST_ITERATOR = - new UnmodifiableListIterator() { - @Override - public boolean hasNext() { - return false; - } - - @Override - public Object next() { - throw new NoSuchElementException(); - } - - @Override - public boolean hasPrevious() { - return false; - } - - @Override - public Object previous() { - throw new NoSuchElementException(); - } - - @Override - public int nextIndex() { - return 0; - } - - @Override - public int previousIndex() { - return -1; - } - }; - - /** - * Returns the empty iterator. - * - *

The {@link Iterable} equivalent of this method is {@link - * ImmutableSet#of()}. - * - * @deprecated Use {@code ImmutableSet.of().iterator()} instead; or for - * Java 7 or later, {@link Collections#emptyIterator}. This method is - * scheduled for removal in May 2016. - */ - @Deprecated - public static UnmodifiableIterator emptyIterator() { - return emptyListIterator(); - } - - /** - * Returns the empty iterator. - * - *

The {@link Iterable} equivalent of this method is {@link - * ImmutableSet#of()}. - */ - // Casting to any type is safe since there are no actual elements. - @SuppressWarnings("unchecked") - static UnmodifiableListIterator emptyListIterator() { - return (UnmodifiableListIterator) EMPTY_LIST_ITERATOR; - } - - private static final Iterator EMPTY_MODIFIABLE_ITERATOR = - new Iterator() { - @Override - public boolean hasNext() { - return false; - } - - @Override - public Object next() { - throw new NoSuchElementException(); - } - - @Override - public void remove() { - checkRemove(false); - } - }; - - /** - * Returns the empty {@code Iterator} that throws - * {@link IllegalStateException} instead of - * {@link UnsupportedOperationException} on a call to - * {@link Iterator#remove()}. - */ - // Casting to any type is safe since there are no actual elements. - @SuppressWarnings("unchecked") - static Iterator emptyModifiableIterator() { - return (Iterator) EMPTY_MODIFIABLE_ITERATOR; - } - - /** Returns an unmodifiable view of {@code iterator}. */ - public static UnmodifiableIterator unmodifiableIterator(final Iterator iterator) { - checkNotNull(iterator); - if (iterator instanceof UnmodifiableIterator) { - return (UnmodifiableIterator) iterator; - } - return new UnmodifiableIterator() { - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public T next() { - return iterator.next(); - } - }; - } - - /** - * Simply returns its argument. - * - * @deprecated no need to use this - * @since 10.0 - */ - @Deprecated - public static UnmodifiableIterator unmodifiableIterator(UnmodifiableIterator iterator) { - return checkNotNull(iterator); - } - - /** - * Returns the number of elements remaining in {@code iterator}. The iterator - * will be left exhausted: its {@code hasNext()} method will return - * {@code false}. - */ - public static int size(Iterator iterator) { - int count = 0; - while (iterator.hasNext()) { - iterator.next(); - count++; - } - return count; - } - - /** - * Returns {@code true} if {@code iterator} contains {@code element}. - */ - public static boolean contains(Iterator iterator, @Nullable Object element) { - return any(iterator, equalTo(element)); - } - - /** - * Traverses an iterator and removes every element that belongs to the - * provided collection. The iterator will be left exhausted: its - * {@code hasNext()} method will return {@code false}. - * - * @param removeFrom the iterator to (potentially) remove elements from - * @param elementsToRemove the elements to remove - * @return {@code true} if any element was removed from {@code iterator} - */ - public static boolean removeAll(Iterator removeFrom, Collection elementsToRemove) { - return removeIf(removeFrom, in(elementsToRemove)); - } - - /** - * Removes every element that satisfies the provided predicate from the - * iterator. The iterator will be left exhausted: its {@code hasNext()} - * method will return {@code false}. - * - * @param removeFrom the iterator to (potentially) remove elements from - * @param predicate a predicate that determines whether an element should - * be removed - * @return {@code true} if any elements were removed from the iterator - * @since 2.0 - */ - public static boolean removeIf(Iterator removeFrom, Predicate predicate) { - checkNotNull(predicate); - boolean modified = false; - while (removeFrom.hasNext()) { - if (predicate.apply(removeFrom.next())) { - removeFrom.remove(); - modified = true; - } - } - return modified; - } - - /** - * Traverses an iterator and removes every element that does not belong to the - * provided collection. The iterator will be left exhausted: its - * {@code hasNext()} method will return {@code false}. - * - * @param removeFrom the iterator to (potentially) remove elements from - * @param elementsToRetain the elements to retain - * @return {@code true} if any element was removed from {@code iterator} - */ - public static boolean retainAll(Iterator removeFrom, Collection elementsToRetain) { - return removeIf(removeFrom, not(in(elementsToRetain))); - } - - /** - * Determines whether two iterators contain equal elements in the same order. - * More specifically, this method returns {@code true} if {@code iterator1} - * and {@code iterator2} contain the same number of elements and every element - * of {@code iterator1} is equal to the corresponding element of - * {@code iterator2}. - * - *

Note that this will modify the supplied iterators, since they will have - * been advanced some number of elements forward. - */ - public static boolean elementsEqual(Iterator iterator1, Iterator iterator2) { - while (iterator1.hasNext()) { - if (!iterator2.hasNext()) { - return false; - } - Object o1 = iterator1.next(); - Object o2 = iterator2.next(); - if (!Objects.equal(o1, o2)) { - return false; - } - } - return !iterator2.hasNext(); - } - - /** - * Returns a string representation of {@code iterator}, with the format - * {@code [e1, e2, ..., en]}. The iterator will be left exhausted: its - * {@code hasNext()} method will return {@code false}. - */ - public static String toString(Iterator iterator) { - return Collections2.STANDARD_JOINER - .appendTo(new StringBuilder().append('['), iterator) - .append(']') - .toString(); - } - - /** - * Returns the single element contained in {@code iterator}. - * - * @throws NoSuchElementException if the iterator is empty - * @throws IllegalArgumentException if the iterator contains multiple - * elements. The state of the iterator is unspecified. - */ - public static T getOnlyElement(Iterator iterator) { - T first = iterator.next(); - if (!iterator.hasNext()) { - return first; - } - - StringBuilder sb = new StringBuilder(); - sb.append("expected one element but was: <" + first); - for (int i = 0; i < 4 && iterator.hasNext(); i++) { - sb.append(", " + iterator.next()); - } - if (iterator.hasNext()) { - sb.append(", ..."); - } - sb.append('>'); - - throw new IllegalArgumentException(sb.toString()); - } - - /** - * Returns the single element contained in {@code iterator}, or {@code - * defaultValue} if the iterator is empty. - * - * @throws IllegalArgumentException if the iterator contains multiple - * elements. The state of the iterator is unspecified. - */ - @Nullable - public static T getOnlyElement(Iterator iterator, @Nullable T defaultValue) { - return iterator.hasNext() ? getOnlyElement(iterator) : defaultValue; - } - - /** - * Copies an iterator's elements into an array. The iterator will be left - * exhausted: its {@code hasNext()} method will return {@code false}. - * - * @param iterator the iterator to copy - * @param type the type of the elements - * @return a newly-allocated array into which all the elements of the iterator - * have been copied - */ - @GwtIncompatible("Array.newInstance(Class, int)") - public static T[] toArray(Iterator iterator, Class type) { - List list = Lists.newArrayList(iterator); - return Iterables.toArray(list, type); - } - - /** - * Adds all elements in {@code iterator} to {@code collection}. The iterator - * will be left exhausted: its {@code hasNext()} method will return - * {@code false}. - * - * @return {@code true} if {@code collection} was modified as a result of this - * operation - */ - public static boolean addAll(Collection addTo, Iterator iterator) { - checkNotNull(addTo); - checkNotNull(iterator); - boolean wasModified = false; - while (iterator.hasNext()) { - wasModified |= addTo.add(iterator.next()); - } - return wasModified; - } - - /** - * Returns the number of elements in the specified iterator that equal the - * specified object. The iterator will be left exhausted: its - * {@code hasNext()} method will return {@code false}. - * - * @see Collections#frequency - */ - public static int frequency(Iterator iterator, @Nullable Object element) { - return size(filter(iterator, equalTo(element))); - } - - /** - * Returns an iterator that cycles indefinitely over the elements of {@code - * iterable}. - * - *

The returned iterator supports {@code remove()} if the provided iterator - * does. After {@code remove()} is called, subsequent cycles omit the removed - * element, which is no longer in {@code iterable}. The iterator's - * {@code hasNext()} method returns {@code true} until {@code iterable} is - * empty. - * - *

Warning: Typical uses of the resulting iterator may produce an - * infinite loop. You should use an explicit {@code break} or be certain that - * you will eventually remove all the elements. - */ - public static Iterator cycle(final Iterable iterable) { - checkNotNull(iterable); - return new Iterator() { - Iterator iterator = emptyModifiableIterator(); - - @Override - public boolean hasNext() { - /* - * Don't store a new Iterator until we know the user can't remove() the last returned - * element anymore. Otherwise, when we remove from the old iterator, we may be invalidating - * the new one. The result is a ConcurrentModificationException or other bad behavior. - * - * (If we decide that we really, really hate allocating two Iterators per cycle instead of - * one, we can optimistically store the new Iterator and then be willing to throw it out if - * the user calls remove().) - */ - return iterator.hasNext() || iterable.iterator().hasNext(); - } - - @Override - public T next() { - if (!iterator.hasNext()) { - iterator = iterable.iterator(); - if (!iterator.hasNext()) { - throw new NoSuchElementException(); - } - } - return iterator.next(); - } - - @Override - public void remove() { - iterator.remove(); - } - }; - } - - /** - * Returns an iterator that cycles indefinitely over the provided elements. - * - *

The returned iterator supports {@code remove()}. After {@code remove()} - * is called, subsequent cycles omit the removed - * element, but {@code elements} does not change. The iterator's - * {@code hasNext()} method returns {@code true} until all of the original - * elements have been removed. - * - *

Warning: Typical uses of the resulting iterator may produce an - * infinite loop. You should use an explicit {@code break} or be certain that - * you will eventually remove all the elements. - */ - public static Iterator cycle(T... elements) { - return cycle(Lists.newArrayList(elements)); - } - - /** - * Combines two iterators into a single iterator. The returned iterator - * iterates across the elements in {@code a}, followed by the elements in - * {@code b}. The source iterators are not polled until necessary. - * - *

The returned iterator supports {@code remove()} when the corresponding - * input iterator supports it. - * - *

Note: the current implementation is not suitable for nested - * concatenated iterators, i.e. the following should be avoided when in a loop: - * {@code iterator = Iterators.concat(iterator, suffix);}, since iteration over the - * resulting iterator has a cubic complexity to the depth of the nesting. - */ - public static Iterator concat(Iterator a, Iterator b) { - checkNotNull(a); - checkNotNull(b); - return concat(new ConsumingQueueIterator>(a, b)); - } - - /** - * Combines three iterators into a single iterator. The returned iterator - * iterates across the elements in {@code a}, followed by the elements in - * {@code b}, followed by the elements in {@code c}. The source iterators - * are not polled until necessary. - * - *

The returned iterator supports {@code remove()} when the corresponding - * input iterator supports it. - * - *

Note: the current implementation is not suitable for nested - * concatenated iterators, i.e. the following should be avoided when in a loop: - * {@code iterator = Iterators.concat(iterator, suffix);}, since iteration over the - * resulting iterator has a cubic complexity to the depth of the nesting. - */ - public static Iterator concat( - Iterator a, Iterator b, Iterator c) { - checkNotNull(a); - checkNotNull(b); - checkNotNull(c); - return concat(new ConsumingQueueIterator>(a, b, c)); - } - - /** - * Combines four iterators into a single iterator. The returned iterator - * iterates across the elements in {@code a}, followed by the elements in - * {@code b}, followed by the elements in {@code c}, followed by the elements - * in {@code d}. The source iterators are not polled until necessary. - * - *

The returned iterator supports {@code remove()} when the corresponding - * input iterator supports it. - * - *

Note: the current implementation is not suitable for nested - * concatenated iterators, i.e. the following should be avoided when in a loop: - * {@code iterator = Iterators.concat(iterator, suffix);}, since iteration over the - * resulting iterator has a cubic complexity to the depth of the nesting. - */ - public static Iterator concat( - Iterator a, - Iterator b, - Iterator c, - Iterator d) { - checkNotNull(a); - checkNotNull(b); - checkNotNull(c); - checkNotNull(d); - return concat(new ConsumingQueueIterator>(a, b, c, d)); - } - - /** - * Combines multiple iterators into a single iterator. The returned iterator - * iterates across the elements of each iterator in {@code inputs}. The input - * iterators are not polled until necessary. - * - *

The returned iterator supports {@code remove()} when the corresponding - * input iterator supports it. - * - *

Note: the current implementation is not suitable for nested - * concatenated iterators, i.e. the following should be avoided when in a loop: - * {@code iterator = Iterators.concat(iterator, suffix);}, since iteration over the - * resulting iterator has a cubic complexity to the depth of the nesting. - * - * @throws NullPointerException if any of the provided iterators is null - */ - public static Iterator concat(Iterator... inputs) { - for (Iterator input : checkNotNull(inputs)) { - checkNotNull(input); - } - return concat(new ConsumingQueueIterator>(inputs)); - } - - /** - * Combines multiple iterators into a single iterator. The returned iterator - * iterates across the elements of each iterator in {@code inputs}. The input - * iterators are not polled until necessary. - * - *

The returned iterator supports {@code remove()} when the corresponding - * input iterator supports it. The methods of the returned iterator may throw - * {@code NullPointerException} if any of the input iterators is null. - * - *

Note: the current implementation is not suitable for nested - * concatenated iterators, i.e. the following should be avoided when in a loop: - * {@code iterator = Iterators.concat(iterator, suffix);}, since iteration over the - * resulting iterator has a cubic complexity to the depth of the nesting. - */ - public static Iterator concat(final Iterator> inputs) { - checkNotNull(inputs); - return new Iterator() { - Iterator current = emptyIterator(); - Iterator removeFrom; - - @Override - public boolean hasNext() { - // http://code.google.com/p/google-collections/issues/detail?id=151 - // current.hasNext() might be relatively expensive, worth minimizing. - boolean currentHasNext; - // checkNotNull eager for GWT - // note: it must be here & not where 'current' is assigned, - // because otherwise we'll have called inputs.next() before throwing - // the first NPE, and the next time around we'll call inputs.next() - // again, incorrectly moving beyond the error. - while (!(currentHasNext = checkNotNull(current).hasNext()) && inputs.hasNext()) { - current = inputs.next(); - } - return currentHasNext; - } - - @Override - public T next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - removeFrom = current; - return current.next(); - } - - @Override - public void remove() { - checkRemove(removeFrom != null); - removeFrom.remove(); - removeFrom = null; - } - }; - } - - /** - * Divides an iterator into unmodifiable sublists of the given size (the final - * list may be smaller). For example, partitioning an iterator containing - * {@code [a, b, c, d, e]} with a partition size of 3 yields {@code - * [[a, b, c], [d, e]]} -- an outer iterator containing two inner lists of - * three and two elements, all in the original order. - * - *

The returned lists implement {@link java.util.RandomAccess}. - * - * @param iterator the iterator to return a partitioned view of - * @param size the desired size of each partition (the last may be smaller) - * @return an iterator of immutable lists containing the elements of {@code - * iterator} divided into partitions - * @throws IllegalArgumentException if {@code size} is nonpositive - */ - public static UnmodifiableIterator> partition(Iterator iterator, int size) { - return partitionImpl(iterator, size, false); - } - - /** - * Divides an iterator into unmodifiable sublists of the given size, padding - * the final iterator with null values if necessary. For example, partitioning - * an iterator containing {@code [a, b, c, d, e]} with a partition size of 3 - * yields {@code [[a, b, c], [d, e, null]]} -- an outer iterator containing - * two inner lists of three elements each, all in the original order. - * - *

The returned lists implement {@link java.util.RandomAccess}. - * - * @param iterator the iterator to return a partitioned view of - * @param size the desired size of each partition - * @return an iterator of immutable lists containing the elements of {@code - * iterator} divided into partitions (the final iterable may have - * trailing null elements) - * @throws IllegalArgumentException if {@code size} is nonpositive - */ - public static UnmodifiableIterator> paddedPartition(Iterator iterator, int size) { - return partitionImpl(iterator, size, true); - } - - private static UnmodifiableIterator> partitionImpl( - final Iterator iterator, final int size, final boolean pad) { - checkNotNull(iterator); - checkArgument(size > 0); - return new UnmodifiableIterator>() { - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public List next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - Object[] array = new Object[size]; - int count = 0; - for (; count < size && iterator.hasNext(); count++) { - array[count] = iterator.next(); - } - for (int i = count; i < size; i++) { - array[i] = null; // for GWT - } - - @SuppressWarnings("unchecked") // we only put Ts in it - List list = Collections.unmodifiableList((List) Arrays.asList(array)); - return (pad || count == size) ? list : list.subList(0, count); - } - }; - } - - /** - * Returns the elements of {@code unfiltered} that satisfy a predicate. - */ - @CheckReturnValue - public static UnmodifiableIterator filter( - final Iterator unfiltered, final Predicate predicate) { - checkNotNull(unfiltered); - checkNotNull(predicate); - return new AbstractIterator() { - @Override - protected T computeNext() { - while (unfiltered.hasNext()) { - T element = unfiltered.next(); - if (predicate.apply(element)) { - return element; - } - } - return endOfData(); - } - }; - } - - /** - * Returns all instances of class {@code type} in {@code unfiltered}. The - * returned iterator has elements whose class is {@code type} or a subclass of - * {@code type}. - * - * @param unfiltered an iterator containing objects of any type - * @param type the type of elements desired - * @return an unmodifiable iterator containing all elements of the original - * iterator that were of the requested type - */ - @SuppressWarnings("unchecked") // can cast to because non-Ts are removed - @GwtIncompatible("Class.isInstance") - @CheckReturnValue - public static UnmodifiableIterator filter(Iterator unfiltered, Class type) { - return (UnmodifiableIterator) filter(unfiltered, instanceOf(type)); - } - - /** - * Returns {@code true} if one or more elements returned by {@code iterator} - * satisfy the given predicate. - */ - public static boolean any(Iterator iterator, Predicate predicate) { - return indexOf(iterator, predicate) != -1; - } - - /** - * Returns {@code true} if every element returned by {@code iterator} - * satisfies the given predicate. If {@code iterator} is empty, {@code true} - * is returned. - */ - public static boolean all(Iterator iterator, Predicate predicate) { - checkNotNull(predicate); - while (iterator.hasNext()) { - T element = iterator.next(); - if (!predicate.apply(element)) { - return false; - } - } - return true; - } - - /** - * Returns the first element in {@code iterator} that satisfies the given - * predicate; use this method only when such an element is known to exist. If - * no such element is found, the iterator will be left exhausted: its {@code - * hasNext()} method will return {@code false}. If it is possible that - * no element will match, use {@link #tryFind} or {@link - * #find(Iterator, Predicate, Object)} instead. - * - * @throws NoSuchElementException if no element in {@code iterator} matches - * the given predicate - */ - public static T find(Iterator iterator, Predicate predicate) { - return filter(iterator, predicate).next(); - } - - /** - * Returns the first element in {@code iterator} that satisfies the given - * predicate. If no such element is found, {@code defaultValue} will be - * returned from this method and the iterator will be left exhausted: its - * {@code hasNext()} method will return {@code false}. Note that this can - * usually be handled more naturally using {@code - * tryFind(iterator, predicate).or(defaultValue)}. - * - * @since 7.0 - */ - @Nullable - public static T find( - Iterator iterator, Predicate predicate, @Nullable T defaultValue) { - return getNext(filter(iterator, predicate), defaultValue); - } - - /** - * Returns an {@link Optional} containing the first element in {@code - * iterator} that satisfies the given predicate, if such an element exists. If - * no such element is found, an empty {@link Optional} will be returned from - * this method and the iterator will be left exhausted: its {@code - * hasNext()} method will return {@code false}. - * - *

Warning: avoid using a {@code predicate} that matches {@code - * null}. If {@code null} is matched in {@code iterator}, a - * NullPointerException will be thrown. - * - * @since 11.0 - */ - public static Optional tryFind(Iterator iterator, Predicate predicate) { - UnmodifiableIterator filteredIterator = filter(iterator, predicate); - return filteredIterator.hasNext() - ? Optional.of(filteredIterator.next()) - : Optional.absent(); - } - - /** - * Returns the index in {@code iterator} of the first element that satisfies - * the provided {@code predicate}, or {@code -1} if the Iterator has no such - * elements. - * - *

More formally, returns the lowest index {@code i} such that - * {@code predicate.apply(Iterators.get(iterator, i))} returns {@code true}, - * or {@code -1} if there is no such index. - * - *

If -1 is returned, the iterator will be left exhausted: its - * {@code hasNext()} method will return {@code false}. Otherwise, - * the iterator will be set to the element which satisfies the - * {@code predicate}. - * - * @since 2.0 - */ - public static int indexOf(Iterator iterator, Predicate predicate) { - checkNotNull(predicate, "predicate"); - for (int i = 0; iterator.hasNext(); i++) { - T current = iterator.next(); - if (predicate.apply(current)) { - return i; - } - } - return -1; - } - - /** - * Returns an iterator that applies {@code function} to each element of {@code - * fromIterator}. - * - *

The returned iterator supports {@code remove()} if the provided iterator - * does. After a successful {@code remove()} call, {@code fromIterator} no - * longer contains the corresponding element. - */ - public static Iterator transform( - final Iterator fromIterator, final Function function) { - checkNotNull(function); - return new TransformedIterator(fromIterator) { - @Override - T transform(F from) { - return function.apply(from); - } - }; - } - - /** - * Advances {@code iterator} {@code position + 1} times, returning the - * element at the {@code position}th position. - * - * @param position position of the element to return - * @return the element at the specified position in {@code iterator} - * @throws IndexOutOfBoundsException if {@code position} is negative or - * greater than or equal to the number of elements remaining in - * {@code iterator} - */ - public static T get(Iterator iterator, int position) { - checkNonnegative(position); - int skipped = advance(iterator, position); - if (!iterator.hasNext()) { - throw new IndexOutOfBoundsException( - "position (" - + position - + ") must be less than the number of elements that remained (" - + skipped - + ")"); - } - return iterator.next(); - } - - static void checkNonnegative(int position) { - if (position < 0) { - throw new IndexOutOfBoundsException("position (" + position + ") must not be negative"); - } - } - - /** - * Advances {@code iterator} {@code position + 1} times, returning the - * element at the {@code position}th position or {@code defaultValue} - * otherwise. - * - * @param position position of the element to return - * @param defaultValue the default value to return if the iterator is empty - * or if {@code position} is greater than the number of elements - * remaining in {@code iterator} - * @return the element at the specified position in {@code iterator} or - * {@code defaultValue} if {@code iterator} produces fewer than - * {@code position + 1} elements. - * @throws IndexOutOfBoundsException if {@code position} is negative - * @since 4.0 - */ - @Nullable - public static T get(Iterator iterator, int position, @Nullable T defaultValue) { - checkNonnegative(position); - advance(iterator, position); - return getNext(iterator, defaultValue); - } - - /** - * Returns the next element in {@code iterator} or {@code defaultValue} if - * the iterator is empty. The {@link Iterables} analog to this method is - * {@link Iterables#getFirst}. - * - * @param defaultValue the default value to return if the iterator is empty - * @return the next element of {@code iterator} or the default value - * @since 7.0 - */ - @Nullable - public static T getNext(Iterator iterator, @Nullable T defaultValue) { - return iterator.hasNext() ? iterator.next() : defaultValue; - } - - /** - * Advances {@code iterator} to the end, returning the last element. - * - * @return the last element of {@code iterator} - * @throws NoSuchElementException if the iterator is empty - */ - public static T getLast(Iterator iterator) { - while (true) { - T current = iterator.next(); - if (!iterator.hasNext()) { - return current; - } - } - } - - /** - * Advances {@code iterator} to the end, returning the last element or - * {@code defaultValue} if the iterator is empty. - * - * @param defaultValue the default value to return if the iterator is empty - * @return the last element of {@code iterator} - * @since 3.0 - */ - @Nullable - public static T getLast(Iterator iterator, @Nullable T defaultValue) { - return iterator.hasNext() ? getLast(iterator) : defaultValue; - } - - /** - * Calls {@code next()} on {@code iterator}, either {@code numberToAdvance} times - * or until {@code hasNext()} returns {@code false}, whichever comes first. - * - * @return the number of elements the iterator was advanced - * @since 13.0 (since 3.0 as {@code Iterators.skip}) - */ - public static int advance(Iterator iterator, int numberToAdvance) { - checkNotNull(iterator); - checkArgument(numberToAdvance >= 0, "numberToAdvance must be nonnegative"); - - int i; - for (i = 0; i < numberToAdvance && iterator.hasNext(); i++) { - iterator.next(); - } - return i; - } - - /** - * Creates an iterator returning the first {@code limitSize} elements of the - * given iterator. If the original iterator does not contain that many - * elements, the returned iterator will have the same behavior as the original - * iterator. The returned iterator supports {@code remove()} if the original - * iterator does. - * - * @param iterator the iterator to limit - * @param limitSize the maximum number of elements in the returned iterator - * @throws IllegalArgumentException if {@code limitSize} is negative - * @since 3.0 - */ - public static Iterator limit(final Iterator iterator, final int limitSize) { - checkNotNull(iterator); - checkArgument(limitSize >= 0, "limit is negative"); - return new Iterator() { - private int count; - - @Override - public boolean hasNext() { - return count < limitSize && iterator.hasNext(); - } - - @Override - public T next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - count++; - return iterator.next(); - } - - @Override - public void remove() { - iterator.remove(); - } - }; - } - - /** - * Returns a view of the supplied {@code iterator} that removes each element - * from the supplied {@code iterator} as it is returned. - * - *

The provided iterator must support {@link Iterator#remove()} or - * else the returned iterator will fail on the first call to {@code - * next}. - * - * @param iterator the iterator to remove and return elements from - * @return an iterator that removes and returns elements from the - * supplied iterator - * @since 2.0 - */ - public static Iterator consumingIterator(final Iterator iterator) { - checkNotNull(iterator); - return new UnmodifiableIterator() { - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public T next() { - T next = iterator.next(); - iterator.remove(); - return next; - } - - @Override - public String toString() { - return "Iterators.consumingIterator(...)"; - } - }; - } - - /** - * Deletes and returns the next value from the iterator, or returns - * {@code null} if there is no such value. - */ - @Nullable - static T pollNext(Iterator iterator) { - if (iterator.hasNext()) { - T result = iterator.next(); - iterator.remove(); - return result; - } else { - return null; - } - } - - // Methods only in Iterators, not in Iterables - - /** - * Clears the iterator using its remove method. - */ - static void clear(Iterator iterator) { - checkNotNull(iterator); - while (iterator.hasNext()) { - iterator.next(); - iterator.remove(); - } - } - - /** - * Returns an iterator containing the elements of {@code array} in order. The - * returned iterator is a view of the array; subsequent changes to the array - * will be reflected in the iterator. - * - *

Note: It is often preferable to represent your data using a - * collection type, for example using {@link Arrays#asList(Object[])}, making - * this method unnecessary. - * - *

The {@code Iterable} equivalent of this method is either {@link - * Arrays#asList(Object[])}, {@link ImmutableList#copyOf(Object[])}}, - * or {@link ImmutableList#of}. - */ - public static UnmodifiableIterator forArray(final T... array) { - return forArray(array, 0, array.length, 0); - } - - /** - * Returns a list iterator containing the elements in the specified range of - * {@code array} in order, starting at the specified index. - * - *

The {@code Iterable} equivalent of this method is {@code - * Arrays.asList(array).subList(offset, offset + length).listIterator(index)}. - */ - static UnmodifiableListIterator forArray( - final T[] array, final int offset, int length, int index) { - checkArgument(length >= 0); - int end = offset + length; - - // Technically we should give a slightly more descriptive error on overflow - Preconditions.checkPositionIndexes(offset, end, array.length); - Preconditions.checkPositionIndex(index, length); - if (length == 0) { - return emptyListIterator(); - } - - /* - * We can't use call the two-arg constructor with arguments (offset, end) - * because the returned Iterator is a ListIterator that may be moved back - * past the beginning of the iteration. - */ - return new AbstractIndexedListIterator(length, index) { - @Override - protected T get(int index) { - return array[offset + index]; - } - }; - } - - /** - * Returns an iterator containing only {@code value}. - * - *

The {@link Iterable} equivalent of this method is {@link - * Collections#singleton}. - */ - public static UnmodifiableIterator singletonIterator(@Nullable final T value) { - return new UnmodifiableIterator() { - boolean done; - - @Override - public boolean hasNext() { - return !done; - } - - @Override - public T next() { - if (done) { - throw new NoSuchElementException(); - } - done = true; - return value; - } - }; - } - - /** - * Adapts an {@code Enumeration} to the {@code Iterator} interface. - * - *

This method has no equivalent in {@link Iterables} because viewing an - * {@code Enumeration} as an {@code Iterable} is impossible. However, the - * contents can be copied into a collection using {@link - * Collections#list}. - */ - public static UnmodifiableIterator forEnumeration(final Enumeration enumeration) { - checkNotNull(enumeration); - return new UnmodifiableIterator() { - @Override - public boolean hasNext() { - return enumeration.hasMoreElements(); - } - - @Override - public T next() { - return enumeration.nextElement(); - } - }; - } - - /** - * Adapts an {@code Iterator} to the {@code Enumeration} interface. - * - *

The {@code Iterable} equivalent of this method is either {@link - * Collections#enumeration} (if you have a {@link Collection}), or - * {@code Iterators.asEnumeration(collection.iterator())}. - */ - public static Enumeration asEnumeration(final Iterator iterator) { - checkNotNull(iterator); - return new Enumeration() { - @Override - public boolean hasMoreElements() { - return iterator.hasNext(); - } - - @Override - public T nextElement() { - return iterator.next(); - } - }; - } - - /** - * Implementation of PeekingIterator that avoids peeking unless necessary. - */ - private static class PeekingImpl implements PeekingIterator { - - private final Iterator iterator; - private boolean hasPeeked; - private E peekedElement; - - public PeekingImpl(Iterator iterator) { - this.iterator = checkNotNull(iterator); - } - - @Override - public boolean hasNext() { - return hasPeeked || iterator.hasNext(); - } - - @Override - public E next() { - if (!hasPeeked) { - return iterator.next(); - } - E result = peekedElement; - hasPeeked = false; - peekedElement = null; - return result; - } - - @Override - public void remove() { - checkState(!hasPeeked, "Can't remove after you've peeked at next"); - iterator.remove(); - } - - @Override - public E peek() { - if (!hasPeeked) { - peekedElement = iterator.next(); - hasPeeked = true; - } - return peekedElement; - } - } - - /** - * Returns a {@code PeekingIterator} backed by the given iterator. - * - *

Calls to the {@code peek} method with no intervening calls to {@code - * next} do not affect the iteration, and hence return the same object each - * time. A subsequent call to {@code next} is guaranteed to return the same - * object again. For example:

   {@code
-   *
-   *   PeekingIterator peekingIterator =
-   *       Iterators.peekingIterator(Iterators.forArray("a", "b"));
-   *   String a1 = peekingIterator.peek(); // returns "a"
-   *   String a2 = peekingIterator.peek(); // also returns "a"
-   *   String a3 = peekingIterator.next(); // also returns "a"}
- * - *

Any structural changes to the underlying iteration (aside from those - * performed by the iterator's own {@link PeekingIterator#remove()} method) - * will leave the iterator in an undefined state. - * - *

The returned iterator does not support removal after peeking, as - * explained by {@link PeekingIterator#remove()}. - * - *

Note: If the given iterator is already a {@code PeekingIterator}, - * it might be returned to the caller, although this is neither - * guaranteed to occur nor required to be consistent. For example, this - * method might choose to pass through recognized implementations of - * {@code PeekingIterator} when the behavior of the implementation is - * known to meet the contract guaranteed by this method. - * - *

There is no {@link Iterable} equivalent to this method, so use this - * method to wrap each individual iterator as it is generated. - * - * @param iterator the backing iterator. The {@link PeekingIterator} assumes - * ownership of this iterator, so users should cease making direct calls - * to it after calling this method. - * @return a peeking iterator backed by that iterator. Apart from the - * additional {@link PeekingIterator#peek()} method, this iterator behaves - * exactly the same as {@code iterator}. - */ - public static PeekingIterator peekingIterator(Iterator iterator) { - if (iterator instanceof PeekingImpl) { - // Safe to cast to because PeekingImpl only uses T - // covariantly (and cannot be subclassed to add non-covariant uses). - @SuppressWarnings("unchecked") - PeekingImpl peeking = (PeekingImpl) iterator; - return peeking; - } - return new PeekingImpl(iterator); - } - - /** - * Simply returns its argument. - * - * @deprecated no need to use this - * @since 10.0 - */ - @Deprecated - public static PeekingIterator peekingIterator(PeekingIterator iterator) { - return checkNotNull(iterator); - } - - /** - * Returns an iterator over the merged contents of all given - * {@code iterators}, traversing every element of the input iterators. - * Equivalent entries will not be de-duplicated. - * - *

Callers must ensure that the source {@code iterators} are in - * non-descending order as this method does not sort its input. - * - *

For any equivalent elements across all {@code iterators}, it is - * undefined which element is returned first. - * - * @since 11.0 - */ - @Beta - public static UnmodifiableIterator mergeSorted( - Iterable> iterators, Comparator comparator) { - checkNotNull(iterators, "iterators"); - checkNotNull(comparator, "comparator"); - - return new MergingIterator(iterators, comparator); - } - - /** - * An iterator that performs a lazy N-way merge, calculating the next value - * each time the iterator is polled. This amortizes the sorting cost over the - * iteration and requires less memory than sorting all elements at once. - * - *

Retrieving a single element takes approximately O(log(M)) time, where M - * is the number of iterators. (Retrieving all elements takes approximately - * O(N*log(M)) time, where N is the total number of elements.) - */ - private static class MergingIterator extends UnmodifiableIterator { - final Queue> queue; - - public MergingIterator( - Iterable> iterators, - final Comparator itemComparator) { - // A comparator that's used by the heap, allowing the heap - // to be sorted based on the top of each iterator. - Comparator> heapComparator = - new Comparator>() { - @Override - public int compare(PeekingIterator o1, PeekingIterator o2) { - return itemComparator.compare(o1.peek(), o2.peek()); - } - }; - - queue = new PriorityQueue>(2, heapComparator); - - for (Iterator iterator : iterators) { - if (iterator.hasNext()) { - queue.add(Iterators.peekingIterator(iterator)); - } - } - } - - @Override - public boolean hasNext() { - return !queue.isEmpty(); - } - - @Override - public T next() { - PeekingIterator nextIter = queue.remove(); - T next = nextIter.next(); - if (nextIter.hasNext()) { - queue.add(nextIter); - } - return next; - } - } - - /** - * Used to avoid http://bugs.sun.com/view_bug.do?bug_id=6558557 - */ - static ListIterator cast(Iterator iterator) { - return (ListIterator) iterator; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/LexicographicalOrdering.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/LexicographicalOrdering.java deleted file mode 100644 index 801af6d400ad..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/LexicographicalOrdering.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; -import java.util.Comparator; -import java.util.Iterator; - -import javax.annotation.Nullable; - -/** - * An ordering which sorts iterables by comparing corresponding elements - * pairwise. - */ -@GwtCompatible(serializable = true) -final class LexicographicalOrdering extends Ordering> implements Serializable { - final Comparator elementOrder; - - LexicographicalOrdering(Comparator elementOrder) { - this.elementOrder = elementOrder; - } - - @Override - public int compare(Iterable leftIterable, Iterable rightIterable) { - Iterator left = leftIterable.iterator(); - Iterator right = rightIterable.iterator(); - while (left.hasNext()) { - if (!right.hasNext()) { - return LEFT_IS_GREATER; // because it's longer - } - int result = elementOrder.compare(left.next(), right.next()); - if (result != 0) { - return result; - } - } - if (right.hasNext()) { - return RIGHT_IS_GREATER; // because it's longer - } - return 0; - } - - @Override - public boolean equals(@Nullable Object object) { - if (object == this) { - return true; - } - if (object instanceof LexicographicalOrdering) { - LexicographicalOrdering that = (LexicographicalOrdering) object; - return this.elementOrder.equals(that.elementOrder); - } - return false; - } - - @Override - public int hashCode() { - return elementOrder.hashCode() ^ 2075626741; // meaningless - } - - @Override - public String toString() { - return elementOrder + ".lexicographical()"; - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/LinkedHashMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/LinkedHashMultimap.java deleted file mode 100644 index 0893619da2b0..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/LinkedHashMultimap.java +++ /dev/null @@ -1,586 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.collect.CollectPreconditions.checkNonnegative; -import static com.google.common.collect.CollectPreconditions.checkRemove; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Objects; -import com.google.j2objc.annotations.WeakOuter; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.Arrays; -import java.util.Collection; -import java.util.ConcurrentModificationException; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * Implementation of {@code Multimap} that does not allow duplicate key-value - * entries and that returns collections whose iterators follow the ordering in - * which the data was added to the multimap. - * - *

The collections returned by {@code keySet}, {@code keys}, and {@code - * asMap} iterate through the keys in the order they were first added to the - * multimap. Similarly, {@code get}, {@code removeAll}, and {@code - * replaceValues} return collections that iterate through the values in the - * order they were added. The collections generated by {@code entries} and - * {@code values} iterate across the key-value mappings in the order they were - * added to the multimap. - * - *

The iteration ordering of the collections generated by {@code keySet}, - * {@code keys}, and {@code asMap} has a few subtleties. As long as the set of - * keys remains unchanged, adding or removing mappings does not affect the key - * iteration order. However, if you remove all values associated with a key and - * then add the key back to the multimap, that key will come last in the key - * iteration order. - * - *

The multimap does not store duplicate key-value pairs. Adding a new - * key-value pair equal to an existing key-value pair has no effect. - * - *

Keys and values may be null. All optional multimap methods are supported, - * and all returned views are modifiable. - * - *

This class is not threadsafe when any concurrent operations update the - * multimap. Concurrent read operations will work correctly. To allow concurrent - * update operations, wrap your multimap with a call to {@link - * Multimaps#synchronizedSetMultimap}. - * - *

See the Guava User Guide article on - * {@code Multimap}. - * - * @author Jared Levy - * @author Louis Wasserman - * @since 2.0 - */ -@GwtCompatible(serializable = true, emulated = true) -public final class LinkedHashMultimap extends AbstractSetMultimap { - - /** - * Creates a new, empty {@code LinkedHashMultimap} with the default initial - * capacities. - */ - public static LinkedHashMultimap create() { - return new LinkedHashMultimap(DEFAULT_KEY_CAPACITY, DEFAULT_VALUE_SET_CAPACITY); - } - - /** - * Constructs an empty {@code LinkedHashMultimap} with enough capacity to hold - * the specified numbers of keys and values without rehashing. - * - * @param expectedKeys the expected number of distinct keys - * @param expectedValuesPerKey the expected average number of values per key - * @throws IllegalArgumentException if {@code expectedKeys} or {@code - * expectedValuesPerKey} is negative - */ - public static LinkedHashMultimap create(int expectedKeys, int expectedValuesPerKey) { - return new LinkedHashMultimap( - Maps.capacity(expectedKeys), Maps.capacity(expectedValuesPerKey)); - } - - /** - * Constructs a {@code LinkedHashMultimap} with the same mappings as the - * specified multimap. If a key-value mapping appears multiple times in the - * input multimap, it only appears once in the constructed multimap. The new - * multimap has the same {@link Multimap#entries()} iteration order as the - * input multimap, except for excluding duplicate mappings. - * - * @param multimap the multimap whose contents are copied to this multimap - */ - public static LinkedHashMultimap create( - Multimap multimap) { - LinkedHashMultimap result = create(multimap.keySet().size(), DEFAULT_VALUE_SET_CAPACITY); - result.putAll(multimap); - return result; - } - - private interface ValueSetLink { - ValueSetLink getPredecessorInValueSet(); - - ValueSetLink getSuccessorInValueSet(); - - void setPredecessorInValueSet(ValueSetLink entry); - - void setSuccessorInValueSet(ValueSetLink entry); - } - - private static void succeedsInValueSet(ValueSetLink pred, ValueSetLink succ) { - pred.setSuccessorInValueSet(succ); - succ.setPredecessorInValueSet(pred); - } - - private static void succeedsInMultimap(ValueEntry pred, ValueEntry succ) { - pred.setSuccessorInMultimap(succ); - succ.setPredecessorInMultimap(pred); - } - - private static void deleteFromValueSet(ValueSetLink entry) { - succeedsInValueSet(entry.getPredecessorInValueSet(), entry.getSuccessorInValueSet()); - } - - private static void deleteFromMultimap(ValueEntry entry) { - succeedsInMultimap(entry.getPredecessorInMultimap(), entry.getSuccessorInMultimap()); - } - - /** - * LinkedHashMultimap entries are in no less than three coexisting linked lists: - * a bucket in the hash table for a Set associated with a key, the linked list - * of insertion-ordered entries in that Set, and the linked list of entries - * in the LinkedHashMultimap as a whole. - */ - @VisibleForTesting - static final class ValueEntry extends ImmutableEntry implements ValueSetLink { - final int smearedValueHash; - - @Nullable ValueEntry nextInValueBucket; - - ValueSetLink predecessorInValueSet; - ValueSetLink successorInValueSet; - - ValueEntry predecessorInMultimap; - ValueEntry successorInMultimap; - - ValueEntry( - @Nullable K key, - @Nullable V value, - int smearedValueHash, - @Nullable ValueEntry nextInValueBucket) { - super(key, value); - this.smearedValueHash = smearedValueHash; - this.nextInValueBucket = nextInValueBucket; - } - - boolean matchesValue(@Nullable Object v, int smearedVHash) { - return smearedValueHash == smearedVHash && Objects.equal(getValue(), v); - } - - @Override - public ValueSetLink getPredecessorInValueSet() { - return predecessorInValueSet; - } - - @Override - public ValueSetLink getSuccessorInValueSet() { - return successorInValueSet; - } - - @Override - public void setPredecessorInValueSet(ValueSetLink entry) { - predecessorInValueSet = entry; - } - - @Override - public void setSuccessorInValueSet(ValueSetLink entry) { - successorInValueSet = entry; - } - - public ValueEntry getPredecessorInMultimap() { - return predecessorInMultimap; - } - - public ValueEntry getSuccessorInMultimap() { - return successorInMultimap; - } - - public void setSuccessorInMultimap(ValueEntry multimapSuccessor) { - this.successorInMultimap = multimapSuccessor; - } - - public void setPredecessorInMultimap(ValueEntry multimapPredecessor) { - this.predecessorInMultimap = multimapPredecessor; - } - } - - private static final int DEFAULT_KEY_CAPACITY = 16; - private static final int DEFAULT_VALUE_SET_CAPACITY = 2; - @VisibleForTesting static final double VALUE_SET_LOAD_FACTOR = 1.0; - - @VisibleForTesting transient int valueSetCapacity = DEFAULT_VALUE_SET_CAPACITY; - private transient ValueEntry multimapHeaderEntry; - - private LinkedHashMultimap(int keyCapacity, int valueSetCapacity) { - super(new LinkedHashMap>(keyCapacity)); - checkNonnegative(valueSetCapacity, "expectedValuesPerKey"); - - this.valueSetCapacity = valueSetCapacity; - this.multimapHeaderEntry = new ValueEntry(null, null, 0, null); - succeedsInMultimap(multimapHeaderEntry, multimapHeaderEntry); - } - - /** - * {@inheritDoc} - * - *

Creates an empty {@code LinkedHashSet} for a collection of values for - * one key. - * - * @return a new {@code LinkedHashSet} containing a collection of values for - * one key - */ - @Override - Set createCollection() { - return new LinkedHashSet(valueSetCapacity); - } - - /** - * {@inheritDoc} - * - *

Creates a decorated insertion-ordered set that also keeps track of the - * order in which key-value pairs are added to the multimap. - * - * @param key key to associate with values in the collection - * @return a new decorated set containing a collection of values for one key - */ - @Override - Collection createCollection(K key) { - return new ValueSet(key, valueSetCapacity); - } - - /** - * {@inheritDoc} - * - *

If {@code values} is not empty and the multimap already contains a - * mapping for {@code key}, the {@code keySet()} ordering is unchanged. - * However, the provided values always come last in the {@link #entries()} and - * {@link #values()} iteration orderings. - */ - @Override - public Set replaceValues(@Nullable K key, Iterable values) { - return super.replaceValues(key, values); - } - - /** - * Returns a set of all key-value pairs. Changes to the returned set will - * update the underlying multimap, and vice versa. The entries set does not - * support the {@code add} or {@code addAll} operations. - * - *

The iterator generated by the returned set traverses the entries in the - * order they were added to the multimap. - * - *

Each entry is an immutable snapshot of a key-value mapping in the - * multimap, taken at the time the entry is returned by a method call to the - * collection or its iterator. - */ - @Override - public Set> entries() { - return super.entries(); - } - - /** - * Returns a collection of all values in the multimap. Changes to the returned - * collection will update the underlying multimap, and vice versa. - * - *

The iterator generated by the returned collection traverses the values - * in the order they were added to the multimap. - */ - @Override - public Collection values() { - return super.values(); - } - - @VisibleForTesting - @WeakOuter - final class ValueSet extends Sets.ImprovedAbstractSet implements ValueSetLink { - /* - * We currently use a fixed load factor of 1.0, a bit higher than normal to reduce memory - * consumption. - */ - - private final K key; - @VisibleForTesting ValueEntry[] hashTable; - private int size = 0; - private int modCount = 0; - - // We use the set object itself as the end of the linked list, avoiding an unnecessary - // entry object per key. - private ValueSetLink firstEntry; - private ValueSetLink lastEntry; - - ValueSet(K key, int expectedValues) { - this.key = key; - this.firstEntry = this; - this.lastEntry = this; - // Round expected values up to a power of 2 to get the table size. - int tableSize = Hashing.closedTableSize(expectedValues, VALUE_SET_LOAD_FACTOR); - - @SuppressWarnings("unchecked") - ValueEntry[] hashTable = new ValueEntry[tableSize]; - this.hashTable = hashTable; - } - - private int mask() { - return hashTable.length - 1; - } - - @Override - public ValueSetLink getPredecessorInValueSet() { - return lastEntry; - } - - @Override - public ValueSetLink getSuccessorInValueSet() { - return firstEntry; - } - - @Override - public void setPredecessorInValueSet(ValueSetLink entry) { - lastEntry = entry; - } - - @Override - public void setSuccessorInValueSet(ValueSetLink entry) { - firstEntry = entry; - } - - @Override - public Iterator iterator() { - return new Iterator() { - ValueSetLink nextEntry = firstEntry; - ValueEntry toRemove; - int expectedModCount = modCount; - - private void checkForComodification() { - if (modCount != expectedModCount) { - throw new ConcurrentModificationException(); - } - } - - @Override - public boolean hasNext() { - checkForComodification(); - return nextEntry != ValueSet.this; - } - - @Override - public V next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - ValueEntry entry = (ValueEntry) nextEntry; - V result = entry.getValue(); - toRemove = entry; - nextEntry = entry.getSuccessorInValueSet(); - return result; - } - - @Override - public void remove() { - checkForComodification(); - checkRemove(toRemove != null); - ValueSet.this.remove(toRemove.getValue()); - expectedModCount = modCount; - toRemove = null; - } - }; - } - - @Override - public int size() { - return size; - } - - @Override - public boolean contains(@Nullable Object o) { - int smearedHash = Hashing.smearedHash(o); - for (ValueEntry entry = hashTable[smearedHash & mask()]; - entry != null; - entry = entry.nextInValueBucket) { - if (entry.matchesValue(o, smearedHash)) { - return true; - } - } - return false; - } - - @Override - public boolean add(@Nullable V value) { - int smearedHash = Hashing.smearedHash(value); - int bucket = smearedHash & mask(); - ValueEntry rowHead = hashTable[bucket]; - for (ValueEntry entry = rowHead; entry != null; entry = entry.nextInValueBucket) { - if (entry.matchesValue(value, smearedHash)) { - return false; - } - } - - ValueEntry newEntry = new ValueEntry(key, value, smearedHash, rowHead); - succeedsInValueSet(lastEntry, newEntry); - succeedsInValueSet(newEntry, this); - succeedsInMultimap(multimapHeaderEntry.getPredecessorInMultimap(), newEntry); - succeedsInMultimap(newEntry, multimapHeaderEntry); - hashTable[bucket] = newEntry; - size++; - modCount++; - rehashIfNecessary(); - return true; - } - - private void rehashIfNecessary() { - if (Hashing.needsResizing(size, hashTable.length, VALUE_SET_LOAD_FACTOR)) { - @SuppressWarnings("unchecked") - ValueEntry[] hashTable = new ValueEntry[this.hashTable.length * 2]; - this.hashTable = hashTable; - int mask = hashTable.length - 1; - for (ValueSetLink entry = firstEntry; - entry != this; - entry = entry.getSuccessorInValueSet()) { - ValueEntry valueEntry = (ValueEntry) entry; - int bucket = valueEntry.smearedValueHash & mask; - valueEntry.nextInValueBucket = hashTable[bucket]; - hashTable[bucket] = valueEntry; - } - } - } - - @Override - public boolean remove(@Nullable Object o) { - int smearedHash = Hashing.smearedHash(o); - int bucket = smearedHash & mask(); - ValueEntry prev = null; - for (ValueEntry entry = hashTable[bucket]; - entry != null; - prev = entry, entry = entry.nextInValueBucket) { - if (entry.matchesValue(o, smearedHash)) { - if (prev == null) { - // first entry in the bucket - hashTable[bucket] = entry.nextInValueBucket; - } else { - prev.nextInValueBucket = entry.nextInValueBucket; - } - deleteFromValueSet(entry); - deleteFromMultimap(entry); - size--; - modCount++; - return true; - } - } - return false; - } - - @Override - public void clear() { - Arrays.fill(hashTable, null); - size = 0; - for (ValueSetLink entry = firstEntry; - entry != this; - entry = entry.getSuccessorInValueSet()) { - ValueEntry valueEntry = (ValueEntry) entry; - deleteFromMultimap(valueEntry); - } - succeedsInValueSet(this, this); - modCount++; - } - } - - @Override - Iterator> entryIterator() { - return new Iterator>() { - ValueEntry nextEntry = multimapHeaderEntry.successorInMultimap; - ValueEntry toRemove; - - @Override - public boolean hasNext() { - return nextEntry != multimapHeaderEntry; - } - - @Override - public Map.Entry next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - ValueEntry result = nextEntry; - toRemove = result; - nextEntry = nextEntry.successorInMultimap; - return result; - } - - @Override - public void remove() { - checkRemove(toRemove != null); - LinkedHashMultimap.this.remove(toRemove.getKey(), toRemove.getValue()); - toRemove = null; - } - }; - } - - @Override - Iterator valueIterator() { - return Maps.valueIterator(entryIterator()); - } - - @Override - public void clear() { - super.clear(); - succeedsInMultimap(multimapHeaderEntry, multimapHeaderEntry); - } - - /** - * @serialData the expected values per key, the number of distinct keys, - * the number of entries, and the entries in order - */ - @GwtIncompatible("java.io.ObjectOutputStream") - private void writeObject(ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); - stream.writeInt(keySet().size()); - for (K key : keySet()) { - stream.writeObject(key); - } - stream.writeInt(size()); - for (Map.Entry entry : entries()) { - stream.writeObject(entry.getKey()); - stream.writeObject(entry.getValue()); - } - } - - @GwtIncompatible("java.io.ObjectInputStream") - private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - multimapHeaderEntry = new ValueEntry(null, null, 0, null); - succeedsInMultimap(multimapHeaderEntry, multimapHeaderEntry); - valueSetCapacity = DEFAULT_VALUE_SET_CAPACITY; - int distinctKeys = stream.readInt(); - Map> map = new LinkedHashMap>(); - for (int i = 0; i < distinctKeys; i++) { - @SuppressWarnings("unchecked") - K key = (K) stream.readObject(); - map.put(key, createCollection(key)); - } - int entries = stream.readInt(); - for (int i = 0; i < entries; i++) { - @SuppressWarnings("unchecked") - K key = (K) stream.readObject(); - @SuppressWarnings("unchecked") - V value = (V) stream.readObject(); - map.get(key).add(value); - } - setMap(map); - } - - @GwtIncompatible("java serialization not supported") - private static final long serialVersionUID = 1; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/LinkedHashMultiset.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/LinkedHashMultiset.java deleted file mode 100644 index e597236e67d7..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/LinkedHashMultiset.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.LinkedHashMap; - -/** - * A {@code Multiset} implementation with predictable iteration order. Its - * iterator orders elements according to when the first occurrence of the - * element was added. When the multiset contains multiple instances of an - * element, those instances are consecutive in the iteration order. If all - * occurrences of an element are removed, after which that element is added to - * the multiset, the element will appear at the end of the iteration. - * - *

See the Guava User Guide article on - * {@code Multiset}. - * - * @author Kevin Bourrillion - * @author Jared Levy - * @since 2.0 - */ -@GwtCompatible(serializable = true, emulated = true) -@SuppressWarnings("serial") // we're overriding default serialization -public final class LinkedHashMultiset extends AbstractMapBasedMultiset { - - /** - * Creates a new, empty {@code LinkedHashMultiset} using the default initial - * capacity. - */ - public static LinkedHashMultiset create() { - return new LinkedHashMultiset(); - } - - /** - * Creates a new, empty {@code LinkedHashMultiset} with the specified expected - * number of distinct elements. - * - * @param distinctElements the expected number of distinct elements - * @throws IllegalArgumentException if {@code distinctElements} is negative - */ - public static LinkedHashMultiset create(int distinctElements) { - return new LinkedHashMultiset(distinctElements); - } - - /** - * Creates a new {@code LinkedHashMultiset} containing the specified elements. - * - *

This implementation is highly efficient when {@code elements} is itself - * a {@link Multiset}. - * - * @param elements the elements that the multiset should contain - */ - public static LinkedHashMultiset create(Iterable elements) { - LinkedHashMultiset multiset = create(Multisets.inferDistinctElements(elements)); - Iterables.addAll(multiset, elements); - return multiset; - } - - private LinkedHashMultiset() { - super(new LinkedHashMap()); - } - - private LinkedHashMultiset(int distinctElements) { - super(Maps.newLinkedHashMapWithExpectedSize(distinctElements)); - } - - /** - * @serialData the number of distinct elements, the first element, its count, - * the second element, its count, and so on - */ - @GwtIncompatible("java.io.ObjectOutputStream") - private void writeObject(ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); - Serialization.writeMultiset(this, stream); - } - - @GwtIncompatible("java.io.ObjectInputStream") - private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - int distinctElements = Serialization.readCount(stream); - setBackingMap(new LinkedHashMap()); - Serialization.populateMultiset(this, stream, distinctElements); - } - - @GwtIncompatible("not needed in emulated source") - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/LinkedListMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/LinkedListMultimap.java deleted file mode 100644 index 99c8ffae04fa..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/LinkedListMultimap.java +++ /dev/null @@ -1,849 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkPositionIndex; -import static com.google.common.base.Preconditions.checkState; -import static com.google.common.collect.CollectPreconditions.checkRemove; -import static java.util.Collections.unmodifiableList; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.j2objc.annotations.WeakOuter; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.util.AbstractSequentialList; -import java.util.Collection; -import java.util.ConcurrentModificationException; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.NoSuchElementException; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * An implementation of {@code ListMultimap} that supports deterministic - * iteration order for both keys and values. The iteration order is preserved - * across non-distinct key values. For example, for the following multimap - * definition:

   {@code
- *
- *   Multimap multimap = LinkedListMultimap.create();
- *   multimap.put(key1, foo);
- *   multimap.put(key2, bar);
- *   multimap.put(key1, baz);}
- * - * ... the iteration order for {@link #keys()} is {@code [key1, key2, key1]}, - * and similarly for {@link #entries()}. Unlike {@link LinkedHashMultimap}, the - * iteration order is kept consistent between keys, entries and values. For - * example, calling:
   {@code
- *
- *   map.remove(key1, foo);}
- * - *

changes the entries iteration order to {@code [key2=bar, key1=baz]} and the - * key iteration order to {@code [key2, key1]}. The {@link #entries()} iterator - * returns mutable map entries, and {@link #replaceValues} attempts to preserve - * iteration order as much as possible. - * - *

The collections returned by {@link #keySet()} and {@link #asMap} iterate - * through the keys in the order they were first added to the multimap. - * Similarly, {@link #get}, {@link #removeAll}, and {@link #replaceValues} - * return collections that iterate through the values in the order they were - * added. The collections generated by {@link #entries()}, {@link #keys()}, and - * {@link #values} iterate across the key-value mappings in the order they were - * added to the multimap. - * - *

The {@link #values()} and {@link #entries()} methods both return a - * {@code List}, instead of the {@code Collection} specified by the {@link - * ListMultimap} interface. - * - *

The methods {@link #get}, {@link #keySet()}, {@link #keys()}, - * {@link #values}, {@link #entries()}, and {@link #asMap} return collections - * that are views of the multimap. If the multimap is modified while an - * iteration over any of those collections is in progress, except through the - * iterator's methods, the results of the iteration are undefined. - * - *

Keys and values may be null. All optional multimap methods are supported, - * and all returned views are modifiable. - * - *

This class is not threadsafe when any concurrent operations update the - * multimap. Concurrent read operations will work correctly. To allow concurrent - * update operations, wrap your multimap with a call to {@link - * Multimaps#synchronizedListMultimap}. - * - *

See the Guava User Guide article on - * {@code Multimap}. - * - * @author Mike Bostock - * @since 2.0 - */ -@GwtCompatible(serializable = true, emulated = true) -public class LinkedListMultimap extends AbstractMultimap - implements ListMultimap, Serializable { - /* - * Order is maintained using a linked list containing all key-value pairs. In - * addition, a series of disjoint linked lists of "siblings", each containing - * the values for a specific key, is used to implement {@link - * ValueForKeyIterator} in constant time. - */ - - private static final class Node extends AbstractMapEntry { - final K key; - V value; - Node next; // the next node (with any key) - Node previous; // the previous node (with any key) - Node nextSibling; // the next node with the same key - Node previousSibling; // the previous node with the same key - - Node(@Nullable K key, @Nullable V value) { - this.key = key; - this.value = value; - } - - @Override - public K getKey() { - return key; - } - - @Override - public V getValue() { - return value; - } - - @Override - public V setValue(@Nullable V newValue) { - V result = value; - this.value = newValue; - return result; - } - } - - private static class KeyList { - Node head; - Node tail; - int count; - - KeyList(Node firstNode) { - this.head = firstNode; - this.tail = firstNode; - firstNode.previousSibling = null; - firstNode.nextSibling = null; - this.count = 1; - } - } - - private transient Node head; // the head for all keys - private transient Node tail; // the tail for all keys - private transient Map> keyToKeyList; - private transient int size; - - /* - * Tracks modifications to keyToKeyList so that addition or removal of keys invalidates - * preexisting iterators. This does *not* track simple additions and removals of values - * that are not the first to be added or last to be removed for their key. - */ - private transient int modCount; - - /** - * Creates a new, empty {@code LinkedListMultimap} with the default initial - * capacity. - */ - public static LinkedListMultimap create() { - return new LinkedListMultimap(); - } - - /** - * Constructs an empty {@code LinkedListMultimap} with enough capacity to hold - * the specified number of keys without rehashing. - * - * @param expectedKeys the expected number of distinct keys - * @throws IllegalArgumentException if {@code expectedKeys} is negative - */ - public static LinkedListMultimap create(int expectedKeys) { - return new LinkedListMultimap(expectedKeys); - } - - /** - * Constructs a {@code LinkedListMultimap} with the same mappings as the - * specified {@code Multimap}. The new multimap has the same - * {@link Multimap#entries()} iteration order as the input multimap. - * - * @param multimap the multimap whose contents are copied to this multimap - */ - public static LinkedListMultimap create( - Multimap multimap) { - return new LinkedListMultimap(multimap); - } - - LinkedListMultimap() { - keyToKeyList = Maps.newHashMap(); - } - - private LinkedListMultimap(int expectedKeys) { - keyToKeyList = new HashMap>(expectedKeys); - } - - private LinkedListMultimap(Multimap multimap) { - this(multimap.keySet().size()); - putAll(multimap); - } - - /** - * Adds a new node for the specified key-value pair before the specified - * {@code nextSibling} element, or at the end of the list if {@code - * nextSibling} is null. Note: if {@code nextSibling} is specified, it MUST be - * for an node for the same {@code key}! - */ - private Node addNode(@Nullable K key, @Nullable V value, @Nullable Node nextSibling) { - Node node = new Node(key, value); - if (head == null) { // empty list - head = tail = node; - keyToKeyList.put(key, new KeyList(node)); - modCount++; - } else if (nextSibling == null) { // non-empty list, add to tail - tail.next = node; - node.previous = tail; - tail = node; - KeyList keyList = keyToKeyList.get(key); - if (keyList == null) { - keyToKeyList.put(key, keyList = new KeyList(node)); - modCount++; - } else { - keyList.count++; - Node keyTail = keyList.tail; - keyTail.nextSibling = node; - node.previousSibling = keyTail; - keyList.tail = node; - } - } else { // non-empty list, insert before nextSibling - KeyList keyList = keyToKeyList.get(key); - keyList.count++; - node.previous = nextSibling.previous; - node.previousSibling = nextSibling.previousSibling; - node.next = nextSibling; - node.nextSibling = nextSibling; - if (nextSibling.previousSibling == null) { // nextSibling was key head - keyToKeyList.get(key).head = node; - } else { - nextSibling.previousSibling.nextSibling = node; - } - if (nextSibling.previous == null) { // nextSibling was head - head = node; - } else { - nextSibling.previous.next = node; - } - nextSibling.previous = node; - nextSibling.previousSibling = node; - } - size++; - return node; - } - - /** - * Removes the specified node from the linked list. This method is only - * intended to be used from the {@code Iterator} classes. See also {@link - * LinkedListMultimap#removeAllNodes(Object)}. - */ - private void removeNode(Node node) { - if (node.previous != null) { - node.previous.next = node.next; - } else { // node was head - head = node.next; - } - if (node.next != null) { - node.next.previous = node.previous; - } else { // node was tail - tail = node.previous; - } - if (node.previousSibling == null && node.nextSibling == null) { - KeyList keyList = keyToKeyList.remove(node.key); - keyList.count = 0; - modCount++; - } else { - KeyList keyList = keyToKeyList.get(node.key); - keyList.count--; - - if (node.previousSibling == null) { - keyList.head = node.nextSibling; - } else { - node.previousSibling.nextSibling = node.nextSibling; - } - - if (node.nextSibling == null) { - keyList.tail = node.previousSibling; - } else { - node.nextSibling.previousSibling = node.previousSibling; - } - } - size--; - } - - /** Removes all nodes for the specified key. */ - private void removeAllNodes(@Nullable Object key) { - Iterators.clear(new ValueForKeyIterator(key)); - } - - /** Helper method for verifying that an iterator element is present. */ - private static void checkElement(@Nullable Object node) { - if (node == null) { - throw new NoSuchElementException(); - } - } - - /** An {@code Iterator} over all nodes. */ - private class NodeIterator implements ListIterator> { - int nextIndex; - Node next; - Node current; - Node previous; - int expectedModCount = modCount; - - NodeIterator(int index) { - int size = size(); - checkPositionIndex(index, size); - if (index >= (size / 2)) { - previous = tail; - nextIndex = size; - while (index++ < size) { - previous(); - } - } else { - next = head; - while (index-- > 0) { - next(); - } - } - current = null; - } - - private void checkForConcurrentModification() { - if (modCount != expectedModCount) { - throw new ConcurrentModificationException(); - } - } - - @Override - public boolean hasNext() { - checkForConcurrentModification(); - return next != null; - } - - @Override - public Node next() { - checkForConcurrentModification(); - checkElement(next); - previous = current = next; - next = next.next; - nextIndex++; - return current; - } - - @Override - public void remove() { - checkForConcurrentModification(); - checkRemove(current != null); - if (current != next) { // after call to next() - previous = current.previous; - nextIndex--; - } else { // after call to previous() - next = current.next; - } - removeNode(current); - current = null; - expectedModCount = modCount; - } - - @Override - public boolean hasPrevious() { - checkForConcurrentModification(); - return previous != null; - } - - @Override - public Node previous() { - checkForConcurrentModification(); - checkElement(previous); - next = current = previous; - previous = previous.previous; - nextIndex--; - return current; - } - - @Override - public int nextIndex() { - return nextIndex; - } - - @Override - public int previousIndex() { - return nextIndex - 1; - } - - @Override - public void set(Entry e) { - throw new UnsupportedOperationException(); - } - - @Override - public void add(Entry e) { - throw new UnsupportedOperationException(); - } - - void setValue(V value) { - checkState(current != null); - current.value = value; - } - } - - /** An {@code Iterator} over distinct keys in key head order. */ - private class DistinctKeyIterator implements Iterator { - final Set seenKeys = Sets.newHashSetWithExpectedSize(keySet().size()); - Node next = head; - Node current; - int expectedModCount = modCount; - - private void checkForConcurrentModification() { - if (modCount != expectedModCount) { - throw new ConcurrentModificationException(); - } - } - - @Override - public boolean hasNext() { - checkForConcurrentModification(); - return next != null; - } - - @Override - public K next() { - checkForConcurrentModification(); - checkElement(next); - current = next; - seenKeys.add(current.key); - do { // skip ahead to next unseen key - next = next.next; - } while ((next != null) && !seenKeys.add(next.key)); - return current.key; - } - - @Override - public void remove() { - checkForConcurrentModification(); - checkRemove(current != null); - removeAllNodes(current.key); - current = null; - expectedModCount = modCount; - } - } - - /** A {@code ListIterator} over values for a specified key. */ - private class ValueForKeyIterator implements ListIterator { - final Object key; - int nextIndex; - Node next; - Node current; - Node previous; - - /** Constructs a new iterator over all values for the specified key. */ - ValueForKeyIterator(@Nullable Object key) { - this.key = key; - KeyList keyList = keyToKeyList.get(key); - next = (keyList == null) ? null : keyList.head; - } - - /** - * Constructs a new iterator over all values for the specified key starting - * at the specified index. This constructor is optimized so that it starts - * at either the head or the tail, depending on which is closer to the - * specified index. This allows adds to the tail to be done in constant - * time. - * - * @throws IndexOutOfBoundsException if index is invalid - */ - public ValueForKeyIterator(@Nullable Object key, int index) { - KeyList keyList = keyToKeyList.get(key); - int size = (keyList == null) ? 0 : keyList.count; - checkPositionIndex(index, size); - if (index >= (size / 2)) { - previous = (keyList == null) ? null : keyList.tail; - nextIndex = size; - while (index++ < size) { - previous(); - } - } else { - next = (keyList == null) ? null : keyList.head; - while (index-- > 0) { - next(); - } - } - this.key = key; - current = null; - } - - @Override - public boolean hasNext() { - return next != null; - } - - @Override - public V next() { - checkElement(next); - previous = current = next; - next = next.nextSibling; - nextIndex++; - return current.value; - } - - @Override - public boolean hasPrevious() { - return previous != null; - } - - @Override - public V previous() { - checkElement(previous); - next = current = previous; - previous = previous.previousSibling; - nextIndex--; - return current.value; - } - - @Override - public int nextIndex() { - return nextIndex; - } - - @Override - public int previousIndex() { - return nextIndex - 1; - } - - @Override - public void remove() { - checkRemove(current != null); - if (current != next) { // after call to next() - previous = current.previousSibling; - nextIndex--; - } else { // after call to previous() - next = current.nextSibling; - } - removeNode(current); - current = null; - } - - @Override - public void set(V value) { - checkState(current != null); - current.value = value; - } - - @Override - @SuppressWarnings("unchecked") - public void add(V value) { - previous = addNode((K) key, value, next); - nextIndex++; - current = null; - } - } - - // Query Operations - - @Override - public int size() { - return size; - } - - @Override - public boolean isEmpty() { - return head == null; - } - - @Override - public boolean containsKey(@Nullable Object key) { - return keyToKeyList.containsKey(key); - } - - @Override - public boolean containsValue(@Nullable Object value) { - return values().contains(value); - } - - // Modification Operations - - /** - * Stores a key-value pair in the multimap. - * - * @param key key to store in the multimap - * @param value value to store in the multimap - * @return {@code true} always - */ - @Override - public boolean put(@Nullable K key, @Nullable V value) { - addNode(key, value, null); - return true; - } - - // Bulk Operations - - /** - * {@inheritDoc} - * - *

If any entries for the specified {@code key} already exist in the - * multimap, their values are changed in-place without affecting the iteration - * order. - * - *

The returned list is immutable and implements - * {@link java.util.RandomAccess}. - */ - @Override - public List replaceValues(@Nullable K key, Iterable values) { - List oldValues = getCopy(key); - ListIterator keyValues = new ValueForKeyIterator(key); - Iterator newValues = values.iterator(); - - // Replace existing values, if any. - while (keyValues.hasNext() && newValues.hasNext()) { - keyValues.next(); - keyValues.set(newValues.next()); - } - - // Remove remaining old values, if any. - while (keyValues.hasNext()) { - keyValues.next(); - keyValues.remove(); - } - - // Add remaining new values, if any. - while (newValues.hasNext()) { - keyValues.add(newValues.next()); - } - - return oldValues; - } - - private List getCopy(@Nullable Object key) { - return unmodifiableList(Lists.newArrayList(new ValueForKeyIterator(key))); - } - - /** - * {@inheritDoc} - * - *

The returned list is immutable and implements - * {@link java.util.RandomAccess}. - */ - @Override - public List removeAll(@Nullable Object key) { - List oldValues = getCopy(key); - removeAllNodes(key); - return oldValues; - } - - @Override - public void clear() { - head = null; - tail = null; - keyToKeyList.clear(); - size = 0; - modCount++; - } - - // Views - - /** - * {@inheritDoc} - * - *

If the multimap is modified while an iteration over the list is in - * progress (except through the iterator's own {@code add}, {@code set} or - * {@code remove} operations) the results of the iteration are undefined. - * - *

The returned list is not serializable and does not have random access. - */ - @Override - public List get(final @Nullable K key) { - return new AbstractSequentialList() { - @Override - public int size() { - KeyList keyList = keyToKeyList.get(key); - return (keyList == null) ? 0 : keyList.count; - } - - @Override - public ListIterator listIterator(int index) { - return new ValueForKeyIterator(key, index); - } - }; - } - - @Override - Set createKeySet() { - @WeakOuter - class KeySetImpl extends Sets.ImprovedAbstractSet { - @Override - public int size() { - return keyToKeyList.size(); - } - - @Override - public Iterator iterator() { - return new DistinctKeyIterator(); - } - - @Override - public boolean contains(Object key) { // for performance - return containsKey(key); - } - - @Override - public boolean remove(Object o) { // for performance - return !LinkedListMultimap.this.removeAll(o).isEmpty(); - } - } - return new KeySetImpl(); - } - - /** - * {@inheritDoc} - * - *

The iterator generated by the returned collection traverses the values - * in the order they were added to the multimap. Because the values may have - * duplicates and follow the insertion ordering, this method returns a {@link - * List}, instead of the {@link Collection} specified in the {@link - * ListMultimap} interface. - */ - @Override - public List values() { - return (List) super.values(); - } - - @Override - List createValues() { - @WeakOuter - class ValuesImpl extends AbstractSequentialList { - @Override - public int size() { - return size; - } - - @Override - public ListIterator listIterator(int index) { - final NodeIterator nodeItr = new NodeIterator(index); - return new TransformedListIterator, V>(nodeItr) { - @Override - V transform(Entry entry) { - return entry.getValue(); - } - - @Override - public void set(V value) { - nodeItr.setValue(value); - } - }; - } - } - return new ValuesImpl(); - } - - /** - * {@inheritDoc} - * - *

The iterator generated by the returned collection traverses the entries - * in the order they were added to the multimap. Because the entries may have - * duplicates and follow the insertion ordering, this method returns a {@link - * List}, instead of the {@link Collection} specified in the {@link - * ListMultimap} interface. - * - *

An entry's {@link Entry#getKey} method always returns the same key, - * regardless of what happens subsequently. As long as the corresponding - * key-value mapping is not removed from the multimap, {@link Entry#getValue} - * returns the value from the multimap, which may change over time, and {@link - * Entry#setValue} modifies that value. Removing the mapping from the - * multimap does not alter the value returned by {@code getValue()}, though a - * subsequent {@code setValue()} call won't update the multimap but will lead - * to a revised value being returned by {@code getValue()}. - */ - @Override - public List> entries() { - return (List>) super.entries(); - } - - @Override - List> createEntries() { - @WeakOuter - class EntriesImpl extends AbstractSequentialList> { - @Override - public int size() { - return size; - } - - @Override - public ListIterator> listIterator(int index) { - return new NodeIterator(index); - } - } - return new EntriesImpl(); - } - - @Override - Iterator> entryIterator() { - throw new AssertionError("should never be called"); - } - - @Override - Map> createAsMap() { - return new Multimaps.AsMap(this); - } - - /** - * @serialData the number of distinct keys, and then for each distinct key: - * the first key, the number of values for that key, and the key's values, - * followed by successive keys and values from the entries() ordering - */ - @GwtIncompatible("java.io.ObjectOutputStream") - private void writeObject(ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); - stream.writeInt(size()); - for (Entry entry : entries()) { - stream.writeObject(entry.getKey()); - stream.writeObject(entry.getValue()); - } - } - - @GwtIncompatible("java.io.ObjectInputStream") - private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - keyToKeyList = Maps.newLinkedHashMap(); - int size = stream.readInt(); - for (int i = 0; i < size; i++) { - @SuppressWarnings("unchecked") // reading data stored by writeObject - K key = (K) stream.readObject(); - @SuppressWarnings("unchecked") // reading data stored by writeObject - V value = (V) stream.readObject(); - put(key, value); - } - } - - @GwtIncompatible("java serialization not supported") - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ListMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ListMultimap.java deleted file mode 100644 index c281c6c7bce7..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ListMultimap.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nullable; - -/** - * A {@code Multimap} that can hold duplicate key-value pairs and that maintains - * the insertion ordering of values for a given key. See the {@link Multimap} - * documentation for information common to all multimaps. - * - *

The {@link #get}, {@link #removeAll}, and {@link #replaceValues} methods - * each return a {@link List} of values. Though the method signature doesn't say - * so explicitly, the map returned by {@link #asMap} has {@code List} values. - * - *

See the Guava User Guide article on - * {@code Multimap}. - * - * @author Jared Levy - * @since 2.0 - */ -@GwtCompatible -public interface ListMultimap extends Multimap { - /** - * {@inheritDoc} - * - *

Because the values for a given key may have duplicates and follow the - * insertion ordering, this method returns a {@link List}, instead of the - * {@link java.util.Collection} specified in the {@link Multimap} interface. - */ - @Override - List get(@Nullable K key); - - /** - * {@inheritDoc} - * - *

Because the values for a given key may have duplicates and follow the - * insertion ordering, this method returns a {@link List}, instead of the - * {@link java.util.Collection} specified in the {@link Multimap} interface. - */ - @Override - List removeAll(@Nullable Object key); - - /** - * {@inheritDoc} - * - *

Because the values for a given key may have duplicates and follow the - * insertion ordering, this method returns a {@link List}, instead of the - * {@link java.util.Collection} specified in the {@link Multimap} interface. - */ - @Override - List replaceValues(K key, Iterable values); - - /** - * {@inheritDoc} - * - *

Note: The returned map's values are guaranteed to be of type - * {@link List}. To obtain this map with the more specific generic type - * {@code Map>}, call {@link Multimaps#asMap(ListMultimap)} - * instead. - */ - @Override - Map> asMap(); - - /** - * Compares the specified object to this multimap for equality. - * - *

Two {@code ListMultimap} instances are equal if, for each key, they - * contain the same values in the same order. If the value orderings disagree, - * the multimaps will not be considered equal. - * - *

An empty {@code ListMultimap} is equal to any other empty {@code - * Multimap}, including an empty {@code SetMultimap}. - */ - @Override - boolean equals(@Nullable Object obj); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Lists.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Lists.java deleted file mode 100644 index edf765138a2c..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Lists.java +++ /dev/null @@ -1,1195 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkElementIndex; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkPositionIndex; -import static com.google.common.base.Preconditions.checkPositionIndexes; -import static com.google.common.base.Preconditions.checkState; -import static com.google.common.collect.CollectPreconditions.checkNonnegative; -import static com.google.common.collect.CollectPreconditions.checkRemove; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Function; -import com.google.common.base.Objects; -import com.google.common.math.IntMath; -import com.google.common.primitives.Ints; - -import java.io.Serializable; -import java.math.RoundingMode; -import java.util.AbstractList; -import java.util.AbstractSequentialList; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.NoSuchElementException; -import java.util.RandomAccess; -import java.util.concurrent.CopyOnWriteArrayList; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * Static utility methods pertaining to {@link List} instances. Also see this - * class's counterparts {@link Sets}, {@link Maps} and {@link Queues}. - * - *

See the Guava User Guide article on - * {@code Lists}. - * - * @author Kevin Bourrillion - * @author Mike Bostock - * @author Louis Wasserman - * @since 2.0 - */ -@GwtCompatible(emulated = true) -public final class Lists { - private Lists() {} - - // ArrayList - - /** - * Creates a mutable, empty {@code ArrayList} instance (for Java 6 and - * earlier). - * - *

Note: if mutability is not required, use {@link - * ImmutableList#of()} instead. - * - *

Note for Java 7 and later: this method is now unnecessary and - * should be treated as deprecated. Instead, use the {@code ArrayList} - * {@linkplain ArrayList#ArrayList() constructor} directly, taking advantage - * of the new "diamond" syntax. - */ - @GwtCompatible(serializable = true) - public static ArrayList newArrayList() { - return new ArrayList(); - } - - /** - * Creates a mutable {@code ArrayList} instance containing the given - * elements. - * - *

Note: essentially the only reason to use this method is when you - * will need to add or remove elements later. Otherwise, for non-null elements - * use {@link ImmutableList#of()} (for varargs) or {@link - * ImmutableList#copyOf(Object[])} (for an array) instead. If any elements - * might be null, or you need support for {@link List#set(int, Object)}, use - * {@link Arrays#asList}. - * - *

Note that even when you do need the ability to add or remove, this method - * provides only a tiny bit of syntactic sugar for {@code newArrayList(}{@link - * Arrays#asList asList}{@code (...))}, or for creating an empty list then - * calling {@link Collections#addAll}. This method is not actually very useful - * and will likely be deprecated in the future. - */ - @GwtCompatible(serializable = true) - public static ArrayList newArrayList(E... elements) { - checkNotNull(elements); // for GWT - // Avoid integer overflow when a large array is passed in - int capacity = computeArrayListCapacity(elements.length); - ArrayList list = new ArrayList(capacity); - Collections.addAll(list, elements); - return list; - } - - @VisibleForTesting - static int computeArrayListCapacity(int arraySize) { - checkNonnegative(arraySize, "arraySize"); - - // TODO(kevinb): Figure out the right behavior, and document it - return Ints.saturatedCast(5L + arraySize + (arraySize / 10)); - } - - /** - * Creates a mutable {@code ArrayList} instance containing the given - * elements; a very thin shortcut for creating an empty list then calling - * {@link Iterables#addAll}. - * - *

Note: if mutability is not required and the elements are - * non-null, use {@link ImmutableList#copyOf(Iterable)} instead. (Or, change - * {@code elements} to be a {@link FluentIterable} and call - * {@code elements.toList()}.) - * - *

Note for Java 7 and later: if {@code elements} is a {@link - * Collection}, you don't need this method. Use the {@code ArrayList} - * {@linkplain ArrayList#ArrayList(Collection) constructor} directly, taking - * advantage of the new "diamond" syntax. - */ - @GwtCompatible(serializable = true) - public static ArrayList newArrayList(Iterable elements) { - checkNotNull(elements); // for GWT - // Let ArrayList's sizing logic work, if possible - return (elements instanceof Collection) - ? new ArrayList(Collections2.cast(elements)) - : newArrayList(elements.iterator()); - } - - /** - * Creates a mutable {@code ArrayList} instance containing the given - * elements; a very thin shortcut for creating an empty list and then calling - * {@link Iterators#addAll}. - * - *

Note: if mutability is not required and the elements are - * non-null, use {@link ImmutableList#copyOf(Iterator)} instead. - */ - @GwtCompatible(serializable = true) - public static ArrayList newArrayList(Iterator elements) { - ArrayList list = newArrayList(); - Iterators.addAll(list, elements); - return list; - } - - /** - * Creates an {@code ArrayList} instance backed by an array with the specified - * initial size; simply delegates to {@link ArrayList#ArrayList(int)}. - * - *

Note for Java 7 and later: this method is now unnecessary and - * should be treated as deprecated. Instead, use {@code new }{@link - * ArrayList#ArrayList(int) ArrayList}{@code <>(int)} directly, taking - * advantage of the new "diamond" syntax. - * (Unlike here, there is no risk of overload ambiguity, since the {@code - * ArrayList} constructors very wisely did not accept varargs.) - * - * @param initialArraySize the exact size of the initial backing array for - * the returned array list ({@code ArrayList} documentation calls this - * value the "capacity") - * @return a new, empty {@code ArrayList} which is guaranteed not to resize - * itself unless its size reaches {@code initialArraySize + 1} - * @throws IllegalArgumentException if {@code initialArraySize} is negative - */ - @GwtCompatible(serializable = true) - public static ArrayList newArrayListWithCapacity(int initialArraySize) { - checkNonnegative(initialArraySize, "initialArraySize"); // for GWT. - return new ArrayList(initialArraySize); - } - - /** - * Creates an {@code ArrayList} instance to hold {@code estimatedSize} - * elements, plus an unspecified amount of padding; you almost - * certainly mean to call {@link #newArrayListWithCapacity} (see that method - * for further advice on usage). - * - *

Note: This method will soon be deprecated. Even in the rare case - * that you do want some amount of padding, it's best if you choose your - * desired amount explicitly. - * - * @param estimatedSize an estimate of the eventual {@link List#size()} of - * the new list - * @return a new, empty {@code ArrayList}, sized appropriately to hold the - * estimated number of elements - * @throws IllegalArgumentException if {@code estimatedSize} is negative - */ - @GwtCompatible(serializable = true) - public static ArrayList newArrayListWithExpectedSize(int estimatedSize) { - return new ArrayList(computeArrayListCapacity(estimatedSize)); - } - - // LinkedList - - /** - * Creates a mutable, empty {@code LinkedList} instance (for Java 6 and - * earlier). - * - *

Note: if you won't be adding any elements to the list, use {@link - * ImmutableList#of()} instead. - * - *

Performance note: {@link ArrayList} and {@link - * java.util.ArrayDeque} consistently outperform {@code LinkedList} except in - * certain rare and specific situations. Unless you have spent a lot of time - * benchmarking your specific needs, use one of those instead. - * - *

Note for Java 7 and later: this method is now unnecessary and - * should be treated as deprecated. Instead, use the {@code LinkedList} - * {@linkplain LinkedList#LinkedList() constructor} directly, taking advantage - * of the new "diamond" syntax. - */ - @GwtCompatible(serializable = true) - public static LinkedList newLinkedList() { - return new LinkedList(); - } - - /** - * Creates a mutable {@code LinkedList} instance containing the given - * elements; a very thin shortcut for creating an empty list then calling - * {@link Iterables#addAll}. - * - *

Note: if mutability is not required and the elements are - * non-null, use {@link ImmutableList#copyOf(Iterable)} instead. (Or, change - * {@code elements} to be a {@link FluentIterable} and call - * {@code elements.toList()}.) - * - *

Performance note: {@link ArrayList} and {@link - * java.util.ArrayDeque} consistently outperform {@code LinkedList} except in - * certain rare and specific situations. Unless you have spent a lot of time - * benchmarking your specific needs, use one of those instead. - * - *

Note for Java 7 and later: if {@code elements} is a {@link - * Collection}, you don't need this method. Use the {@code LinkedList} - * {@linkplain LinkedList#LinkedList(Collection) constructor} directly, taking - * advantage of the new "diamond" syntax. - */ - @GwtCompatible(serializable = true) - public static LinkedList newLinkedList(Iterable elements) { - LinkedList list = newLinkedList(); - Iterables.addAll(list, elements); - return list; - } - - /** - * Creates an empty {@code CopyOnWriteArrayList} instance. - * - *

Note: if you need an immutable empty {@link List}, use - * {@link Collections#emptyList} instead. - * - * @return a new, empty {@code CopyOnWriteArrayList} - * @since 12.0 - */ - @GwtIncompatible("CopyOnWriteArrayList") - public static CopyOnWriteArrayList newCopyOnWriteArrayList() { - return new CopyOnWriteArrayList(); - } - - /** - * Creates a {@code CopyOnWriteArrayList} instance containing the given elements. - * - * @param elements the elements that the list should contain, in order - * @return a new {@code CopyOnWriteArrayList} containing those elements - * @since 12.0 - */ - @GwtIncompatible("CopyOnWriteArrayList") - public static CopyOnWriteArrayList newCopyOnWriteArrayList( - Iterable elements) { - // We copy elements to an ArrayList first, rather than incurring the - // quadratic cost of adding them to the COWAL directly. - Collection elementsCollection = - (elements instanceof Collection) - ? Collections2.cast(elements) - : newArrayList(elements); - return new CopyOnWriteArrayList(elementsCollection); - } - - /** - * Returns an unmodifiable list containing the specified first element and - * backed by the specified array of additional elements. Changes to the {@code - * rest} array will be reflected in the returned list. Unlike {@link - * Arrays#asList}, the returned list is unmodifiable. - * - *

This is useful when a varargs method needs to use a signature such as - * {@code (Foo firstFoo, Foo... moreFoos)}, in order to avoid overload - * ambiguity or to enforce a minimum argument count. - * - *

The returned list is serializable and implements {@link RandomAccess}. - * - * @param first the first element - * @param rest an array of additional elements, possibly empty - * @return an unmodifiable list containing the specified elements - */ - public static List asList(@Nullable E first, E[] rest) { - return new OnePlusArrayList(first, rest); - } - - /** @see Lists#asList(Object, Object[]) */ - private static class OnePlusArrayList extends AbstractList - implements Serializable, RandomAccess { - final E first; - final E[] rest; - - OnePlusArrayList(@Nullable E first, E[] rest) { - this.first = first; - this.rest = checkNotNull(rest); - } - - @Override - public int size() { - return rest.length + 1; - } - - @Override - public E get(int index) { - // check explicitly so the IOOBE will have the right message - checkElementIndex(index, size()); - return (index == 0) ? first : rest[index - 1]; - } - - private static final long serialVersionUID = 0; - } - - /** - * Returns an unmodifiable list containing the specified first and second - * element, and backed by the specified array of additional elements. Changes - * to the {@code rest} array will be reflected in the returned list. Unlike - * {@link Arrays#asList}, the returned list is unmodifiable. - * - *

This is useful when a varargs method needs to use a signature such as - * {@code (Foo firstFoo, Foo secondFoo, Foo... moreFoos)}, in order to avoid - * overload ambiguity or to enforce a minimum argument count. - * - *

The returned list is serializable and implements {@link RandomAccess}. - * - * @param first the first element - * @param second the second element - * @param rest an array of additional elements, possibly empty - * @return an unmodifiable list containing the specified elements - */ - public static List asList(@Nullable E first, @Nullable E second, E[] rest) { - return new TwoPlusArrayList(first, second, rest); - } - - /** @see Lists#asList(Object, Object, Object[]) */ - private static class TwoPlusArrayList extends AbstractList - implements Serializable, RandomAccess { - final E first; - final E second; - final E[] rest; - - TwoPlusArrayList(@Nullable E first, @Nullable E second, E[] rest) { - this.first = first; - this.second = second; - this.rest = checkNotNull(rest); - } - - @Override - public int size() { - return rest.length + 2; - } - - @Override - public E get(int index) { - switch (index) { - case 0: - return first; - case 1: - return second; - default: - // check explicitly so the IOOBE will have the right message - checkElementIndex(index, size()); - return rest[index - 2]; - } - } - - private static final long serialVersionUID = 0; - } - - /** - * Returns every possible list that can be formed by choosing one element - * from each of the given lists in order; the "n-ary - * Cartesian - * product" of the lists. For example:

   {@code
-   *
-   *   Lists.cartesianProduct(ImmutableList.of(
-   *       ImmutableList.of(1, 2),
-   *       ImmutableList.of("A", "B", "C")))}
- * - *

returns a list containing six lists in the following order: - * - *

    - *
  • {@code ImmutableList.of(1, "A")} - *
  • {@code ImmutableList.of(1, "B")} - *
  • {@code ImmutableList.of(1, "C")} - *
  • {@code ImmutableList.of(2, "A")} - *
  • {@code ImmutableList.of(2, "B")} - *
  • {@code ImmutableList.of(2, "C")} - *
- * - *

The result is guaranteed to be in the "traditional", lexicographical - * order for Cartesian products that you would get from nesting for loops: - *

   {@code
-   *
-   *   for (B b0 : lists.get(0)) {
-   *     for (B b1 : lists.get(1)) {
-   *       ...
-   *       ImmutableList tuple = ImmutableList.of(b0, b1, ...);
-   *       // operate on tuple
-   *     }
-   *   }}
- * - *

Note that if any input list is empty, the Cartesian product will also be - * empty. If no lists at all are provided (an empty list), the resulting - * Cartesian product has one element, an empty list (counter-intuitive, but - * mathematically consistent). - * - *

Performance notes: while the cartesian product of lists of size - * {@code m, n, p} is a list of size {@code m x n x p}, its actual memory - * consumption is much smaller. When the cartesian product is constructed, the - * input lists are merely copied. Only as the resulting list is iterated are - * the individual lists created, and these are not retained after iteration. - * - * @param lists the lists to choose elements from, in the order that - * the elements chosen from those lists should appear in the resulting - * lists - * @param any common base class shared by all axes (often just {@link - * Object}) - * @return the Cartesian product, as an immutable list containing immutable - * lists - * @throws IllegalArgumentException if the size of the cartesian product would - * be greater than {@link Integer#MAX_VALUE} - * @throws NullPointerException if {@code lists}, any one of the {@code lists}, - * or any element of a provided list is null - * @since 19.0 - */ - public static List> cartesianProduct(List> lists) { - return CartesianList.create(lists); - } - - /** - * Returns every possible list that can be formed by choosing one element - * from each of the given lists in order; the "n-ary - * Cartesian - * product" of the lists. For example:

   {@code
-   *
-   *   Lists.cartesianProduct(ImmutableList.of(
-   *       ImmutableList.of(1, 2),
-   *       ImmutableList.of("A", "B", "C")))}
- * - *

returns a list containing six lists in the following order: - * - *

    - *
  • {@code ImmutableList.of(1, "A")} - *
  • {@code ImmutableList.of(1, "B")} - *
  • {@code ImmutableList.of(1, "C")} - *
  • {@code ImmutableList.of(2, "A")} - *
  • {@code ImmutableList.of(2, "B")} - *
  • {@code ImmutableList.of(2, "C")} - *
- * - *

The result is guaranteed to be in the "traditional", lexicographical - * order for Cartesian products that you would get from nesting for loops: - *

   {@code
-   *
-   *   for (B b0 : lists.get(0)) {
-   *     for (B b1 : lists.get(1)) {
-   *       ...
-   *       ImmutableList tuple = ImmutableList.of(b0, b1, ...);
-   *       // operate on tuple
-   *     }
-   *   }}
- * - *

Note that if any input list is empty, the Cartesian product will also be - * empty. If no lists at all are provided (an empty list), the resulting - * Cartesian product has one element, an empty list (counter-intuitive, but - * mathematically consistent). - * - *

Performance notes: while the cartesian product of lists of size - * {@code m, n, p} is a list of size {@code m x n x p}, its actual memory - * consumption is much smaller. When the cartesian product is constructed, the - * input lists are merely copied. Only as the resulting list is iterated are - * the individual lists created, and these are not retained after iteration. - * - * @param lists the lists to choose elements from, in the order that - * the elements chosen from those lists should appear in the resulting - * lists - * @param any common base class shared by all axes (often just {@link - * Object}) - * @return the Cartesian product, as an immutable list containing immutable - * lists - * @throws IllegalArgumentException if the size of the cartesian product would - * be greater than {@link Integer#MAX_VALUE} - * @throws NullPointerException if {@code lists}, any one of the - * {@code lists}, or any element of a provided list is null - * @since 19.0 - */ - public static List> cartesianProduct(List... lists) { - return cartesianProduct(Arrays.asList(lists)); - } - - /** - * Returns a list that applies {@code function} to each element of {@code - * fromList}. The returned list is a transformed view of {@code fromList}; - * changes to {@code fromList} will be reflected in the returned list and vice - * versa. - * - *

Since functions are not reversible, the transform is one-way and new - * items cannot be stored in the returned list. The {@code add}, - * {@code addAll} and {@code set} methods are unsupported in the returned - * list. - * - *

The function is applied lazily, invoked when needed. This is necessary - * for the returned list to be a view, but it means that the function will be - * applied many times for bulk operations like {@link List#contains} and - * {@link List#hashCode}. For this to perform well, {@code function} should be - * fast. To avoid lazy evaluation when the returned list doesn't need to be a - * view, copy the returned list into a new list of your choosing. - * - *

If {@code fromList} implements {@link RandomAccess}, so will the - * returned list. The returned list is threadsafe if the supplied list and - * function are. - * - *

If only a {@code Collection} or {@code Iterable} input is available, use - * {@link Collections2#transform} or {@link Iterables#transform}. - * - *

Note: serializing the returned list is implemented by serializing - * {@code fromList}, its contents, and {@code function} -- not by - * serializing the transformed values. This can lead to surprising behavior, - * so serializing the returned list is not recommended. Instead, - * copy the list using {@link ImmutableList#copyOf(Collection)} (for example), - * then serialize the copy. Other methods similar to this do not implement - * serialization at all for this reason. - */ - @CheckReturnValue - public static List transform( - List fromList, Function function) { - return (fromList instanceof RandomAccess) - ? new TransformingRandomAccessList(fromList, function) - : new TransformingSequentialList(fromList, function); - } - - /** - * Implementation of a sequential transforming list. - * - * @see Lists#transform - */ - private static class TransformingSequentialList extends AbstractSequentialList - implements Serializable { - final List fromList; - final Function function; - - TransformingSequentialList(List fromList, Function function) { - this.fromList = checkNotNull(fromList); - this.function = checkNotNull(function); - } - /** - * The default implementation inherited is based on iteration and removal of - * each element which can be overkill. That's why we forward this call - * directly to the backing list. - */ - @Override - public void clear() { - fromList.clear(); - } - - @Override - public int size() { - return fromList.size(); - } - - @Override - public ListIterator listIterator(final int index) { - return new TransformedListIterator(fromList.listIterator(index)) { - @Override - T transform(F from) { - return function.apply(from); - } - }; - } - - private static final long serialVersionUID = 0; - } - - /** - * Implementation of a transforming random access list. We try to make as many - * of these methods pass-through to the source list as possible so that the - * performance characteristics of the source list and transformed list are - * similar. - * - * @see Lists#transform - */ - private static class TransformingRandomAccessList extends AbstractList - implements RandomAccess, Serializable { - final List fromList; - final Function function; - - TransformingRandomAccessList(List fromList, Function function) { - this.fromList = checkNotNull(fromList); - this.function = checkNotNull(function); - } - - @Override - public void clear() { - fromList.clear(); - } - - @Override - public T get(int index) { - return function.apply(fromList.get(index)); - } - - @Override - public Iterator iterator() { - return listIterator(); - } - - @Override - public ListIterator listIterator(int index) { - return new TransformedListIterator(fromList.listIterator(index)) { - @Override - T transform(F from) { - return function.apply(from); - } - }; - } - - @Override - public boolean isEmpty() { - return fromList.isEmpty(); - } - - @Override - public T remove(int index) { - return function.apply(fromList.remove(index)); - } - - @Override - public int size() { - return fromList.size(); - } - - private static final long serialVersionUID = 0; - } - - /** - * Returns consecutive {@linkplain List#subList(int, int) sublists} of a list, - * each of the same size (the final list may be smaller). For example, - * partitioning a list containing {@code [a, b, c, d, e]} with a partition - * size of 3 yields {@code [[a, b, c], [d, e]]} -- an outer list containing - * two inner lists of three and two elements, all in the original order. - * - *

The outer list is unmodifiable, but reflects the latest state of the - * source list. The inner lists are sublist views of the original list, - * produced on demand using {@link List#subList(int, int)}, and are subject - * to all the usual caveats about modification as explained in that API. - * - * @param list the list to return consecutive sublists of - * @param size the desired size of each sublist (the last may be - * smaller) - * @return a list of consecutive sublists - * @throws IllegalArgumentException if {@code partitionSize} is nonpositive - */ - public static List> partition(List list, int size) { - checkNotNull(list); - checkArgument(size > 0); - return (list instanceof RandomAccess) - ? new RandomAccessPartition(list, size) - : new Partition(list, size); - } - - private static class Partition extends AbstractList> { - final List list; - final int size; - - Partition(List list, int size) { - this.list = list; - this.size = size; - } - - @Override - public List get(int index) { - checkElementIndex(index, size()); - int start = index * size; - int end = Math.min(start + size, list.size()); - return list.subList(start, end); - } - - @Override - public int size() { - return IntMath.divide(list.size(), size, RoundingMode.CEILING); - } - - @Override - public boolean isEmpty() { - return list.isEmpty(); - } - } - - private static class RandomAccessPartition extends Partition implements RandomAccess { - RandomAccessPartition(List list, int size) { - super(list, size); - } - } - - /** - * Returns a view of the specified string as an immutable list of {@code - * Character} values. - * - * @since 7.0 - */ - @Beta - public static ImmutableList charactersOf(String string) { - return new StringAsImmutableList(checkNotNull(string)); - } - - @SuppressWarnings("serial") // serialized using ImmutableList serialization - private static final class StringAsImmutableList extends ImmutableList { - - private final String string; - - StringAsImmutableList(String string) { - this.string = string; - } - - @Override - public int indexOf(@Nullable Object object) { - return (object instanceof Character) ? string.indexOf((Character) object) : -1; - } - - @Override - public int lastIndexOf(@Nullable Object object) { - return (object instanceof Character) ? string.lastIndexOf((Character) object) : -1; - } - - @Override - public ImmutableList subList(int fromIndex, int toIndex) { - checkPositionIndexes(fromIndex, toIndex, size()); // for GWT - return charactersOf(string.substring(fromIndex, toIndex)); - } - - @Override - boolean isPartialView() { - return false; - } - - @Override - public Character get(int index) { - checkElementIndex(index, size()); // for GWT - return string.charAt(index); - } - - @Override - public int size() { - return string.length(); - } - } - - /** - * Returns a view of the specified {@code CharSequence} as a {@code - * List}, viewing {@code sequence} as a sequence of Unicode code - * units. The view does not support any modification operations, but reflects - * any changes to the underlying character sequence. - * - * @param sequence the character sequence to view as a {@code List} of - * characters - * @return an {@code List} view of the character sequence - * @since 7.0 - */ - @Beta - public static List charactersOf(CharSequence sequence) { - return new CharSequenceAsList(checkNotNull(sequence)); - } - - private static final class CharSequenceAsList extends AbstractList { - private final CharSequence sequence; - - CharSequenceAsList(CharSequence sequence) { - this.sequence = sequence; - } - - @Override - public Character get(int index) { - checkElementIndex(index, size()); // for GWT - return sequence.charAt(index); - } - - @Override - public int size() { - return sequence.length(); - } - } - - /** - * Returns a reversed view of the specified list. For example, {@code - * Lists.reverse(Arrays.asList(1, 2, 3))} returns a list containing {@code 3, - * 2, 1}. The returned list is backed by this list, so changes in the returned - * list are reflected in this list, and vice-versa. The returned list supports - * all of the optional list operations supported by this list. - * - *

The returned list is random-access if the specified list is random - * access. - * - * @since 7.0 - */ - @CheckReturnValue - public static List reverse(List list) { - if (list instanceof ImmutableList) { - return ((ImmutableList) list).reverse(); - } else if (list instanceof ReverseList) { - return ((ReverseList) list).getForwardList(); - } else if (list instanceof RandomAccess) { - return new RandomAccessReverseList(list); - } else { - return new ReverseList(list); - } - } - - private static class ReverseList extends AbstractList { - private final List forwardList; - - ReverseList(List forwardList) { - this.forwardList = checkNotNull(forwardList); - } - - List getForwardList() { - return forwardList; - } - - private int reverseIndex(int index) { - int size = size(); - checkElementIndex(index, size); - return (size - 1) - index; - } - - private int reversePosition(int index) { - int size = size(); - checkPositionIndex(index, size); - return size - index; - } - - @Override - public void add(int index, @Nullable T element) { - forwardList.add(reversePosition(index), element); - } - - @Override - public void clear() { - forwardList.clear(); - } - - @Override - public T remove(int index) { - return forwardList.remove(reverseIndex(index)); - } - - @Override - protected void removeRange(int fromIndex, int toIndex) { - subList(fromIndex, toIndex).clear(); - } - - @Override - public T set(int index, @Nullable T element) { - return forwardList.set(reverseIndex(index), element); - } - - @Override - public T get(int index) { - return forwardList.get(reverseIndex(index)); - } - - @Override - public int size() { - return forwardList.size(); - } - - @Override - public List subList(int fromIndex, int toIndex) { - checkPositionIndexes(fromIndex, toIndex, size()); - return reverse(forwardList.subList(reversePosition(toIndex), reversePosition(fromIndex))); - } - - @Override - public Iterator iterator() { - return listIterator(); - } - - @Override - public ListIterator listIterator(int index) { - int start = reversePosition(index); - final ListIterator forwardIterator = forwardList.listIterator(start); - return new ListIterator() { - - boolean canRemoveOrSet; - - @Override - public void add(T e) { - forwardIterator.add(e); - forwardIterator.previous(); - canRemoveOrSet = false; - } - - @Override - public boolean hasNext() { - return forwardIterator.hasPrevious(); - } - - @Override - public boolean hasPrevious() { - return forwardIterator.hasNext(); - } - - @Override - public T next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - canRemoveOrSet = true; - return forwardIterator.previous(); - } - - @Override - public int nextIndex() { - return reversePosition(forwardIterator.nextIndex()); - } - - @Override - public T previous() { - if (!hasPrevious()) { - throw new NoSuchElementException(); - } - canRemoveOrSet = true; - return forwardIterator.next(); - } - - @Override - public int previousIndex() { - return nextIndex() - 1; - } - - @Override - public void remove() { - checkRemove(canRemoveOrSet); - forwardIterator.remove(); - canRemoveOrSet = false; - } - - @Override - public void set(T e) { - checkState(canRemoveOrSet); - forwardIterator.set(e); - } - }; - } - } - - private static class RandomAccessReverseList extends ReverseList implements RandomAccess { - RandomAccessReverseList(List forwardList) { - super(forwardList); - } - } - - /** - * An implementation of {@link List#hashCode()}. - */ - static int hashCodeImpl(List list) { - // TODO(lowasser): worth optimizing for RandomAccess? - int hashCode = 1; - for (Object o : list) { - hashCode = 31 * hashCode + (o == null ? 0 : o.hashCode()); - - hashCode = ~~hashCode; - // needed to deal with GWT integer overflow - } - return hashCode; - } - - /** - * An implementation of {@link List#equals(Object)}. - */ - static boolean equalsImpl(List thisList, @Nullable Object other) { - if (other == checkNotNull(thisList)) { - return true; - } - if (!(other instanceof List)) { - return false; - } - List otherList = (List) other; - int size = thisList.size(); - if (size != otherList.size()) { - return false; - } - if (thisList instanceof RandomAccess && otherList instanceof RandomAccess) { - // avoid allocation and use the faster loop - for (int i = 0; i < size; i++) { - if (!Objects.equal(thisList.get(i), otherList.get(i))) { - return false; - } - } - return true; - } else { - return Iterators.elementsEqual(thisList.iterator(), otherList.iterator()); - } - } - - /** - * An implementation of {@link List#addAll(int, Collection)}. - */ - static boolean addAllImpl(List list, int index, Iterable elements) { - boolean changed = false; - ListIterator listIterator = list.listIterator(index); - for (E e : elements) { - listIterator.add(e); - changed = true; - } - return changed; - } - - /** - * An implementation of {@link List#indexOf(Object)}. - */ - static int indexOfImpl(List list, @Nullable Object element) { - if (list instanceof RandomAccess) { - return indexOfRandomAccess(list, element); - } else { - ListIterator listIterator = list.listIterator(); - while (listIterator.hasNext()) { - if (Objects.equal(element, listIterator.next())) { - return listIterator.previousIndex(); - } - } - return -1; - } - } - - private static int indexOfRandomAccess(List list, @Nullable Object element) { - int size = list.size(); - if (element == null) { - for (int i = 0; i < size; i++) { - if (list.get(i) == null) { - return i; - } - } - } else { - for (int i = 0; i < size; i++) { - if (element.equals(list.get(i))) { - return i; - } - } - } - return -1; - } - - /** - * An implementation of {@link List#lastIndexOf(Object)}. - */ - static int lastIndexOfImpl(List list, @Nullable Object element) { - if (list instanceof RandomAccess) { - return lastIndexOfRandomAccess(list, element); - } else { - ListIterator listIterator = list.listIterator(list.size()); - while (listIterator.hasPrevious()) { - if (Objects.equal(element, listIterator.previous())) { - return listIterator.nextIndex(); - } - } - return -1; - } - } - - private static int lastIndexOfRandomAccess(List list, @Nullable Object element) { - if (element == null) { - for (int i = list.size() - 1; i >= 0; i--) { - if (list.get(i) == null) { - return i; - } - } - } else { - for (int i = list.size() - 1; i >= 0; i--) { - if (element.equals(list.get(i))) { - return i; - } - } - } - return -1; - } - - /** - * Returns an implementation of {@link List#listIterator(int)}. - */ - static ListIterator listIteratorImpl(List list, int index) { - return new AbstractListWrapper(list).listIterator(index); - } - - /** - * An implementation of {@link List#subList(int, int)}. - */ - static List subListImpl(final List list, int fromIndex, int toIndex) { - List wrapper; - if (list instanceof RandomAccess) { - wrapper = new RandomAccessListWrapper(list) { - @Override - public ListIterator listIterator(int index) { - return backingList.listIterator(index); - } - - private static final long serialVersionUID = 0; - }; - } else { - wrapper = new AbstractListWrapper(list) { - @Override - public ListIterator listIterator(int index) { - return backingList.listIterator(index); - } - - private static final long serialVersionUID = 0; - }; - } - return wrapper.subList(fromIndex, toIndex); - } - - private static class AbstractListWrapper extends AbstractList { - final List backingList; - - AbstractListWrapper(List backingList) { - this.backingList = checkNotNull(backingList); - } - - @Override - public void add(int index, E element) { - backingList.add(index, element); - } - - @Override - public boolean addAll(int index, Collection c) { - return backingList.addAll(index, c); - } - - @Override - public E get(int index) { - return backingList.get(index); - } - - @Override - public E remove(int index) { - return backingList.remove(index); - } - - @Override - public E set(int index, E element) { - return backingList.set(index, element); - } - - @Override - public boolean contains(Object o) { - return backingList.contains(o); - } - - @Override - public int size() { - return backingList.size(); - } - } - - private static class RandomAccessListWrapper extends AbstractListWrapper - implements RandomAccess { - RandomAccessListWrapper(List backingList) { - super(backingList); - } - } - - /** - * Used to avoid http://bugs.sun.com/view_bug.do?bug_id=6558557 - */ - static List cast(Iterable iterable) { - return (List) iterable; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/MapConstraint.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/MapConstraint.java deleted file mode 100644 index fb8f6948a0c5..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/MapConstraint.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import javax.annotation.Nullable; - -/** - * A constraint on the keys and values that may be added to a {@code Map} or - * {@code Multimap}. For example, {@link MapConstraints#notNull()}, which - * prevents a map from including any null keys or values, could be implemented - * like this:

   {@code
- *
- *   public void checkKeyValue(Object key, Object value) {
- *     if (key == null || value == null) {
- *       throw new NullPointerException();
- *     }
- *   }}
- * - *

In order to be effective, constraints should be deterministic; that is, they - * should not depend on state that can change (such as external state, random - * variables, and time) and should only depend on the value of the passed-in key - * and value. A non-deterministic constraint cannot reliably enforce that all - * the collection's elements meet the constraint, since the constraint is only - * enforced when elements are added. - * - * @author Mike Bostock - * @see MapConstraints - * @see Constraint - * @since 3.0 - * @deprecated Use {@link Preconditions} for basic checks. In place of - * constrained maps, we encourage you to check your preconditions - * explicitly instead of leaving that work to the map implementation. - * For the specific case of rejecting null, consider {@link ImmutableMap}. - * This class is scheduled for removal in Guava 20.0. - */ -@GwtCompatible -@Beta -@Deprecated -public interface MapConstraint { - /** - * Throws a suitable {@code RuntimeException} if the specified key or value is - * illegal. Typically this is either a {@link NullPointerException}, an - * {@link IllegalArgumentException}, or a {@link ClassCastException}, though - * an application-specific exception class may be used if appropriate. - */ - void checkKeyValue(@Nullable K key, @Nullable V value); - - /** - * Returns a brief human readable description of this constraint, such as - * "Not null". - */ - @Override - String toString(); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/MapConstraints.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/MapConstraints.java deleted file mode 100644 index 7b2636ec6f57..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/MapConstraints.java +++ /dev/null @@ -1,870 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.j2objc.annotations.WeakOuter; - -import java.io.Serializable; -import java.util.Collection; -import java.util.Comparator; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.SortedSet; - -import javax.annotation.Nullable; - -/** - * Factory and utilities pertaining to the {@code MapConstraint} interface. - * - * @see Constraints - * @author Mike Bostock - * @since 3.0 - * @deprecated Use {@link Preconditions} for basic checks. In place of - * constrained maps, we encourage you to check your preconditions - * explicitly instead of leaving that work to the map implementation. - * For the specific case of rejecting null, consider {@link ImmutableMap}. - * This class is scheduled for removal in Guava 20.0. - */ -@Beta -@GwtCompatible -@Deprecated -public final class MapConstraints { - private MapConstraints() {} - - /** - * Returns a constraint that verifies that neither the key nor the value is - * null. If either is null, a {@link NullPointerException} is thrown. - */ - public static MapConstraint notNull() { - return NotNullMapConstraint.INSTANCE; - } - - // enum singleton pattern - private enum NotNullMapConstraint implements MapConstraint { - INSTANCE; - - @Override - public void checkKeyValue(Object key, Object value) { - checkNotNull(key); - checkNotNull(value); - } - - @Override - public String toString() { - return "Not null"; - } - } - - /** - * Returns a constrained view of the specified map, using the specified - * constraint. Any operations that add new mappings will call the provided - * constraint. However, this method does not verify that existing mappings - * satisfy the constraint. - * - *

The returned map is not serializable. - * - * @param map the map to constrain - * @param constraint the constraint that validates added entries - * @return a constrained view of the specified map - */ - public static Map constrainedMap( - Map map, MapConstraint constraint) { - return new ConstrainedMap(map, constraint); - } - - /** - * Returns a constrained view of the specified multimap, using the specified - * constraint. Any operations that add new mappings will call the provided - * constraint. However, this method does not verify that existing mappings - * satisfy the constraint. - * - *

Note that the generated multimap's {@link Multimap#removeAll} and - * {@link Multimap#replaceValues} methods return collections that are not - * constrained. - * - *

The returned multimap is not serializable. - * - * @param multimap the multimap to constrain - * @param constraint the constraint that validates added entries - * @return a constrained view of the multimap - */ - public static Multimap constrainedMultimap( - Multimap multimap, MapConstraint constraint) { - return new ConstrainedMultimap(multimap, constraint); - } - - /** - * Returns a constrained view of the specified list multimap, using the - * specified constraint. Any operations that add new mappings will call the - * provided constraint. However, this method does not verify that existing - * mappings satisfy the constraint. - * - *

Note that the generated multimap's {@link Multimap#removeAll} and - * {@link Multimap#replaceValues} methods return collections that are not - * constrained. - * - *

The returned multimap is not serializable. - * - * @param multimap the multimap to constrain - * @param constraint the constraint that validates added entries - * @return a constrained view of the specified multimap - */ - public static ListMultimap constrainedListMultimap( - ListMultimap multimap, MapConstraint constraint) { - return new ConstrainedListMultimap(multimap, constraint); - } - - /** - * Returns a constrained view of the specified set multimap, using the - * specified constraint. Any operations that add new mappings will call the - * provided constraint. However, this method does not verify that existing - * mappings satisfy the constraint. - * - *

Note that the generated multimap's {@link Multimap#removeAll} and - * {@link Multimap#replaceValues} methods return collections that are not - * constrained. - *

The returned multimap is not serializable. - * - * @param multimap the multimap to constrain - * @param constraint the constraint that validates added entries - * @return a constrained view of the specified multimap - */ - public static SetMultimap constrainedSetMultimap( - SetMultimap multimap, MapConstraint constraint) { - return new ConstrainedSetMultimap(multimap, constraint); - } - - /** - * Returns a constrained view of the specified sorted-set multimap, using the - * specified constraint. Any operations that add new mappings will call the - * provided constraint. However, this method does not verify that existing - * mappings satisfy the constraint. - * - *

Note that the generated multimap's {@link Multimap#removeAll} and - * {@link Multimap#replaceValues} methods return collections that are not - * constrained. - *

The returned multimap is not serializable. - * - * @param multimap the multimap to constrain - * @param constraint the constraint that validates added entries - * @return a constrained view of the specified multimap - */ - public static SortedSetMultimap constrainedSortedSetMultimap( - SortedSetMultimap multimap, MapConstraint constraint) { - return new ConstrainedSortedSetMultimap(multimap, constraint); - } - - /** - * Returns a constrained view of the specified entry, using the specified - * constraint. The {@link Entry#setValue} operation will be verified with the - * constraint. - * - * @param entry the entry to constrain - * @param constraint the constraint for the entry - * @return a constrained view of the specified entry - */ - private static Entry constrainedEntry( - final Entry entry, final MapConstraint constraint) { - checkNotNull(entry); - checkNotNull(constraint); - return new ForwardingMapEntry() { - @Override - protected Entry delegate() { - return entry; - } - - @Override - public V setValue(V value) { - constraint.checkKeyValue(getKey(), value); - return entry.setValue(value); - } - }; - } - - /** - * Returns a constrained view of the specified {@code asMap} entry, using the - * specified constraint. The {@link Entry#setValue} operation will be verified - * with the constraint, and the collection returned by {@link Entry#getValue} - * will be similarly constrained. - * - * @param entry the {@code asMap} entry to constrain - * @param constraint the constraint for the entry - * @return a constrained view of the specified entry - */ - private static Entry> constrainedAsMapEntry( - final Entry> entry, final MapConstraint constraint) { - checkNotNull(entry); - checkNotNull(constraint); - return new ForwardingMapEntry>() { - @Override - protected Entry> delegate() { - return entry; - } - - @Override - public Collection getValue() { - return Constraints.constrainedTypePreservingCollection( - entry.getValue(), - new Constraint() { - @Override - public V checkElement(V value) { - constraint.checkKeyValue(getKey(), value); - return value; - } - }); - } - }; - } - - /** - * Returns a constrained view of the specified set of {@code asMap} entries, - * using the specified constraint. The {@link Entry#setValue} operation will - * be verified with the constraint, and the collection returned by {@link - * Entry#getValue} will be similarly constrained. The {@code add} and {@code - * addAll} operations simply forward to the underlying set, which throws an - * {@link UnsupportedOperationException} per the multimap specification. - * - * @param entries the entries to constrain - * @param constraint the constraint for the entries - * @return a constrained view of the entries - */ - private static Set>> constrainedAsMapEntries( - Set>> entries, MapConstraint constraint) { - return new ConstrainedAsMapEntries(entries, constraint); - } - - /** - * Returns a constrained view of the specified collection (or set) of entries, - * using the specified constraint. The {@link Entry#setValue} operation will - * be verified with the constraint, along with add operations on the returned - * collection. The {@code add} and {@code addAll} operations simply forward to - * the underlying collection, which throws an {@link - * UnsupportedOperationException} per the map and multimap specification. - * - * @param entries the entries to constrain - * @param constraint the constraint for the entries - * @return a constrained view of the specified entries - */ - private static Collection> constrainedEntries( - Collection> entries, MapConstraint constraint) { - if (entries instanceof Set) { - return constrainedEntrySet((Set>) entries, constraint); - } - return new ConstrainedEntries(entries, constraint); - } - - /** - * Returns a constrained view of the specified set of entries, using the - * specified constraint. The {@link Entry#setValue} operation will be verified - * with the constraint, along with add operations on the returned set. The - * {@code add} and {@code addAll} operations simply forward to the underlying - * set, which throws an {@link UnsupportedOperationException} per the map and - * multimap specification. - * - *

The returned multimap is not serializable. - * - * @param entries the entries to constrain - * @param constraint the constraint for the entries - * @return a constrained view of the specified entries - */ - private static Set> constrainedEntrySet( - Set> entries, MapConstraint constraint) { - return new ConstrainedEntrySet(entries, constraint); - } - - /** @see MapConstraints#constrainedMap */ - static class ConstrainedMap extends ForwardingMap { - private final Map delegate; - final MapConstraint constraint; - private transient Set> entrySet; - - ConstrainedMap(Map delegate, MapConstraint constraint) { - this.delegate = checkNotNull(delegate); - this.constraint = checkNotNull(constraint); - } - - @Override - protected Map delegate() { - return delegate; - } - - @Override - public Set> entrySet() { - Set> result = entrySet; - if (result == null) { - entrySet = result = constrainedEntrySet(delegate.entrySet(), constraint); - } - return result; - } - - @Override - public V put(K key, V value) { - constraint.checkKeyValue(key, value); - return delegate.put(key, value); - } - - @Override - public void putAll(Map map) { - delegate.putAll(checkMap(map, constraint)); - } - } - - /** - * Returns a constrained view of the specified bimap, using the specified - * constraint. Any operations that modify the bimap will have the associated - * keys and values verified with the constraint. - * - *

The returned bimap is not serializable. - * - * @param map the bimap to constrain - * @param constraint the constraint that validates added entries - * @return a constrained view of the specified bimap - */ - public static BiMap constrainedBiMap( - BiMap map, MapConstraint constraint) { - return new ConstrainedBiMap(map, null, constraint); - } - - /** @see MapConstraints#constrainedBiMap */ - private static class ConstrainedBiMap extends ConstrainedMap implements BiMap { - /* - * We could switch to racy single-check lazy init and remove volatile, but - * there's a downside. That's because this field is also written in the - * constructor. Without volatile, the constructor's write of the existing - * inverse BiMap could occur after inverse()'s read of the field's initial - * null value, leading inverse() to overwrite the existing inverse with a - * doubly indirect version. This wouldn't be catastrophic, but it's - * something to keep in mind if we make the change. - * - * Note that UnmodifiableBiMap *does* use racy single-check lazy init. - * TODO(cpovirk): pick one and standardize - */ - volatile BiMap inverse; - - ConstrainedBiMap( - BiMap delegate, - @Nullable BiMap inverse, - MapConstraint constraint) { - super(delegate, constraint); - this.inverse = inverse; - } - - @Override - protected BiMap delegate() { - return (BiMap) super.delegate(); - } - - @Override - public V forcePut(K key, V value) { - constraint.checkKeyValue(key, value); - return delegate().forcePut(key, value); - } - - @Override - public BiMap inverse() { - if (inverse == null) { - inverse = new ConstrainedBiMap( - delegate().inverse(), this, new InverseConstraint(constraint)); - } - return inverse; - } - - @Override - public Set values() { - return delegate().values(); - } - } - - /** @see MapConstraints#constrainedBiMap */ - private static class InverseConstraint implements MapConstraint { - final MapConstraint constraint; - - public InverseConstraint(MapConstraint constraint) { - this.constraint = checkNotNull(constraint); - } - - @Override - public void checkKeyValue(K key, V value) { - constraint.checkKeyValue(value, key); - } - } - - /** @see MapConstraints#constrainedMultimap */ - private static class ConstrainedMultimap extends ForwardingMultimap - implements Serializable { - final MapConstraint constraint; - final Multimap delegate; - - transient Collection> entries; - - transient Map> asMap; - - public ConstrainedMultimap( - Multimap delegate, MapConstraint constraint) { - this.delegate = checkNotNull(delegate); - this.constraint = checkNotNull(constraint); - } - - @Override - protected Multimap delegate() { - return delegate; - } - - @Override - public Map> asMap() { - Map> result = asMap; - if (result == null) { - final Map> asMapDelegate = delegate.asMap(); - - @WeakOuter - class AsMap extends ForwardingMap> { - Set>> entrySet; - Collection> values; - - @Override - protected Map> delegate() { - return asMapDelegate; - } - - @Override - public Set>> entrySet() { - Set>> result = entrySet; - if (result == null) { - entrySet = result = constrainedAsMapEntries(asMapDelegate.entrySet(), constraint); - } - return result; - } - - @SuppressWarnings("unchecked") - @Override - public Collection get(Object key) { - try { - Collection collection = ConstrainedMultimap.this.get((K) key); - return collection.isEmpty() ? null : collection; - } catch (ClassCastException e) { - return null; // key wasn't a K - } - } - - @Override - public Collection> values() { - Collection> result = values; - if (result == null) { - values = result = new ConstrainedAsMapValues(delegate().values(), entrySet()); - } - return result; - } - - @Override - public boolean containsValue(Object o) { - return values().contains(o); - } - } - asMap = result = new AsMap(); - } - return result; - } - - @Override - public Collection> entries() { - Collection> result = entries; - if (result == null) { - entries = result = constrainedEntries(delegate.entries(), constraint); - } - return result; - } - - @Override - public Collection get(final K key) { - return Constraints.constrainedTypePreservingCollection( - delegate.get(key), - new Constraint() { - @Override - public V checkElement(V value) { - constraint.checkKeyValue(key, value); - return value; - } - }); - } - - @Override - public boolean put(K key, V value) { - constraint.checkKeyValue(key, value); - return delegate.put(key, value); - } - - @Override - public boolean putAll(K key, Iterable values) { - return delegate.putAll(key, checkValues(key, values, constraint)); - } - - @Override - public boolean putAll(Multimap multimap) { - boolean changed = false; - for (Entry entry : multimap.entries()) { - changed |= put(entry.getKey(), entry.getValue()); - } - return changed; - } - - @Override - public Collection replaceValues(K key, Iterable values) { - return delegate.replaceValues(key, checkValues(key, values, constraint)); - } - } - - /** @see ConstrainedMultimap#asMap */ - private static class ConstrainedAsMapValues extends ForwardingCollection> { - final Collection> delegate; - final Set>> entrySet; - - /** - * @param entrySet map entries, linking each key with its corresponding - * values, that already enforce the constraint - */ - ConstrainedAsMapValues( - Collection> delegate, Set>> entrySet) { - this.delegate = delegate; - this.entrySet = entrySet; - } - - @Override - protected Collection> delegate() { - return delegate; - } - - @Override - public Iterator> iterator() { - final Iterator>> iterator = entrySet.iterator(); - return new Iterator>() { - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public Collection next() { - return iterator.next().getValue(); - } - - @Override - public void remove() { - iterator.remove(); - } - }; - } - - @Override - public Object[] toArray() { - return standardToArray(); - } - - @Override - public T[] toArray(T[] array) { - return standardToArray(array); - } - - @Override - public boolean contains(Object o) { - return standardContains(o); - } - - @Override - public boolean containsAll(Collection c) { - return standardContainsAll(c); - } - - @Override - public boolean remove(Object o) { - return standardRemove(o); - } - - @Override - public boolean removeAll(Collection c) { - return standardRemoveAll(c); - } - - @Override - public boolean retainAll(Collection c) { - return standardRetainAll(c); - } - } - - /** @see MapConstraints#constrainedEntries */ - private static class ConstrainedEntries extends ForwardingCollection> { - final MapConstraint constraint; - final Collection> entries; - - ConstrainedEntries( - Collection> entries, MapConstraint constraint) { - this.entries = entries; - this.constraint = constraint; - } - - @Override - protected Collection> delegate() { - return entries; - } - - @Override - public Iterator> iterator() { - return new TransformedIterator, Entry>(entries.iterator()) { - @Override - Entry transform(Entry from) { - return constrainedEntry(from, constraint); - } - }; - } - - // See Collections.CheckedMap.CheckedEntrySet for details on attacks. - - @Override - public Object[] toArray() { - return standardToArray(); - } - - @Override - public T[] toArray(T[] array) { - return standardToArray(array); - } - - @Override - public boolean contains(Object o) { - return Maps.containsEntryImpl(delegate(), o); - } - - @Override - public boolean containsAll(Collection c) { - return standardContainsAll(c); - } - - @Override - public boolean remove(Object o) { - return Maps.removeEntryImpl(delegate(), o); - } - - @Override - public boolean removeAll(Collection c) { - return standardRemoveAll(c); - } - - @Override - public boolean retainAll(Collection c) { - return standardRetainAll(c); - } - } - - /** @see MapConstraints#constrainedEntrySet */ - static class ConstrainedEntrySet extends ConstrainedEntries - implements Set> { - ConstrainedEntrySet(Set> entries, MapConstraint constraint) { - super(entries, constraint); - } - - // See Collections.CheckedMap.CheckedEntrySet for details on attacks. - - @Override - public boolean equals(@Nullable Object object) { - return Sets.equalsImpl(this, object); - } - - @Override - public int hashCode() { - return Sets.hashCodeImpl(this); - } - } - - /** @see MapConstraints#constrainedAsMapEntries */ - static class ConstrainedAsMapEntries extends ForwardingSet>> { - private final MapConstraint constraint; - private final Set>> entries; - - ConstrainedAsMapEntries( - Set>> entries, MapConstraint constraint) { - this.entries = entries; - this.constraint = constraint; - } - - @Override - protected Set>> delegate() { - return entries; - } - - @Override - public Iterator>> iterator() { - return new TransformedIterator>, Entry>>( - entries.iterator()) { - @Override - Entry> transform(Entry> from) { - return constrainedAsMapEntry(from, constraint); - } - }; - } - - // See Collections.CheckedMap.CheckedEntrySet for details on attacks. - - @Override - public Object[] toArray() { - return standardToArray(); - } - - @Override - public T[] toArray(T[] array) { - return standardToArray(array); - } - - @Override - public boolean contains(Object o) { - return Maps.containsEntryImpl(delegate(), o); - } - - @Override - public boolean containsAll(Collection c) { - return standardContainsAll(c); - } - - @Override - public boolean equals(@Nullable Object object) { - return standardEquals(object); - } - - @Override - public int hashCode() { - return standardHashCode(); - } - - @Override - public boolean remove(Object o) { - return Maps.removeEntryImpl(delegate(), o); - } - - @Override - public boolean removeAll(Collection c) { - return standardRemoveAll(c); - } - - @Override - public boolean retainAll(Collection c) { - return standardRetainAll(c); - } - } - - private static class ConstrainedListMultimap extends ConstrainedMultimap - implements ListMultimap { - ConstrainedListMultimap( - ListMultimap delegate, MapConstraint constraint) { - super(delegate, constraint); - } - - @Override - public List get(K key) { - return (List) super.get(key); - } - - @Override - public List removeAll(Object key) { - return (List) super.removeAll(key); - } - - @Override - public List replaceValues(K key, Iterable values) { - return (List) super.replaceValues(key, values); - } - } - - private static class ConstrainedSetMultimap extends ConstrainedMultimap - implements SetMultimap { - ConstrainedSetMultimap( - SetMultimap delegate, MapConstraint constraint) { - super(delegate, constraint); - } - - @Override - public Set get(K key) { - return (Set) super.get(key); - } - - @Override - public Set> entries() { - return (Set>) super.entries(); - } - - @Override - public Set removeAll(Object key) { - return (Set) super.removeAll(key); - } - - @Override - public Set replaceValues(K key, Iterable values) { - return (Set) super.replaceValues(key, values); - } - } - - private static class ConstrainedSortedSetMultimap extends ConstrainedSetMultimap - implements SortedSetMultimap { - ConstrainedSortedSetMultimap( - SortedSetMultimap delegate, MapConstraint constraint) { - super(delegate, constraint); - } - - @Override - public SortedSet get(K key) { - return (SortedSet) super.get(key); - } - - @Override - public SortedSet removeAll(Object key) { - return (SortedSet) super.removeAll(key); - } - - @Override - public SortedSet replaceValues(K key, Iterable values) { - return (SortedSet) super.replaceValues(key, values); - } - - @Override - public Comparator valueComparator() { - return ((SortedSetMultimap) delegate()).valueComparator(); - } - } - - private static Collection checkValues( - K key, Iterable values, MapConstraint constraint) { - Collection copy = Lists.newArrayList(values); - for (V value : copy) { - constraint.checkKeyValue(key, value); - } - return copy; - } - - private static Map checkMap( - Map map, MapConstraint constraint) { - Map copy = new LinkedHashMap(map); - for (Entry entry : copy.entrySet()) { - constraint.checkKeyValue(entry.getKey(), entry.getValue()); - } - return copy; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/MapDifference.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/MapDifference.java deleted file mode 100644 index c1c279ea5194..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/MapDifference.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Map; - -import javax.annotation.Nullable; - -/** - * An object representing the differences between two maps. - * - * @author Kevin Bourrillion - * @since 2.0 - */ -@GwtCompatible -public interface MapDifference { - /** - * Returns {@code true} if there are no differences between the two maps; - * that is, if the maps are equal. - */ - boolean areEqual(); - - /** - * Returns an unmodifiable map containing the entries from the left map whose - * keys are not present in the right map. - */ - Map entriesOnlyOnLeft(); - - /** - * Returns an unmodifiable map containing the entries from the right map whose - * keys are not present in the left map. - */ - Map entriesOnlyOnRight(); - - /** - * Returns an unmodifiable map containing the entries that appear in both - * maps; that is, the intersection of the two maps. - */ - Map entriesInCommon(); - - /** - * Returns an unmodifiable map describing keys that appear in both maps, but - * with different values. - */ - Map> entriesDiffering(); - - /** - * Compares the specified object with this instance for equality. Returns - * {@code true} if the given object is also a {@code MapDifference} and the - * values returned by the {@link #entriesOnlyOnLeft()}, {@link - * #entriesOnlyOnRight()}, {@link #entriesInCommon()} and {@link - * #entriesDiffering()} of the two instances are equal. - */ - @Override - boolean equals(@Nullable Object object); - - /** - * Returns the hash code for this instance. This is defined as the hash code - * of

   {@code
-   *
-   *   Arrays.asList(entriesOnlyOnLeft(), entriesOnlyOnRight(),
-   *       entriesInCommon(), entriesDiffering())}
- */ - @Override - int hashCode(); - - /** - * A difference between the mappings from two maps with the same key. The - * {@link #leftValue} and {@link #rightValue} are not equal, and one but not - * both of them may be null. - * - * @since 2.0 - */ - interface ValueDifference { - /** - * Returns the value from the left map (possibly null). - */ - V leftValue(); - - /** - * Returns the value from the right map (possibly null). - */ - V rightValue(); - - /** - * Two instances are considered equal if their {@link #leftValue()} - * values are equal and their {@link #rightValue()} values are also equal. - */ - @Override - boolean equals(@Nullable Object other); - - /** - * The hash code equals the value - * {@code Arrays.asList(leftValue(), rightValue()).hashCode()}. - */ - @Override - int hashCode(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/MapMaker.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/MapMaker.java deleted file mode 100644 index 169d122b3ef9..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/MapMaker.java +++ /dev/null @@ -1,904 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; -import static com.google.common.collect.MapMakerInternalMap.Strength.SOFT; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.base.Ascii; -import com.google.common.base.Equivalence; -import com.google.common.base.Function; -import com.google.common.base.MoreObjects; -import com.google.common.base.Throwables; -import com.google.common.base.Ticker; -import com.google.common.collect.MapMakerInternalMap.Strength; - -import java.io.Serializable; -import java.lang.ref.SoftReference; -import java.lang.ref.WeakReference; -import java.util.AbstractMap; -import java.util.Collections; -import java.util.ConcurrentModificationException; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; - -import javax.annotation.Nullable; - -/** - *

A builder of {@link ConcurrentMap} instances having any combination of the following features: - * - *

    - *
  • keys or values automatically wrapped in {@linkplain WeakReference weak} or {@linkplain - * SoftReference soft} references - *
  • notification of evicted (or otherwise removed) entries - *
- * - *

Usage example:

   {@code
- *
- *   ConcurrentMap timers = new MapMaker()
- *       .concurrencyLevel(4)
- *       .weakKeys()
- *       .makeMap();}
- * - *

These features are all optional; {@code new MapMaker().makeMap()} returns a valid concurrent - * map that behaves similarly to a {@link ConcurrentHashMap}. - * - *

The returned map is implemented as a hash table with similar performance characteristics to - * {@link ConcurrentHashMap}. It supports all optional operations of the {@code ConcurrentMap} - * interface. It does not permit null keys or values. - * - *

Note: by default, the returned map uses equality comparisons (the {@link Object#equals - * equals} method) to determine equality for keys or values. However, if {@link #weakKeys} was - * specified, the map uses identity ({@code ==}) comparisons instead for keys. Likewise, if {@link - * #weakValues} or {@link #softValues} was specified, the map uses identity comparisons for values. - * - *

The view collections of the returned map have weakly consistent iterators. This means - * that they are safe for concurrent use, but if other threads modify the map after the iterator is - * created, it is undefined which of these changes, if any, are reflected in that iterator. These - * iterators never throw {@link ConcurrentModificationException}. - * - *

If {@link #weakKeys}, {@link #weakValues}, or {@link #softValues} are requested, it is - * possible for a key or value present in the map to be reclaimed by the garbage collector. Entries - * with reclaimed keys or values may be removed from the map on each map modification or on - * occasional map accesses; such entries may be counted by {@link Map#size}, but will never be - * visible to read or write operations. A partially-reclaimed entry is never exposed to the user. - * Any {@link java.util.Map.Entry} instance retrieved from the map's - * {@linkplain Map#entrySet entry set} is a snapshot of that entry's state at the time of - * retrieval; such entries do, however, support {@link java.util.Map.Entry#setValue}, which simply - * calls {@link Map#put} on the entry's key. - * - *

The maps produced by {@code MapMaker} are serializable, and the deserialized maps retain all - * the configuration properties of the original map. During deserialization, if the original map had - * used soft or weak references, the entries are reconstructed as they were, but it's not unlikely - * they'll be quickly garbage-collected before they are ever accessed. - * - *

{@code new MapMaker().weakKeys().makeMap()} is a recommended replacement for {@link - * java.util.WeakHashMap}, but note that it compares keys using object identity whereas {@code - * WeakHashMap} uses {@link Object#equals}. - * - * @author Bob Lee - * @author Charles Fry - * @author Kevin Bourrillion - * @since 2.0 - */ -@GwtCompatible(emulated = true) -public final class MapMaker extends GenericMapMaker { - private static final int DEFAULT_INITIAL_CAPACITY = 16; - private static final int DEFAULT_CONCURRENCY_LEVEL = 4; - private static final int DEFAULT_EXPIRATION_NANOS = 0; - - static final int UNSET_INT = -1; - - // TODO(kevinb): dispense with this after benchmarking - boolean useCustomMap; - - int initialCapacity = UNSET_INT; - int concurrencyLevel = UNSET_INT; - int maximumSize = UNSET_INT; - - Strength keyStrength; - Strength valueStrength; - - long expireAfterWriteNanos = UNSET_INT; - long expireAfterAccessNanos = UNSET_INT; - - RemovalCause nullRemovalCause; - - Equivalence keyEquivalence; - - Ticker ticker; - - /** - * Constructs a new {@code MapMaker} instance with default settings, including strong keys, strong - * values, and no automatic eviction of any kind. - */ - public MapMaker() {} - - /** - * Sets a custom {@code Equivalence} strategy for comparing keys. - * - *

By default, the map uses {@link Equivalence#identity} to determine key equality when {@link - * #weakKeys} is specified, and {@link Equivalence#equals()} otherwise. The only place this is - * used is in {@link Interners.WeakInterner}. - */ - @GwtIncompatible("To be supported") - @Override - MapMaker keyEquivalence(Equivalence equivalence) { - checkState(keyEquivalence == null, "key equivalence was already set to %s", keyEquivalence); - keyEquivalence = checkNotNull(equivalence); - this.useCustomMap = true; - return this; - } - - Equivalence getKeyEquivalence() { - return MoreObjects.firstNonNull(keyEquivalence, getKeyStrength().defaultEquivalence()); - } - - /** - * Sets the minimum total size for the internal hash tables. For example, if the initial capacity - * is {@code 60}, and the concurrency level is {@code 8}, then eight segments are created, each - * having a hash table of size eight. Providing a large enough estimate at construction time - * avoids the need for expensive resizing operations later, but setting this value unnecessarily - * high wastes memory. - * - * @throws IllegalArgumentException if {@code initialCapacity} is negative - * @throws IllegalStateException if an initial capacity was already set - */ - @Override - public MapMaker initialCapacity(int initialCapacity) { - checkState( - this.initialCapacity == UNSET_INT, - "initial capacity was already set to %s", - this.initialCapacity); - checkArgument(initialCapacity >= 0); - this.initialCapacity = initialCapacity; - return this; - } - - int getInitialCapacity() { - return (initialCapacity == UNSET_INT) ? DEFAULT_INITIAL_CAPACITY : initialCapacity; - } - - /** - * Specifies the maximum number of entries the map may contain. Note that the map may evict an - * entry before this limit is exceeded. As the map size grows close to the maximum, the map - * evicts entries that are less likely to be used again. For example, the map may evict an entry - * because it hasn't been used recently or very often. - * - *

When {@code size} is zero, elements can be successfully added to the map, but are evicted - * immediately. This has the same effect as invoking {@link #expireAfterWrite - * expireAfterWrite}{@code (0, unit)} or {@link #expireAfterAccess expireAfterAccess}{@code (0, - * unit)}. It can be useful in testing, or to disable caching temporarily without a code change. - * - *

Caching functionality in {@code MapMaker} has been moved to - * {@link com.google.common.cache.CacheBuilder}. - * - * @param size the maximum size of the map - * @throws IllegalArgumentException if {@code size} is negative - * @throws IllegalStateException if a maximum size was already set - * @deprecated Caching functionality in {@code MapMaker} has been moved to - * {@link com.google.common.cache.CacheBuilder}, with {@link #maximumSize} being - * replaced by {@link com.google.common.cache.CacheBuilder#maximumSize}. Note that {@code - * CacheBuilder} is simply an enhanced API for an implementation which was branched from - * {@code MapMaker}. - */ - @Deprecated - @Override - MapMaker maximumSize(int size) { - checkState( - this.maximumSize == UNSET_INT, - "maximum size was already set to %s", - this.maximumSize); - checkArgument(size >= 0, "maximum size must not be negative"); - this.maximumSize = size; - this.useCustomMap = true; - if (maximumSize == 0) { - // SIZE trumps EXPIRED - this.nullRemovalCause = RemovalCause.SIZE; - } - return this; - } - - /** - * Guides the allowed concurrency among update operations. Used as a hint for internal sizing. The - * table is internally partitioned to try to permit the indicated number of concurrent updates - * without contention. Because assignment of entries to these partitions is not necessarily - * uniform, the actual concurrency observed may vary. Ideally, you should choose a value to - * accommodate as many threads as will ever concurrently modify the table. Using a significantly - * higher value than you need can waste space and time, and a significantly lower value can lead - * to thread contention. But overestimates and underestimates within an order of magnitude do not - * usually have much noticeable impact. A value of one permits only one thread to modify the map - * at a time, but since read operations can proceed concurrently, this still yields higher - * concurrency than full synchronization. Defaults to 4. - * - *

Note: Prior to Guava release 9.0, the default was 16. It is possible the default will - * change again in the future. If you care about this value, you should always choose it - * explicitly. - * - * @throws IllegalArgumentException if {@code concurrencyLevel} is nonpositive - * @throws IllegalStateException if a concurrency level was already set - */ - @Override - public MapMaker concurrencyLevel(int concurrencyLevel) { - checkState( - this.concurrencyLevel == UNSET_INT, - "concurrency level was already set to %s", - this.concurrencyLevel); - checkArgument(concurrencyLevel > 0); - this.concurrencyLevel = concurrencyLevel; - return this; - } - - int getConcurrencyLevel() { - return (concurrencyLevel == UNSET_INT) ? DEFAULT_CONCURRENCY_LEVEL : concurrencyLevel; - } - - /** - * Specifies that each key (not value) stored in the map should be wrapped in a {@link - * WeakReference} (by default, strong references are used). - * - *

Warning: when this method is used, the resulting map will use identity ({@code ==}) - * comparison to determine equality of keys, which is a technical violation of the {@link Map} - * specification, and may not be what you expect. - * - * @throws IllegalStateException if the key strength was already set - * @see WeakReference - */ - @GwtIncompatible("java.lang.ref.WeakReference") - @Override - public MapMaker weakKeys() { - return setKeyStrength(Strength.WEAK); - } - - MapMaker setKeyStrength(Strength strength) { - checkState(keyStrength == null, "Key strength was already set to %s", keyStrength); - keyStrength = checkNotNull(strength); - checkArgument(keyStrength != SOFT, "Soft keys are not supported"); - if (strength != Strength.STRONG) { - // STRONG could be used during deserialization. - useCustomMap = true; - } - return this; - } - - Strength getKeyStrength() { - return MoreObjects.firstNonNull(keyStrength, Strength.STRONG); - } - - /** - * Specifies that each value (not key) stored in the map should be wrapped in a - * {@link WeakReference} (by default, strong references are used). - * - *

Weak values will be garbage collected once they are weakly reachable. This makes them a poor - * candidate for caching; consider {@link #softValues} instead. - * - *

Warning: when this method is used, the resulting map will use identity ({@code ==}) - * comparison to determine equality of values. This technically violates the specifications of - * the methods {@link Map#containsValue containsValue}, - * {@link ConcurrentMap#remove(Object, Object) remove(Object, Object)} and - * {@link ConcurrentMap#replace(Object, Object, Object) replace(K, V, V)}, and may not be what you - * expect. - * - * @throws IllegalStateException if the value strength was already set - * @see WeakReference - */ - @GwtIncompatible("java.lang.ref.WeakReference") - @Override - public MapMaker weakValues() { - return setValueStrength(Strength.WEAK); - } - - /** - * Specifies that each value (not key) stored in the map should be wrapped in a - * {@link SoftReference} (by default, strong references are used). Softly-referenced objects will - * be garbage-collected in a globally least-recently-used manner, in response to memory - * demand. - * - *

Warning: in most circumstances it is better to set a per-cache {@linkplain - * #maximumSize maximum size} instead of using soft references. You should only use this method if - * you are well familiar with the practical consequences of soft references. - * - *

Warning: when this method is used, the resulting map will use identity ({@code ==}) - * comparison to determine equality of values. This technically violates the specifications of - * the methods {@link Map#containsValue containsValue}, - * {@link ConcurrentMap#remove(Object, Object) remove(Object, Object)} and - * {@link ConcurrentMap#replace(Object, Object, Object) replace(K, V, V)}, and may not be what you - * expect. - * - * @throws IllegalStateException if the value strength was already set - * @see SoftReference - * @deprecated Caching functionality in {@code MapMaker} has been moved to {@link - * com.google.common.cache.CacheBuilder}, with {@link #softValues} being replaced by {@link - * com.google.common.cache.CacheBuilder#softValues}. Note that {@code CacheBuilder} is simply - * an enhanced API for an implementation which was branched from {@code MapMaker}. - */ - @Deprecated - @GwtIncompatible("java.lang.ref.SoftReference") - @Override - MapMaker softValues() { - return setValueStrength(Strength.SOFT); - } - - MapMaker setValueStrength(Strength strength) { - checkState(valueStrength == null, "Value strength was already set to %s", valueStrength); - valueStrength = checkNotNull(strength); - if (strength != Strength.STRONG) { - // STRONG could be used during deserialization. - useCustomMap = true; - } - return this; - } - - Strength getValueStrength() { - return MoreObjects.firstNonNull(valueStrength, Strength.STRONG); - } - - /** - * Specifies that each entry should be automatically removed from the map once a fixed duration - * has elapsed after the entry's creation, or the most recent replacement of its value. - * - *

When {@code duration} is zero, elements can be successfully added to the map, but are - * evicted immediately. This has a very similar effect to invoking {@link #maximumSize - * maximumSize}{@code (0)}. It can be useful in testing, or to disable caching temporarily without - * a code change. - * - *

Expired entries may be counted by {@link Map#size}, but will never be visible to read or - * write operations. Expired entries are currently cleaned up during write operations, or during - * occasional read operations in the absense of writes; though this behavior may change in the - * future. - * - * @param duration the length of time after an entry is created that it should be automatically - * removed - * @param unit the unit that {@code duration} is expressed in - * @throws IllegalArgumentException if {@code duration} is negative - * @throws IllegalStateException if the time to live or time to idle was already set - * @deprecated Caching functionality in {@code MapMaker} has been moved to - * {@link com.google.common.cache.CacheBuilder}, with {@link #expireAfterWrite} being - * replaced by {@link com.google.common.cache.CacheBuilder#expireAfterWrite}. Note that {@code - * CacheBuilder} is simply an enhanced API for an implementation which was branched from - * {@code MapMaker}. - */ - @Deprecated - @Override - MapMaker expireAfterWrite(long duration, TimeUnit unit) { - checkExpiration(duration, unit); - this.expireAfterWriteNanos = unit.toNanos(duration); - if (duration == 0 && this.nullRemovalCause == null) { - // SIZE trumps EXPIRED - this.nullRemovalCause = RemovalCause.EXPIRED; - } - useCustomMap = true; - return this; - } - - private void checkExpiration(long duration, TimeUnit unit) { - checkState( - expireAfterWriteNanos == UNSET_INT, - "expireAfterWrite was already set to %s ns", - expireAfterWriteNanos); - checkState( - expireAfterAccessNanos == UNSET_INT, - "expireAfterAccess was already set to %s ns", - expireAfterAccessNanos); - checkArgument(duration >= 0, "duration cannot be negative: %s %s", duration, unit); - } - - long getExpireAfterWriteNanos() { - return (expireAfterWriteNanos == UNSET_INT) ? DEFAULT_EXPIRATION_NANOS : expireAfterWriteNanos; - } - - /** - * Specifies that each entry should be automatically removed from the map once a fixed duration - * has elapsed after the entry's last read or write access. - * - *

When {@code duration} is zero, elements can be successfully added to the map, but are - * evicted immediately. This has a very similar effect to invoking {@link #maximumSize - * maximumSize}{@code (0)}. It can be useful in testing, or to disable caching temporarily without - * a code change. - * - *

Expired entries may be counted by {@link Map#size}, but will never be visible to read or - * write operations. Expired entries are currently cleaned up during write operations, or during - * occasional read operations in the absense of writes; though this behavior may change in the - * future. - * - * @param duration the length of time after an entry is last accessed that it should be - * automatically removed - * @param unit the unit that {@code duration} is expressed in - * @throws IllegalArgumentException if {@code duration} is negative - * @throws IllegalStateException if the time to idle or time to live was already set - * @deprecated Caching functionality in {@code MapMaker} has been moved to - * {@link com.google.common.cache.CacheBuilder}, with {@link #expireAfterAccess} being - * replaced by {@link com.google.common.cache.CacheBuilder#expireAfterAccess}. Note that - * {@code CacheBuilder} is simply an enhanced API for an implementation which was branched - * from {@code MapMaker}. - */ - @Deprecated - @GwtIncompatible("To be supported") - @Override - MapMaker expireAfterAccess(long duration, TimeUnit unit) { - checkExpiration(duration, unit); - this.expireAfterAccessNanos = unit.toNanos(duration); - if (duration == 0 && this.nullRemovalCause == null) { - // SIZE trumps EXPIRED - this.nullRemovalCause = RemovalCause.EXPIRED; - } - useCustomMap = true; - return this; - } - - long getExpireAfterAccessNanos() { - return (expireAfterAccessNanos == UNSET_INT) - ? DEFAULT_EXPIRATION_NANOS - : expireAfterAccessNanos; - } - - Ticker getTicker() { - return MoreObjects.firstNonNull(ticker, Ticker.systemTicker()); - } - - /** - * Specifies a listener instance, which all maps built using this {@code MapMaker} will notify - * each time an entry is removed from the map by any means. - * - *

Each map built by this map maker after this method is called invokes the supplied listener - * after removing an element for any reason (see removal causes in {@link RemovalCause}). It will - * invoke the listener during invocations of any of that map's public methods (even read-only - * methods). - * - *

Important note: Instead of returning this as a {@code MapMaker} instance, - * this method returns {@code GenericMapMaker}. From this point on, either the original - * reference or the returned reference may be used to complete configuration and build the map, - * but only the "generic" one is type-safe. That is, it will properly prevent you from building - * maps whose key or value types are incompatible with the types accepted by the listener already - * provided; the {@code MapMaker} type cannot do this. For best results, simply use the standard - * method-chaining idiom, as illustrated in the documentation at top, configuring a {@code - * MapMaker} and building your {@link Map} all in a single statement. - * - *

Warning: if you ignore the above advice, and use this {@code MapMaker} to build a map - * or cache whose key or value type is incompatible with the listener, you will likely experience - * a {@link ClassCastException} at some undefined point in the future. - * - * @throws IllegalStateException if a removal listener was already set - * @deprecated Caching functionality in {@code MapMaker} has been moved to - * {@link com.google.common.cache.CacheBuilder}, with {@link #removalListener} being - * replaced by {@link com.google.common.cache.CacheBuilder#removalListener}. Note that {@code - * CacheBuilder} is simply an enhanced API for an implementation which was branched from - * {@code MapMaker}. - */ - @Deprecated - @GwtIncompatible("To be supported") - GenericMapMaker removalListener(RemovalListener listener) { - checkState(this.removalListener == null); - - // safely limiting the kinds of maps this can produce - @SuppressWarnings("unchecked") - GenericMapMaker me = (GenericMapMaker) this; - me.removalListener = checkNotNull(listener); - useCustomMap = true; - return me; - } - - /** - * Builds a thread-safe map. This method does not alter the state of this {@code MapMaker} - * instance, so it can be invoked again to create multiple independent maps. - * - *

The bulk operations {@code putAll}, {@code equals}, and {@code clear} are not guaranteed to - * be performed atomically on the returned map. Additionally, {@code size} and {@code - * containsValue} are implemented as bulk read operations, and thus may fail to observe concurrent - * writes. - * - * @return a serializable concurrent map having the requested features - */ - @Override - public ConcurrentMap makeMap() { - if (!useCustomMap) { - return new ConcurrentHashMap(getInitialCapacity(), 0.75f, getConcurrencyLevel()); - } - return (nullRemovalCause == null) - ? new MapMakerInternalMap(this) - : new NullConcurrentMap(this); - } - - /** - * Returns a MapMakerInternalMap for the benefit of internal callers that use features of - * that class not exposed through ConcurrentMap. - */ - @Override - @GwtIncompatible("MapMakerInternalMap") - MapMakerInternalMap makeCustomMap() { - return new MapMakerInternalMap(this); - } - - /** - * Builds a map that supports atomic, on-demand computation of values. {@link Map#get} either - * returns an already-computed value for the given key, atomically computes it using the supplied - * function, or, if another thread is currently computing the value for this key, simply waits for - * that thread to finish and returns its computed value. Note that the function may be executed - * concurrently by multiple threads, but only for distinct keys. - * - *

New code should use {@link com.google.common.cache.CacheBuilder}, which supports - * {@linkplain com.google.common.cache.CacheStats statistics} collection, introduces the - * {@link com.google.common.cache.CacheLoader} interface for loading entries into the cache - * (allowing checked exceptions to be thrown in the process), and more cleanly separates - * computation from the cache's {@code Map} view. - * - *

If an entry's value has not finished computing yet, query methods besides {@code get} return - * immediately as if an entry doesn't exist. In other words, an entry isn't externally visible - * until the value's computation completes. - * - *

{@link Map#get} on the returned map will never return {@code null}. It may throw: - * - *

    - *
  • {@link NullPointerException} if the key is null or the computing function returns a null - * result - *
  • {@link ComputationException} if an exception was thrown by the computing function. If that - * exception is already of type {@link ComputationException} it is propagated directly; otherwise - * it is wrapped. - *
- * - *

Note: Callers of {@code get} must ensure that the key argument is of type - * {@code K}. The {@code get} method accepts {@code Object}, so the key type is not checked at - * compile time. Passing an object of a type other than {@code K} can result in that object being - * unsafely passed to the computing function as type {@code K}, and unsafely stored in the map. - * - *

If {@link Map#put} is called before a computation completes, other threads waiting on the - * computation will wake up and return the stored value. - * - *

This method does not alter the state of this {@code MapMaker} instance, so it can be invoked - * again to create multiple independent maps. - * - *

Insertion, removal, update, and access operations on the returned map safely execute - * concurrently by multiple threads. Iterators on the returned map are weakly consistent, - * returning elements reflecting the state of the map at some point at or since the creation of - * the iterator. They do not throw {@link ConcurrentModificationException}, and may proceed - * concurrently with other operations. - * - *

The bulk operations {@code putAll}, {@code equals}, and {@code clear} are not guaranteed to - * be performed atomically on the returned map. Additionally, {@code size} and {@code - * containsValue} are implemented as bulk read operations, and thus may fail to observe concurrent - * writes. - * - * @param computingFunction the function used to compute new values - * @return a serializable concurrent map having the requested features - * @deprecated Caching functionality in {@code MapMaker} has been moved to - * {@link com.google.common.cache.CacheBuilder}, with {@link #makeComputingMap} being replaced - * by {@link com.google.common.cache.CacheBuilder#build}. See the - * MapMaker - * Migration Guide for more details. - */ - @Deprecated - @Override - ConcurrentMap makeComputingMap(Function computingFunction) { - return (nullRemovalCause == null) - ? new MapMaker.ComputingMapAdapter(this, computingFunction) - : new NullComputingConcurrentMap(this, computingFunction); - } - - /** - * Returns a string representation for this MapMaker instance. The exact form of the returned - * string is not specificed. - */ - @Override - public String toString() { - MoreObjects.ToStringHelper s = MoreObjects.toStringHelper(this); - if (initialCapacity != UNSET_INT) { - s.add("initialCapacity", initialCapacity); - } - if (concurrencyLevel != UNSET_INT) { - s.add("concurrencyLevel", concurrencyLevel); - } - if (maximumSize != UNSET_INT) { - s.add("maximumSize", maximumSize); - } - if (expireAfterWriteNanos != UNSET_INT) { - s.add("expireAfterWrite", expireAfterWriteNanos + "ns"); - } - if (expireAfterAccessNanos != UNSET_INT) { - s.add("expireAfterAccess", expireAfterAccessNanos + "ns"); - } - if (keyStrength != null) { - s.add("keyStrength", Ascii.toLowerCase(keyStrength.toString())); - } - if (valueStrength != null) { - s.add("valueStrength", Ascii.toLowerCase(valueStrength.toString())); - } - if (keyEquivalence != null) { - s.addValue("keyEquivalence"); - } - if (removalListener != null) { - s.addValue("removalListener"); - } - return s.toString(); - } - - /** - * An object that can receive a notification when an entry is removed from a map. The removal - * resulting in notification could have occured to an entry being manually removed or replaced, or - * due to eviction resulting from timed expiration, exceeding a maximum size, or garbage - * collection. - * - *

An instance may be called concurrently by multiple threads to process different entries. - * Implementations of this interface should avoid performing blocking calls or synchronizing on - * shared resources. - * - * @param the most general type of keys this listener can listen for; for - * example {@code Object} if any key is acceptable - * @param the most general type of values this listener can listen for; for - * example {@code Object} if any key is acceptable - */ - interface RemovalListener { - /** - * Notifies the listener that a removal occurred at some point in the past. - */ - void onRemoval(RemovalNotification notification); - } - - /** - * A notification of the removal of a single entry. The key or value may be null if it was already - * garbage collected. - * - *

Like other {@code Map.Entry} instances associated with MapMaker, this class holds strong - * references to the key and value, regardless of the type of references the map may be using. - */ - static final class RemovalNotification extends ImmutableEntry { - private static final long serialVersionUID = 0; - - private final RemovalCause cause; - - RemovalNotification(@Nullable K key, @Nullable V value, RemovalCause cause) { - super(key, value); - this.cause = cause; - } - - /** - * Returns the cause for which the entry was removed. - */ - public RemovalCause getCause() { - return cause; - } - - /** - * Returns {@code true} if there was an automatic removal due to eviction (the cause is neither - * {@link RemovalCause#EXPLICIT} nor {@link RemovalCause#REPLACED}). - */ - public boolean wasEvicted() { - return cause.wasEvicted(); - } - } - - /** - * The reason why an entry was removed. - */ - enum RemovalCause { - /** - * The entry was manually removed by the user. This can result from the user invoking - * {@link Map#remove}, {@link ConcurrentMap#remove}, or {@link java.util.Iterator#remove}. - */ - EXPLICIT { - @Override - boolean wasEvicted() { - return false; - } - }, - - /** - * The entry itself was not actually removed, but its value was replaced by the user. This can - * result from the user invoking {@link Map#put}, {@link Map#putAll}, - * {@link ConcurrentMap#replace(Object, Object)}, or - * {@link ConcurrentMap#replace(Object, Object, Object)}. - */ - REPLACED { - @Override - boolean wasEvicted() { - return false; - } - }, - - /** - * The entry was removed automatically because its key or value was garbage-collected. This can - * occur when using {@link #softValues}, {@link #weakKeys}, or {@link #weakValues}. - */ - COLLECTED { - @Override - boolean wasEvicted() { - return true; - } - }, - - /** - * The entry's expiration timestamp has passed. This can occur when using {@link - * #expireAfterWrite} or {@link #expireAfterAccess}. - */ - EXPIRED { - @Override - boolean wasEvicted() { - return true; - } - }, - - /** - * The entry was evicted due to size constraints. This can occur when using {@link - * #maximumSize}. - */ - SIZE { - @Override - boolean wasEvicted() { - return true; - } - }; - - /** - * Returns {@code true} if there was an automatic removal due to eviction (the cause is neither - * {@link #EXPLICIT} nor {@link #REPLACED}). - */ - abstract boolean wasEvicted(); - } - - /** A map that is always empty and evicts on insertion. */ - static class NullConcurrentMap extends AbstractMap - implements ConcurrentMap, Serializable { - private static final long serialVersionUID = 0; - - private final RemovalListener removalListener; - private final RemovalCause removalCause; - - NullConcurrentMap(MapMaker mapMaker) { - removalListener = mapMaker.getRemovalListener(); - removalCause = mapMaker.nullRemovalCause; - } - - // implements ConcurrentMap - - @Override - public boolean containsKey(@Nullable Object key) { - return false; - } - - @Override - public boolean containsValue(@Nullable Object value) { - return false; - } - - @Override - public V get(@Nullable Object key) { - return null; - } - - void notifyRemoval(K key, V value) { - RemovalNotification notification = - new RemovalNotification(key, value, removalCause); - removalListener.onRemoval(notification); - } - - @Override - public V put(K key, V value) { - checkNotNull(key); - checkNotNull(value); - notifyRemoval(key, value); - return null; - } - - @Override - public V putIfAbsent(K key, V value) { - return put(key, value); - } - - @Override - public V remove(@Nullable Object key) { - return null; - } - - @Override - public boolean remove(@Nullable Object key, @Nullable Object value) { - return false; - } - - @Override - public V replace(K key, V value) { - checkNotNull(key); - checkNotNull(value); - return null; - } - - @Override - public boolean replace(K key, @Nullable V oldValue, V newValue) { - checkNotNull(key); - checkNotNull(newValue); - return false; - } - - @Override - public Set> entrySet() { - return Collections.emptySet(); - } - } - - /** Computes on retrieval and evicts the result. */ - static final class NullComputingConcurrentMap extends NullConcurrentMap { - private static final long serialVersionUID = 0; - - final Function computingFunction; - - NullComputingConcurrentMap( - MapMaker mapMaker, Function computingFunction) { - super(mapMaker); - this.computingFunction = checkNotNull(computingFunction); - } - - @SuppressWarnings("unchecked") // unsafe, which is why Cache is preferred - @Override - public V get(Object k) { - K key = (K) k; - V value = compute(key); - checkNotNull(value, "%s returned null for key %s.", computingFunction, key); - notifyRemoval(key, value); - return value; - } - - private V compute(K key) { - checkNotNull(key); - try { - return computingFunction.apply(key); - } catch (ComputationException e) { - throw e; - } catch (Throwable t) { - throw new ComputationException(t); - } - } - } - - /** - * Overrides get() to compute on demand. Also throws an exception when {@code null} is returned - * from a computation. - */ - /* - * This might make more sense in ComputingConcurrentHashMap, but it causes a javac crash in some - * cases there: http://code.google.com/p/guava-libraries/issues/detail?id=950 - */ - static final class ComputingMapAdapter extends ComputingConcurrentHashMap - implements Serializable { - private static final long serialVersionUID = 0; - - ComputingMapAdapter(MapMaker mapMaker, Function computingFunction) { - super(mapMaker, computingFunction); - } - - @SuppressWarnings("unchecked") // unsafe, which is one advantage of Cache over Map - @Override - public V get(Object key) { - V value; - try { - value = getOrCompute((K) key); - } catch (ExecutionException e) { - Throwable cause = e.getCause(); - Throwables.propagateIfInstanceOf(cause, ComputationException.class); - throw new ComputationException(cause); - } - - if (value == null) { - throw new NullPointerException(computingFunction + " returned null for key " + key + "."); - } - return value; - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/MapMakerInternalMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/MapMakerInternalMap.java deleted file mode 100644 index a7af6e8b9298..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/MapMakerInternalMap.java +++ /dev/null @@ -1,4092 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.CollectPreconditions.checkRemove; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Equivalence; -import com.google.common.base.Ticker; -import com.google.common.collect.GenericMapMaker.NullListener; -import com.google.common.collect.MapMaker.RemovalCause; -import com.google.common.collect.MapMaker.RemovalListener; -import com.google.common.collect.MapMaker.RemovalNotification; -import com.google.common.primitives.Ints; -import com.google.j2objc.annotations.Weak; -import com.google.j2objc.annotations.WeakOuter; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.SoftReference; -import java.lang.ref.WeakReference; -import java.util.AbstractCollection; -import java.util.AbstractMap; -import java.util.AbstractQueue; -import java.util.AbstractSet; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Queue; -import java.util.Set; -import java.util.concurrent.CancellationException; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReferenceArray; -import java.util.concurrent.locks.ReentrantLock; -import com.google.common.logging.Level; -import com.google.common.logging.Logger; - -import javax.annotation.Nullable; -import javax.annotation.concurrent.GuardedBy; - -/** - * The concurrent hash map implementation built by {@link MapMaker}. - * - *

This implementation is heavily derived from revision 1.96 of ConcurrentHashMap.java. - * - * @author Bob Lee - * @author Charles Fry - * @author Doug Lea ({@code ConcurrentHashMap}) - */ -class MapMakerInternalMap extends AbstractMap - implements ConcurrentMap, Serializable { - - /* - * The basic strategy is to subdivide the table among Segments, each of which itself is a - * concurrently readable hash table. The map supports non-blocking reads and concurrent writes - * across different segments. - * - * If a maximum size is specified, a best-effort bounding is performed per segment, using a - * page-replacement algorithm to determine which entries to evict when the capacity has been - * exceeded. - * - * The page replacement algorithm's data structures are kept casually consistent with the map. The - * ordering of writes to a segment is sequentially consistent. An update to the map and recording - * of reads may not be immediately reflected on the algorithm's data structures. These structures - * are guarded by a lock and operations are applied in batches to avoid lock contention. The - * penalty of applying the batches is spread across threads so that the amortized cost is slightly - * higher than performing just the operation without enforcing the capacity constraint. - * - * This implementation uses a per-segment queue to record a memento of the additions, removals, - * and accesses that were performed on the map. The queue is drained on writes and when it exceeds - * its capacity threshold. - * - * The Least Recently Used page replacement algorithm was chosen due to its simplicity, high hit - * rate, and ability to be implemented with O(1) time complexity. The initial LRU implementation - * operates per-segment rather than globally for increased implementation simplicity. We expect - * the cache hit rate to be similar to that of a global LRU algorithm. - */ - - // Constants - - /** - * The maximum capacity, used if a higher value is implicitly specified by either of the - * constructors with arguments. MUST be a power of two <= 1<<30 to ensure that entries are - * indexable using ints. - */ - static final int MAXIMUM_CAPACITY = Ints.MAX_POWER_OF_TWO; - - /** The maximum number of segments to allow; used to bound constructor arguments. */ - static final int MAX_SEGMENTS = 1 << 16; // slightly conservative - - /** Number of (unsynchronized) retries in the containsValue method. */ - static final int CONTAINS_VALUE_RETRIES = 3; - - /** - * Number of cache access operations that can be buffered per segment before the cache's recency - * ordering information is updated. This is used to avoid lock contention by recording a memento - * of reads and delaying a lock acquisition until the threshold is crossed or a mutation occurs. - * - *

This must be a (2^n)-1 as it is used as a mask. - */ - static final int DRAIN_THRESHOLD = 0x3F; - - /** - * Maximum number of entries to be drained in a single cleanup run. This applies independently to - * the cleanup queue and both reference queues. - */ - // TODO(fry): empirically optimize this - static final int DRAIN_MAX = 16; - - static final long CLEANUP_EXECUTOR_DELAY_SECS = 60; - - // Fields - - private static final Logger logger = Logger.getLogger(MapMakerInternalMap.class.getName()); - - /** - * Mask value for indexing into segments. The upper bits of a key's hash code are used to choose - * the segment. - */ - final transient int segmentMask; - - /** - * Shift value for indexing within segments. Helps prevent entries that end up in the same segment - * from also ending up in the same bucket. - */ - final transient int segmentShift; - - /** The segments, each of which is a specialized hash table. */ - final transient Segment[] segments; - - /** The concurrency level. */ - final int concurrencyLevel; - - /** Strategy for comparing keys. */ - final Equivalence keyEquivalence; - - /** Strategy for comparing values. */ - final Equivalence valueEquivalence; - - /** Strategy for referencing keys. */ - final Strength keyStrength; - - /** Strategy for referencing values. */ - final Strength valueStrength; - - /** The maximum size of this map. MapMaker.UNSET_INT if there is no maximum. */ - final int maximumSize; - - /** How long after the last access to an entry the map will retain that entry. */ - final long expireAfterAccessNanos; - - /** How long after the last write to an entry the map will retain that entry. */ - final long expireAfterWriteNanos; - - /** Entries waiting to be consumed by the removal listener. */ - // TODO(fry): define a new type which creates event objects and automates the clear logic - final Queue> removalNotificationQueue; - - /** - * A listener that is invoked when an entry is removed due to expiration or garbage collection of - * soft/weak entries. - */ - final RemovalListener removalListener; - - /** Factory used to create new entries. */ - final transient EntryFactory entryFactory; - - /** Measures time in a testable way. */ - final Ticker ticker; - - /** - * Creates a new, empty map with the specified strategy, initial capacity and concurrency level. - */ - MapMakerInternalMap(MapMaker builder) { - concurrencyLevel = Math.min(builder.getConcurrencyLevel(), MAX_SEGMENTS); - - keyStrength = builder.getKeyStrength(); - valueStrength = builder.getValueStrength(); - - keyEquivalence = builder.getKeyEquivalence(); - valueEquivalence = valueStrength.defaultEquivalence(); - - maximumSize = builder.maximumSize; - expireAfterAccessNanos = builder.getExpireAfterAccessNanos(); - expireAfterWriteNanos = builder.getExpireAfterWriteNanos(); - - entryFactory = EntryFactory.getFactory(keyStrength, expires(), evictsBySize()); - ticker = builder.getTicker(); - - removalListener = builder.getRemovalListener(); - removalNotificationQueue = - (removalListener == NullListener.INSTANCE) - ? MapMakerInternalMap.>discardingQueue() - : new ConcurrentLinkedQueue>(); - - int initialCapacity = Math.min(builder.getInitialCapacity(), MAXIMUM_CAPACITY); - if (evictsBySize()) { - initialCapacity = Math.min(initialCapacity, maximumSize); - } - - // Find power-of-two sizes best matching arguments. Constraints: - // (segmentCount <= maximumSize) - // && (concurrencyLevel > maximumSize || segmentCount > concurrencyLevel) - int segmentShift = 0; - int segmentCount = 1; - while (segmentCount < concurrencyLevel - && (!evictsBySize() || segmentCount * 2 <= maximumSize)) { - ++segmentShift; - segmentCount <<= 1; - } - this.segmentShift = 32 - segmentShift; - segmentMask = segmentCount - 1; - - this.segments = newSegmentArray(segmentCount); - - int segmentCapacity = initialCapacity / segmentCount; - if (segmentCapacity * segmentCount < initialCapacity) { - ++segmentCapacity; - } - - int segmentSize = 1; - while (segmentSize < segmentCapacity) { - segmentSize <<= 1; - } - - if (evictsBySize()) { - // Ensure sum of segment max sizes = overall max size - int maximumSegmentSize = maximumSize / segmentCount + 1; - int remainder = maximumSize % segmentCount; - for (int i = 0; i < this.segments.length; ++i) { - if (i == remainder) { - maximumSegmentSize--; - } - this.segments[i] = createSegment(segmentSize, maximumSegmentSize); - } - } else { - for (int i = 0; i < this.segments.length; ++i) { - this.segments[i] = createSegment(segmentSize, MapMaker.UNSET_INT); - } - } - } - - boolean evictsBySize() { - return maximumSize != MapMaker.UNSET_INT; - } - - boolean expires() { - return expiresAfterWrite() || expiresAfterAccess(); - } - - boolean expiresAfterWrite() { - return expireAfterWriteNanos > 0; - } - - boolean expiresAfterAccess() { - return expireAfterAccessNanos > 0; - } - - boolean usesKeyReferences() { - return keyStrength != Strength.STRONG; - } - - boolean usesValueReferences() { - return valueStrength != Strength.STRONG; - } - - enum Strength { - /* - * TODO(kevinb): If we strongly reference the value and aren't computing, we needn't wrap the - * value. This could save ~8 bytes per entry. - */ - - STRONG { - @Override - ValueReference referenceValue( - Segment segment, ReferenceEntry entry, V value) { - return new StrongValueReference(value); - } - - @Override - Equivalence defaultEquivalence() { - return Equivalence.equals(); - } - }, - - SOFT { - @Override - ValueReference referenceValue( - Segment segment, ReferenceEntry entry, V value) { - return new SoftValueReference(segment.valueReferenceQueue, value, entry); - } - - @Override - Equivalence defaultEquivalence() { - return Equivalence.identity(); - } - }, - - WEAK { - @Override - ValueReference referenceValue( - Segment segment, ReferenceEntry entry, V value) { - return new WeakValueReference(segment.valueReferenceQueue, value, entry); - } - - @Override - Equivalence defaultEquivalence() { - return Equivalence.identity(); - } - }; - - /** - * Creates a reference for the given value according to this value strength. - */ - abstract ValueReference referenceValue( - Segment segment, ReferenceEntry entry, V value); - - /** - * Returns the default equivalence strategy used to compare and hash keys or values referenced - * at this strength. This strategy will be used unless the user explicitly specifies an - * alternate strategy. - */ - abstract Equivalence defaultEquivalence(); - } - - /** - * Creates new entries. - */ - enum EntryFactory { - STRONG { - @Override - ReferenceEntry newEntry( - Segment segment, K key, int hash, @Nullable ReferenceEntry next) { - return new StrongEntry(key, hash, next); - } - }, - STRONG_EXPIRABLE { - @Override - ReferenceEntry newEntry( - Segment segment, K key, int hash, @Nullable ReferenceEntry next) { - return new StrongExpirableEntry(key, hash, next); - } - - @Override - ReferenceEntry copyEntry( - Segment segment, ReferenceEntry original, ReferenceEntry newNext) { - ReferenceEntry newEntry = super.copyEntry(segment, original, newNext); - copyExpirableEntry(original, newEntry); - return newEntry; - } - }, - STRONG_EVICTABLE { - @Override - ReferenceEntry newEntry( - Segment segment, K key, int hash, @Nullable ReferenceEntry next) { - return new StrongEvictableEntry(key, hash, next); - } - - @Override - ReferenceEntry copyEntry( - Segment segment, ReferenceEntry original, ReferenceEntry newNext) { - ReferenceEntry newEntry = super.copyEntry(segment, original, newNext); - copyEvictableEntry(original, newEntry); - return newEntry; - } - }, - STRONG_EXPIRABLE_EVICTABLE { - @Override - ReferenceEntry newEntry( - Segment segment, K key, int hash, @Nullable ReferenceEntry next) { - return new StrongExpirableEvictableEntry(key, hash, next); - } - - @Override - ReferenceEntry copyEntry( - Segment segment, ReferenceEntry original, ReferenceEntry newNext) { - ReferenceEntry newEntry = super.copyEntry(segment, original, newNext); - copyExpirableEntry(original, newEntry); - copyEvictableEntry(original, newEntry); - return newEntry; - } - }, - - WEAK { - @Override - ReferenceEntry newEntry( - Segment segment, K key, int hash, @Nullable ReferenceEntry next) { - return new WeakEntry(segment.keyReferenceQueue, key, hash, next); - } - }, - WEAK_EXPIRABLE { - @Override - ReferenceEntry newEntry( - Segment segment, K key, int hash, @Nullable ReferenceEntry next) { - return new WeakExpirableEntry(segment.keyReferenceQueue, key, hash, next); - } - - @Override - ReferenceEntry copyEntry( - Segment segment, ReferenceEntry original, ReferenceEntry newNext) { - ReferenceEntry newEntry = super.copyEntry(segment, original, newNext); - copyExpirableEntry(original, newEntry); - return newEntry; - } - }, - WEAK_EVICTABLE { - @Override - ReferenceEntry newEntry( - Segment segment, K key, int hash, @Nullable ReferenceEntry next) { - return new WeakEvictableEntry(segment.keyReferenceQueue, key, hash, next); - } - - @Override - ReferenceEntry copyEntry( - Segment segment, ReferenceEntry original, ReferenceEntry newNext) { - ReferenceEntry newEntry = super.copyEntry(segment, original, newNext); - copyEvictableEntry(original, newEntry); - return newEntry; - } - }, - WEAK_EXPIRABLE_EVICTABLE { - @Override - ReferenceEntry newEntry( - Segment segment, K key, int hash, @Nullable ReferenceEntry next) { - return new WeakExpirableEvictableEntry(segment.keyReferenceQueue, key, hash, next); - } - - @Override - ReferenceEntry copyEntry( - Segment segment, ReferenceEntry original, ReferenceEntry newNext) { - ReferenceEntry newEntry = super.copyEntry(segment, original, newNext); - copyExpirableEntry(original, newEntry); - copyEvictableEntry(original, newEntry); - return newEntry; - } - }; - - /** - * Masks used to compute indices in the following table. - */ - static final int EXPIRABLE_MASK = 1; - - static final int EVICTABLE_MASK = 2; - - /** - * Look-up table for factories. First dimension is the reference type. The second dimension is - * the result of OR-ing the feature masks. - */ - static final EntryFactory[][] factories = { - {STRONG, STRONG_EXPIRABLE, STRONG_EVICTABLE, STRONG_EXPIRABLE_EVICTABLE}, - {}, // no support for SOFT keys - {WEAK, WEAK_EXPIRABLE, WEAK_EVICTABLE, WEAK_EXPIRABLE_EVICTABLE} - }; - - static EntryFactory getFactory( - Strength keyStrength, boolean expireAfterWrite, boolean evictsBySize) { - int flags = (expireAfterWrite ? EXPIRABLE_MASK : 0) | (evictsBySize ? EVICTABLE_MASK : 0); - return factories[keyStrength.ordinal()][flags]; - } - - /** - * Creates a new entry. - * - * @param segment to create the entry for - * @param key of the entry - * @param hash of the key - * @param next entry in the same bucket - */ - abstract ReferenceEntry newEntry( - Segment segment, K key, int hash, @Nullable ReferenceEntry next); - - /** - * Copies an entry, assigning it a new {@code next} entry. - * - * @param original the entry to copy - * @param newNext entry in the same bucket - */ - // Guarded By Segment.this - ReferenceEntry copyEntry( - Segment segment, ReferenceEntry original, ReferenceEntry newNext) { - return newEntry(segment, original.getKey(), original.getHash(), newNext); - } - - // Guarded By Segment.this - void copyExpirableEntry(ReferenceEntry original, ReferenceEntry newEntry) { - // TODO(fry): when we link values instead of entries this method can go - // away, as can connectExpirables, nullifyExpirable. - newEntry.setExpirationTime(original.getExpirationTime()); - - connectExpirables(original.getPreviousExpirable(), newEntry); - connectExpirables(newEntry, original.getNextExpirable()); - - nullifyExpirable(original); - } - - // Guarded By Segment.this - void copyEvictableEntry(ReferenceEntry original, ReferenceEntry newEntry) { - // TODO(fry): when we link values instead of entries this method can go - // away, as can connectEvictables, nullifyEvictable. - connectEvictables(original.getPreviousEvictable(), newEntry); - connectEvictables(newEntry, original.getNextEvictable()); - - nullifyEvictable(original); - } - } - - /** - * A reference to a value. - */ - interface ValueReference { - /** - * Gets the value. Does not block or throw exceptions. - */ - V get(); - - /** - * Waits for a value that may still be computing. Unlike get(), this method can block (in the - * case of FutureValueReference). - * - * @throws ExecutionException if the computing thread throws an exception - */ - V waitForValue() throws ExecutionException; - - /** - * Returns the entry associated with this value reference, or {@code null} if this value - * reference is independent of any entry. - */ - ReferenceEntry getEntry(); - - /** - * Creates a copy of this reference for the given entry. - * - *

{@code value} may be null only for a loading reference. - */ - ValueReference copyFor( - ReferenceQueue queue, @Nullable V value, ReferenceEntry entry); - - /** - * Clears this reference object. - * - * @param newValue the new value reference which will replace this one; this is only used during - * computation to immediately notify blocked threads of the new value - */ - void clear(@Nullable ValueReference newValue); - - /** - * Returns {@code true} if the value type is a computing reference (regardless of whether or not - * computation has completed). This is necessary to distiguish between partially-collected - * entries and computing entries, which need to be cleaned up differently. - */ - boolean isComputingReference(); - } - - /** - * Placeholder. Indicates that the value hasn't been set yet. - */ - static final ValueReference UNSET = - new ValueReference() { - @Override - public Object get() { - return null; - } - - @Override - public ReferenceEntry getEntry() { - return null; - } - - @Override - public ValueReference copyFor( - ReferenceQueue queue, - @Nullable Object value, - ReferenceEntry entry) { - return this; - } - - @Override - public boolean isComputingReference() { - return false; - } - - @Override - public Object waitForValue() { - return null; - } - - @Override - public void clear(ValueReference newValue) {} - }; - - /** - * Singleton placeholder that indicates a value is being computed. - */ - @SuppressWarnings("unchecked") // impl never uses a parameter or returns any non-null value - static ValueReference unset() { - return (ValueReference) UNSET; - } - - /** - * An entry in a reference map. - * - * Entries in the map can be in the following states: - * - * Valid: - * - Live: valid key/value are set - * - Computing: computation is pending - * - * Invalid: - * - Expired: time expired (key/value may still be set) - * - Collected: key/value was partially collected, but not yet cleaned up - */ - interface ReferenceEntry { - /** - * Gets the value reference from this entry. - */ - ValueReference getValueReference(); - - /** - * Sets the value reference for this entry. - */ - void setValueReference(ValueReference valueReference); - - /** - * Gets the next entry in the chain. - */ - ReferenceEntry getNext(); - - /** - * Gets the entry's hash. - */ - int getHash(); - - /** - * Gets the key for this entry. - */ - K getKey(); - - /* - * Used by entries that are expirable. Expirable entries are maintained in a doubly-linked list. - * New entries are added at the tail of the list at write time; stale entries are expired from - * the head of the list. - */ - - /** - * Gets the entry expiration time in ns. - */ - long getExpirationTime(); - - /** - * Sets the entry expiration time in ns. - */ - void setExpirationTime(long time); - - /** - * Gets the next entry in the recency list. - */ - ReferenceEntry getNextExpirable(); - - /** - * Sets the next entry in the recency list. - */ - void setNextExpirable(ReferenceEntry next); - - /** - * Gets the previous entry in the recency list. - */ - ReferenceEntry getPreviousExpirable(); - - /** - * Sets the previous entry in the recency list. - */ - void setPreviousExpirable(ReferenceEntry previous); - - /* - * Implemented by entries that are evictable. Evictable entries are maintained in a - * doubly-linked list. New entries are added at the tail of the list at write time and stale - * entries are expired from the head of the list. - */ - - /** - * Gets the next entry in the recency list. - */ - ReferenceEntry getNextEvictable(); - - /** - * Sets the next entry in the recency list. - */ - void setNextEvictable(ReferenceEntry next); - - /** - * Gets the previous entry in the recency list. - */ - ReferenceEntry getPreviousEvictable(); - - /** - * Sets the previous entry in the recency list. - */ - void setPreviousEvictable(ReferenceEntry previous); - } - - private enum NullEntry implements ReferenceEntry { - INSTANCE; - - @Override - public ValueReference getValueReference() { - return null; - } - - @Override - public void setValueReference(ValueReference valueReference) {} - - @Override - public ReferenceEntry getNext() { - return null; - } - - @Override - public int getHash() { - return 0; - } - - @Override - public Object getKey() { - return null; - } - - @Override - public long getExpirationTime() { - return 0; - } - - @Override - public void setExpirationTime(long time) {} - - @Override - public ReferenceEntry getNextExpirable() { - return this; - } - - @Override - public void setNextExpirable(ReferenceEntry next) {} - - @Override - public ReferenceEntry getPreviousExpirable() { - return this; - } - - @Override - public void setPreviousExpirable(ReferenceEntry previous) {} - - @Override - public ReferenceEntry getNextEvictable() { - return this; - } - - @Override - public void setNextEvictable(ReferenceEntry next) {} - - @Override - public ReferenceEntry getPreviousEvictable() { - return this; - } - - @Override - public void setPreviousEvictable(ReferenceEntry previous) {} - } - - abstract static class AbstractReferenceEntry implements ReferenceEntry { - @Override - public ValueReference getValueReference() { - throw new UnsupportedOperationException(); - } - - @Override - public void setValueReference(ValueReference valueReference) { - throw new UnsupportedOperationException(); - } - - @Override - public ReferenceEntry getNext() { - throw new UnsupportedOperationException(); - } - - @Override - public int getHash() { - throw new UnsupportedOperationException(); - } - - @Override - public K getKey() { - throw new UnsupportedOperationException(); - } - - @Override - public long getExpirationTime() { - throw new UnsupportedOperationException(); - } - - @Override - public void setExpirationTime(long time) { - throw new UnsupportedOperationException(); - } - - @Override - public ReferenceEntry getNextExpirable() { - throw new UnsupportedOperationException(); - } - - @Override - public void setNextExpirable(ReferenceEntry next) { - throw new UnsupportedOperationException(); - } - - @Override - public ReferenceEntry getPreviousExpirable() { - throw new UnsupportedOperationException(); - } - - @Override - public void setPreviousExpirable(ReferenceEntry previous) { - throw new UnsupportedOperationException(); - } - - @Override - public ReferenceEntry getNextEvictable() { - throw new UnsupportedOperationException(); - } - - @Override - public void setNextEvictable(ReferenceEntry next) { - throw new UnsupportedOperationException(); - } - - @Override - public ReferenceEntry getPreviousEvictable() { - throw new UnsupportedOperationException(); - } - - @Override - public void setPreviousEvictable(ReferenceEntry previous) { - throw new UnsupportedOperationException(); - } - } - - @SuppressWarnings("unchecked") // impl never uses a parameter or returns any non-null value - static ReferenceEntry nullEntry() { - return (ReferenceEntry) NullEntry.INSTANCE; - } - - static final Queue DISCARDING_QUEUE = - new AbstractQueue() { - @Override - public boolean offer(Object o) { - return true; - } - - @Override - public Object peek() { - return null; - } - - @Override - public Object poll() { - return null; - } - - @Override - public int size() { - return 0; - } - - @Override - public Iterator iterator() { - return Iterators.emptyIterator(); - } - }; - - /** - * Queue that discards all elements. - */ - @SuppressWarnings("unchecked") // impl never uses a parameter or returns any non-null value - static Queue discardingQueue() { - return (Queue) DISCARDING_QUEUE; - } - - /* - * Note: All of this duplicate code sucks, but it saves a lot of memory. If only Java had mixins! - * To maintain this code, make a change for the strong reference type. Then, cut and paste, and - * replace "Strong" with "Soft" or "Weak" within the pasted text. The primary difference is that - * strong entries store the key reference directly while soft and weak entries delegate to their - * respective superclasses. - */ - - /** - * Used for strongly-referenced keys. - */ - static class StrongEntry implements ReferenceEntry { - final K key; - - StrongEntry(K key, int hash, @Nullable ReferenceEntry next) { - this.key = key; - this.hash = hash; - this.next = next; - } - - @Override - public K getKey() { - return this.key; - } - - // null expiration - - @Override - public long getExpirationTime() { - throw new UnsupportedOperationException(); - } - - @Override - public void setExpirationTime(long time) { - throw new UnsupportedOperationException(); - } - - @Override - public ReferenceEntry getNextExpirable() { - throw new UnsupportedOperationException(); - } - - @Override - public void setNextExpirable(ReferenceEntry next) { - throw new UnsupportedOperationException(); - } - - @Override - public ReferenceEntry getPreviousExpirable() { - throw new UnsupportedOperationException(); - } - - @Override - public void setPreviousExpirable(ReferenceEntry previous) { - throw new UnsupportedOperationException(); - } - - // null eviction - - @Override - public ReferenceEntry getNextEvictable() { - throw new UnsupportedOperationException(); - } - - @Override - public void setNextEvictable(ReferenceEntry next) { - throw new UnsupportedOperationException(); - } - - @Override - public ReferenceEntry getPreviousEvictable() { - throw new UnsupportedOperationException(); - } - - @Override - public void setPreviousEvictable(ReferenceEntry previous) { - throw new UnsupportedOperationException(); - } - - // The code below is exactly the same for each entry type. - - final int hash; - final ReferenceEntry next; - volatile ValueReference valueReference = unset(); - - @Override - public ValueReference getValueReference() { - return valueReference; - } - - @Override - public void setValueReference(ValueReference valueReference) { - ValueReference previous = this.valueReference; - this.valueReference = valueReference; - previous.clear(valueReference); - } - - @Override - public int getHash() { - return hash; - } - - @Override - public ReferenceEntry getNext() { - return next; - } - } - - static final class StrongExpirableEntry extends StrongEntry - implements ReferenceEntry { - StrongExpirableEntry(K key, int hash, @Nullable ReferenceEntry next) { - super(key, hash, next); - } - - // The code below is exactly the same for each expirable entry type. - - volatile long time = Long.MAX_VALUE; - - @Override - public long getExpirationTime() { - return time; - } - - @Override - public void setExpirationTime(long time) { - this.time = time; - } - - // Guarded By Segment.this - ReferenceEntry nextExpirable = nullEntry(); - - @Override - public ReferenceEntry getNextExpirable() { - return nextExpirable; - } - - @Override - public void setNextExpirable(ReferenceEntry next) { - this.nextExpirable = next; - } - - // Guarded By Segment.this - ReferenceEntry previousExpirable = nullEntry(); - - @Override - public ReferenceEntry getPreviousExpirable() { - return previousExpirable; - } - - @Override - public void setPreviousExpirable(ReferenceEntry previous) { - this.previousExpirable = previous; - } - } - - static final class StrongEvictableEntry extends StrongEntry - implements ReferenceEntry { - StrongEvictableEntry(K key, int hash, @Nullable ReferenceEntry next) { - super(key, hash, next); - } - - // The code below is exactly the same for each evictable entry type. - - // Guarded By Segment.this - ReferenceEntry nextEvictable = nullEntry(); - - @Override - public ReferenceEntry getNextEvictable() { - return nextEvictable; - } - - @Override - public void setNextEvictable(ReferenceEntry next) { - this.nextEvictable = next; - } - - // Guarded By Segment.this - ReferenceEntry previousEvictable = nullEntry(); - - @Override - public ReferenceEntry getPreviousEvictable() { - return previousEvictable; - } - - @Override - public void setPreviousEvictable(ReferenceEntry previous) { - this.previousEvictable = previous; - } - } - - static final class StrongExpirableEvictableEntry extends StrongEntry - implements ReferenceEntry { - StrongExpirableEvictableEntry(K key, int hash, @Nullable ReferenceEntry next) { - super(key, hash, next); - } - - // The code below is exactly the same for each expirable entry type. - - volatile long time = Long.MAX_VALUE; - - @Override - public long getExpirationTime() { - return time; - } - - @Override - public void setExpirationTime(long time) { - this.time = time; - } - - // Guarded By Segment.this - ReferenceEntry nextExpirable = nullEntry(); - - @Override - public ReferenceEntry getNextExpirable() { - return nextExpirable; - } - - @Override - public void setNextExpirable(ReferenceEntry next) { - this.nextExpirable = next; - } - - // Guarded By Segment.this - ReferenceEntry previousExpirable = nullEntry(); - - @Override - public ReferenceEntry getPreviousExpirable() { - return previousExpirable; - } - - @Override - public void setPreviousExpirable(ReferenceEntry previous) { - this.previousExpirable = previous; - } - - // The code below is exactly the same for each evictable entry type. - - // Guarded By Segment.this - ReferenceEntry nextEvictable = nullEntry(); - - @Override - public ReferenceEntry getNextEvictable() { - return nextEvictable; - } - - @Override - public void setNextEvictable(ReferenceEntry next) { - this.nextEvictable = next; - } - - // Guarded By Segment.this - ReferenceEntry previousEvictable = nullEntry(); - - @Override - public ReferenceEntry getPreviousEvictable() { - return previousEvictable; - } - - @Override - public void setPreviousEvictable(ReferenceEntry previous) { - this.previousEvictable = previous; - } - } - - /** - * Used for softly-referenced keys. - */ - static class SoftEntry extends SoftReference implements ReferenceEntry { - SoftEntry(ReferenceQueue queue, K key, int hash, @Nullable ReferenceEntry next) { - super(key, queue); - this.hash = hash; - this.next = next; - } - - @Override - public K getKey() { - return get(); - } - - // null expiration - @Override - public long getExpirationTime() { - throw new UnsupportedOperationException(); - } - - @Override - public void setExpirationTime(long time) { - throw new UnsupportedOperationException(); - } - - @Override - public ReferenceEntry getNextExpirable() { - throw new UnsupportedOperationException(); - } - - @Override - public void setNextExpirable(ReferenceEntry next) { - throw new UnsupportedOperationException(); - } - - @Override - public ReferenceEntry getPreviousExpirable() { - throw new UnsupportedOperationException(); - } - - @Override - public void setPreviousExpirable(ReferenceEntry previous) { - throw new UnsupportedOperationException(); - } - - // null eviction - - @Override - public ReferenceEntry getNextEvictable() { - throw new UnsupportedOperationException(); - } - - @Override - public void setNextEvictable(ReferenceEntry next) { - throw new UnsupportedOperationException(); - } - - @Override - public ReferenceEntry getPreviousEvictable() { - throw new UnsupportedOperationException(); - } - - @Override - public void setPreviousEvictable(ReferenceEntry previous) { - throw new UnsupportedOperationException(); - } - - // The code below is exactly the same for each entry type. - - final int hash; - final ReferenceEntry next; - volatile ValueReference valueReference = unset(); - - @Override - public ValueReference getValueReference() { - return valueReference; - } - - @Override - public void setValueReference(ValueReference valueReference) { - ValueReference previous = this.valueReference; - this.valueReference = valueReference; - previous.clear(valueReference); - } - - @Override - public int getHash() { - return hash; - } - - @Override - public ReferenceEntry getNext() { - return next; - } - } - - static final class SoftExpirableEntry extends SoftEntry - implements ReferenceEntry { - SoftExpirableEntry( - ReferenceQueue queue, K key, int hash, @Nullable ReferenceEntry next) { - super(queue, key, hash, next); - } - - // The code below is exactly the same for each expirable entry type. - - volatile long time = Long.MAX_VALUE; - - @Override - public long getExpirationTime() { - return time; - } - - @Override - public void setExpirationTime(long time) { - this.time = time; - } - - // Guarded By Segment.this - ReferenceEntry nextExpirable = nullEntry(); - - @Override - public ReferenceEntry getNextExpirable() { - return nextExpirable; - } - - @Override - public void setNextExpirable(ReferenceEntry next) { - this.nextExpirable = next; - } - - // Guarded By Segment.this - ReferenceEntry previousExpirable = nullEntry(); - - @Override - public ReferenceEntry getPreviousExpirable() { - return previousExpirable; - } - - @Override - public void setPreviousExpirable(ReferenceEntry previous) { - this.previousExpirable = previous; - } - } - - static final class SoftEvictableEntry extends SoftEntry - implements ReferenceEntry { - SoftEvictableEntry( - ReferenceQueue queue, K key, int hash, @Nullable ReferenceEntry next) { - super(queue, key, hash, next); - } - - // The code below is exactly the same for each evictable entry type. - - // Guarded By Segment.this - ReferenceEntry nextEvictable = nullEntry(); - - @Override - public ReferenceEntry getNextEvictable() { - return nextEvictable; - } - - @Override - public void setNextEvictable(ReferenceEntry next) { - this.nextEvictable = next; - } - - // Guarded By Segment.this - ReferenceEntry previousEvictable = nullEntry(); - - @Override - public ReferenceEntry getPreviousEvictable() { - return previousEvictable; - } - - @Override - public void setPreviousEvictable(ReferenceEntry previous) { - this.previousEvictable = previous; - } - } - - static final class SoftExpirableEvictableEntry extends SoftEntry - implements ReferenceEntry { - SoftExpirableEvictableEntry( - ReferenceQueue queue, K key, int hash, @Nullable ReferenceEntry next) { - super(queue, key, hash, next); - } - - // The code below is exactly the same for each expirable entry type. - - volatile long time = Long.MAX_VALUE; - - @Override - public long getExpirationTime() { - return time; - } - - @Override - public void setExpirationTime(long time) { - this.time = time; - } - - // Guarded By Segment.this - ReferenceEntry nextExpirable = nullEntry(); - - @Override - public ReferenceEntry getNextExpirable() { - return nextExpirable; - } - - @Override - public void setNextExpirable(ReferenceEntry next) { - this.nextExpirable = next; - } - - // Guarded By Segment.this - ReferenceEntry previousExpirable = nullEntry(); - - @Override - public ReferenceEntry getPreviousExpirable() { - return previousExpirable; - } - - @Override - public void setPreviousExpirable(ReferenceEntry previous) { - this.previousExpirable = previous; - } - - // The code below is exactly the same for each evictable entry type. - - // Guarded By Segment.this - ReferenceEntry nextEvictable = nullEntry(); - - @Override - public ReferenceEntry getNextEvictable() { - return nextEvictable; - } - - @Override - public void setNextEvictable(ReferenceEntry next) { - this.nextEvictable = next; - } - - // Guarded By Segment.this - ReferenceEntry previousEvictable = nullEntry(); - - @Override - public ReferenceEntry getPreviousEvictable() { - return previousEvictable; - } - - @Override - public void setPreviousEvictable(ReferenceEntry previous) { - this.previousEvictable = previous; - } - } - - /** - * Used for weakly-referenced keys. - */ - static class WeakEntry extends WeakReference implements ReferenceEntry { - WeakEntry(ReferenceQueue queue, K key, int hash, @Nullable ReferenceEntry next) { - super(key, queue); - this.hash = hash; - this.next = next; - } - - @Override - public K getKey() { - return get(); - } - - // null expiration - - @Override - public long getExpirationTime() { - throw new UnsupportedOperationException(); - } - - @Override - public void setExpirationTime(long time) { - throw new UnsupportedOperationException(); - } - - @Override - public ReferenceEntry getNextExpirable() { - throw new UnsupportedOperationException(); - } - - @Override - public void setNextExpirable(ReferenceEntry next) { - throw new UnsupportedOperationException(); - } - - @Override - public ReferenceEntry getPreviousExpirable() { - throw new UnsupportedOperationException(); - } - - @Override - public void setPreviousExpirable(ReferenceEntry previous) { - throw new UnsupportedOperationException(); - } - - // null eviction - - @Override - public ReferenceEntry getNextEvictable() { - throw new UnsupportedOperationException(); - } - - @Override - public void setNextEvictable(ReferenceEntry next) { - throw new UnsupportedOperationException(); - } - - @Override - public ReferenceEntry getPreviousEvictable() { - throw new UnsupportedOperationException(); - } - - @Override - public void setPreviousEvictable(ReferenceEntry previous) { - throw new UnsupportedOperationException(); - } - - // The code below is exactly the same for each entry type. - - final int hash; - final ReferenceEntry next; - volatile ValueReference valueReference = unset(); - - @Override - public ValueReference getValueReference() { - return valueReference; - } - - @Override - public void setValueReference(ValueReference valueReference) { - ValueReference previous = this.valueReference; - this.valueReference = valueReference; - previous.clear(valueReference); - } - - @Override - public int getHash() { - return hash; - } - - @Override - public ReferenceEntry getNext() { - return next; - } - } - - static final class WeakExpirableEntry extends WeakEntry - implements ReferenceEntry { - WeakExpirableEntry( - ReferenceQueue queue, K key, int hash, @Nullable ReferenceEntry next) { - super(queue, key, hash, next); - } - - // The code below is exactly the same for each expirable entry type. - - volatile long time = Long.MAX_VALUE; - - @Override - public long getExpirationTime() { - return time; - } - - @Override - public void setExpirationTime(long time) { - this.time = time; - } - - // Guarded By Segment.this - ReferenceEntry nextExpirable = nullEntry(); - - @Override - public ReferenceEntry getNextExpirable() { - return nextExpirable; - } - - @Override - public void setNextExpirable(ReferenceEntry next) { - this.nextExpirable = next; - } - - // Guarded By Segment.this - ReferenceEntry previousExpirable = nullEntry(); - - @Override - public ReferenceEntry getPreviousExpirable() { - return previousExpirable; - } - - @Override - public void setPreviousExpirable(ReferenceEntry previous) { - this.previousExpirable = previous; - } - } - - static final class WeakEvictableEntry extends WeakEntry - implements ReferenceEntry { - WeakEvictableEntry( - ReferenceQueue queue, K key, int hash, @Nullable ReferenceEntry next) { - super(queue, key, hash, next); - } - - // The code below is exactly the same for each evictable entry type. - - // Guarded By Segment.this - ReferenceEntry nextEvictable = nullEntry(); - - @Override - public ReferenceEntry getNextEvictable() { - return nextEvictable; - } - - @Override - public void setNextEvictable(ReferenceEntry next) { - this.nextEvictable = next; - } - - // Guarded By Segment.this - ReferenceEntry previousEvictable = nullEntry(); - - @Override - public ReferenceEntry getPreviousEvictable() { - return previousEvictable; - } - - @Override - public void setPreviousEvictable(ReferenceEntry previous) { - this.previousEvictable = previous; - } - } - - static final class WeakExpirableEvictableEntry extends WeakEntry - implements ReferenceEntry { - WeakExpirableEvictableEntry( - ReferenceQueue queue, K key, int hash, @Nullable ReferenceEntry next) { - super(queue, key, hash, next); - } - - // The code below is exactly the same for each expirable entry type. - - volatile long time = Long.MAX_VALUE; - - @Override - public long getExpirationTime() { - return time; - } - - @Override - public void setExpirationTime(long time) { - this.time = time; - } - - // Guarded By Segment.this - ReferenceEntry nextExpirable = nullEntry(); - - @Override - public ReferenceEntry getNextExpirable() { - return nextExpirable; - } - - @Override - public void setNextExpirable(ReferenceEntry next) { - this.nextExpirable = next; - } - - // Guarded By Segment.this - ReferenceEntry previousExpirable = nullEntry(); - - @Override - public ReferenceEntry getPreviousExpirable() { - return previousExpirable; - } - - @Override - public void setPreviousExpirable(ReferenceEntry previous) { - this.previousExpirable = previous; - } - - // The code below is exactly the same for each evictable entry type. - - // Guarded By Segment.this - ReferenceEntry nextEvictable = nullEntry(); - - @Override - public ReferenceEntry getNextEvictable() { - return nextEvictable; - } - - @Override - public void setNextEvictable(ReferenceEntry next) { - this.nextEvictable = next; - } - - // Guarded By Segment.this - ReferenceEntry previousEvictable = nullEntry(); - - @Override - public ReferenceEntry getPreviousEvictable() { - return previousEvictable; - } - - @Override - public void setPreviousEvictable(ReferenceEntry previous) { - this.previousEvictable = previous; - } - } - - /** - * References a weak value. - */ - static final class WeakValueReference extends WeakReference - implements ValueReference { - final ReferenceEntry entry; - - WeakValueReference(ReferenceQueue queue, V referent, ReferenceEntry entry) { - super(referent, queue); - this.entry = entry; - } - - @Override - public ReferenceEntry getEntry() { - return entry; - } - - @Override - public void clear(ValueReference newValue) { - clear(); - } - - @Override - public ValueReference copyFor( - ReferenceQueue queue, V value, ReferenceEntry entry) { - return new WeakValueReference(queue, value, entry); - } - - @Override - public boolean isComputingReference() { - return false; - } - - @Override - public V waitForValue() { - return get(); - } - } - - /** - * References a soft value. - */ - static final class SoftValueReference extends SoftReference - implements ValueReference { - final ReferenceEntry entry; - - SoftValueReference(ReferenceQueue queue, V referent, ReferenceEntry entry) { - super(referent, queue); - this.entry = entry; - } - - @Override - public ReferenceEntry getEntry() { - return entry; - } - - @Override - public void clear(ValueReference newValue) { - clear(); - } - - @Override - public ValueReference copyFor( - ReferenceQueue queue, V value, ReferenceEntry entry) { - return new SoftValueReference(queue, value, entry); - } - - @Override - public boolean isComputingReference() { - return false; - } - - @Override - public V waitForValue() { - return get(); - } - } - - /** - * References a strong value. - */ - static final class StrongValueReference implements ValueReference { - final V referent; - - StrongValueReference(V referent) { - this.referent = referent; - } - - @Override - public V get() { - return referent; - } - - @Override - public ReferenceEntry getEntry() { - return null; - } - - @Override - public ValueReference copyFor( - ReferenceQueue queue, V value, ReferenceEntry entry) { - return this; - } - - @Override - public boolean isComputingReference() { - return false; - } - - @Override - public V waitForValue() { - return get(); - } - - @Override - public void clear(ValueReference newValue) {} - } - - /** - * Applies a supplemental hash function to a given hash code, which defends against poor quality - * hash functions. This is critical when the concurrent hash map uses power-of-two length hash - * tables, that otherwise encounter collisions for hash codes that do not differ in lower or - * upper bits. - * - * @param h hash code - */ - static int rehash(int h) { - // Spread bits to regularize both segment and index locations, - // using variant of single-word Wang/Jenkins hash. - // TODO(kevinb): use Hashing/move this to Hashing? - h += (h << 15) ^ 0xffffcd7d; - h ^= (h >>> 10); - h += (h << 3); - h ^= (h >>> 6); - h += (h << 2) + (h << 14); - return h ^ (h >>> 16); - } - - /** - * This method is a convenience for testing. Code should call {@link Segment#newEntry} directly. - */ - // Guarded By Segment.this - @VisibleForTesting - ReferenceEntry newEntry(K key, int hash, @Nullable ReferenceEntry next) { - return segmentFor(hash).newEntry(key, hash, next); - } - - /** - * This method is a convenience for testing. Code should call {@link Segment#copyEntry} directly. - */ - // Guarded By Segment.this - @VisibleForTesting - ReferenceEntry copyEntry(ReferenceEntry original, ReferenceEntry newNext) { - int hash = original.getHash(); - return segmentFor(hash).copyEntry(original, newNext); - } - - /** - * This method is a convenience for testing. Code should call {@link Segment#setValue} instead. - */ - // Guarded By Segment.this - @VisibleForTesting - ValueReference newValueReference(ReferenceEntry entry, V value) { - int hash = entry.getHash(); - return valueStrength.referenceValue(segmentFor(hash), entry, value); - } - - int hash(Object key) { - int h = keyEquivalence.hash(key); - return rehash(h); - } - - void reclaimValue(ValueReference valueReference) { - ReferenceEntry entry = valueReference.getEntry(); - int hash = entry.getHash(); - segmentFor(hash).reclaimValue(entry.getKey(), hash, valueReference); - } - - void reclaimKey(ReferenceEntry entry) { - int hash = entry.getHash(); - segmentFor(hash).reclaimKey(entry, hash); - } - - /** - * This method is a convenience for testing. Code should call {@link Segment#getLiveValue} - * instead. - */ - @VisibleForTesting - boolean isLive(ReferenceEntry entry) { - return segmentFor(entry.getHash()).getLiveValue(entry) != null; - } - - /** - * Returns the segment that should be used for a key with the given hash. - * - * @param hash the hash code for the key - * @return the segment - */ - Segment segmentFor(int hash) { - // TODO(fry): Lazily create segments? - return segments[(hash >>> segmentShift) & segmentMask]; - } - - Segment createSegment(int initialCapacity, int maxSegmentSize) { - return new Segment(this, initialCapacity, maxSegmentSize); - } - - /** - * Gets the value from an entry. Returns {@code null} if the entry is invalid, - * partially-collected, computing, or expired. Unlike {@link Segment#getLiveValue} this method - * does not attempt to clean up stale entries. - */ - V getLiveValue(ReferenceEntry entry) { - if (entry.getKey() == null) { - return null; - } - V value = entry.getValueReference().get(); - if (value == null) { - return null; - } - - if (expires() && isExpired(entry)) { - return null; - } - return value; - } - - // expiration - - /** - * Returns {@code true} if the entry has expired. - */ - boolean isExpired(ReferenceEntry entry) { - return isExpired(entry, ticker.read()); - } - - /** - * Returns {@code true} if the entry has expired. - */ - boolean isExpired(ReferenceEntry entry, long now) { - // if the expiration time had overflowed, this "undoes" the overflow - return now - entry.getExpirationTime() > 0; - } - - // Guarded By Segment.this - static void connectExpirables(ReferenceEntry previous, ReferenceEntry next) { - previous.setNextExpirable(next); - next.setPreviousExpirable(previous); - } - - // Guarded By Segment.this - static void nullifyExpirable(ReferenceEntry nulled) { - ReferenceEntry nullEntry = nullEntry(); - nulled.setNextExpirable(nullEntry); - nulled.setPreviousExpirable(nullEntry); - } - - // eviction - - /** - * Notifies listeners that an entry has been automatically removed due to expiration, eviction, - * or eligibility for garbage collection. This should be called every time expireEntries or - * evictEntry is called (once the lock is released). - */ - void processPendingNotifications() { - RemovalNotification notification; - while ((notification = removalNotificationQueue.poll()) != null) { - try { - removalListener.onRemoval(notification); - } catch (Exception e) { - logger.log(Level.WARNING, "Exception thrown by removal listener", e); - } - } - } - - /** Links the evitables together. */ - // Guarded By Segment.this - static void connectEvictables(ReferenceEntry previous, ReferenceEntry next) { - previous.setNextEvictable(next); - next.setPreviousEvictable(previous); - } - - // Guarded By Segment.this - static void nullifyEvictable(ReferenceEntry nulled) { - ReferenceEntry nullEntry = nullEntry(); - nulled.setNextEvictable(nullEntry); - nulled.setPreviousEvictable(nullEntry); - } - - @SuppressWarnings("unchecked") - final Segment[] newSegmentArray(int ssize) { - return new Segment[ssize]; - } - - // Inner Classes - - /** - * Segments are specialized versions of hash tables. This subclass inherits from ReentrantLock - * opportunistically, just to simplify some locking and avoid separate construction. - */ - @SuppressWarnings("serial") // This class is never serialized. - static class Segment extends ReentrantLock { - - /* - * TODO(fry): Consider copying variables (like evictsBySize) from outer class into this class. - * It will require more memory but will reduce indirection. - */ - - /* - * Segments maintain a table of entry lists that are ALWAYS kept in a consistent state, so can - * be read without locking. Next fields of nodes are immutable (final). All list additions are - * performed at the front of each bin. This makes it easy to check changes, and also fast to - * traverse. When nodes would otherwise be changed, new nodes are created to replace them. This - * works well for hash tables since the bin lists tend to be short. (The average length is less - * than two.) - * - * Read operations can thus proceed without locking, but rely on selected uses of volatiles to - * ensure that completed write operations performed by other threads are noticed. For most - * purposes, the "count" field, tracking the number of elements, serves as that volatile - * variable ensuring visibility. This is convenient because this field needs to be read in many - * read operations anyway: - * - * - All (unsynchronized) read operations must first read the "count" field, and should not - * look at table entries if it is 0. - * - * - All (synchronized) write operations should write to the "count" field after structurally - * changing any bin. The operations must not take any action that could even momentarily - * cause a concurrent read operation to see inconsistent data. This is made easier by the - * nature of the read operations in Map. For example, no operation can reveal that the table - * has grown but the threshold has not yet been updated, so there are no atomicity requirements - * for this with respect to reads. - * - * As a guide, all critical volatile reads and writes to the count field are marked in code - * comments. - */ - - @Weak final MapMakerInternalMap map; - - /** - * The number of live elements in this segment's region. This does not include unset elements - * which are awaiting cleanup. - */ - volatile int count; - - /** - * Number of updates that alter the size of the table. This is used during bulk-read methods to - * make sure they see a consistent snapshot: If modCounts change during a traversal of segments - * computing size or checking containsValue, then we might have an inconsistent view of state - * so (usually) must retry. - */ - int modCount; - - /** - * The table is expanded when its size exceeds this threshold. (The value of this field is - * always {@code (int) (capacity * 0.75)}.) - */ - int threshold; - - /** - * The per-segment table. - */ - volatile AtomicReferenceArray> table; - - /** - * The maximum size of this map. MapMaker.UNSET_INT if there is no maximum. - */ - final int maxSegmentSize; - - /** - * The key reference queue contains entries whose keys have been garbage collected, and which - * need to be cleaned up internally. - */ - final ReferenceQueue keyReferenceQueue; - - /** - * The value reference queue contains value references whose values have been garbage collected, - * and which need to be cleaned up internally. - */ - final ReferenceQueue valueReferenceQueue; - - /** - * The recency queue is used to record which entries were accessed for updating the eviction - * list's ordering. It is drained as a batch operation when either the DRAIN_THRESHOLD is - * crossed or a write occurs on the segment. - */ - final Queue> recencyQueue; - - /** - * A counter of the number of reads since the last write, used to drain queues on a small - * fraction of read operations. - */ - final AtomicInteger readCount = new AtomicInteger(); - - /** - * A queue of elements currently in the map, ordered by access time. Elements are added to the - * tail of the queue on access/write. - */ - @GuardedBy("this") - final Queue> evictionQueue; - - /** - * A queue of elements currently in the map, ordered by expiration time (either access or write - * time). Elements are added to the tail of the queue on access/write. - */ - @GuardedBy("this") - final Queue> expirationQueue; - - Segment(MapMakerInternalMap map, int initialCapacity, int maxSegmentSize) { - this.map = map; - this.maxSegmentSize = maxSegmentSize; - initTable(newEntryArray(initialCapacity)); - - keyReferenceQueue = map.usesKeyReferences() ? new ReferenceQueue() : null; - - valueReferenceQueue = map.usesValueReferences() ? new ReferenceQueue() : null; - - recencyQueue = - (map.evictsBySize() || map.expiresAfterAccess()) - ? new ConcurrentLinkedQueue>() - : MapMakerInternalMap.>discardingQueue(); - - evictionQueue = - map.evictsBySize() - ? new EvictionQueue() - : MapMakerInternalMap.>discardingQueue(); - - expirationQueue = - map.expires() - ? new ExpirationQueue() - : MapMakerInternalMap.>discardingQueue(); - } - - AtomicReferenceArray> newEntryArray(int size) { - return new AtomicReferenceArray>(size); - } - - void initTable(AtomicReferenceArray> newTable) { - this.threshold = newTable.length() * 3 / 4; // 0.75 - if (this.threshold == maxSegmentSize) { - // prevent spurious expansion before eviction - this.threshold++; - } - this.table = newTable; - } - - @GuardedBy("this") - ReferenceEntry newEntry(K key, int hash, @Nullable ReferenceEntry next) { - return map.entryFactory.newEntry(this, key, hash, next); - } - - /** - * Copies {@code original} into a new entry chained to {@code newNext}. Returns the new entry, - * or {@code null} if {@code original} was already garbage collected. - */ - @GuardedBy("this") - ReferenceEntry copyEntry(ReferenceEntry original, ReferenceEntry newNext) { - if (original.getKey() == null) { - // key collected - return null; - } - - ValueReference valueReference = original.getValueReference(); - V value = valueReference.get(); - if ((value == null) && !valueReference.isComputingReference()) { - // value collected - return null; - } - - ReferenceEntry newEntry = map.entryFactory.copyEntry(this, original, newNext); - newEntry.setValueReference(valueReference.copyFor(this.valueReferenceQueue, value, newEntry)); - return newEntry; - } - - /** - * Sets a new value of an entry. Adds newly created entries at the end of the expiration queue. - */ - @GuardedBy("this") - void setValue(ReferenceEntry entry, V value) { - ValueReference valueReference = map.valueStrength.referenceValue(this, entry, value); - entry.setValueReference(valueReference); - recordWrite(entry); - } - - // reference queues, for garbage collection cleanup - - /** - * Cleanup collected entries when the lock is available. - */ - void tryDrainReferenceQueues() { - if (tryLock()) { - try { - drainReferenceQueues(); - } finally { - unlock(); - } - } - } - - /** - * Drain the key and value reference queues, cleaning up internal entries containing garbage - * collected keys or values. - */ - @GuardedBy("this") - void drainReferenceQueues() { - if (map.usesKeyReferences()) { - drainKeyReferenceQueue(); - } - if (map.usesValueReferences()) { - drainValueReferenceQueue(); - } - } - - @GuardedBy("this") - void drainKeyReferenceQueue() { - Reference ref; - int i = 0; - while ((ref = keyReferenceQueue.poll()) != null) { - @SuppressWarnings("unchecked") - ReferenceEntry entry = (ReferenceEntry) ref; - map.reclaimKey(entry); - if (++i == DRAIN_MAX) { - break; - } - } - } - - @GuardedBy("this") - void drainValueReferenceQueue() { - Reference ref; - int i = 0; - while ((ref = valueReferenceQueue.poll()) != null) { - @SuppressWarnings("unchecked") - ValueReference valueReference = (ValueReference) ref; - map.reclaimValue(valueReference); - if (++i == DRAIN_MAX) { - break; - } - } - } - - /** - * Clears all entries from the key and value reference queues. - */ - void clearReferenceQueues() { - if (map.usesKeyReferences()) { - clearKeyReferenceQueue(); - } - if (map.usesValueReferences()) { - clearValueReferenceQueue(); - } - } - - void clearKeyReferenceQueue() { - while (keyReferenceQueue.poll() != null) {} - } - - void clearValueReferenceQueue() { - while (valueReferenceQueue.poll() != null) {} - } - - // recency queue, shared by expiration and eviction - - /** - * Records the relative order in which this read was performed by adding {@code entry} to the - * recency queue. At write-time, or when the queue is full past the threshold, the queue will - * be drained and the entries therein processed. - * - *

Note: locked reads should use {@link #recordLockedRead}. - */ - void recordRead(ReferenceEntry entry) { - if (map.expiresAfterAccess()) { - recordExpirationTime(entry, map.expireAfterAccessNanos); - } - recencyQueue.add(entry); - } - - /** - * Updates the eviction metadata that {@code entry} was just read. This currently amounts to - * adding {@code entry} to relevant eviction lists. - * - *

Note: this method should only be called under lock, as it directly manipulates the - * eviction queues. Unlocked reads should use {@link #recordRead}. - */ - @GuardedBy("this") - void recordLockedRead(ReferenceEntry entry) { - evictionQueue.add(entry); - if (map.expiresAfterAccess()) { - recordExpirationTime(entry, map.expireAfterAccessNanos); - expirationQueue.add(entry); - } - } - - /** - * Updates eviction metadata that {@code entry} was just written. This currently amounts to - * adding {@code entry} to relevant eviction lists. - */ - @GuardedBy("this") - void recordWrite(ReferenceEntry entry) { - // we are already under lock, so drain the recency queue immediately - drainRecencyQueue(); - evictionQueue.add(entry); - if (map.expires()) { - // currently MapMaker ensures that expireAfterWrite and - // expireAfterAccess are mutually exclusive - long expiration = - map.expiresAfterAccess() ? map.expireAfterAccessNanos : map.expireAfterWriteNanos; - recordExpirationTime(entry, expiration); - expirationQueue.add(entry); - } - } - - /** - * Drains the recency queue, updating eviction metadata that the entries therein were read in - * the specified relative order. This currently amounts to adding them to relevant eviction - * lists (accounting for the fact that they could have been removed from the map since being - * added to the recency queue). - */ - @GuardedBy("this") - void drainRecencyQueue() { - ReferenceEntry e; - while ((e = recencyQueue.poll()) != null) { - // An entry may be in the recency queue despite it being removed from - // the map . This can occur when the entry was concurrently read while a - // writer is removing it from the segment or after a clear has removed - // all of the segment's entries. - if (evictionQueue.contains(e)) { - evictionQueue.add(e); - } - if (map.expiresAfterAccess() && expirationQueue.contains(e)) { - expirationQueue.add(e); - } - } - } - - // expiration - - void recordExpirationTime(ReferenceEntry entry, long expirationNanos) { - // might overflow, but that's okay (see isExpired()) - entry.setExpirationTime(map.ticker.read() + expirationNanos); - } - - /** - * Cleanup expired entries when the lock is available. - */ - void tryExpireEntries() { - if (tryLock()) { - try { - expireEntries(); - } finally { - unlock(); - // don't call postWriteCleanup as we're in a read - } - } - } - - @GuardedBy("this") - void expireEntries() { - drainRecencyQueue(); - - if (expirationQueue.isEmpty()) { - // There's no point in calling nanoTime() if we have no entries to - // expire. - return; - } - long now = map.ticker.read(); - ReferenceEntry e; - while ((e = expirationQueue.peek()) != null && map.isExpired(e, now)) { - if (!removeEntry(e, e.getHash(), RemovalCause.EXPIRED)) { - throw new AssertionError(); - } - } - } - - // eviction - - void enqueueNotification(ReferenceEntry entry, RemovalCause cause) { - enqueueNotification(entry.getKey(), entry.getHash(), entry.getValueReference().get(), cause); - } - - void enqueueNotification(@Nullable K key, int hash, @Nullable V value, RemovalCause cause) { - if (map.removalNotificationQueue != DISCARDING_QUEUE) { - RemovalNotification notification = new RemovalNotification(key, value, cause); - map.removalNotificationQueue.offer(notification); - } - } - - /** - * Performs eviction if the segment is full. This should only be called prior to adding a new - * entry and increasing {@code count}. - * - * @return {@code true} if eviction occurred - */ - @GuardedBy("this") - boolean evictEntries() { - if (map.evictsBySize() && count >= maxSegmentSize) { - drainRecencyQueue(); - - ReferenceEntry e = evictionQueue.remove(); - if (!removeEntry(e, e.getHash(), RemovalCause.SIZE)) { - throw new AssertionError(); - } - return true; - } - return false; - } - - /** - * Returns first entry of bin for given hash. - */ - ReferenceEntry getFirst(int hash) { - // read this volatile field only once - AtomicReferenceArray> table = this.table; - return table.get(hash & (table.length() - 1)); - } - - // Specialized implementations of map methods - - ReferenceEntry getEntry(Object key, int hash) { - if (count != 0) { // read-volatile - for (ReferenceEntry e = getFirst(hash); e != null; e = e.getNext()) { - if (e.getHash() != hash) { - continue; - } - - K entryKey = e.getKey(); - if (entryKey == null) { - tryDrainReferenceQueues(); - continue; - } - - if (map.keyEquivalence.equivalent(key, entryKey)) { - return e; - } - } - } - - return null; - } - - ReferenceEntry getLiveEntry(Object key, int hash) { - ReferenceEntry e = getEntry(key, hash); - if (e == null) { - return null; - } else if (map.expires() && map.isExpired(e)) { - tryExpireEntries(); - return null; - } - return e; - } - - V get(Object key, int hash) { - try { - ReferenceEntry e = getLiveEntry(key, hash); - if (e == null) { - return null; - } - - V value = e.getValueReference().get(); - if (value != null) { - recordRead(e); - } else { - tryDrainReferenceQueues(); - } - return value; - } finally { - postReadCleanup(); - } - } - - boolean containsKey(Object key, int hash) { - try { - if (count != 0) { // read-volatile - ReferenceEntry e = getLiveEntry(key, hash); - if (e == null) { - return false; - } - return e.getValueReference().get() != null; - } - - return false; - } finally { - postReadCleanup(); - } - } - - /** - * This method is a convenience for testing. Code should call {@link - * MapMakerInternalMap#containsValue} directly. - */ - @VisibleForTesting - boolean containsValue(Object value) { - try { - if (count != 0) { // read-volatile - AtomicReferenceArray> table = this.table; - int length = table.length(); - for (int i = 0; i < length; ++i) { - for (ReferenceEntry e = table.get(i); e != null; e = e.getNext()) { - V entryValue = getLiveValue(e); - if (entryValue == null) { - continue; - } - if (map.valueEquivalence.equivalent(value, entryValue)) { - return true; - } - } - } - } - - return false; - } finally { - postReadCleanup(); - } - } - - V put(K key, int hash, V value, boolean onlyIfAbsent) { - lock(); - try { - preWriteCleanup(); - - int newCount = this.count + 1; - if (newCount > this.threshold) { // ensure capacity - expand(); - newCount = this.count + 1; - } - - AtomicReferenceArray> table = this.table; - int index = hash & (table.length() - 1); - ReferenceEntry first = table.get(index); - - // Look for an existing entry. - for (ReferenceEntry e = first; e != null; e = e.getNext()) { - K entryKey = e.getKey(); - if (e.getHash() == hash - && entryKey != null - && map.keyEquivalence.equivalent(key, entryKey)) { - // We found an existing entry. - - ValueReference valueReference = e.getValueReference(); - V entryValue = valueReference.get(); - - if (entryValue == null) { - ++modCount; - setValue(e, value); - if (!valueReference.isComputingReference()) { - enqueueNotification(key, hash, entryValue, RemovalCause.COLLECTED); - newCount = this.count; // count remains unchanged - } else if (evictEntries()) { // evictEntries after setting new value - newCount = this.count + 1; - } - this.count = newCount; // write-volatile - return null; - } else if (onlyIfAbsent) { - // Mimic - // "if (!map.containsKey(key)) ... - // else return map.get(key); - recordLockedRead(e); - return entryValue; - } else { - // clobber existing entry, count remains unchanged - ++modCount; - enqueueNotification(key, hash, entryValue, RemovalCause.REPLACED); - setValue(e, value); - return entryValue; - } - } - } - - // Create a new entry. - ++modCount; - ReferenceEntry newEntry = newEntry(key, hash, first); - setValue(newEntry, value); - table.set(index, newEntry); - if (evictEntries()) { // evictEntries after setting new value - newCount = this.count + 1; - } - this.count = newCount; // write-volatile - return null; - } finally { - unlock(); - postWriteCleanup(); - } - } - - /** - * Expands the table if possible. - */ - @GuardedBy("this") - void expand() { - AtomicReferenceArray> oldTable = table; - int oldCapacity = oldTable.length(); - if (oldCapacity >= MAXIMUM_CAPACITY) { - return; - } - - /* - * Reclassify nodes in each list to new Map. Because we are using power-of-two expansion, the - * elements from each bin must either stay at same index, or move with a power of two offset. - * We eliminate unnecessary node creation by catching cases where old nodes can be reused - * because their next fields won't change. Statistically, at the default threshold, only - * about one-sixth of them need cloning when a table doubles. The nodes they replace will be - * garbage collectable as soon as they are no longer referenced by any reader thread that may - * be in the midst of traversing table right now. - */ - - int newCount = count; - AtomicReferenceArray> newTable = newEntryArray(oldCapacity << 1); - threshold = newTable.length() * 3 / 4; - int newMask = newTable.length() - 1; - for (int oldIndex = 0; oldIndex < oldCapacity; ++oldIndex) { - // We need to guarantee that any existing reads of old Map can - // proceed. So we cannot yet null out each bin. - ReferenceEntry head = oldTable.get(oldIndex); - - if (head != null) { - ReferenceEntry next = head.getNext(); - int headIndex = head.getHash() & newMask; - - // Single node on list - if (next == null) { - newTable.set(headIndex, head); - } else { - // Reuse the consecutive sequence of nodes with the same target - // index from the end of the list. tail points to the first - // entry in the reusable list. - ReferenceEntry tail = head; - int tailIndex = headIndex; - for (ReferenceEntry e = next; e != null; e = e.getNext()) { - int newIndex = e.getHash() & newMask; - if (newIndex != tailIndex) { - // The index changed. We'll need to copy the previous entry. - tailIndex = newIndex; - tail = e; - } - } - newTable.set(tailIndex, tail); - - // Clone nodes leading up to the tail. - for (ReferenceEntry e = head; e != tail; e = e.getNext()) { - int newIndex = e.getHash() & newMask; - ReferenceEntry newNext = newTable.get(newIndex); - ReferenceEntry newFirst = copyEntry(e, newNext); - if (newFirst != null) { - newTable.set(newIndex, newFirst); - } else { - removeCollectedEntry(e); - newCount--; - } - } - } - } - } - table = newTable; - this.count = newCount; - } - - boolean replace(K key, int hash, V oldValue, V newValue) { - lock(); - try { - preWriteCleanup(); - - AtomicReferenceArray> table = this.table; - int index = hash & (table.length() - 1); - ReferenceEntry first = table.get(index); - - for (ReferenceEntry e = first; e != null; e = e.getNext()) { - K entryKey = e.getKey(); - if (e.getHash() == hash - && entryKey != null - && map.keyEquivalence.equivalent(key, entryKey)) { - // If the value disappeared, this entry is partially collected, - // and we should pretend like it doesn't exist. - ValueReference valueReference = e.getValueReference(); - V entryValue = valueReference.get(); - if (entryValue == null) { - if (isCollected(valueReference)) { - int newCount = this.count - 1; - ++modCount; - enqueueNotification(entryKey, hash, entryValue, RemovalCause.COLLECTED); - ReferenceEntry newFirst = removeFromChain(first, e); - newCount = this.count - 1; - table.set(index, newFirst); - this.count = newCount; // write-volatile - } - return false; - } - - if (map.valueEquivalence.equivalent(oldValue, entryValue)) { - ++modCount; - enqueueNotification(key, hash, entryValue, RemovalCause.REPLACED); - setValue(e, newValue); - return true; - } else { - // Mimic - // "if (map.containsKey(key) && map.get(key).equals(oldValue))..." - recordLockedRead(e); - return false; - } - } - } - - return false; - } finally { - unlock(); - postWriteCleanup(); - } - } - - V replace(K key, int hash, V newValue) { - lock(); - try { - preWriteCleanup(); - - AtomicReferenceArray> table = this.table; - int index = hash & (table.length() - 1); - ReferenceEntry first = table.get(index); - - for (ReferenceEntry e = first; e != null; e = e.getNext()) { - K entryKey = e.getKey(); - if (e.getHash() == hash - && entryKey != null - && map.keyEquivalence.equivalent(key, entryKey)) { - // If the value disappeared, this entry is partially collected, - // and we should pretend like it doesn't exist. - ValueReference valueReference = e.getValueReference(); - V entryValue = valueReference.get(); - if (entryValue == null) { - if (isCollected(valueReference)) { - int newCount = this.count - 1; - ++modCount; - enqueueNotification(entryKey, hash, entryValue, RemovalCause.COLLECTED); - ReferenceEntry newFirst = removeFromChain(first, e); - newCount = this.count - 1; - table.set(index, newFirst); - this.count = newCount; // write-volatile - } - return null; - } - - ++modCount; - enqueueNotification(key, hash, entryValue, RemovalCause.REPLACED); - setValue(e, newValue); - return entryValue; - } - } - - return null; - } finally { - unlock(); - postWriteCleanup(); - } - } - - V remove(Object key, int hash) { - lock(); - try { - preWriteCleanup(); - - int newCount = this.count - 1; - AtomicReferenceArray> table = this.table; - int index = hash & (table.length() - 1); - ReferenceEntry first = table.get(index); - - for (ReferenceEntry e = first; e != null; e = e.getNext()) { - K entryKey = e.getKey(); - if (e.getHash() == hash - && entryKey != null - && map.keyEquivalence.equivalent(key, entryKey)) { - ValueReference valueReference = e.getValueReference(); - V entryValue = valueReference.get(); - - RemovalCause cause; - if (entryValue != null) { - cause = RemovalCause.EXPLICIT; - } else if (isCollected(valueReference)) { - cause = RemovalCause.COLLECTED; - } else { - return null; - } - - ++modCount; - enqueueNotification(entryKey, hash, entryValue, cause); - ReferenceEntry newFirst = removeFromChain(first, e); - newCount = this.count - 1; - table.set(index, newFirst); - this.count = newCount; // write-volatile - return entryValue; - } - } - - return null; - } finally { - unlock(); - postWriteCleanup(); - } - } - - boolean remove(Object key, int hash, Object value) { - lock(); - try { - preWriteCleanup(); - - int newCount = this.count - 1; - AtomicReferenceArray> table = this.table; - int index = hash & (table.length() - 1); - ReferenceEntry first = table.get(index); - - for (ReferenceEntry e = first; e != null; e = e.getNext()) { - K entryKey = e.getKey(); - if (e.getHash() == hash - && entryKey != null - && map.keyEquivalence.equivalent(key, entryKey)) { - ValueReference valueReference = e.getValueReference(); - V entryValue = valueReference.get(); - - RemovalCause cause; - if (map.valueEquivalence.equivalent(value, entryValue)) { - cause = RemovalCause.EXPLICIT; - } else if (isCollected(valueReference)) { - cause = RemovalCause.COLLECTED; - } else { - return false; - } - - ++modCount; - enqueueNotification(entryKey, hash, entryValue, cause); - ReferenceEntry newFirst = removeFromChain(first, e); - newCount = this.count - 1; - table.set(index, newFirst); - this.count = newCount; // write-volatile - return (cause == RemovalCause.EXPLICIT); - } - } - - return false; - } finally { - unlock(); - postWriteCleanup(); - } - } - - void clear() { - if (count != 0) { - lock(); - try { - AtomicReferenceArray> table = this.table; - if (map.removalNotificationQueue != DISCARDING_QUEUE) { - for (int i = 0; i < table.length(); ++i) { - for (ReferenceEntry e = table.get(i); e != null; e = e.getNext()) { - // Computing references aren't actually in the map yet. - if (!e.getValueReference().isComputingReference()) { - enqueueNotification(e, RemovalCause.EXPLICIT); - } - } - } - } - for (int i = 0; i < table.length(); ++i) { - table.set(i, null); - } - clearReferenceQueues(); - evictionQueue.clear(); - expirationQueue.clear(); - readCount.set(0); - - ++modCount; - count = 0; // write-volatile - } finally { - unlock(); - postWriteCleanup(); - } - } - } - - /** - * Removes an entry from within a table. All entries following the removed node can stay, but - * all preceding ones need to be cloned. - * - *

This method does not decrement count for the removed entry, but does decrement count for - * all partially collected entries which are skipped. As such callers which are modifying count - * must re-read it after calling removeFromChain. - * - * @param first the first entry of the table - * @param entry the entry being removed from the table - * @return the new first entry for the table - */ - @GuardedBy("this") - ReferenceEntry removeFromChain(ReferenceEntry first, ReferenceEntry entry) { - evictionQueue.remove(entry); - expirationQueue.remove(entry); - - int newCount = count; - ReferenceEntry newFirst = entry.getNext(); - for (ReferenceEntry e = first; e != entry; e = e.getNext()) { - ReferenceEntry next = copyEntry(e, newFirst); - if (next != null) { - newFirst = next; - } else { - removeCollectedEntry(e); - newCount--; - } - } - this.count = newCount; - return newFirst; - } - - void removeCollectedEntry(ReferenceEntry entry) { - enqueueNotification(entry, RemovalCause.COLLECTED); - evictionQueue.remove(entry); - expirationQueue.remove(entry); - } - - /** - * Removes an entry whose key has been garbage collected. - */ - boolean reclaimKey(ReferenceEntry entry, int hash) { - lock(); - try { - int newCount = count - 1; - AtomicReferenceArray> table = this.table; - int index = hash & (table.length() - 1); - ReferenceEntry first = table.get(index); - - for (ReferenceEntry e = first; e != null; e = e.getNext()) { - if (e == entry) { - ++modCount; - enqueueNotification( - e.getKey(), hash, e.getValueReference().get(), RemovalCause.COLLECTED); - ReferenceEntry newFirst = removeFromChain(first, e); - newCount = this.count - 1; - table.set(index, newFirst); - this.count = newCount; // write-volatile - return true; - } - } - - return false; - } finally { - unlock(); - postWriteCleanup(); - } - } - - /** - * Removes an entry whose value has been garbage collected. - */ - boolean reclaimValue(K key, int hash, ValueReference valueReference) { - lock(); - try { - int newCount = this.count - 1; - AtomicReferenceArray> table = this.table; - int index = hash & (table.length() - 1); - ReferenceEntry first = table.get(index); - - for (ReferenceEntry e = first; e != null; e = e.getNext()) { - K entryKey = e.getKey(); - if (e.getHash() == hash - && entryKey != null - && map.keyEquivalence.equivalent(key, entryKey)) { - ValueReference v = e.getValueReference(); - if (v == valueReference) { - ++modCount; - enqueueNotification(key, hash, valueReference.get(), RemovalCause.COLLECTED); - ReferenceEntry newFirst = removeFromChain(first, e); - newCount = this.count - 1; - table.set(index, newFirst); - this.count = newCount; // write-volatile - return true; - } - return false; - } - } - - return false; - } finally { - unlock(); - if (!isHeldByCurrentThread()) { // don't cleanup inside of put - postWriteCleanup(); - } - } - } - - /** - * Clears a value that has not yet been set, and thus does not require count to be modified. - */ - boolean clearValue(K key, int hash, ValueReference valueReference) { - lock(); - try { - AtomicReferenceArray> table = this.table; - int index = hash & (table.length() - 1); - ReferenceEntry first = table.get(index); - - for (ReferenceEntry e = first; e != null; e = e.getNext()) { - K entryKey = e.getKey(); - if (e.getHash() == hash - && entryKey != null - && map.keyEquivalence.equivalent(key, entryKey)) { - ValueReference v = e.getValueReference(); - if (v == valueReference) { - ReferenceEntry newFirst = removeFromChain(first, e); - table.set(index, newFirst); - return true; - } - return false; - } - } - - return false; - } finally { - unlock(); - postWriteCleanup(); - } - } - - @GuardedBy("this") - boolean removeEntry(ReferenceEntry entry, int hash, RemovalCause cause) { - int newCount = this.count - 1; - AtomicReferenceArray> table = this.table; - int index = hash & (table.length() - 1); - ReferenceEntry first = table.get(index); - - for (ReferenceEntry e = first; e != null; e = e.getNext()) { - if (e == entry) { - ++modCount; - enqueueNotification(e.getKey(), hash, e.getValueReference().get(), cause); - ReferenceEntry newFirst = removeFromChain(first, e); - newCount = this.count - 1; - table.set(index, newFirst); - this.count = newCount; // write-volatile - return true; - } - } - - return false; - } - - /** - * Returns {@code true} if the value has been partially collected, meaning that the value is - * null and it is not computing. - */ - boolean isCollected(ValueReference valueReference) { - if (valueReference.isComputingReference()) { - return false; - } - return (valueReference.get() == null); - } - - /** - * Gets the value from an entry. Returns {@code null} if the entry is invalid, - * partially-collected, computing, or expired. - */ - V getLiveValue(ReferenceEntry entry) { - if (entry.getKey() == null) { - tryDrainReferenceQueues(); - return null; - } - V value = entry.getValueReference().get(); - if (value == null) { - tryDrainReferenceQueues(); - return null; - } - - if (map.expires() && map.isExpired(entry)) { - tryExpireEntries(); - return null; - } - return value; - } - - /** - * Performs routine cleanup following a read. Normally cleanup happens during writes, or from - * the cleanupExecutor. If cleanup is not observed after a sufficient number of reads, try - * cleaning up from the read thread. - */ - void postReadCleanup() { - if ((readCount.incrementAndGet() & DRAIN_THRESHOLD) == 0) { - runCleanup(); - } - } - - /** - * Performs routine cleanup prior to executing a write. This should be called every time a - * write thread acquires the segment lock, immediately after acquiring the lock. - * - *

Post-condition: expireEntries has been run. - */ - @GuardedBy("this") - void preWriteCleanup() { - runLockedCleanup(); - } - - /** - * Performs routine cleanup following a write. - */ - void postWriteCleanup() { - runUnlockedCleanup(); - } - - void runCleanup() { - runLockedCleanup(); - runUnlockedCleanup(); - } - - void runLockedCleanup() { - if (tryLock()) { - try { - drainReferenceQueues(); - expireEntries(); // calls drainRecencyQueue - readCount.set(0); - } finally { - unlock(); - } - } - } - - void runUnlockedCleanup() { - // locked cleanup may generate notifications we can send unlocked - if (!isHeldByCurrentThread()) { - map.processPendingNotifications(); - } - } - } - - // Queues - - /** - * A custom queue for managing eviction order. Note that this is tightly integrated with {@code - * ReferenceEntry}, upon which it relies to perform its linking. - * - *

Note that this entire implementation makes the assumption that all elements which are in - * the map are also in this queue, and that all elements not in the queue are not in the map. - * - *

The benefits of creating our own queue are that (1) we can replace elements in the middle - * of the queue as part of copyEvictableEntry, and (2) the contains method is highly optimized - * for the current model. - */ - static final class EvictionQueue extends AbstractQueue> { - final ReferenceEntry head = - new AbstractReferenceEntry() { - - ReferenceEntry nextEvictable = this; - - @Override - public ReferenceEntry getNextEvictable() { - return nextEvictable; - } - - @Override - public void setNextEvictable(ReferenceEntry next) { - this.nextEvictable = next; - } - - ReferenceEntry previousEvictable = this; - - @Override - public ReferenceEntry getPreviousEvictable() { - return previousEvictable; - } - - @Override - public void setPreviousEvictable(ReferenceEntry previous) { - this.previousEvictable = previous; - } - }; - - // implements Queue - - @Override - public boolean offer(ReferenceEntry entry) { - // unlink - connectEvictables(entry.getPreviousEvictable(), entry.getNextEvictable()); - - // add to tail - connectEvictables(head.getPreviousEvictable(), entry); - connectEvictables(entry, head); - - return true; - } - - @Override - public ReferenceEntry peek() { - ReferenceEntry next = head.getNextEvictable(); - return (next == head) ? null : next; - } - - @Override - public ReferenceEntry poll() { - ReferenceEntry next = head.getNextEvictable(); - if (next == head) { - return null; - } - - remove(next); - return next; - } - - @Override - @SuppressWarnings("unchecked") - public boolean remove(Object o) { - ReferenceEntry e = (ReferenceEntry) o; - ReferenceEntry previous = e.getPreviousEvictable(); - ReferenceEntry next = e.getNextEvictable(); - connectEvictables(previous, next); - nullifyEvictable(e); - - return next != NullEntry.INSTANCE; - } - - @Override - @SuppressWarnings("unchecked") - public boolean contains(Object o) { - ReferenceEntry e = (ReferenceEntry) o; - return e.getNextEvictable() != NullEntry.INSTANCE; - } - - @Override - public boolean isEmpty() { - return head.getNextEvictable() == head; - } - - @Override - public int size() { - int size = 0; - for (ReferenceEntry e = head.getNextEvictable(); e != head; e = e.getNextEvictable()) { - size++; - } - return size; - } - - @Override - public void clear() { - ReferenceEntry e = head.getNextEvictable(); - while (e != head) { - ReferenceEntry next = e.getNextEvictable(); - nullifyEvictable(e); - e = next; - } - - head.setNextEvictable(head); - head.setPreviousEvictable(head); - } - - @Override - public Iterator> iterator() { - return new AbstractSequentialIterator>(peek()) { - @Override - protected ReferenceEntry computeNext(ReferenceEntry previous) { - ReferenceEntry next = previous.getNextEvictable(); - return (next == head) ? null : next; - } - }; - } - } - - /** - * A custom queue for managing expiration order. Note that this is tightly integrated with - * {@code ReferenceEntry}, upon which it reliese to perform its linking. - * - *

Note that this entire implementation makes the assumption that all elements which are in - * the map are also in this queue, and that all elements not in the queue are not in the map. - * - *

The benefits of creating our own queue are that (1) we can replace elements in the middle - * of the queue as part of copyEvictableEntry, and (2) the contains method is highly optimized - * for the current model. - */ - static final class ExpirationQueue extends AbstractQueue> { - final ReferenceEntry head = - new AbstractReferenceEntry() { - - @Override - public long getExpirationTime() { - return Long.MAX_VALUE; - } - - @Override - public void setExpirationTime(long time) {} - - ReferenceEntry nextExpirable = this; - - @Override - public ReferenceEntry getNextExpirable() { - return nextExpirable; - } - - @Override - public void setNextExpirable(ReferenceEntry next) { - this.nextExpirable = next; - } - - ReferenceEntry previousExpirable = this; - - @Override - public ReferenceEntry getPreviousExpirable() { - return previousExpirable; - } - - @Override - public void setPreviousExpirable(ReferenceEntry previous) { - this.previousExpirable = previous; - } - }; - - // implements Queue - - @Override - public boolean offer(ReferenceEntry entry) { - // unlink - connectExpirables(entry.getPreviousExpirable(), entry.getNextExpirable()); - - // add to tail - connectExpirables(head.getPreviousExpirable(), entry); - connectExpirables(entry, head); - - return true; - } - - @Override - public ReferenceEntry peek() { - ReferenceEntry next = head.getNextExpirable(); - return (next == head) ? null : next; - } - - @Override - public ReferenceEntry poll() { - ReferenceEntry next = head.getNextExpirable(); - if (next == head) { - return null; - } - - remove(next); - return next; - } - - @Override - @SuppressWarnings("unchecked") - public boolean remove(Object o) { - ReferenceEntry e = (ReferenceEntry) o; - ReferenceEntry previous = e.getPreviousExpirable(); - ReferenceEntry next = e.getNextExpirable(); - connectExpirables(previous, next); - nullifyExpirable(e); - - return next != NullEntry.INSTANCE; - } - - @Override - @SuppressWarnings("unchecked") - public boolean contains(Object o) { - ReferenceEntry e = (ReferenceEntry) o; - return e.getNextExpirable() != NullEntry.INSTANCE; - } - - @Override - public boolean isEmpty() { - return head.getNextExpirable() == head; - } - - @Override - public int size() { - int size = 0; - for (ReferenceEntry e = head.getNextExpirable(); e != head; e = e.getNextExpirable()) { - size++; - } - return size; - } - - @Override - public void clear() { - ReferenceEntry e = head.getNextExpirable(); - while (e != head) { - ReferenceEntry next = e.getNextExpirable(); - nullifyExpirable(e); - e = next; - } - - head.setNextExpirable(head); - head.setPreviousExpirable(head); - } - - @Override - public Iterator> iterator() { - return new AbstractSequentialIterator>(peek()) { - @Override - protected ReferenceEntry computeNext(ReferenceEntry previous) { - ReferenceEntry next = previous.getNextExpirable(); - return (next == head) ? null : next; - } - }; - } - } - - static final class CleanupMapTask implements Runnable { - final WeakReference> mapReference; - - public CleanupMapTask(MapMakerInternalMap map) { - this.mapReference = new WeakReference>(map); - } - - @Override - public void run() { - MapMakerInternalMap map = mapReference.get(); - if (map == null) { - throw new CancellationException(); - } - - for (Segment segment : map.segments) { - segment.runCleanup(); - } - } - } - - // ConcurrentMap methods - - @Override - public boolean isEmpty() { - /* - * Sum per-segment modCounts to avoid mis-reporting when elements are concurrently added and - * removed in one segment while checking another, in which case the table was never actually - * empty at any point. (The sum ensures accuracy up through at least 1<<31 per-segment - * modifications before recheck.) Method containsValue() uses similar constructions for - * stability checks. - */ - long sum = 0L; - Segment[] segments = this.segments; - for (int i = 0; i < segments.length; ++i) { - if (segments[i].count != 0) { - return false; - } - sum += segments[i].modCount; - } - - if (sum != 0L) { // recheck unless no modifications - for (int i = 0; i < segments.length; ++i) { - if (segments[i].count != 0) { - return false; - } - sum -= segments[i].modCount; - } - if (sum != 0L) { - return false; - } - } - return true; - } - - @Override - public int size() { - Segment[] segments = this.segments; - long sum = 0; - for (int i = 0; i < segments.length; ++i) { - sum += segments[i].count; - } - return Ints.saturatedCast(sum); - } - - @Override - public V get(@Nullable Object key) { - if (key == null) { - return null; - } - int hash = hash(key); - return segmentFor(hash).get(key, hash); - } - - /** - * Returns the internal entry for the specified key. The entry may be computing, expired, or - * partially collected. Does not impact recency ordering. - */ - ReferenceEntry getEntry(@Nullable Object key) { - if (key == null) { - return null; - } - int hash = hash(key); - return segmentFor(hash).getEntry(key, hash); - } - - @Override - public boolean containsKey(@Nullable Object key) { - if (key == null) { - return false; - } - int hash = hash(key); - return segmentFor(hash).containsKey(key, hash); - } - - @Override - public boolean containsValue(@Nullable Object value) { - if (value == null) { - return false; - } - - // This implementation is patterned after ConcurrentHashMap, but without the locking. The only - // way for it to return a false negative would be for the target value to jump around in the map - // such that none of the subsequent iterations observed it, despite the fact that at every point - // in time it was present somewhere int the map. This becomes increasingly unlikely as - // CONTAINS_VALUE_RETRIES increases, though without locking it is theoretically possible. - final Segment[] segments = this.segments; - long last = -1L; - for (int i = 0; i < CONTAINS_VALUE_RETRIES; i++) { - long sum = 0L; - for (Segment segment : segments) { - // ensure visibility of most recent completed write - int unused = segment.count; // read-volatile - - AtomicReferenceArray> table = segment.table; - for (int j = 0; j < table.length(); j++) { - for (ReferenceEntry e = table.get(j); e != null; e = e.getNext()) { - V v = segment.getLiveValue(e); - if (v != null && valueEquivalence.equivalent(value, v)) { - return true; - } - } - } - sum += segment.modCount; - } - if (sum == last) { - break; - } - last = sum; - } - return false; - } - - @Override - public V put(K key, V value) { - checkNotNull(key); - checkNotNull(value); - int hash = hash(key); - return segmentFor(hash).put(key, hash, value, false); - } - - @Override - public V putIfAbsent(K key, V value) { - checkNotNull(key); - checkNotNull(value); - int hash = hash(key); - return segmentFor(hash).put(key, hash, value, true); - } - - @Override - public void putAll(Map m) { - for (Entry e : m.entrySet()) { - put(e.getKey(), e.getValue()); - } - } - - @Override - public V remove(@Nullable Object key) { - if (key == null) { - return null; - } - int hash = hash(key); - return segmentFor(hash).remove(key, hash); - } - - @Override - public boolean remove(@Nullable Object key, @Nullable Object value) { - if (key == null || value == null) { - return false; - } - int hash = hash(key); - return segmentFor(hash).remove(key, hash, value); - } - - @Override - public boolean replace(K key, @Nullable V oldValue, V newValue) { - checkNotNull(key); - checkNotNull(newValue); - if (oldValue == null) { - return false; - } - int hash = hash(key); - return segmentFor(hash).replace(key, hash, oldValue, newValue); - } - - @Override - public V replace(K key, V value) { - checkNotNull(key); - checkNotNull(value); - int hash = hash(key); - return segmentFor(hash).replace(key, hash, value); - } - - @Override - public void clear() { - for (Segment segment : segments) { - segment.clear(); - } - } - - transient Set keySet; - - @Override - public Set keySet() { - Set ks = keySet; - return (ks != null) ? ks : (keySet = new KeySet()); - } - - transient Collection values; - - @Override - public Collection values() { - Collection vs = values; - return (vs != null) ? vs : (values = new Values()); - } - - transient Set> entrySet; - - @Override - public Set> entrySet() { - Set> es = entrySet; - return (es != null) ? es : (entrySet = new EntrySet()); - } - - // Iterator Support - - abstract class HashIterator implements Iterator { - - int nextSegmentIndex; - int nextTableIndex; - Segment currentSegment; - AtomicReferenceArray> currentTable; - ReferenceEntry nextEntry; - WriteThroughEntry nextExternal; - WriteThroughEntry lastReturned; - - HashIterator() { - nextSegmentIndex = segments.length - 1; - nextTableIndex = -1; - advance(); - } - - @Override - public abstract E next(); - - final void advance() { - nextExternal = null; - - if (nextInChain()) { - return; - } - - if (nextInTable()) { - return; - } - - while (nextSegmentIndex >= 0) { - currentSegment = segments[nextSegmentIndex--]; - if (currentSegment.count != 0) { - currentTable = currentSegment.table; - nextTableIndex = currentTable.length() - 1; - if (nextInTable()) { - return; - } - } - } - } - - /** - * Finds the next entry in the current chain. Returns {@code true} if an entry was found. - */ - boolean nextInChain() { - if (nextEntry != null) { - for (nextEntry = nextEntry.getNext(); nextEntry != null; nextEntry = nextEntry.getNext()) { - if (advanceTo(nextEntry)) { - return true; - } - } - } - return false; - } - - /** - * Finds the next entry in the current table. Returns {@code true} if an entry was found. - */ - boolean nextInTable() { - while (nextTableIndex >= 0) { - if ((nextEntry = currentTable.get(nextTableIndex--)) != null) { - if (advanceTo(nextEntry) || nextInChain()) { - return true; - } - } - } - return false; - } - - /** - * Advances to the given entry. Returns {@code true} if the entry was valid, {@code false} if it - * should be skipped. - */ - boolean advanceTo(ReferenceEntry entry) { - try { - K key = entry.getKey(); - V value = getLiveValue(entry); - if (value != null) { - nextExternal = new WriteThroughEntry(key, value); - return true; - } else { - // Skip stale entry. - return false; - } - } finally { - currentSegment.postReadCleanup(); - } - } - - @Override - public boolean hasNext() { - return nextExternal != null; - } - - WriteThroughEntry nextEntry() { - if (nextExternal == null) { - throw new NoSuchElementException(); - } - lastReturned = nextExternal; - advance(); - return lastReturned; - } - - @Override - public void remove() { - checkRemove(lastReturned != null); - MapMakerInternalMap.this.remove(lastReturned.getKey()); - lastReturned = null; - } - } - - final class KeyIterator extends HashIterator { - - @Override - public K next() { - return nextEntry().getKey(); - } - } - - final class ValueIterator extends HashIterator { - - @Override - public V next() { - return nextEntry().getValue(); - } - } - - /** - * Custom Entry class used by EntryIterator.next(), that relays setValue changes to the - * underlying map. - */ - final class WriteThroughEntry extends AbstractMapEntry { - final K key; // non-null - V value; // non-null - - WriteThroughEntry(K key, V value) { - this.key = key; - this.value = value; - } - - @Override - public K getKey() { - return key; - } - - @Override - public V getValue() { - return value; - } - - @Override - public boolean equals(@Nullable Object object) { - // Cannot use key and value equivalence - if (object instanceof Entry) { - Entry that = (Entry) object; - return key.equals(that.getKey()) && value.equals(that.getValue()); - } - return false; - } - - @Override - public int hashCode() { - // Cannot use key and value equivalence - return key.hashCode() ^ value.hashCode(); - } - - @Override - public V setValue(V newValue) { - V oldValue = put(key, newValue); - value = newValue; // only if put succeeds - return oldValue; - } - } - - final class EntryIterator extends HashIterator> { - - @Override - public Entry next() { - return nextEntry(); - } - } - - @WeakOuter - final class KeySet extends SafeToArraySet { - - @Override - public Iterator iterator() { - return new KeyIterator(); - } - - @Override - public int size() { - return MapMakerInternalMap.this.size(); - } - - @Override - public boolean isEmpty() { - return MapMakerInternalMap.this.isEmpty(); - } - - @Override - public boolean contains(Object o) { - return MapMakerInternalMap.this.containsKey(o); - } - - @Override - public boolean remove(Object o) { - return MapMakerInternalMap.this.remove(o) != null; - } - - @Override - public void clear() { - MapMakerInternalMap.this.clear(); - } - } - - @WeakOuter - final class Values extends AbstractCollection { - - @Override - public Iterator iterator() { - return new ValueIterator(); - } - - @Override - public int size() { - return MapMakerInternalMap.this.size(); - } - - @Override - public boolean isEmpty() { - return MapMakerInternalMap.this.isEmpty(); - } - - @Override - public boolean contains(Object o) { - return MapMakerInternalMap.this.containsValue(o); - } - - @Override - public void clear() { - MapMakerInternalMap.this.clear(); - } - - // super.toArray() may misbehave if size() is inaccurate, at least on old versions of Android. - // https://code.google.com/p/android/issues/detail?id=36519 / http://r.android.com/47508 - - @Override - public Object[] toArray() { - return toArrayList(this).toArray(); - } - - @Override - public E[] toArray(E[] a) { - return toArrayList(this).toArray(a); - } - } - - @WeakOuter - final class EntrySet extends SafeToArraySet> { - - @Override - public Iterator> iterator() { - return new EntryIterator(); - } - - @Override - public boolean contains(Object o) { - if (!(o instanceof Entry)) { - return false; - } - Entry e = (Entry) o; - Object key = e.getKey(); - if (key == null) { - return false; - } - V v = MapMakerInternalMap.this.get(key); - - return v != null && valueEquivalence.equivalent(e.getValue(), v); - } - - @Override - public boolean remove(Object o) { - if (!(o instanceof Entry)) { - return false; - } - Entry e = (Entry) o; - Object key = e.getKey(); - return key != null && MapMakerInternalMap.this.remove(key, e.getValue()); - } - - @Override - public int size() { - return MapMakerInternalMap.this.size(); - } - - @Override - public boolean isEmpty() { - return MapMakerInternalMap.this.isEmpty(); - } - - @Override - public void clear() { - MapMakerInternalMap.this.clear(); - } - } - - private abstract static class SafeToArraySet extends AbstractSet { - // super.toArray() may misbehave if size() is inaccurate, at least on old versions of Android. - // https://code.google.com/p/android/issues/detail?id=36519 / http://r.android.com/47508 - - @Override - public Object[] toArray() { - return toArrayList(this).toArray(); - } - - @Override - public E[] toArray(E[] a) { - return toArrayList(this).toArray(a); - } - } - - private static ArrayList toArrayList(Collection c) { - // Avoid calling ArrayList(Collection), which may call back into toArray. - ArrayList result = new ArrayList(c.size()); - Iterators.addAll(result, c.iterator()); - return result; - } - - // Serialization Support - - private static final long serialVersionUID = 5; - - Object writeReplace() { - return new SerializationProxy( - keyStrength, - valueStrength, - keyEquivalence, - valueEquivalence, - expireAfterWriteNanos, - expireAfterAccessNanos, - maximumSize, - concurrencyLevel, - removalListener, - this); - } - - /** - * The actual object that gets serialized. Unfortunately, readResolve() doesn't get called when a - * circular dependency is present, so the proxy must be able to behave as the map itself. - */ - abstract static class AbstractSerializationProxy extends ForwardingConcurrentMap - implements Serializable { - private static final long serialVersionUID = 3; - - final Strength keyStrength; - final Strength valueStrength; - final Equivalence keyEquivalence; - final Equivalence valueEquivalence; - final long expireAfterWriteNanos; - final long expireAfterAccessNanos; - final int maximumSize; - final int concurrencyLevel; - final RemovalListener removalListener; - - transient ConcurrentMap delegate; - - AbstractSerializationProxy( - Strength keyStrength, - Strength valueStrength, - Equivalence keyEquivalence, - Equivalence valueEquivalence, - long expireAfterWriteNanos, - long expireAfterAccessNanos, - int maximumSize, - int concurrencyLevel, - RemovalListener removalListener, - ConcurrentMap delegate) { - this.keyStrength = keyStrength; - this.valueStrength = valueStrength; - this.keyEquivalence = keyEquivalence; - this.valueEquivalence = valueEquivalence; - this.expireAfterWriteNanos = expireAfterWriteNanos; - this.expireAfterAccessNanos = expireAfterAccessNanos; - this.maximumSize = maximumSize; - this.concurrencyLevel = concurrencyLevel; - this.removalListener = removalListener; - this.delegate = delegate; - } - - @Override - protected ConcurrentMap delegate() { - return delegate; - } - - void writeMapTo(ObjectOutputStream out) throws IOException { - out.writeInt(delegate.size()); - for (Entry entry : delegate.entrySet()) { - out.writeObject(entry.getKey()); - out.writeObject(entry.getValue()); - } - out.writeObject(null); // terminate entries - } - - @SuppressWarnings("deprecation") // serialization of deprecated feature - MapMaker readMapMaker(ObjectInputStream in) throws IOException { - int size = in.readInt(); - MapMaker mapMaker = - new MapMaker() - .initialCapacity(size) - .setKeyStrength(keyStrength) - .setValueStrength(valueStrength) - .keyEquivalence(keyEquivalence) - .concurrencyLevel(concurrencyLevel); - mapMaker.removalListener(removalListener); - if (expireAfterWriteNanos > 0) { - mapMaker.expireAfterWrite(expireAfterWriteNanos, TimeUnit.NANOSECONDS); - } - if (expireAfterAccessNanos > 0) { - mapMaker.expireAfterAccess(expireAfterAccessNanos, TimeUnit.NANOSECONDS); - } - if (maximumSize != MapMaker.UNSET_INT) { - mapMaker.maximumSize(maximumSize); - } - return mapMaker; - } - - @SuppressWarnings("unchecked") - void readEntries(ObjectInputStream in) throws IOException, ClassNotFoundException { - while (true) { - K key = (K) in.readObject(); - if (key == null) { - break; // terminator - } - V value = (V) in.readObject(); - delegate.put(key, value); - } - } - } - - /** - * The actual object that gets serialized. Unfortunately, readResolve() doesn't get called when a - * circular dependency is present, so the proxy must be able to behave as the map itself. - */ - private static final class SerializationProxy extends AbstractSerializationProxy { - private static final long serialVersionUID = 3; - - SerializationProxy( - Strength keyStrength, - Strength valueStrength, - Equivalence keyEquivalence, - Equivalence valueEquivalence, - long expireAfterWriteNanos, - long expireAfterAccessNanos, - int maximumSize, - int concurrencyLevel, - RemovalListener removalListener, - ConcurrentMap delegate) { - super( - keyStrength, - valueStrength, - keyEquivalence, - valueEquivalence, - expireAfterWriteNanos, - expireAfterAccessNanos, - maximumSize, - concurrencyLevel, - removalListener, - delegate); - } - - private void writeObject(ObjectOutputStream out) throws IOException { - out.defaultWriteObject(); - writeMapTo(out); - } - - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - in.defaultReadObject(); - MapMaker mapMaker = readMapMaker(in); - delegate = mapMaker.makeMap(); - readEntries(in); - } - - private Object readResolve() { - return delegate; - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Maps.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Maps.java deleted file mode 100644 index 3cd4558d2a6f..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Maps.java +++ /dev/null @@ -1,4145 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Predicates.compose; -import static com.google.common.base.Predicates.equalTo; -import static com.google.common.base.Predicates.in; -import static com.google.common.base.Predicates.not; -import static com.google.common.collect.CollectPreconditions.checkNonnegative; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.base.Converter; -import com.google.common.base.Equivalence; -import com.google.common.base.Function; -import com.google.common.base.Joiner.MapJoiner; -import com.google.common.base.Objects; -import com.google.common.base.Preconditions; -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import com.google.common.collect.MapDifference.ValueDifference; -import com.google.common.primitives.Ints; -import com.google.j2objc.annotations.Weak; -import com.google.j2objc.annotations.WeakOuter; - -import java.io.Serializable; -import java.util.AbstractCollection; -import java.util.AbstractMap; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.EnumMap; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.NavigableMap; -import java.util.NavigableSet; -import java.util.Properties; -import java.util.Set; -import java.util.SortedMap; -import java.util.SortedSet; -import java.util.TreeMap; -import java.util.concurrent.ConcurrentMap; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * Static utility methods pertaining to {@link Map} instances (including instances of - * {@link SortedMap}, {@link BiMap}, etc.). Also see this class's counterparts - * {@link Lists}, {@link Sets} and {@link Queues}. - * - *

See the Guava User Guide article on - * {@code Maps}. - * - * @author Kevin Bourrillion - * @author Mike Bostock - * @author Isaac Shum - * @author Louis Wasserman - * @since 2.0 - */ -@GwtCompatible(emulated = true) -public final class Maps { - private Maps() {} - - private enum EntryFunction implements Function, Object> { - KEY { - @Override - @Nullable - public Object apply(Entry entry) { - return entry.getKey(); - } - }, - VALUE { - @Override - @Nullable - public Object apply(Entry entry) { - return entry.getValue(); - } - }; - } - - @SuppressWarnings("unchecked") - static Function, K> keyFunction() { - return (Function) EntryFunction.KEY; - } - - @SuppressWarnings("unchecked") - static Function, V> valueFunction() { - return (Function) EntryFunction.VALUE; - } - - static Iterator keyIterator(Iterator> entryIterator) { - return Iterators.transform(entryIterator, Maps.keyFunction()); - } - - static Iterator valueIterator(Iterator> entryIterator) { - return Iterators.transform(entryIterator, Maps.valueFunction()); - } - - /** - * Returns an immutable map instance containing the given entries. - * Internally, the returned map will be backed by an {@link EnumMap}. - * - *

The iteration order of the returned map follows the enum's iteration - * order, not the order in which the elements appear in the given map. - * - * @param map the map to make an immutable copy of - * @return an immutable map containing those entries - * @since 14.0 - */ - @GwtCompatible(serializable = true) - @Beta - public static , V> ImmutableMap immutableEnumMap( - Map map) { - if (map instanceof ImmutableEnumMap) { - @SuppressWarnings("unchecked") // safe covariant cast - ImmutableEnumMap result = (ImmutableEnumMap) map; - return result; - } else if (map.isEmpty()) { - return ImmutableMap.of(); - } else { - for (Map.Entry entry : map.entrySet()) { - checkNotNull(entry.getKey()); - checkNotNull(entry.getValue()); - } - return ImmutableEnumMap.asImmutable(new EnumMap(map)); - } - } - - /** - * Creates a mutable, empty {@code HashMap} instance. - * - *

Note: if mutability is not required, use {@link - * ImmutableMap#of()} instead. - * - *

Note: if {@code K} is an {@code enum} type, use {@link - * #newEnumMap} instead. - * - * @return a new, empty {@code HashMap} - */ - public static HashMap newHashMap() { - return new HashMap(); - } - - /** - * Creates a {@code HashMap} instance, with a high enough "initial capacity" - * that it should hold {@code expectedSize} elements without growth. - * This behavior cannot be broadly guaranteed, but it is observed to be true - * for OpenJDK 1.7. It also can't be guaranteed that the method isn't - * inadvertently oversizing the returned map. - * - * @param expectedSize the number of entries you expect to add to the - * returned map - * @return a new, empty {@code HashMap} with enough capacity to hold {@code - * expectedSize} entries without resizing - * @throws IllegalArgumentException if {@code expectedSize} is negative - */ - public static HashMap newHashMapWithExpectedSize(int expectedSize) { - return new HashMap(capacity(expectedSize)); - } - - /** - * Returns a capacity that is sufficient to keep the map from being resized as - * long as it grows no larger than expectedSize and the load factor is >= its - * default (0.75). - */ - static int capacity(int expectedSize) { - if (expectedSize < 3) { - checkNonnegative(expectedSize, "expectedSize"); - return expectedSize + 1; - } - if (expectedSize < Ints.MAX_POWER_OF_TWO) { - // This is the calculation used in JDK8 to resize when a putAll - // happens; it seems to be the most conservative calculation we - // can make. 0.75 is the default load factor. - return (int) ((float) expectedSize / 0.75F + 1.0F); - } - return Integer.MAX_VALUE; // any large value - } - - /** - * Creates a mutable {@code HashMap} instance with the same mappings as - * the specified map. - * - *

Note: if mutability is not required, use {@link - * ImmutableMap#copyOf(Map)} instead. - * - *

Note: if {@code K} is an {@link Enum} type, use {@link - * #newEnumMap} instead. - * - * @param map the mappings to be placed in the new map - * @return a new {@code HashMap} initialized with the mappings from {@code - * map} - */ - public static HashMap newHashMap(Map map) { - return new HashMap(map); - } - - /** - * Creates a mutable, empty, insertion-ordered {@code LinkedHashMap} - * instance. - * - *

Note: if mutability is not required, use {@link - * ImmutableMap#of()} instead. - * - * @return a new, empty {@code LinkedHashMap} - */ - public static LinkedHashMap newLinkedHashMap() { - return new LinkedHashMap(); - } - - /** - * Creates a {@code LinkedHashMap} instance, with a high enough - * "initial capacity" that it should hold {@code expectedSize} - * elements without growth. This behavior cannot be broadly guaranteed, but - * it is observed to be true for OpenJDK 1.7. It also can't be guaranteed - * that the method isn't inadvertently oversizing the returned map. - * - * @param expectedSize the number of entries you expect to add to the - * returned map - * @return a new, empty {@code LinkedHashMap} with enough capacity to hold - * {@code expectedSize} entries without resizing - * @throws IllegalArgumentException if {@code expectedSize} is negative - * @since 19.0 - */ - public static LinkedHashMap newLinkedHashMapWithExpectedSize(int expectedSize) { - return new LinkedHashMap(capacity(expectedSize)); - } - - /** - * Creates a mutable, insertion-ordered {@code LinkedHashMap} instance - * with the same mappings as the specified map. - * - *

Note: if mutability is not required, use {@link - * ImmutableMap#copyOf(Map)} instead. - * - * @param map the mappings to be placed in the new map - * @return a new, {@code LinkedHashMap} initialized with the mappings from - * {@code map} - */ - public static LinkedHashMap newLinkedHashMap(Map map) { - return new LinkedHashMap(map); - } - - /** - * Returns a general-purpose instance of {@code ConcurrentMap}, which supports - * all optional operations of the ConcurrentMap interface. It does not permit - * null keys or values. It is serializable. - * - *

This is currently accomplished by calling {@link MapMaker#makeMap()}. - * - *

It is preferable to use {@code MapMaker} directly (rather than through - * this method), as it presents numerous useful configuration options, - * such as the concurrency level, load factor, key/value reference types, - * and value computation. - * - * @return a new, empty {@code ConcurrentMap} - * @since 3.0 - */ - public static ConcurrentMap newConcurrentMap() { - return new MapMaker().makeMap(); - } - - /** - * Creates a mutable, empty {@code TreeMap} instance using the natural - * ordering of its elements. - * - *

Note: if mutability is not required, use {@link - * ImmutableSortedMap#of()} instead. - * - * @return a new, empty {@code TreeMap} - */ - public static TreeMap newTreeMap() { - return new TreeMap(); - } - - /** - * Creates a mutable {@code TreeMap} instance with the same mappings as - * the specified map and using the same ordering as the specified map. - * - *

Note: if mutability is not required, use {@link - * ImmutableSortedMap#copyOfSorted(SortedMap)} instead. - * - * @param map the sorted map whose mappings are to be placed in the new map - * and whose comparator is to be used to sort the new map - * @return a new {@code TreeMap} initialized with the mappings from {@code - * map} and using the comparator of {@code map} - */ - public static TreeMap newTreeMap(SortedMap map) { - return new TreeMap(map); - } - - /** - * Creates a mutable, empty {@code TreeMap} instance using the given - * comparator. - * - *

Note: if mutability is not required, use {@code - * ImmutableSortedMap.orderedBy(comparator).build()} instead. - * - * @param comparator the comparator to sort the keys with - * @return a new, empty {@code TreeMap} - */ - public static TreeMap newTreeMap(@Nullable Comparator comparator) { - // Ideally, the extra type parameter "C" shouldn't be necessary. It is a - // work-around of a compiler type inference quirk that prevents the - // following code from being compiled: - // Comparator> comparator = null; - // Map, String> map = newTreeMap(comparator); - return new TreeMap(comparator); - } - - /** - * Creates an {@code EnumMap} instance. - * - * @param type the key type for this map - * @return a new, empty {@code EnumMap} - */ - public static , V> EnumMap newEnumMap(Class type) { - return new EnumMap(checkNotNull(type)); - } - - /** - * Creates an {@code EnumMap} with the same mappings as the specified map. - * - * @param map the map from which to initialize this {@code EnumMap} - * @return a new {@code EnumMap} initialized with the mappings from {@code - * map} - * @throws IllegalArgumentException if {@code m} is not an {@code EnumMap} - * instance and contains no mappings - */ - public static , V> EnumMap newEnumMap(Map map) { - return new EnumMap(map); - } - - /** - * Creates an {@code IdentityHashMap} instance. - * - * @return a new, empty {@code IdentityHashMap} - */ - public static IdentityHashMap newIdentityHashMap() { - return new IdentityHashMap(); - } - - /** - * Computes the difference between two maps. This difference is an immutable - * snapshot of the state of the maps at the time this method is called. It - * will never change, even if the maps change at a later time. - * - *

Since this method uses {@code HashMap} instances internally, the keys of - * the supplied maps must be well-behaved with respect to - * {@link Object#equals} and {@link Object#hashCode}. - * - *

Note:If you only need to know whether two maps have the same - * mappings, call {@code left.equals(right)} instead of this method. - * - * @param left the map to treat as the "left" map for purposes of comparison - * @param right the map to treat as the "right" map for purposes of comparison - * @return the difference between the two maps - */ - @SuppressWarnings("unchecked") - public static MapDifference difference( - Map left, Map right) { - if (left instanceof SortedMap) { - SortedMap sortedLeft = (SortedMap) left; - SortedMapDifference result = difference(sortedLeft, right); - return result; - } - return difference(left, right, Equivalence.equals()); - } - - /** - * Computes the difference between two maps. This difference is an immutable - * snapshot of the state of the maps at the time this method is called. It - * will never change, even if the maps change at a later time. - * - *

Values are compared using a provided equivalence, in the case of - * equality, the value on the 'left' is returned in the difference. - * - *

Since this method uses {@code HashMap} instances internally, the keys of - * the supplied maps must be well-behaved with respect to - * {@link Object#equals} and {@link Object#hashCode}. - * - * @param left the map to treat as the "left" map for purposes of comparison - * @param right the map to treat as the "right" map for purposes of comparison - * @param valueEquivalence the equivalence relationship to use to compare - * values - * @return the difference between the two maps - * @since 10.0 - */ - @Beta - public static MapDifference difference( - Map left, - Map right, - Equivalence valueEquivalence) { - Preconditions.checkNotNull(valueEquivalence); - - Map onlyOnLeft = newLinkedHashMap(); - Map onlyOnRight = new LinkedHashMap(right); // will whittle it down - Map onBoth = newLinkedHashMap(); - Map> differences = newLinkedHashMap(); - doDifference(left, right, valueEquivalence, onlyOnLeft, onlyOnRight, onBoth, differences); - return new MapDifferenceImpl(onlyOnLeft, onlyOnRight, onBoth, differences); - } - - private static void doDifference( - Map left, - Map right, - Equivalence valueEquivalence, - Map onlyOnLeft, - Map onlyOnRight, - Map onBoth, - Map> differences) { - for (Entry entry : left.entrySet()) { - K leftKey = entry.getKey(); - V leftValue = entry.getValue(); - if (right.containsKey(leftKey)) { - V rightValue = onlyOnRight.remove(leftKey); - if (valueEquivalence.equivalent(leftValue, rightValue)) { - onBoth.put(leftKey, leftValue); - } else { - differences.put(leftKey, ValueDifferenceImpl.create(leftValue, rightValue)); - } - } else { - onlyOnLeft.put(leftKey, leftValue); - } - } - } - - private static Map unmodifiableMap(Map map) { - if (map instanceof SortedMap) { - return Collections.unmodifiableSortedMap((SortedMap) map); - } else { - return Collections.unmodifiableMap(map); - } - } - - static class MapDifferenceImpl implements MapDifference { - final Map onlyOnLeft; - final Map onlyOnRight; - final Map onBoth; - final Map> differences; - - MapDifferenceImpl( - Map onlyOnLeft, - Map onlyOnRight, - Map onBoth, - Map> differences) { - this.onlyOnLeft = unmodifiableMap(onlyOnLeft); - this.onlyOnRight = unmodifiableMap(onlyOnRight); - this.onBoth = unmodifiableMap(onBoth); - this.differences = unmodifiableMap(differences); - } - - @Override - public boolean areEqual() { - return onlyOnLeft.isEmpty() && onlyOnRight.isEmpty() && differences.isEmpty(); - } - - @Override - public Map entriesOnlyOnLeft() { - return onlyOnLeft; - } - - @Override - public Map entriesOnlyOnRight() { - return onlyOnRight; - } - - @Override - public Map entriesInCommon() { - return onBoth; - } - - @Override - public Map> entriesDiffering() { - return differences; - } - - @Override - public boolean equals(Object object) { - if (object == this) { - return true; - } - if (object instanceof MapDifference) { - MapDifference other = (MapDifference) object; - return entriesOnlyOnLeft().equals(other.entriesOnlyOnLeft()) - && entriesOnlyOnRight().equals(other.entriesOnlyOnRight()) - && entriesInCommon().equals(other.entriesInCommon()) - && entriesDiffering().equals(other.entriesDiffering()); - } - return false; - } - - @Override - public int hashCode() { - return Objects.hashCode( - entriesOnlyOnLeft(), entriesOnlyOnRight(), entriesInCommon(), entriesDiffering()); - } - - @Override - public String toString() { - if (areEqual()) { - return "equal"; - } - - StringBuilder result = new StringBuilder("not equal"); - if (!onlyOnLeft.isEmpty()) { - result.append(": only on left=").append(onlyOnLeft); - } - if (!onlyOnRight.isEmpty()) { - result.append(": only on right=").append(onlyOnRight); - } - if (!differences.isEmpty()) { - result.append(": value differences=").append(differences); - } - return result.toString(); - } - } - - static class ValueDifferenceImpl implements MapDifference.ValueDifference { - private final V left; - private final V right; - - static ValueDifference create(@Nullable V left, @Nullable V right) { - return new ValueDifferenceImpl(left, right); - } - - private ValueDifferenceImpl(@Nullable V left, @Nullable V right) { - this.left = left; - this.right = right; - } - - @Override - public V leftValue() { - return left; - } - - @Override - public V rightValue() { - return right; - } - - @Override - public boolean equals(@Nullable Object object) { - if (object instanceof MapDifference.ValueDifference) { - MapDifference.ValueDifference that = (MapDifference.ValueDifference) object; - return Objects.equal(this.left, that.leftValue()) - && Objects.equal(this.right, that.rightValue()); - } - return false; - } - - @Override - public int hashCode() { - return Objects.hashCode(left, right); - } - - @Override - public String toString() { - return "(" + left + ", " + right + ")"; - } - } - - /** - * Computes the difference between two sorted maps, using the comparator of - * the left map, or {@code Ordering.natural()} if the left map uses the - * natural ordering of its elements. This difference is an immutable snapshot - * of the state of the maps at the time this method is called. It will never - * change, even if the maps change at a later time. - * - *

Since this method uses {@code TreeMap} instances internally, the keys of - * the right map must all compare as distinct according to the comparator - * of the left map. - * - *

Note:If you only need to know whether two sorted maps have the - * same mappings, call {@code left.equals(right)} instead of this method. - * - * @param left the map to treat as the "left" map for purposes of comparison - * @param right the map to treat as the "right" map for purposes of comparison - * @return the difference between the two maps - * @since 11.0 - */ - public static SortedMapDifference difference( - SortedMap left, Map right) { - checkNotNull(left); - checkNotNull(right); - Comparator comparator = orNaturalOrder(left.comparator()); - SortedMap onlyOnLeft = Maps.newTreeMap(comparator); - SortedMap onlyOnRight = Maps.newTreeMap(comparator); - onlyOnRight.putAll(right); // will whittle it down - SortedMap onBoth = Maps.newTreeMap(comparator); - SortedMap> differences = Maps.newTreeMap(comparator); - doDifference(left, right, Equivalence.equals(), onlyOnLeft, onlyOnRight, onBoth, differences); - return new SortedMapDifferenceImpl(onlyOnLeft, onlyOnRight, onBoth, differences); - } - - static class SortedMapDifferenceImpl extends MapDifferenceImpl - implements SortedMapDifference { - SortedMapDifferenceImpl( - SortedMap onlyOnLeft, - SortedMap onlyOnRight, - SortedMap onBoth, - SortedMap> differences) { - super(onlyOnLeft, onlyOnRight, onBoth, differences); - } - - @Override - public SortedMap> entriesDiffering() { - return (SortedMap>) super.entriesDiffering(); - } - - @Override - public SortedMap entriesInCommon() { - return (SortedMap) super.entriesInCommon(); - } - - @Override - public SortedMap entriesOnlyOnLeft() { - return (SortedMap) super.entriesOnlyOnLeft(); - } - - @Override - public SortedMap entriesOnlyOnRight() { - return (SortedMap) super.entriesOnlyOnRight(); - } - } - - /** - * Returns the specified comparator if not null; otherwise returns {@code - * Ordering.natural()}. This method is an abomination of generics; the only - * purpose of this method is to contain the ugly type-casting in one place. - */ - @SuppressWarnings("unchecked") - static Comparator orNaturalOrder(@Nullable Comparator comparator) { - if (comparator != null) { // can't use ? : because of javac bug 5080917 - return comparator; - } - return (Comparator) Ordering.natural(); - } - - /** - * Returns a live {@link Map} view whose keys are the contents of {@code set} - * and whose values are computed on demand using {@code function}. To get an - * immutable copy instead, use {@link #toMap(Iterable, Function)}. - * - *

Specifically, for each {@code k} in the backing set, the returned map - * has an entry mapping {@code k} to {@code function.apply(k)}. The {@code - * keySet}, {@code values}, and {@code entrySet} views of the returned map - * iterate in the same order as the backing set. - * - *

Modifications to the backing set are read through to the returned map. - * The returned map supports removal operations if the backing set does. - * Removal operations write through to the backing set. The returned map - * does not support put operations. - * - *

Warning: If the function rejects {@code null}, caution is - * required to make sure the set does not contain {@code null}, because the - * view cannot stop {@code null} from being added to the set. - * - *

Warning: This method assumes that for any instance {@code k} of - * key type {@code K}, {@code k.equals(k2)} implies that {@code k2} is also - * of type {@code K}. Using a key type for which this may not hold, such as - * {@code ArrayList}, may risk a {@code ClassCastException} when calling - * methods on the resulting map view. - * - * @since 14.0 - */ - public static Map asMap(Set set, Function function) { - if (set instanceof SortedSet) { - return asMap((SortedSet) set, function); - } else { - return new AsMapView(set, function); - } - } - - /** - * Returns a view of the sorted set as a map, mapping keys from the set - * according to the specified function. - * - *

Specifically, for each {@code k} in the backing set, the returned map - * has an entry mapping {@code k} to {@code function.apply(k)}. The {@code - * keySet}, {@code values}, and {@code entrySet} views of the returned map - * iterate in the same order as the backing set. - * - *

Modifications to the backing set are read through to the returned map. - * The returned map supports removal operations if the backing set does. - * Removal operations write through to the backing set. The returned map does - * not support put operations. - * - *

Warning: If the function rejects {@code null}, caution is - * required to make sure the set does not contain {@code null}, because the - * view cannot stop {@code null} from being added to the set. - * - *

Warning: This method assumes that for any instance {@code k} of - * key type {@code K}, {@code k.equals(k2)} implies that {@code k2} is also of - * type {@code K}. Using a key type for which this may not hold, such as - * {@code ArrayList}, may risk a {@code ClassCastException} when calling - * methods on the resulting map view. - * - * @since 14.0 - */ - public static SortedMap asMap(SortedSet set, Function function) { - return Platform.mapsAsMapSortedSet(set, function); - } - - static SortedMap asMapSortedIgnoreNavigable( - SortedSet set, Function function) { - return new SortedAsMapView(set, function); - } - - /** - * Returns a view of the navigable set as a map, mapping keys from the set - * according to the specified function. - * - *

Specifically, for each {@code k} in the backing set, the returned map - * has an entry mapping {@code k} to {@code function.apply(k)}. The {@code - * keySet}, {@code values}, and {@code entrySet} views of the returned map - * iterate in the same order as the backing set. - * - *

Modifications to the backing set are read through to the returned map. - * The returned map supports removal operations if the backing set does. - * Removal operations write through to the backing set. The returned map - * does not support put operations. - * - *

Warning: If the function rejects {@code null}, caution is - * required to make sure the set does not contain {@code null}, because the - * view cannot stop {@code null} from being added to the set. - * - *

Warning: This method assumes that for any instance {@code k} of - * key type {@code K}, {@code k.equals(k2)} implies that {@code k2} is also - * of type {@code K}. Using a key type for which this may not hold, such as - * {@code ArrayList}, may risk a {@code ClassCastException} when calling - * methods on the resulting map view. - * - * @since 14.0 - */ - @GwtIncompatible("NavigableMap") - public static NavigableMap asMap( - NavigableSet set, Function function) { - return new NavigableAsMapView(set, function); - } - - private static class AsMapView extends ViewCachingAbstractMap { - - private final Set set; - final Function function; - - Set backingSet() { - return set; - } - - AsMapView(Set set, Function function) { - this.set = checkNotNull(set); - this.function = checkNotNull(function); - } - - @Override - public Set createKeySet() { - return removeOnlySet(backingSet()); - } - - @Override - Collection createValues() { - return Collections2.transform(set, function); - } - - @Override - public int size() { - return backingSet().size(); - } - - @Override - public boolean containsKey(@Nullable Object key) { - return backingSet().contains(key); - } - - @Override - public V get(@Nullable Object key) { - if (Collections2.safeContains(backingSet(), key)) { - @SuppressWarnings("unchecked") // unsafe, but Javadoc warns about it - K k = (K) key; - return function.apply(k); - } else { - return null; - } - } - - @Override - public V remove(@Nullable Object key) { - if (backingSet().remove(key)) { - @SuppressWarnings("unchecked") // unsafe, but Javadoc warns about it - K k = (K) key; - return function.apply(k); - } else { - return null; - } - } - - @Override - public void clear() { - backingSet().clear(); - } - - @Override - protected Set> createEntrySet() { - @WeakOuter - class EntrySetImpl extends EntrySet { - @Override - Map map() { - return AsMapView.this; - } - - @Override - public Iterator> iterator() { - return asMapEntryIterator(backingSet(), function); - } - } - return new EntrySetImpl(); - } - } - - static Iterator> asMapEntryIterator( - Set set, final Function function) { - return new TransformedIterator>(set.iterator()) { - @Override - Entry transform(final K key) { - return immutableEntry(key, function.apply(key)); - } - }; - } - - private static class SortedAsMapView extends AsMapView implements SortedMap { - - SortedAsMapView(SortedSet set, Function function) { - super(set, function); - } - - @Override - SortedSet backingSet() { - return (SortedSet) super.backingSet(); - } - - @Override - public Comparator comparator() { - return backingSet().comparator(); - } - - @Override - public Set keySet() { - return removeOnlySortedSet(backingSet()); - } - - @Override - public SortedMap subMap(K fromKey, K toKey) { - return asMap(backingSet().subSet(fromKey, toKey), function); - } - - @Override - public SortedMap headMap(K toKey) { - return asMap(backingSet().headSet(toKey), function); - } - - @Override - public SortedMap tailMap(K fromKey) { - return asMap(backingSet().tailSet(fromKey), function); - } - - @Override - public K firstKey() { - return backingSet().first(); - } - - @Override - public K lastKey() { - return backingSet().last(); - } - } - - @GwtIncompatible("NavigableMap") - private static final class NavigableAsMapView extends AbstractNavigableMap { - /* - * Using AbstractNavigableMap is simpler than extending SortedAsMapView and rewriting all the - * NavigableMap methods. - */ - - private final NavigableSet set; - private final Function function; - - NavigableAsMapView(NavigableSet ks, Function vFunction) { - this.set = checkNotNull(ks); - this.function = checkNotNull(vFunction); - } - - @Override - public NavigableMap subMap( - K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { - return asMap(set.subSet(fromKey, fromInclusive, toKey, toInclusive), function); - } - - @Override - public NavigableMap headMap(K toKey, boolean inclusive) { - return asMap(set.headSet(toKey, inclusive), function); - } - - @Override - public NavigableMap tailMap(K fromKey, boolean inclusive) { - return asMap(set.tailSet(fromKey, inclusive), function); - } - - @Override - public Comparator comparator() { - return set.comparator(); - } - - @Override - @Nullable - public V get(@Nullable Object key) { - if (Collections2.safeContains(set, key)) { - @SuppressWarnings("unchecked") // unsafe, but Javadoc warns about it - K k = (K) key; - return function.apply(k); - } else { - return null; - } - } - - @Override - public void clear() { - set.clear(); - } - - @Override - Iterator> entryIterator() { - return asMapEntryIterator(set, function); - } - - @Override - Iterator> descendingEntryIterator() { - return descendingMap().entrySet().iterator(); - } - - @Override - public NavigableSet navigableKeySet() { - return removeOnlyNavigableSet(set); - } - - @Override - public int size() { - return set.size(); - } - - @Override - public NavigableMap descendingMap() { - return asMap(set.descendingSet(), function); - } - } - - private static Set removeOnlySet(final Set set) { - return new ForwardingSet() { - @Override - protected Set delegate() { - return set; - } - - @Override - public boolean add(E element) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean addAll(Collection es) { - throw new UnsupportedOperationException(); - } - }; - } - - private static SortedSet removeOnlySortedSet(final SortedSet set) { - return new ForwardingSortedSet() { - @Override - protected SortedSet delegate() { - return set; - } - - @Override - public boolean add(E element) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean addAll(Collection es) { - throw new UnsupportedOperationException(); - } - - @Override - public SortedSet headSet(E toElement) { - return removeOnlySortedSet(super.headSet(toElement)); - } - - @Override - public SortedSet subSet(E fromElement, E toElement) { - return removeOnlySortedSet(super.subSet(fromElement, toElement)); - } - - @Override - public SortedSet tailSet(E fromElement) { - return removeOnlySortedSet(super.tailSet(fromElement)); - } - }; - } - - @GwtIncompatible("NavigableSet") - private static NavigableSet removeOnlyNavigableSet(final NavigableSet set) { - return new ForwardingNavigableSet() { - @Override - protected NavigableSet delegate() { - return set; - } - - @Override - public boolean add(E element) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean addAll(Collection es) { - throw new UnsupportedOperationException(); - } - - @Override - public SortedSet headSet(E toElement) { - return removeOnlySortedSet(super.headSet(toElement)); - } - - @Override - public SortedSet subSet(E fromElement, E toElement) { - return removeOnlySortedSet(super.subSet(fromElement, toElement)); - } - - @Override - public SortedSet tailSet(E fromElement) { - return removeOnlySortedSet(super.tailSet(fromElement)); - } - - @Override - public NavigableSet headSet(E toElement, boolean inclusive) { - return removeOnlyNavigableSet(super.headSet(toElement, inclusive)); - } - - @Override - public NavigableSet tailSet(E fromElement, boolean inclusive) { - return removeOnlyNavigableSet(super.tailSet(fromElement, inclusive)); - } - - @Override - public NavigableSet subSet( - E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { - return removeOnlyNavigableSet( - super.subSet(fromElement, fromInclusive, toElement, toInclusive)); - } - - @Override - public NavigableSet descendingSet() { - return removeOnlyNavigableSet(super.descendingSet()); - } - }; - } - - /** - * Returns an immutable map whose keys are the distinct elements of {@code - * keys} and whose value for each key was computed by {@code valueFunction}. - * The map's iteration order is the order of the first appearance of each key - * in {@code keys}. - * - *

When there are multiple instances of a key in {@code keys}, it is - * unspecified whether {@code valueFunction} will be applied to more than one - * instance of that key and, if it is, which result will be mapped to that - * key in the returned map. - * - *

If {@code keys} is a {@link Set}, a live view can be obtained instead of - * a copy using {@link Maps#asMap(Set, Function)}. - * - * @throws NullPointerException if any element of {@code keys} is - * {@code null}, or if {@code valueFunction} produces {@code null} - * for any key - * @since 14.0 - */ - public static ImmutableMap toMap( - Iterable keys, Function valueFunction) { - return toMap(keys.iterator(), valueFunction); - } - - /** - * Returns an immutable map whose keys are the distinct elements of {@code - * keys} and whose value for each key was computed by {@code valueFunction}. - * The map's iteration order is the order of the first appearance of each key - * in {@code keys}. - * - *

When there are multiple instances of a key in {@code keys}, it is - * unspecified whether {@code valueFunction} will be applied to more than one - * instance of that key and, if it is, which result will be mapped to that - * key in the returned map. - * - * @throws NullPointerException if any element of {@code keys} is - * {@code null}, or if {@code valueFunction} produces {@code null} - * for any key - * @since 14.0 - */ - public static ImmutableMap toMap( - Iterator keys, Function valueFunction) { - checkNotNull(valueFunction); - // Using LHM instead of a builder so as not to fail on duplicate keys - Map builder = newLinkedHashMap(); - while (keys.hasNext()) { - K key = keys.next(); - builder.put(key, valueFunction.apply(key)); - } - return ImmutableMap.copyOf(builder); - } - - /** - * Returns a map with the given {@code values}, indexed by keys derived from - * those values. In other words, each input value produces an entry in the map - * whose key is the result of applying {@code keyFunction} to that value. - * These entries appear in the same order as the input values. Example usage: - *

   {@code
-   *
-   *   Color red = new Color("red", 255, 0, 0);
-   *   ...
-   *   ImmutableSet allColors = ImmutableSet.of(red, green, blue);
-   *
-   *   Map colorForName =
-   *       uniqueIndex(allColors, toStringFunction());
-   *   assertThat(colorForName).containsEntry("red", red);}
- * - *

If your index may associate multiple values with each key, use {@link - * Multimaps#index(Iterable, Function) Multimaps.index}. - * - * @param values the values to use when constructing the {@code Map} - * @param keyFunction the function used to produce the key for each value - * @return a map mapping the result of evaluating the function {@code - * keyFunction} on each value in the input collection to that value - * @throws IllegalArgumentException if {@code keyFunction} produces the same - * key for more than one value in the input collection - * @throws NullPointerException if any elements of {@code values} is null, or - * if {@code keyFunction} produces {@code null} for any value - */ - public static ImmutableMap uniqueIndex( - Iterable values, Function keyFunction) { - // TODO(lowasser): consider presizing the builder if values is a Collection - return uniqueIndex(values.iterator(), keyFunction); - } - - /** - * Returns a map with the given {@code values}, indexed by keys derived from - * those values. In other words, each input value produces an entry in the map - * whose key is the result of applying {@code keyFunction} to that value. - * These entries appear in the same order as the input values. Example usage: - *

   {@code
-   *
-   *   Color red = new Color("red", 255, 0, 0);
-   *   ...
-   *   Iterator allColors = ImmutableSet.of(red, green, blue).iterator();
-   *
-   *   Map colorForName =
-   *       uniqueIndex(allColors, toStringFunction());
-   *   assertThat(colorForName).containsEntry("red", red);}
- * - *

If your index may associate multiple values with each key, use {@link - * Multimaps#index(Iterator, Function) Multimaps.index}. - * - * @param values the values to use when constructing the {@code Map} - * @param keyFunction the function used to produce the key for each value - * @return a map mapping the result of evaluating the function {@code - * keyFunction} on each value in the input collection to that value - * @throws IllegalArgumentException if {@code keyFunction} produces the same - * key for more than one value in the input collection - * @throws NullPointerException if any elements of {@code values} is null, or - * if {@code keyFunction} produces {@code null} for any value - * @since 10.0 - */ - public static ImmutableMap uniqueIndex( - Iterator values, Function keyFunction) { - checkNotNull(keyFunction); - ImmutableMap.Builder builder = ImmutableMap.builder(); - while (values.hasNext()) { - V value = values.next(); - builder.put(keyFunction.apply(value), value); - } - try { - return builder.build(); - } catch (IllegalArgumentException duplicateKeys) { - throw new IllegalArgumentException( - duplicateKeys.getMessage() - + ". To index multiple values under a key, use Multimaps.index."); - } - } - - /** - * Creates an {@code ImmutableMap} from a {@code Properties} - * instance. Properties normally derive from {@code Map}, but - * they typically contain strings, which is awkward. This method lets you get - * a plain-old-{@code Map} out of a {@code Properties}. - * - * @param properties a {@code Properties} object to be converted - * @return an immutable map containing all the entries in {@code properties} - * @throws ClassCastException if any key in {@code Properties} is not a {@code - * String} - * @throws NullPointerException if any key or value in {@code Properties} is - * null - */ - @GwtIncompatible("java.util.Properties") - public static ImmutableMap fromProperties(Properties properties) { - ImmutableMap.Builder builder = ImmutableMap.builder(); - - for (Enumeration e = properties.propertyNames(); e.hasMoreElements(); ) { - String key = (String) e.nextElement(); - builder.put(key, properties.getProperty(key)); - } - - return builder.build(); - } - - /** - * Returns an immutable map entry with the specified key and value. The {@link - * Entry#setValue} operation throws an {@link UnsupportedOperationException}. - * - *

The returned entry is serializable. - * - * @param key the key to be associated with the returned entry - * @param value the value to be associated with the returned entry - */ - @GwtCompatible(serializable = true) - public static Entry immutableEntry(@Nullable K key, @Nullable V value) { - return new ImmutableEntry(key, value); - } - - /** - * Returns an unmodifiable view of the specified set of entries. The {@link - * Entry#setValue} operation throws an {@link UnsupportedOperationException}, - * as do any operations that would modify the returned set. - * - * @param entrySet the entries for which to return an unmodifiable view - * @return an unmodifiable view of the entries - */ - static Set> unmodifiableEntrySet(Set> entrySet) { - return new UnmodifiableEntrySet(Collections.unmodifiableSet(entrySet)); - } - - /** - * Returns an unmodifiable view of the specified map entry. The {@link - * Entry#setValue} operation throws an {@link UnsupportedOperationException}. - * This also has the side-effect of redefining {@code equals} to comply with - * the Entry contract, to avoid a possible nefarious implementation of equals. - * - * @param entry the entry for which to return an unmodifiable view - * @return an unmodifiable view of the entry - */ - static Entry unmodifiableEntry(final Entry entry) { - checkNotNull(entry); - return new AbstractMapEntry() { - @Override - public K getKey() { - return entry.getKey(); - } - - @Override - public V getValue() { - return entry.getValue(); - } - }; - } - - static UnmodifiableIterator> unmodifiableEntryIterator( - final Iterator> entryIterator) { - return new UnmodifiableIterator>() { - @Override - public boolean hasNext() { - return entryIterator.hasNext(); - } - - @Override - public Entry next() { - return unmodifiableEntry(entryIterator.next()); - } - }; - } - - /** @see Multimaps#unmodifiableEntries */ - static class UnmodifiableEntries extends ForwardingCollection> { - private final Collection> entries; - - UnmodifiableEntries(Collection> entries) { - this.entries = entries; - } - - @Override - protected Collection> delegate() { - return entries; - } - - @Override - public Iterator> iterator() { - return unmodifiableEntryIterator(entries.iterator()); - } - - // See java.util.Collections.UnmodifiableEntrySet for details on attacks. - - @Override - public Object[] toArray() { - return standardToArray(); - } - - @Override - public T[] toArray(T[] array) { - return standardToArray(array); - } - } - - /** @see Maps#unmodifiableEntrySet(Set) */ - static class UnmodifiableEntrySet extends UnmodifiableEntries - implements Set> { - UnmodifiableEntrySet(Set> entries) { - super(entries); - } - - // See java.util.Collections.UnmodifiableEntrySet for details on attacks. - - @Override - public boolean equals(@Nullable Object object) { - return Sets.equalsImpl(this, object); - } - - @Override - public int hashCode() { - return Sets.hashCodeImpl(this); - } - } - - /** - * Returns a {@link Converter} that converts values using {@link BiMap#get bimap.get()}, - * and whose inverse view converts values using - * {@link BiMap#inverse bimap.inverse()}{@code .get()}. - * - *

To use a plain {@link Map} as a {@link Function}, see - * {@link com.google.common.base.Functions#forMap(Map)} or - * {@link com.google.common.base.Functions#forMap(Map, Object)}. - * - * @since 16.0 - */ - @Beta - public static Converter asConverter(final BiMap bimap) { - return new BiMapConverter(bimap); - } - - private static final class BiMapConverter extends Converter implements Serializable { - private final BiMap bimap; - - BiMapConverter(BiMap bimap) { - this.bimap = checkNotNull(bimap); - } - - @Override - protected B doForward(A a) { - return convert(bimap, a); - } - - @Override - protected A doBackward(B b) { - return convert(bimap.inverse(), b); - } - - private static Y convert(BiMap bimap, X input) { - Y output = bimap.get(input); - checkArgument(output != null, "No non-null mapping present for input: %s", input); - return output; - } - - @Override - public boolean equals(@Nullable Object object) { - if (object instanceof BiMapConverter) { - BiMapConverter that = (BiMapConverter) object; - return this.bimap.equals(that.bimap); - } - return false; - } - - @Override - public int hashCode() { - return bimap.hashCode(); - } - - // There's really no good way to implement toString() without printing the entire BiMap, right? - @Override - public String toString() { - return "Maps.asConverter(" + bimap + ")"; - } - - private static final long serialVersionUID = 0L; - } - - /** - * Returns a synchronized (thread-safe) bimap backed by the specified bimap. - * In order to guarantee serial access, it is critical that all access - * to the backing bimap is accomplished through the returned bimap. - * - *

It is imperative that the user manually synchronize on the returned map - * when accessing any of its collection views:

   {@code
-   *
-   *   BiMap map = Maps.synchronizedBiMap(
-   *       HashBiMap.create());
-   *   ...
-   *   Set set = map.keySet();  // Needn't be in synchronized block
-   *   ...
-   *   synchronized (map) {  // Synchronizing on map, not set!
-   *     Iterator it = set.iterator(); // Must be in synchronized block
-   *     while (it.hasNext()) {
-   *       foo(it.next());
-   *     }
-   *   }}
- * - *

Failure to follow this advice may result in non-deterministic behavior. - * - *

The returned bimap will be serializable if the specified bimap is - * serializable. - * - * @param bimap the bimap to be wrapped in a synchronized view - * @return a sychronized view of the specified bimap - */ - public static BiMap synchronizedBiMap(BiMap bimap) { - return Synchronized.biMap(bimap, null); - } - - /** - * Returns an unmodifiable view of the specified bimap. This method allows - * modules to provide users with "read-only" access to internal bimaps. Query - * operations on the returned bimap "read through" to the specified bimap, and - * attempts to modify the returned map, whether direct or via its collection - * views, result in an {@code UnsupportedOperationException}. - * - *

The returned bimap will be serializable if the specified bimap is - * serializable. - * - * @param bimap the bimap for which an unmodifiable view is to be returned - * @return an unmodifiable view of the specified bimap - */ - public static BiMap unmodifiableBiMap(BiMap bimap) { - return new UnmodifiableBiMap(bimap, null); - } - - /** @see Maps#unmodifiableBiMap(BiMap) */ - private static class UnmodifiableBiMap extends ForwardingMap - implements BiMap, Serializable { - final Map unmodifiableMap; - final BiMap delegate; - BiMap inverse; - transient Set values; - - UnmodifiableBiMap(BiMap delegate, @Nullable BiMap inverse) { - unmodifiableMap = Collections.unmodifiableMap(delegate); - this.delegate = delegate; - this.inverse = inverse; - } - - @Override - protected Map delegate() { - return unmodifiableMap; - } - - @Override - public V forcePut(K key, V value) { - throw new UnsupportedOperationException(); - } - - @Override - public BiMap inverse() { - BiMap result = inverse; - return (result == null) - ? inverse = new UnmodifiableBiMap(delegate.inverse(), this) - : result; - } - - @Override - public Set values() { - Set result = values; - return (result == null) - ? values = Collections.unmodifiableSet(delegate.values()) - : result; - } - - private static final long serialVersionUID = 0; - } - - /** - * Returns a view of a map where each value is transformed by a function. All - * other properties of the map, such as iteration order, are left intact. For - * example, the code:

   {@code
-   *
-   *   Map map = ImmutableMap.of("a", 4, "b", 9);
-   *   Function sqrt =
-   *       new Function() {
-   *         public Double apply(Integer in) {
-   *           return Math.sqrt((int) in);
-   *         }
-   *       };
-   *   Map transformed = Maps.transformValues(map, sqrt);
-   *   System.out.println(transformed);}
- * - * ... prints {@code {a=2.0, b=3.0}}. - * - *

Changes in the underlying map are reflected in this view. Conversely, - * this view supports removal operations, and these are reflected in the - * underlying map. - * - *

It's acceptable for the underlying map to contain null keys, and even - * null values provided that the function is capable of accepting null input. - * The transformed map might contain null values, if the function sometimes - * gives a null result. - * - *

The returned map is not thread-safe or serializable, even if the - * underlying map is. - * - *

The function is applied lazily, invoked when needed. This is necessary - * for the returned map to be a view, but it means that the function will be - * applied many times for bulk operations like {@link Map#containsValue} and - * {@code Map.toString()}. For this to perform well, {@code function} should - * be fast. To avoid lazy evaluation when the returned map doesn't need to be - * a view, copy the returned map into a new map of your choosing. - */ - public static Map transformValues( - Map fromMap, Function function) { - return transformEntries(fromMap, asEntryTransformer(function)); - } - - /** - * Returns a view of a sorted map where each value is transformed by a - * function. All other properties of the map, such as iteration order, are - * left intact. For example, the code:

   {@code
-   *
-   *   SortedMap map = ImmutableSortedMap.of("a", 4, "b", 9);
-   *   Function sqrt =
-   *       new Function() {
-   *         public Double apply(Integer in) {
-   *           return Math.sqrt((int) in);
-   *         }
-   *       };
-   *   SortedMap transformed =
-   *        Maps.transformValues(map, sqrt);
-   *   System.out.println(transformed);}
- * - * ... prints {@code {a=2.0, b=3.0}}. - * - *

Changes in the underlying map are reflected in this view. Conversely, - * this view supports removal operations, and these are reflected in the - * underlying map. - * - *

It's acceptable for the underlying map to contain null keys, and even - * null values provided that the function is capable of accepting null input. - * The transformed map might contain null values, if the function sometimes - * gives a null result. - * - *

The returned map is not thread-safe or serializable, even if the - * underlying map is. - * - *

The function is applied lazily, invoked when needed. This is necessary - * for the returned map to be a view, but it means that the function will be - * applied many times for bulk operations like {@link Map#containsValue} and - * {@code Map.toString()}. For this to perform well, {@code function} should - * be fast. To avoid lazy evaluation when the returned map doesn't need to be - * a view, copy the returned map into a new map of your choosing. - * - * @since 11.0 - */ - public static SortedMap transformValues( - SortedMap fromMap, Function function) { - return transformEntries(fromMap, asEntryTransformer(function)); - } - - /** - * Returns a view of a navigable map where each value is transformed by a - * function. All other properties of the map, such as iteration order, are - * left intact. For example, the code:

   {@code
-   *
-   *   NavigableMap map = Maps.newTreeMap();
-   *   map.put("a", 4);
-   *   map.put("b", 9);
-   *   Function sqrt =
-   *       new Function() {
-   *         public Double apply(Integer in) {
-   *           return Math.sqrt((int) in);
-   *         }
-   *       };
-   *   NavigableMap transformed =
-   *        Maps.transformNavigableValues(map, sqrt);
-   *   System.out.println(transformed);}
- * - * ... prints {@code {a=2.0, b=3.0}}. - * - * Changes in the underlying map are reflected in this view. - * Conversely, this view supports removal operations, and these are reflected - * in the underlying map. - * - *

It's acceptable for the underlying map to contain null keys, and even - * null values provided that the function is capable of accepting null input. - * The transformed map might contain null values, if the function sometimes - * gives a null result. - * - *

The returned map is not thread-safe or serializable, even if the - * underlying map is. - * - *

The function is applied lazily, invoked when needed. This is necessary - * for the returned map to be a view, but it means that the function will be - * applied many times for bulk operations like {@link Map#containsValue} and - * {@code Map.toString()}. For this to perform well, {@code function} should - * be fast. To avoid lazy evaluation when the returned map doesn't need to be - * a view, copy the returned map into a new map of your choosing. - * - * @since 13.0 - */ - @GwtIncompatible("NavigableMap") - public static NavigableMap transformValues( - NavigableMap fromMap, Function function) { - return transformEntries(fromMap, asEntryTransformer(function)); - } - - /** - * Returns a view of a map whose values are derived from the original map's - * entries. In contrast to {@link #transformValues}, this method's - * entry-transformation logic may depend on the key as well as the value. - * - *

All other properties of the transformed map, such as iteration order, - * are left intact. For example, the code:

   {@code
-   *
-   *   Map options =
-   *       ImmutableMap.of("verbose", true, "sort", false);
-   *   EntryTransformer flagPrefixer =
-   *       new EntryTransformer() {
-   *         public String transformEntry(String key, Boolean value) {
-   *           return value ? key : "no" + key;
-   *         }
-   *       };
-   *   Map transformed =
-   *       Maps.transformEntries(options, flagPrefixer);
-   *   System.out.println(transformed);}
- * - * ... prints {@code {verbose=verbose, sort=nosort}}. - * - *

Changes in the underlying map are reflected in this view. Conversely, - * this view supports removal operations, and these are reflected in the - * underlying map. - * - *

It's acceptable for the underlying map to contain null keys and null - * values provided that the transformer is capable of accepting null inputs. - * The transformed map might contain null values if the transformer sometimes - * gives a null result. - * - *

The returned map is not thread-safe or serializable, even if the - * underlying map is. - * - *

The transformer is applied lazily, invoked when needed. This is - * necessary for the returned map to be a view, but it means that the - * transformer will be applied many times for bulk operations like {@link - * Map#containsValue} and {@link Object#toString}. For this to perform well, - * {@code transformer} should be fast. To avoid lazy evaluation when the - * returned map doesn't need to be a view, copy the returned map into a new - * map of your choosing. - * - *

Warning: This method assumes that for any instance {@code k} of - * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies - * that {@code k2} is also of type {@code K}. Using an {@code - * EntryTransformer} key type for which this may not hold, such as {@code - * ArrayList}, may risk a {@code ClassCastException} when calling methods on - * the transformed map. - * - * @since 7.0 - */ - public static Map transformEntries( - Map fromMap, EntryTransformer transformer) { - if (fromMap instanceof SortedMap) { - return transformEntries((SortedMap) fromMap, transformer); - } - return new TransformedEntriesMap(fromMap, transformer); - } - - /** - * Returns a view of a sorted map whose values are derived from the original - * sorted map's entries. In contrast to {@link #transformValues}, this - * method's entry-transformation logic may depend on the key as well as the - * value. - * - *

All other properties of the transformed map, such as iteration order, - * are left intact. For example, the code:

   {@code
-   *
-   *   Map options =
-   *       ImmutableSortedMap.of("verbose", true, "sort", false);
-   *   EntryTransformer flagPrefixer =
-   *       new EntryTransformer() {
-   *         public String transformEntry(String key, Boolean value) {
-   *           return value ? key : "yes" + key;
-   *         }
-   *       };
-   *   SortedMap transformed =
-   *       Maps.transformEntries(options, flagPrefixer);
-   *   System.out.println(transformed);}
- * - * ... prints {@code {sort=yessort, verbose=verbose}}. - * - *

Changes in the underlying map are reflected in this view. Conversely, - * this view supports removal operations, and these are reflected in the - * underlying map. - * - *

It's acceptable for the underlying map to contain null keys and null - * values provided that the transformer is capable of accepting null inputs. - * The transformed map might contain null values if the transformer sometimes - * gives a null result. - * - *

The returned map is not thread-safe or serializable, even if the - * underlying map is. - * - *

The transformer is applied lazily, invoked when needed. This is - * necessary for the returned map to be a view, but it means that the - * transformer will be applied many times for bulk operations like {@link - * Map#containsValue} and {@link Object#toString}. For this to perform well, - * {@code transformer} should be fast. To avoid lazy evaluation when the - * returned map doesn't need to be a view, copy the returned map into a new - * map of your choosing. - * - *

Warning: This method assumes that for any instance {@code k} of - * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies - * that {@code k2} is also of type {@code K}. Using an {@code - * EntryTransformer} key type for which this may not hold, such as {@code - * ArrayList}, may risk a {@code ClassCastException} when calling methods on - * the transformed map. - * - * @since 11.0 - */ - public static SortedMap transformEntries( - SortedMap fromMap, EntryTransformer transformer) { - return Platform.mapsTransformEntriesSortedMap(fromMap, transformer); - } - - /** - * Returns a view of a navigable map whose values are derived from the - * original navigable map's entries. In contrast to {@link - * #transformValues}, this method's entry-transformation logic may - * depend on the key as well as the value. - * - *

All other properties of the transformed map, such as iteration order, - * are left intact. For example, the code:

   {@code
-   *
-   *   NavigableMap options = Maps.newTreeMap();
-   *   options.put("verbose", false);
-   *   options.put("sort", true);
-   *   EntryTransformer flagPrefixer =
-   *       new EntryTransformer() {
-   *         public String transformEntry(String key, Boolean value) {
-   *           return value ? key : ("yes" + key);
-   *         }
-   *       };
-   *   NavigableMap transformed =
-   *       LabsMaps.transformNavigableEntries(options, flagPrefixer);
-   *   System.out.println(transformed);}
- * - * ... prints {@code {sort=yessort, verbose=verbose}}. - * - *

Changes in the underlying map are reflected in this view. - * Conversely, this view supports removal operations, and these are reflected - * in the underlying map. - * - *

It's acceptable for the underlying map to contain null keys and null - * values provided that the transformer is capable of accepting null inputs. - * The transformed map might contain null values if the transformer sometimes - * gives a null result. - * - *

The returned map is not thread-safe or serializable, even if the - * underlying map is. - * - *

The transformer is applied lazily, invoked when needed. This is - * necessary for the returned map to be a view, but it means that the - * transformer will be applied many times for bulk operations like {@link - * Map#containsValue} and {@link Object#toString}. For this to perform well, - * {@code transformer} should be fast. To avoid lazy evaluation when the - * returned map doesn't need to be a view, copy the returned map into a new - * map of your choosing. - * - *

Warning: This method assumes that for any instance {@code k} of - * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies - * that {@code k2} is also of type {@code K}. Using an {@code - * EntryTransformer} key type for which this may not hold, such as {@code - * ArrayList}, may risk a {@code ClassCastException} when calling methods on - * the transformed map. - * - * @since 13.0 - */ - @GwtIncompatible("NavigableMap") - public static NavigableMap transformEntries( - NavigableMap fromMap, EntryTransformer transformer) { - return new TransformedEntriesNavigableMap(fromMap, transformer); - } - - static SortedMap transformEntriesIgnoreNavigable( - SortedMap fromMap, EntryTransformer transformer) { - return new TransformedEntriesSortedMap(fromMap, transformer); - } - - /** - * A transformation of the value of a key-value pair, using both key and value - * as inputs. To apply the transformation to a map, use - * {@link Maps#transformEntries(Map, EntryTransformer)}. - * - * @param the key type of the input and output entries - * @param the value type of the input entry - * @param the value type of the output entry - * @since 7.0 - */ - public interface EntryTransformer { - /** - * Determines an output value based on a key-value pair. This method is - * generally expected, but not absolutely required, to have the - * following properties: - * - *

    - *
  • Its execution does not cause any observable side effects. - *
  • The computation is consistent with equals; that is, - * {@link Objects#equal Objects.equal}{@code (k1, k2) &&} - * {@link Objects#equal}{@code (v1, v2)} implies that {@code - * Objects.equal(transformer.transform(k1, v1), - * transformer.transform(k2, v2))}. - *
- * - * @throws NullPointerException if the key or value is null and this - * transformer does not accept null arguments - */ - V2 transformEntry(@Nullable K key, @Nullable V1 value); - } - - /** - * Views a function as an entry transformer that ignores the entry key. - */ - static EntryTransformer asEntryTransformer( - final Function function) { - checkNotNull(function); - return new EntryTransformer() { - @Override - public V2 transformEntry(K key, V1 value) { - return function.apply(value); - } - }; - } - - static Function asValueToValueFunction( - final EntryTransformer transformer, final K key) { - checkNotNull(transformer); - return new Function() { - @Override - public V2 apply(@Nullable V1 v1) { - return transformer.transformEntry(key, v1); - } - }; - } - - /** - * Views an entry transformer as a function from {@code Entry} to values. - */ - static Function, V2> asEntryToValueFunction( - final EntryTransformer transformer) { - checkNotNull(transformer); - return new Function, V2>() { - @Override - public V2 apply(Entry entry) { - return transformer.transformEntry(entry.getKey(), entry.getValue()); - } - }; - } - - /** - * Returns a view of an entry transformed by the specified transformer. - */ - static Entry transformEntry( - final EntryTransformer transformer, final Entry entry) { - checkNotNull(transformer); - checkNotNull(entry); - return new AbstractMapEntry() { - @Override - public K getKey() { - return entry.getKey(); - } - - @Override - public V2 getValue() { - return transformer.transformEntry(entry.getKey(), entry.getValue()); - } - }; - } - - /** - * Views an entry transformer as a function from entries to entries. - */ - static Function, Entry> asEntryToEntryFunction( - final EntryTransformer transformer) { - checkNotNull(transformer); - return new Function, Entry>() { - @Override - public Entry apply(final Entry entry) { - return transformEntry(transformer, entry); - } - }; - } - - static class TransformedEntriesMap extends IteratorBasedAbstractMap { - final Map fromMap; - final EntryTransformer transformer; - - TransformedEntriesMap( - Map fromMap, EntryTransformer transformer) { - this.fromMap = checkNotNull(fromMap); - this.transformer = checkNotNull(transformer); - } - - @Override - public int size() { - return fromMap.size(); - } - - @Override - public boolean containsKey(Object key) { - return fromMap.containsKey(key); - } - - // safe as long as the user followed the Warning in the javadoc - @SuppressWarnings("unchecked") - @Override - public V2 get(Object key) { - V1 value = fromMap.get(key); - return (value != null || fromMap.containsKey(key)) - ? transformer.transformEntry((K) key, value) - : null; - } - - // safe as long as the user followed the Warning in the javadoc - @SuppressWarnings("unchecked") - @Override - public V2 remove(Object key) { - return fromMap.containsKey(key) - ? transformer.transformEntry((K) key, fromMap.remove(key)) - : null; - } - - @Override - public void clear() { - fromMap.clear(); - } - - @Override - public Set keySet() { - return fromMap.keySet(); - } - - @Override - Iterator> entryIterator() { - return Iterators.transform( - fromMap.entrySet().iterator(), Maps.asEntryToEntryFunction(transformer)); - } - - @Override - public Collection values() { - return new Values(this); - } - } - - static class TransformedEntriesSortedMap extends TransformedEntriesMap - implements SortedMap { - - protected SortedMap fromMap() { - return (SortedMap) fromMap; - } - - TransformedEntriesSortedMap( - SortedMap fromMap, EntryTransformer transformer) { - super(fromMap, transformer); - } - - @Override - public Comparator comparator() { - return fromMap().comparator(); - } - - @Override - public K firstKey() { - return fromMap().firstKey(); - } - - @Override - public SortedMap headMap(K toKey) { - return transformEntries(fromMap().headMap(toKey), transformer); - } - - @Override - public K lastKey() { - return fromMap().lastKey(); - } - - @Override - public SortedMap subMap(K fromKey, K toKey) { - return transformEntries(fromMap().subMap(fromKey, toKey), transformer); - } - - @Override - public SortedMap tailMap(K fromKey) { - return transformEntries(fromMap().tailMap(fromKey), transformer); - } - } - - @GwtIncompatible("NavigableMap") - private static class TransformedEntriesNavigableMap - extends TransformedEntriesSortedMap implements NavigableMap { - - TransformedEntriesNavigableMap( - NavigableMap fromMap, EntryTransformer transformer) { - super(fromMap, transformer); - } - - @Override - public Entry ceilingEntry(K key) { - return transformEntry(fromMap().ceilingEntry(key)); - } - - @Override - public K ceilingKey(K key) { - return fromMap().ceilingKey(key); - } - - @Override - public NavigableSet descendingKeySet() { - return fromMap().descendingKeySet(); - } - - @Override - public NavigableMap descendingMap() { - return transformEntries(fromMap().descendingMap(), transformer); - } - - @Override - public Entry firstEntry() { - return transformEntry(fromMap().firstEntry()); - } - - @Override - public Entry floorEntry(K key) { - return transformEntry(fromMap().floorEntry(key)); - } - - @Override - public K floorKey(K key) { - return fromMap().floorKey(key); - } - - @Override - public NavigableMap headMap(K toKey) { - return headMap(toKey, false); - } - - @Override - public NavigableMap headMap(K toKey, boolean inclusive) { - return transformEntries(fromMap().headMap(toKey, inclusive), transformer); - } - - @Override - public Entry higherEntry(K key) { - return transformEntry(fromMap().higherEntry(key)); - } - - @Override - public K higherKey(K key) { - return fromMap().higherKey(key); - } - - @Override - public Entry lastEntry() { - return transformEntry(fromMap().lastEntry()); - } - - @Override - public Entry lowerEntry(K key) { - return transformEntry(fromMap().lowerEntry(key)); - } - - @Override - public K lowerKey(K key) { - return fromMap().lowerKey(key); - } - - @Override - public NavigableSet navigableKeySet() { - return fromMap().navigableKeySet(); - } - - @Override - public Entry pollFirstEntry() { - return transformEntry(fromMap().pollFirstEntry()); - } - - @Override - public Entry pollLastEntry() { - return transformEntry(fromMap().pollLastEntry()); - } - - @Override - public NavigableMap subMap( - K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { - return transformEntries( - fromMap().subMap(fromKey, fromInclusive, toKey, toInclusive), transformer); - } - - @Override - public NavigableMap subMap(K fromKey, K toKey) { - return subMap(fromKey, true, toKey, false); - } - - @Override - public NavigableMap tailMap(K fromKey) { - return tailMap(fromKey, true); - } - - @Override - public NavigableMap tailMap(K fromKey, boolean inclusive) { - return transformEntries(fromMap().tailMap(fromKey, inclusive), transformer); - } - - @Nullable - private Entry transformEntry(@Nullable Entry entry) { - return (entry == null) ? null : Maps.transformEntry(transformer, entry); - } - - @Override - protected NavigableMap fromMap() { - return (NavigableMap) super.fromMap(); - } - } - - static Predicate> keyPredicateOnEntries(Predicate keyPredicate) { - return compose(keyPredicate, Maps.keyFunction()); - } - - static Predicate> valuePredicateOnEntries(Predicate valuePredicate) { - return compose(valuePredicate, Maps.valueFunction()); - } - - /** - * Returns a map containing the mappings in {@code unfiltered} whose keys - * satisfy a predicate. The returned map is a live view of {@code unfiltered}; - * changes to one affect the other. - * - *

The resulting map's {@code keySet()}, {@code entrySet()}, and {@code - * values()} views have iterators that don't support {@code remove()}, but all - * other methods are supported by the map and its views. When given a key that - * doesn't satisfy the predicate, the map's {@code put()} and {@code putAll()} - * methods throw an {@link IllegalArgumentException}. - * - *

When methods such as {@code removeAll()} and {@code clear()} are called - * on the filtered map or its views, only mappings whose keys satisfy the - * filter will be removed from the underlying map. - * - *

The returned map isn't threadsafe or serializable, even if {@code - * unfiltered} is. - * - *

Many of the filtered map's methods, such as {@code size()}, - * iterate across every key/value mapping in the underlying map and determine - * which satisfy the filter. When a live view is not needed, it may be - * faster to copy the filtered map and use the copy. - * - *

Warning: {@code keyPredicate} must be consistent with - * equals, as documented at {@link Predicate#apply}. Do not provide a - * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is - * inconsistent with equals. - */ - @CheckReturnValue - public static Map filterKeys( - Map unfiltered, final Predicate keyPredicate) { - if (unfiltered instanceof SortedMap) { - return filterKeys((SortedMap) unfiltered, keyPredicate); - } else if (unfiltered instanceof BiMap) { - return filterKeys((BiMap) unfiltered, keyPredicate); - } - checkNotNull(keyPredicate); - Predicate> entryPredicate = keyPredicateOnEntries(keyPredicate); - return (unfiltered instanceof AbstractFilteredMap) - ? filterFiltered((AbstractFilteredMap) unfiltered, entryPredicate) - : new FilteredKeyMap(checkNotNull(unfiltered), keyPredicate, entryPredicate); - } - - /** - * Returns a sorted map containing the mappings in {@code unfiltered} whose - * keys satisfy a predicate. The returned map is a live view of {@code - * unfiltered}; changes to one affect the other. - * - *

The resulting map's {@code keySet()}, {@code entrySet()}, and {@code - * values()} views have iterators that don't support {@code remove()}, but all - * other methods are supported by the map and its views. When given a key that - * doesn't satisfy the predicate, the map's {@code put()} and {@code putAll()} - * methods throw an {@link IllegalArgumentException}. - * - *

When methods such as {@code removeAll()} and {@code clear()} are called - * on the filtered map or its views, only mappings whose keys satisfy the - * filter will be removed from the underlying map. - * - *

The returned map isn't threadsafe or serializable, even if {@code - * unfiltered} is. - * - *

Many of the filtered map's methods, such as {@code size()}, - * iterate across every key/value mapping in the underlying map and determine - * which satisfy the filter. When a live view is not needed, it may be - * faster to copy the filtered map and use the copy. - * - *

Warning: {@code keyPredicate} must be consistent with - * equals, as documented at {@link Predicate#apply}. Do not provide a - * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is - * inconsistent with equals. - * - * @since 11.0 - */ - @CheckReturnValue - public static SortedMap filterKeys( - SortedMap unfiltered, final Predicate keyPredicate) { - // TODO(lowasser): Return a subclass of Maps.FilteredKeyMap for slightly better - // performance. - return filterEntries(unfiltered, Maps.keyPredicateOnEntries(keyPredicate)); - } - - /** - * Returns a navigable map containing the mappings in {@code unfiltered} whose - * keys satisfy a predicate. The returned map is a live view of {@code - * unfiltered}; changes to one affect the other. - * - *

The resulting map's {@code keySet()}, {@code entrySet()}, and {@code - * values()} views have iterators that don't support {@code remove()}, but all - * other methods are supported by the map and its views. When given a key that - * doesn't satisfy the predicate, the map's {@code put()} and {@code putAll()} - * methods throw an {@link IllegalArgumentException}. - * - *

When methods such as {@code removeAll()} and {@code clear()} are called - * on the filtered map or its views, only mappings whose keys satisfy the - * filter will be removed from the underlying map. - * - *

The returned map isn't threadsafe or serializable, even if {@code - * unfiltered} is. - * - *

Many of the filtered map's methods, such as {@code size()}, - * iterate across every key/value mapping in the underlying map and determine - * which satisfy the filter. When a live view is not needed, it may be - * faster to copy the filtered map and use the copy. - * - *

Warning: {@code keyPredicate} must be consistent with - * equals, as documented at {@link Predicate#apply}. Do not provide a - * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is - * inconsistent with equals. - * - * @since 14.0 - */ - @GwtIncompatible("NavigableMap") - @CheckReturnValue - public static NavigableMap filterKeys( - NavigableMap unfiltered, final Predicate keyPredicate) { - // TODO(lowasser): Return a subclass of Maps.FilteredKeyMap for slightly better - // performance. - return filterEntries(unfiltered, Maps.keyPredicateOnEntries(keyPredicate)); - } - - /** - * Returns a bimap containing the mappings in {@code unfiltered} whose keys satisfy a predicate. - * The returned bimap is a live view of {@code unfiltered}; changes to one affect the other. - * - *

The resulting bimap's {@code keySet()}, {@code entrySet()}, and {@code values()} views have - * iterators that don't support {@code remove()}, but all other methods are supported by the - * bimap and its views. When given a key that doesn't satisfy the predicate, the bimap's {@code - * put()}, {@code forcePut()} and {@code putAll()} methods throw an {@link - * IllegalArgumentException}. - * - *

When methods such as {@code removeAll()} and {@code clear()} are called on the filtered - * bimap or its views, only mappings that satisfy the filter will be removed from the underlying - * bimap. - * - *

The returned bimap isn't threadsafe or serializable, even if {@code unfiltered} is. - * - *

Many of the filtered bimap's methods, such as {@code size()}, iterate across every key in - * the underlying bimap and determine which satisfy the filter. When a live view is not - * needed, it may be faster to copy the filtered bimap and use the copy. - * - *

Warning: {@code entryPredicate} must be consistent with equals , as - * documented at {@link Predicate#apply}. - * - * @since 14.0 - */ - @CheckReturnValue - public static BiMap filterKeys( - BiMap unfiltered, final Predicate keyPredicate) { - checkNotNull(keyPredicate); - return filterEntries(unfiltered, Maps.keyPredicateOnEntries(keyPredicate)); - } - - /** - * Returns a map containing the mappings in {@code unfiltered} whose values - * satisfy a predicate. The returned map is a live view of {@code unfiltered}; - * changes to one affect the other. - * - *

The resulting map's {@code keySet()}, {@code entrySet()}, and {@code - * values()} views have iterators that don't support {@code remove()}, but all - * other methods are supported by the map and its views. When given a value - * that doesn't satisfy the predicate, the map's {@code put()}, {@code - * putAll()}, and {@link Entry#setValue} methods throw an {@link - * IllegalArgumentException}. - * - *

When methods such as {@code removeAll()} and {@code clear()} are called - * on the filtered map or its views, only mappings whose values satisfy the - * filter will be removed from the underlying map. - * - *

The returned map isn't threadsafe or serializable, even if {@code - * unfiltered} is. - * - *

Many of the filtered map's methods, such as {@code size()}, - * iterate across every key/value mapping in the underlying map and determine - * which satisfy the filter. When a live view is not needed, it may be - * faster to copy the filtered map and use the copy. - * - *

Warning: {@code valuePredicate} must be consistent with - * equals, as documented at {@link Predicate#apply}. Do not provide a - * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is - * inconsistent with equals. - */ - @CheckReturnValue - public static Map filterValues( - Map unfiltered, final Predicate valuePredicate) { - if (unfiltered instanceof SortedMap) { - return filterValues((SortedMap) unfiltered, valuePredicate); - } else if (unfiltered instanceof BiMap) { - return filterValues((BiMap) unfiltered, valuePredicate); - } - return filterEntries(unfiltered, Maps.valuePredicateOnEntries(valuePredicate)); - } - - /** - * Returns a sorted map containing the mappings in {@code unfiltered} whose - * values satisfy a predicate. The returned map is a live view of {@code - * unfiltered}; changes to one affect the other. - * - *

The resulting map's {@code keySet()}, {@code entrySet()}, and {@code - * values()} views have iterators that don't support {@code remove()}, but all - * other methods are supported by the map and its views. When given a value - * that doesn't satisfy the predicate, the map's {@code put()}, {@code - * putAll()}, and {@link Entry#setValue} methods throw an {@link - * IllegalArgumentException}. - * - *

When methods such as {@code removeAll()} and {@code clear()} are called - * on the filtered map or its views, only mappings whose values satisfy the - * filter will be removed from the underlying map. - * - *

The returned map isn't threadsafe or serializable, even if {@code - * unfiltered} is. - * - *

Many of the filtered map's methods, such as {@code size()}, - * iterate across every key/value mapping in the underlying map and determine - * which satisfy the filter. When a live view is not needed, it may be - * faster to copy the filtered map and use the copy. - * - *

Warning: {@code valuePredicate} must be consistent with - * equals, as documented at {@link Predicate#apply}. Do not provide a - * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is - * inconsistent with equals. - * - * @since 11.0 - */ - @CheckReturnValue - public static SortedMap filterValues( - SortedMap unfiltered, final Predicate valuePredicate) { - return filterEntries(unfiltered, Maps.valuePredicateOnEntries(valuePredicate)); - } - - /** - * Returns a navigable map containing the mappings in {@code unfiltered} whose - * values satisfy a predicate. The returned map is a live view of {@code - * unfiltered}; changes to one affect the other. - * - *

The resulting map's {@code keySet()}, {@code entrySet()}, and {@code - * values()} views have iterators that don't support {@code remove()}, but all - * other methods are supported by the map and its views. When given a value - * that doesn't satisfy the predicate, the map's {@code put()}, {@code - * putAll()}, and {@link Entry#setValue} methods throw an {@link - * IllegalArgumentException}. - * - *

When methods such as {@code removeAll()} and {@code clear()} are called - * on the filtered map or its views, only mappings whose values satisfy the - * filter will be removed from the underlying map. - * - *

The returned map isn't threadsafe or serializable, even if {@code - * unfiltered} is. - * - *

Many of the filtered map's methods, such as {@code size()}, - * iterate across every key/value mapping in the underlying map and determine - * which satisfy the filter. When a live view is not needed, it may be - * faster to copy the filtered map and use the copy. - * - *

Warning: {@code valuePredicate} must be consistent with - * equals, as documented at {@link Predicate#apply}. Do not provide a - * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is - * inconsistent with equals. - * - * @since 14.0 - */ - @GwtIncompatible("NavigableMap") - @CheckReturnValue - public static NavigableMap filterValues( - NavigableMap unfiltered, final Predicate valuePredicate) { - return filterEntries(unfiltered, Maps.valuePredicateOnEntries(valuePredicate)); - } - - /** - * Returns a bimap containing the mappings in {@code unfiltered} whose values satisfy a - * predicate. The returned bimap is a live view of {@code unfiltered}; changes to one affect the - * other. - * - *

The resulting bimap's {@code keySet()}, {@code entrySet()}, and {@code values()} views have - * iterators that don't support {@code remove()}, but all other methods are supported by the - * bimap and its views. When given a value that doesn't satisfy the predicate, the bimap's - * {@code put()}, {@code forcePut()} and {@code putAll()} methods throw an {@link - * IllegalArgumentException}. Similarly, the map's entries have a {@link Entry#setValue} method - * that throws an {@link IllegalArgumentException} when the provided value doesn't satisfy the - * predicate. - * - *

When methods such as {@code removeAll()} and {@code clear()} are called on the filtered - * bimap or its views, only mappings that satisfy the filter will be removed from the underlying - * bimap. - * - *

The returned bimap isn't threadsafe or serializable, even if {@code unfiltered} is. - * - *

Many of the filtered bimap's methods, such as {@code size()}, iterate across every value in - * the underlying bimap and determine which satisfy the filter. When a live view is not - * needed, it may be faster to copy the filtered bimap and use the copy. - * - *

Warning: {@code entryPredicate} must be consistent with equals , as - * documented at {@link Predicate#apply}. - * - * @since 14.0 - */ - @CheckReturnValue - public static BiMap filterValues( - BiMap unfiltered, final Predicate valuePredicate) { - return filterEntries(unfiltered, Maps.valuePredicateOnEntries(valuePredicate)); - } - - /** - * Returns a map containing the mappings in {@code unfiltered} that satisfy a - * predicate. The returned map is a live view of {@code unfiltered}; changes - * to one affect the other. - * - *

The resulting map's {@code keySet()}, {@code entrySet()}, and {@code - * values()} views have iterators that don't support {@code remove()}, but all - * other methods are supported by the map and its views. When given a - * key/value pair that doesn't satisfy the predicate, the map's {@code put()} - * and {@code putAll()} methods throw an {@link IllegalArgumentException}. - * Similarly, the map's entries have a {@link Entry#setValue} method that - * throws an {@link IllegalArgumentException} when the existing key and the - * provided value don't satisfy the predicate. - * - *

When methods such as {@code removeAll()} and {@code clear()} are called - * on the filtered map or its views, only mappings that satisfy the filter - * will be removed from the underlying map. - * - *

The returned map isn't threadsafe or serializable, even if {@code - * unfiltered} is. - * - *

Many of the filtered map's methods, such as {@code size()}, - * iterate across every key/value mapping in the underlying map and determine - * which satisfy the filter. When a live view is not needed, it may be - * faster to copy the filtered map and use the copy. - * - *

Warning: {@code entryPredicate} must be consistent with - * equals, as documented at {@link Predicate#apply}. - */ - @CheckReturnValue - public static Map filterEntries( - Map unfiltered, Predicate> entryPredicate) { - if (unfiltered instanceof SortedMap) { - return filterEntries((SortedMap) unfiltered, entryPredicate); - } else if (unfiltered instanceof BiMap) { - return filterEntries((BiMap) unfiltered, entryPredicate); - } - checkNotNull(entryPredicate); - return (unfiltered instanceof AbstractFilteredMap) - ? filterFiltered((AbstractFilteredMap) unfiltered, entryPredicate) - : new FilteredEntryMap(checkNotNull(unfiltered), entryPredicate); - } - - /** - * Returns a sorted map containing the mappings in {@code unfiltered} that - * satisfy a predicate. The returned map is a live view of {@code unfiltered}; - * changes to one affect the other. - * - *

The resulting map's {@code keySet()}, {@code entrySet()}, and {@code - * values()} views have iterators that don't support {@code remove()}, but all - * other methods are supported by the map and its views. When given a - * key/value pair that doesn't satisfy the predicate, the map's {@code put()} - * and {@code putAll()} methods throw an {@link IllegalArgumentException}. - * Similarly, the map's entries have a {@link Entry#setValue} method that - * throws an {@link IllegalArgumentException} when the existing key and the - * provided value don't satisfy the predicate. - * - *

When methods such as {@code removeAll()} and {@code clear()} are called - * on the filtered map or its views, only mappings that satisfy the filter - * will be removed from the underlying map. - * - *

The returned map isn't threadsafe or serializable, even if {@code - * unfiltered} is. - * - *

Many of the filtered map's methods, such as {@code size()}, - * iterate across every key/value mapping in the underlying map and determine - * which satisfy the filter. When a live view is not needed, it may be - * faster to copy the filtered map and use the copy. - * - *

Warning: {@code entryPredicate} must be consistent with - * equals, as documented at {@link Predicate#apply}. - * - * @since 11.0 - */ - @CheckReturnValue - public static SortedMap filterEntries( - SortedMap unfiltered, Predicate> entryPredicate) { - return Platform.mapsFilterSortedMap(unfiltered, entryPredicate); - } - - static SortedMap filterSortedIgnoreNavigable( - SortedMap unfiltered, Predicate> entryPredicate) { - checkNotNull(entryPredicate); - return (unfiltered instanceof FilteredEntrySortedMap) - ? filterFiltered((FilteredEntrySortedMap) unfiltered, entryPredicate) - : new FilteredEntrySortedMap(checkNotNull(unfiltered), entryPredicate); - } - - /** - * Returns a sorted map containing the mappings in {@code unfiltered} that - * satisfy a predicate. The returned map is a live view of {@code unfiltered}; - * changes to one affect the other. - * - *

The resulting map's {@code keySet()}, {@code entrySet()}, and {@code - * values()} views have iterators that don't support {@code remove()}, but all - * other methods are supported by the map and its views. When given a - * key/value pair that doesn't satisfy the predicate, the map's {@code put()} - * and {@code putAll()} methods throw an {@link IllegalArgumentException}. - * Similarly, the map's entries have a {@link Entry#setValue} method that - * throws an {@link IllegalArgumentException} when the existing key and the - * provided value don't satisfy the predicate. - * - *

When methods such as {@code removeAll()} and {@code clear()} are called - * on the filtered map or its views, only mappings that satisfy the filter - * will be removed from the underlying map. - * - *

The returned map isn't threadsafe or serializable, even if {@code - * unfiltered} is. - * - *

Many of the filtered map's methods, such as {@code size()}, - * iterate across every key/value mapping in the underlying map and determine - * which satisfy the filter. When a live view is not needed, it may be - * faster to copy the filtered map and use the copy. - * - *

Warning: {@code entryPredicate} must be consistent with - * equals, as documented at {@link Predicate#apply}. - * - * @since 14.0 - */ - @GwtIncompatible("NavigableMap") - @CheckReturnValue - public static NavigableMap filterEntries( - NavigableMap unfiltered, Predicate> entryPredicate) { - checkNotNull(entryPredicate); - return (unfiltered instanceof FilteredEntryNavigableMap) - ? filterFiltered((FilteredEntryNavigableMap) unfiltered, entryPredicate) - : new FilteredEntryNavigableMap(checkNotNull(unfiltered), entryPredicate); - } - - /** - * Returns a bimap containing the mappings in {@code unfiltered} that satisfy a predicate. The - * returned bimap is a live view of {@code unfiltered}; changes to one affect the other. - * - *

The resulting bimap's {@code keySet()}, {@code entrySet()}, and {@code values()} views have - * iterators that don't support {@code remove()}, but all other methods are supported by the bimap - * and its views. When given a key/value pair that doesn't satisfy the predicate, the bimap's - * {@code put()}, {@code forcePut()} and {@code putAll()} methods throw an - * {@link IllegalArgumentException}. Similarly, the map's entries have an {@link Entry#setValue} - * method that throws an {@link IllegalArgumentException} when the existing key and the provided - * value don't satisfy the predicate. - * - *

When methods such as {@code removeAll()} and {@code clear()} are called on the filtered - * bimap or its views, only mappings that satisfy the filter will be removed from the underlying - * bimap. - * - *

The returned bimap isn't threadsafe or serializable, even if {@code unfiltered} is. - * - *

Many of the filtered bimap's methods, such as {@code size()}, iterate across every - * key/value mapping in the underlying bimap and determine which satisfy the filter. When a live - * view is not needed, it may be faster to copy the filtered bimap and use the copy. - * - *

Warning: {@code entryPredicate} must be consistent with equals , as - * documented at {@link Predicate#apply}. - * - * @since 14.0 - */ - @CheckReturnValue - public static BiMap filterEntries( - BiMap unfiltered, Predicate> entryPredicate) { - checkNotNull(unfiltered); - checkNotNull(entryPredicate); - return (unfiltered instanceof FilteredEntryBiMap) - ? filterFiltered((FilteredEntryBiMap) unfiltered, entryPredicate) - : new FilteredEntryBiMap(unfiltered, entryPredicate); - } - - /** - * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when - * filtering a filtered map. - */ - private static Map filterFiltered( - AbstractFilteredMap map, Predicate> entryPredicate) { - return new FilteredEntryMap( - map.unfiltered, Predicates.>and(map.predicate, entryPredicate)); - } - - private abstract static class AbstractFilteredMap extends ViewCachingAbstractMap { - final Map unfiltered; - final Predicate> predicate; - - AbstractFilteredMap(Map unfiltered, Predicate> predicate) { - this.unfiltered = unfiltered; - this.predicate = predicate; - } - - boolean apply(@Nullable Object key, @Nullable V value) { - // This method is called only when the key is in the map, implying that - // key is a K. - @SuppressWarnings("unchecked") - K k = (K) key; - return predicate.apply(Maps.immutableEntry(k, value)); - } - - @Override - public V put(K key, V value) { - checkArgument(apply(key, value)); - return unfiltered.put(key, value); - } - - @Override - public void putAll(Map map) { - for (Entry entry : map.entrySet()) { - checkArgument(apply(entry.getKey(), entry.getValue())); - } - unfiltered.putAll(map); - } - - @Override - public boolean containsKey(Object key) { - return unfiltered.containsKey(key) && apply(key, unfiltered.get(key)); - } - - @Override - public V get(Object key) { - V value = unfiltered.get(key); - return ((value != null) && apply(key, value)) ? value : null; - } - - @Override - public boolean isEmpty() { - return entrySet().isEmpty(); - } - - @Override - public V remove(Object key) { - return containsKey(key) ? unfiltered.remove(key) : null; - } - - @Override - Collection createValues() { - return new FilteredMapValues(this, unfiltered, predicate); - } - } - - private static final class FilteredMapValues extends Maps.Values { - Map unfiltered; - Predicate> predicate; - - FilteredMapValues( - Map filteredMap, Map unfiltered, Predicate> predicate) { - super(filteredMap); - this.unfiltered = unfiltered; - this.predicate = predicate; - } - - @Override - public boolean remove(Object o) { - return Iterables.removeFirstMatching( - unfiltered.entrySet(), - Predicates.>and(predicate, Maps.valuePredicateOnEntries(equalTo(o)))) - != null; - } - - private boolean removeIf(Predicate valuePredicate) { - return Iterables.removeIf( - unfiltered.entrySet(), - Predicates.>and(predicate, Maps.valuePredicateOnEntries(valuePredicate))); - } - - @Override - public boolean removeAll(Collection collection) { - return removeIf(in(collection)); - } - - @Override - public boolean retainAll(Collection collection) { - return removeIf(not(in(collection))); - } - - @Override - public Object[] toArray() { - // creating an ArrayList so filtering happens once - return Lists.newArrayList(iterator()).toArray(); - } - - @Override - public T[] toArray(T[] array) { - return Lists.newArrayList(iterator()).toArray(array); - } - } - - private static class FilteredKeyMap extends AbstractFilteredMap { - Predicate keyPredicate; - - FilteredKeyMap( - Map unfiltered, - Predicate keyPredicate, - Predicate> entryPredicate) { - super(unfiltered, entryPredicate); - this.keyPredicate = keyPredicate; - } - - @Override - protected Set> createEntrySet() { - return Sets.filter(unfiltered.entrySet(), predicate); - } - - @Override - Set createKeySet() { - return Sets.filter(unfiltered.keySet(), keyPredicate); - } - - // The cast is called only when the key is in the unfiltered map, implying - // that key is a K. - @Override - @SuppressWarnings("unchecked") - public boolean containsKey(Object key) { - return unfiltered.containsKey(key) && keyPredicate.apply((K) key); - } - } - - static class FilteredEntryMap extends AbstractFilteredMap { - /** - * Entries in this set satisfy the predicate, but they don't validate the - * input to {@code Entry.setValue()}. - */ - final Set> filteredEntrySet; - - FilteredEntryMap(Map unfiltered, Predicate> entryPredicate) { - super(unfiltered, entryPredicate); - filteredEntrySet = Sets.filter(unfiltered.entrySet(), predicate); - } - - @Override - protected Set> createEntrySet() { - return new EntrySet(); - } - - @WeakOuter - private class EntrySet extends ForwardingSet> { - @Override - protected Set> delegate() { - return filteredEntrySet; - } - - @Override - public Iterator> iterator() { - return new TransformedIterator, Entry>(filteredEntrySet.iterator()) { - @Override - Entry transform(final Entry entry) { - return new ForwardingMapEntry() { - @Override - protected Entry delegate() { - return entry; - } - - @Override - public V setValue(V newValue) { - checkArgument(apply(getKey(), newValue)); - return super.setValue(newValue); - } - }; - } - }; - } - } - - @Override - Set createKeySet() { - return new KeySet(); - } - - @WeakOuter - class KeySet extends Maps.KeySet { - KeySet() { - super(FilteredEntryMap.this); - } - - @Override - public boolean remove(Object o) { - if (containsKey(o)) { - unfiltered.remove(o); - return true; - } - return false; - } - - private boolean removeIf(Predicate keyPredicate) { - return Iterables.removeIf( - unfiltered.entrySet(), - Predicates.>and(predicate, Maps.keyPredicateOnEntries(keyPredicate))); - } - - @Override - public boolean removeAll(Collection c) { - return removeIf(in(c)); - } - - @Override - public boolean retainAll(Collection c) { - return removeIf(not(in(c))); - } - - @Override - public Object[] toArray() { - // creating an ArrayList so filtering happens once - return Lists.newArrayList(iterator()).toArray(); - } - - @Override - public T[] toArray(T[] array) { - return Lists.newArrayList(iterator()).toArray(array); - } - } - } - - /** - * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when - * filtering a filtered sorted map. - */ - private static SortedMap filterFiltered( - FilteredEntrySortedMap map, Predicate> entryPredicate) { - Predicate> predicate = Predicates.and(map.predicate, entryPredicate); - return new FilteredEntrySortedMap(map.sortedMap(), predicate); - } - - private static class FilteredEntrySortedMap extends FilteredEntryMap - implements SortedMap { - - FilteredEntrySortedMap( - SortedMap unfiltered, Predicate> entryPredicate) { - super(unfiltered, entryPredicate); - } - - SortedMap sortedMap() { - return (SortedMap) unfiltered; - } - - @Override - public SortedSet keySet() { - return (SortedSet) super.keySet(); - } - - @Override - SortedSet createKeySet() { - return new SortedKeySet(); - } - - @WeakOuter - class SortedKeySet extends KeySet implements SortedSet { - @Override - public Comparator comparator() { - return sortedMap().comparator(); - } - - @Override - public SortedSet subSet(K fromElement, K toElement) { - return (SortedSet) subMap(fromElement, toElement).keySet(); - } - - @Override - public SortedSet headSet(K toElement) { - return (SortedSet) headMap(toElement).keySet(); - } - - @Override - public SortedSet tailSet(K fromElement) { - return (SortedSet) tailMap(fromElement).keySet(); - } - - @Override - public K first() { - return firstKey(); - } - - @Override - public K last() { - return lastKey(); - } - } - - @Override - public Comparator comparator() { - return sortedMap().comparator(); - } - - @Override - public K firstKey() { - // correctly throws NoSuchElementException when filtered map is empty. - return keySet().iterator().next(); - } - - @Override - public K lastKey() { - SortedMap headMap = sortedMap(); - while (true) { - // correctly throws NoSuchElementException when filtered map is empty. - K key = headMap.lastKey(); - if (apply(key, unfiltered.get(key))) { - return key; - } - headMap = sortedMap().headMap(key); - } - } - - @Override - public SortedMap headMap(K toKey) { - return new FilteredEntrySortedMap(sortedMap().headMap(toKey), predicate); - } - - @Override - public SortedMap subMap(K fromKey, K toKey) { - return new FilteredEntrySortedMap(sortedMap().subMap(fromKey, toKey), predicate); - } - - @Override - public SortedMap tailMap(K fromKey) { - return new FilteredEntrySortedMap(sortedMap().tailMap(fromKey), predicate); - } - } - - /** - * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when - * filtering a filtered navigable map. - */ - @GwtIncompatible("NavigableMap") - private static NavigableMap filterFiltered( - FilteredEntryNavigableMap map, Predicate> entryPredicate) { - Predicate> predicate = Predicates.and(map.entryPredicate, entryPredicate); - return new FilteredEntryNavigableMap(map.unfiltered, predicate); - } - - @GwtIncompatible("NavigableMap") - private static class FilteredEntryNavigableMap extends AbstractNavigableMap { - /* - * It's less code to extend AbstractNavigableMap and forward the filtering logic to - * FilteredEntryMap than to extend FilteredEntrySortedMap and reimplement all the NavigableMap - * methods. - */ - - private final NavigableMap unfiltered; - private final Predicate> entryPredicate; - private final Map filteredDelegate; - - FilteredEntryNavigableMap( - NavigableMap unfiltered, Predicate> entryPredicate) { - this.unfiltered = checkNotNull(unfiltered); - this.entryPredicate = entryPredicate; - this.filteredDelegate = new FilteredEntryMap(unfiltered, entryPredicate); - } - - @Override - public Comparator comparator() { - return unfiltered.comparator(); - } - - @Override - public NavigableSet navigableKeySet() { - return new Maps.NavigableKeySet(this) { - @Override - public boolean removeAll(Collection c) { - return Iterators.removeIf( - unfiltered.entrySet().iterator(), - Predicates.>and(entryPredicate, Maps.keyPredicateOnEntries(in(c)))); - } - - @Override - public boolean retainAll(Collection c) { - return Iterators.removeIf( - unfiltered.entrySet().iterator(), - Predicates.>and( - entryPredicate, Maps.keyPredicateOnEntries(not(in(c))))); - } - }; - } - - @Override - public Collection values() { - return new FilteredMapValues(this, unfiltered, entryPredicate); - } - - @Override - Iterator> entryIterator() { - return Iterators.filter(unfiltered.entrySet().iterator(), entryPredicate); - } - - @Override - Iterator> descendingEntryIterator() { - return Iterators.filter(unfiltered.descendingMap().entrySet().iterator(), entryPredicate); - } - - @Override - public int size() { - return filteredDelegate.size(); - } - - @Override - public boolean isEmpty() { - return !Iterables.any(unfiltered.entrySet(), entryPredicate); - } - - @Override - @Nullable - public V get(@Nullable Object key) { - return filteredDelegate.get(key); - } - - @Override - public boolean containsKey(@Nullable Object key) { - return filteredDelegate.containsKey(key); - } - - @Override - public V put(K key, V value) { - return filteredDelegate.put(key, value); - } - - @Override - public V remove(@Nullable Object key) { - return filteredDelegate.remove(key); - } - - @Override - public void putAll(Map m) { - filteredDelegate.putAll(m); - } - - @Override - public void clear() { - filteredDelegate.clear(); - } - - @Override - public Set> entrySet() { - return filteredDelegate.entrySet(); - } - - @Override - public Entry pollFirstEntry() { - return Iterables.removeFirstMatching(unfiltered.entrySet(), entryPredicate); - } - - @Override - public Entry pollLastEntry() { - return Iterables.removeFirstMatching(unfiltered.descendingMap().entrySet(), entryPredicate); - } - - @Override - public NavigableMap descendingMap() { - return filterEntries(unfiltered.descendingMap(), entryPredicate); - } - - @Override - public NavigableMap subMap( - K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { - return filterEntries( - unfiltered.subMap(fromKey, fromInclusive, toKey, toInclusive), entryPredicate); - } - - @Override - public NavigableMap headMap(K toKey, boolean inclusive) { - return filterEntries(unfiltered.headMap(toKey, inclusive), entryPredicate); - } - - @Override - public NavigableMap tailMap(K fromKey, boolean inclusive) { - return filterEntries(unfiltered.tailMap(fromKey, inclusive), entryPredicate); - } - } - - /** - * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when - * filtering a filtered map. - */ - private static BiMap filterFiltered( - FilteredEntryBiMap map, Predicate> entryPredicate) { - Predicate> predicate = Predicates.and(map.predicate, entryPredicate); - return new FilteredEntryBiMap(map.unfiltered(), predicate); - } - - static final class FilteredEntryBiMap extends FilteredEntryMap - implements BiMap { - private final BiMap inverse; - - private static Predicate> inversePredicate( - final Predicate> forwardPredicate) { - return new Predicate>() { - @Override - public boolean apply(Entry input) { - return forwardPredicate.apply(Maps.immutableEntry(input.getValue(), input.getKey())); - } - }; - } - - FilteredEntryBiMap(BiMap delegate, Predicate> predicate) { - super(delegate, predicate); - this.inverse = - new FilteredEntryBiMap(delegate.inverse(), inversePredicate(predicate), this); - } - - private FilteredEntryBiMap( - BiMap delegate, Predicate> predicate, BiMap inverse) { - super(delegate, predicate); - this.inverse = inverse; - } - - BiMap unfiltered() { - return (BiMap) unfiltered; - } - - @Override - public V forcePut(@Nullable K key, @Nullable V value) { - checkArgument(apply(key, value)); - return unfiltered().forcePut(key, value); - } - - @Override - public BiMap inverse() { - return inverse; - } - - @Override - public Set values() { - return inverse.keySet(); - } - } - - /** - * Returns an unmodifiable view of the specified navigable map. Query operations on the returned - * map read through to the specified map, and attempts to modify the returned map, whether direct - * or via its views, result in an {@code UnsupportedOperationException}. - * - *

The returned navigable map will be serializable if the specified navigable map is - * serializable. - * - * @param map the navigable map for which an unmodifiable view is to be returned - * @return an unmodifiable view of the specified navigable map - * @since 12.0 - */ - @GwtIncompatible("NavigableMap") - public static NavigableMap unmodifiableNavigableMap(NavigableMap map) { - checkNotNull(map); - if (map instanceof UnmodifiableNavigableMap) { - return map; - } else { - return new UnmodifiableNavigableMap(map); - } - } - - @Nullable - private static Entry unmodifiableOrNull(@Nullable Entry entry) { - return (entry == null) ? null : Maps.unmodifiableEntry(entry); - } - - @GwtIncompatible("NavigableMap") - static class UnmodifiableNavigableMap extends ForwardingSortedMap - implements NavigableMap, Serializable { - private final NavigableMap delegate; - - UnmodifiableNavigableMap(NavigableMap delegate) { - this.delegate = delegate; - } - - UnmodifiableNavigableMap( - NavigableMap delegate, UnmodifiableNavigableMap descendingMap) { - this.delegate = delegate; - this.descendingMap = descendingMap; - } - - @Override - protected SortedMap delegate() { - return Collections.unmodifiableSortedMap(delegate); - } - - @Override - public Entry lowerEntry(K key) { - return unmodifiableOrNull(delegate.lowerEntry(key)); - } - - @Override - public K lowerKey(K key) { - return delegate.lowerKey(key); - } - - @Override - public Entry floorEntry(K key) { - return unmodifiableOrNull(delegate.floorEntry(key)); - } - - @Override - public K floorKey(K key) { - return delegate.floorKey(key); - } - - @Override - public Entry ceilingEntry(K key) { - return unmodifiableOrNull(delegate.ceilingEntry(key)); - } - - @Override - public K ceilingKey(K key) { - return delegate.ceilingKey(key); - } - - @Override - public Entry higherEntry(K key) { - return unmodifiableOrNull(delegate.higherEntry(key)); - } - - @Override - public K higherKey(K key) { - return delegate.higherKey(key); - } - - @Override - public Entry firstEntry() { - return unmodifiableOrNull(delegate.firstEntry()); - } - - @Override - public Entry lastEntry() { - return unmodifiableOrNull(delegate.lastEntry()); - } - - @Override - public final Entry pollFirstEntry() { - throw new UnsupportedOperationException(); - } - - @Override - public final Entry pollLastEntry() { - throw new UnsupportedOperationException(); - } - - private transient UnmodifiableNavigableMap descendingMap; - - @Override - public NavigableMap descendingMap() { - UnmodifiableNavigableMap result = descendingMap; - return (result == null) - ? descendingMap = new UnmodifiableNavigableMap(delegate.descendingMap(), this) - : result; - } - - @Override - public Set keySet() { - return navigableKeySet(); - } - - @Override - public NavigableSet navigableKeySet() { - return Sets.unmodifiableNavigableSet(delegate.navigableKeySet()); - } - - @Override - public NavigableSet descendingKeySet() { - return Sets.unmodifiableNavigableSet(delegate.descendingKeySet()); - } - - @Override - public SortedMap subMap(K fromKey, K toKey) { - return subMap(fromKey, true, toKey, false); - } - - @Override - public SortedMap headMap(K toKey) { - return headMap(toKey, false); - } - - @Override - public SortedMap tailMap(K fromKey) { - return tailMap(fromKey, true); - } - - @Override - public NavigableMap subMap( - K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { - return Maps.unmodifiableNavigableMap( - delegate.subMap(fromKey, fromInclusive, toKey, toInclusive)); - } - - @Override - public NavigableMap headMap(K toKey, boolean inclusive) { - return Maps.unmodifiableNavigableMap(delegate.headMap(toKey, inclusive)); - } - - @Override - public NavigableMap tailMap(K fromKey, boolean inclusive) { - return Maps.unmodifiableNavigableMap(delegate.tailMap(fromKey, inclusive)); - } - } - - /** - * Returns a synchronized (thread-safe) navigable map backed by the specified - * navigable map. In order to guarantee serial access, it is critical that - * all access to the backing navigable map is accomplished - * through the returned navigable map (or its views). - * - *

It is imperative that the user manually synchronize on the returned - * navigable map when iterating over any of its collection views, or the - * collections views of any of its {@code descendingMap}, {@code subMap}, - * {@code headMap} or {@code tailMap} views.

   {@code
-   *
-   *   NavigableMap map = synchronizedNavigableMap(new TreeMap());
-   *
-   *   // Needn't be in synchronized block
-   *   NavigableSet set = map.navigableKeySet();
-   *
-   *   synchronized (map) { // Synchronizing on map, not set!
-   *     Iterator it = set.iterator(); // Must be in synchronized block
-   *     while (it.hasNext()) {
-   *       foo(it.next());
-   *     }
-   *   }}
- * - *

or:

   {@code
-   *
-   *   NavigableMap map = synchronizedNavigableMap(new TreeMap());
-   *   NavigableMap map2 = map.subMap(foo, false, bar, true);
-   *
-   *   // Needn't be in synchronized block
-   *   NavigableSet set2 = map2.descendingKeySet();
-   *
-   *   synchronized (map) { // Synchronizing on map, not map2 or set2!
-   *     Iterator it = set2.iterator(); // Must be in synchronized block
-   *     while (it.hasNext()) {
-   *       foo(it.next());
-   *     }
-   *   }}
- * - *

Failure to follow this advice may result in non-deterministic behavior. - * - *

The returned navigable map will be serializable if the specified - * navigable map is serializable. - * - * @param navigableMap the navigable map to be "wrapped" in a synchronized - * navigable map. - * @return a synchronized view of the specified navigable map. - * @since 13.0 - */ - @GwtIncompatible("NavigableMap") - public static NavigableMap synchronizedNavigableMap( - NavigableMap navigableMap) { - return Synchronized.navigableMap(navigableMap); - } - - /** - * {@code AbstractMap} extension that makes it easy to cache customized keySet, values, - * and entrySet views. - */ - @GwtCompatible - abstract static class ViewCachingAbstractMap extends AbstractMap { - /** - * Creates the entry set to be returned by {@link #entrySet()}. This method - * is invoked at most once on a given map, at the time when {@code entrySet} - * is first called. - */ - abstract Set> createEntrySet(); - - private transient Set> entrySet; - - @Override - public Set> entrySet() { - Set> result = entrySet; - return (result == null) ? entrySet = createEntrySet() : result; - } - - private transient Set keySet; - - @Override - public Set keySet() { - Set result = keySet; - return (result == null) ? keySet = createKeySet() : result; - } - - Set createKeySet() { - return new KeySet(this); - } - - private transient Collection values; - - @Override - public Collection values() { - Collection result = values; - return (result == null) ? values = createValues() : result; - } - - Collection createValues() { - return new Values(this); - } - } - - abstract static class IteratorBasedAbstractMap extends AbstractMap { - @Override - public abstract int size(); - - abstract Iterator> entryIterator(); - - @Override - public Set> entrySet() { - return new EntrySet() { - @Override - Map map() { - return IteratorBasedAbstractMap.this; - } - - @Override - public Iterator> iterator() { - return entryIterator(); - } - }; - } - - @Override - public void clear() { - Iterators.clear(entryIterator()); - } - } - - /** - * Delegates to {@link Map#get}. Returns {@code null} on {@code - * ClassCastException} and {@code NullPointerException}. - */ - static V safeGet(Map map, @Nullable Object key) { - checkNotNull(map); - try { - return map.get(key); - } catch (ClassCastException e) { - return null; - } catch (NullPointerException e) { - return null; - } - } - - /** - * Delegates to {@link Map#containsKey}. Returns {@code false} on {@code - * ClassCastException} and {@code NullPointerException}. - */ - static boolean safeContainsKey(Map map, Object key) { - checkNotNull(map); - try { - return map.containsKey(key); - } catch (ClassCastException e) { - return false; - } catch (NullPointerException e) { - return false; - } - } - - /** - * Delegates to {@link Map#remove}. Returns {@code null} on {@code - * ClassCastException} and {@code NullPointerException}. - */ - static V safeRemove(Map map, Object key) { - checkNotNull(map); - try { - return map.remove(key); - } catch (ClassCastException e) { - return null; - } catch (NullPointerException e) { - return null; - } - } - - /** - * An admittedly inefficient implementation of {@link Map#containsKey}. - */ - static boolean containsKeyImpl(Map map, @Nullable Object key) { - return Iterators.contains(keyIterator(map.entrySet().iterator()), key); - } - - /** - * An implementation of {@link Map#containsValue}. - */ - static boolean containsValueImpl(Map map, @Nullable Object value) { - return Iterators.contains(valueIterator(map.entrySet().iterator()), value); - } - - /** - * Implements {@code Collection.contains} safely for forwarding collections of - * map entries. If {@code o} is an instance of {@code Map.Entry}, it is - * wrapped using {@link #unmodifiableEntry} to protect against a possible - * nefarious equals method. - * - *

Note that {@code c} is the backing (delegate) collection, rather than - * the forwarding collection. - * - * @param c the delegate (unwrapped) collection of map entries - * @param o the object that might be contained in {@code c} - * @return {@code true} if {@code c} contains {@code o} - */ - static boolean containsEntryImpl(Collection> c, Object o) { - if (!(o instanceof Entry)) { - return false; - } - return c.contains(unmodifiableEntry((Entry) o)); - } - - /** - * Implements {@code Collection.remove} safely for forwarding collections of - * map entries. If {@code o} is an instance of {@code Map.Entry}, it is - * wrapped using {@link #unmodifiableEntry} to protect against a possible - * nefarious equals method. - * - *

Note that {@code c} is backing (delegate) collection, rather than the - * forwarding collection. - * - * @param c the delegate (unwrapped) collection of map entries - * @param o the object to remove from {@code c} - * @return {@code true} if {@code c} was changed - */ - static boolean removeEntryImpl(Collection> c, Object o) { - if (!(o instanceof Entry)) { - return false; - } - return c.remove(unmodifiableEntry((Entry) o)); - } - - /** - * An implementation of {@link Map#equals}. - */ - static boolean equalsImpl(Map map, Object object) { - if (map == object) { - return true; - } else if (object instanceof Map) { - Map o = (Map) object; - return map.entrySet().equals(o.entrySet()); - } - return false; - } - - static final MapJoiner STANDARD_JOINER = Collections2.STANDARD_JOINER.withKeyValueSeparator("="); - - /** - * An implementation of {@link Map#toString}. - */ - static String toStringImpl(Map map) { - StringBuilder sb = Collections2.newStringBuilderForCollection(map.size()).append('{'); - STANDARD_JOINER.appendTo(sb, map); - return sb.append('}').toString(); - } - - /** - * An implementation of {@link Map#putAll}. - */ - static void putAllImpl(Map self, Map map) { - for (Map.Entry entry : map.entrySet()) { - self.put(entry.getKey(), entry.getValue()); - } - } - - static class KeySet extends Sets.ImprovedAbstractSet { - @Weak final Map map; - - KeySet(Map map) { - this.map = checkNotNull(map); - } - - Map map() { - return map; - } - - @Override - public Iterator iterator() { - return keyIterator(map().entrySet().iterator()); - } - - @Override - public int size() { - return map().size(); - } - - @Override - public boolean isEmpty() { - return map().isEmpty(); - } - - @Override - public boolean contains(Object o) { - return map().containsKey(o); - } - - @Override - public boolean remove(Object o) { - if (contains(o)) { - map().remove(o); - return true; - } - return false; - } - - @Override - public void clear() { - map().clear(); - } - } - - @Nullable - static K keyOrNull(@Nullable Entry entry) { - return (entry == null) ? null : entry.getKey(); - } - - @Nullable - static V valueOrNull(@Nullable Entry entry) { - return (entry == null) ? null : entry.getValue(); - } - - static class SortedKeySet extends KeySet implements SortedSet { - SortedKeySet(SortedMap map) { - super(map); - } - - @Override - SortedMap map() { - return (SortedMap) super.map(); - } - - @Override - public Comparator comparator() { - return map().comparator(); - } - - @Override - public SortedSet subSet(K fromElement, K toElement) { - return new SortedKeySet(map().subMap(fromElement, toElement)); - } - - @Override - public SortedSet headSet(K toElement) { - return new SortedKeySet(map().headMap(toElement)); - } - - @Override - public SortedSet tailSet(K fromElement) { - return new SortedKeySet(map().tailMap(fromElement)); - } - - @Override - public K first() { - return map().firstKey(); - } - - @Override - public K last() { - return map().lastKey(); - } - } - - @GwtIncompatible("NavigableMap") - static class NavigableKeySet extends SortedKeySet implements NavigableSet { - NavigableKeySet(NavigableMap map) { - super(map); - } - - @Override - NavigableMap map() { - return (NavigableMap) map; - } - - @Override - public K lower(K e) { - return map().lowerKey(e); - } - - @Override - public K floor(K e) { - return map().floorKey(e); - } - - @Override - public K ceiling(K e) { - return map().ceilingKey(e); - } - - @Override - public K higher(K e) { - return map().higherKey(e); - } - - @Override - public K pollFirst() { - return keyOrNull(map().pollFirstEntry()); - } - - @Override - public K pollLast() { - return keyOrNull(map().pollLastEntry()); - } - - @Override - public NavigableSet descendingSet() { - return map().descendingKeySet(); - } - - @Override - public Iterator descendingIterator() { - return descendingSet().iterator(); - } - - @Override - public NavigableSet subSet( - K fromElement, boolean fromInclusive, K toElement, boolean toInclusive) { - return map().subMap(fromElement, fromInclusive, toElement, toInclusive).navigableKeySet(); - } - - @Override - public NavigableSet headSet(K toElement, boolean inclusive) { - return map().headMap(toElement, inclusive).navigableKeySet(); - } - - @Override - public NavigableSet tailSet(K fromElement, boolean inclusive) { - return map().tailMap(fromElement, inclusive).navigableKeySet(); - } - - @Override - public SortedSet subSet(K fromElement, K toElement) { - return subSet(fromElement, true, toElement, false); - } - - @Override - public SortedSet headSet(K toElement) { - return headSet(toElement, false); - } - - @Override - public SortedSet tailSet(K fromElement) { - return tailSet(fromElement, true); - } - } - - static class Values extends AbstractCollection { - @Weak final Map map; - - Values(Map map) { - this.map = checkNotNull(map); - } - - final Map map() { - return map; - } - - @Override - public Iterator iterator() { - return valueIterator(map().entrySet().iterator()); - } - - @Override - public boolean remove(Object o) { - try { - return super.remove(o); - } catch (UnsupportedOperationException e) { - for (Entry entry : map().entrySet()) { - if (Objects.equal(o, entry.getValue())) { - map().remove(entry.getKey()); - return true; - } - } - return false; - } - } - - @Override - public boolean removeAll(Collection c) { - try { - return super.removeAll(checkNotNull(c)); - } catch (UnsupportedOperationException e) { - Set toRemove = Sets.newHashSet(); - for (Entry entry : map().entrySet()) { - if (c.contains(entry.getValue())) { - toRemove.add(entry.getKey()); - } - } - return map().keySet().removeAll(toRemove); - } - } - - @Override - public boolean retainAll(Collection c) { - try { - return super.retainAll(checkNotNull(c)); - } catch (UnsupportedOperationException e) { - Set toRetain = Sets.newHashSet(); - for (Entry entry : map().entrySet()) { - if (c.contains(entry.getValue())) { - toRetain.add(entry.getKey()); - } - } - return map().keySet().retainAll(toRetain); - } - } - - @Override - public int size() { - return map().size(); - } - - @Override - public boolean isEmpty() { - return map().isEmpty(); - } - - @Override - public boolean contains(@Nullable Object o) { - return map().containsValue(o); - } - - @Override - public void clear() { - map().clear(); - } - } - - abstract static class EntrySet extends Sets.ImprovedAbstractSet> { - abstract Map map(); - - @Override - public int size() { - return map().size(); - } - - @Override - public void clear() { - map().clear(); - } - - @Override - public boolean contains(Object o) { - if (o instanceof Entry) { - Entry entry = (Entry) o; - Object key = entry.getKey(); - V value = Maps.safeGet(map(), key); - return Objects.equal(value, entry.getValue()) && (value != null || map().containsKey(key)); - } - return false; - } - - @Override - public boolean isEmpty() { - return map().isEmpty(); - } - - @Override - public boolean remove(Object o) { - if (contains(o)) { - Entry entry = (Entry) o; - return map().keySet().remove(entry.getKey()); - } - return false; - } - - @Override - public boolean removeAll(Collection c) { - try { - return super.removeAll(checkNotNull(c)); - } catch (UnsupportedOperationException e) { - // if the iterators don't support remove - return Sets.removeAllImpl(this, c.iterator()); - } - } - - @Override - public boolean retainAll(Collection c) { - try { - return super.retainAll(checkNotNull(c)); - } catch (UnsupportedOperationException e) { - // if the iterators don't support remove - Set keys = Sets.newHashSetWithExpectedSize(c.size()); - for (Object o : c) { - if (contains(o)) { - Entry entry = (Entry) o; - keys.add(entry.getKey()); - } - } - return map().keySet().retainAll(keys); - } - } - } - - @GwtIncompatible("NavigableMap") - abstract static class DescendingMap extends ForwardingMap - implements NavigableMap { - - abstract NavigableMap forward(); - - @Override - protected final Map delegate() { - return forward(); - } - - private transient Comparator comparator; - - @SuppressWarnings("unchecked") - @Override - public Comparator comparator() { - Comparator result = comparator; - if (result == null) { - Comparator forwardCmp = forward().comparator(); - if (forwardCmp == null) { - forwardCmp = (Comparator) Ordering.natural(); - } - result = comparator = reverse(forwardCmp); - } - return result; - } - - // If we inline this, we get a javac error. - private static Ordering reverse(Comparator forward) { - return Ordering.from(forward).reverse(); - } - - @Override - public K firstKey() { - return forward().lastKey(); - } - - @Override - public K lastKey() { - return forward().firstKey(); - } - - @Override - public Entry lowerEntry(K key) { - return forward().higherEntry(key); - } - - @Override - public K lowerKey(K key) { - return forward().higherKey(key); - } - - @Override - public Entry floorEntry(K key) { - return forward().ceilingEntry(key); - } - - @Override - public K floorKey(K key) { - return forward().ceilingKey(key); - } - - @Override - public Entry ceilingEntry(K key) { - return forward().floorEntry(key); - } - - @Override - public K ceilingKey(K key) { - return forward().floorKey(key); - } - - @Override - public Entry higherEntry(K key) { - return forward().lowerEntry(key); - } - - @Override - public K higherKey(K key) { - return forward().lowerKey(key); - } - - @Override - public Entry firstEntry() { - return forward().lastEntry(); - } - - @Override - public Entry lastEntry() { - return forward().firstEntry(); - } - - @Override - public Entry pollFirstEntry() { - return forward().pollLastEntry(); - } - - @Override - public Entry pollLastEntry() { - return forward().pollFirstEntry(); - } - - @Override - public NavigableMap descendingMap() { - return forward(); - } - - private transient Set> entrySet; - - @Override - public Set> entrySet() { - Set> result = entrySet; - return (result == null) ? entrySet = createEntrySet() : result; - } - - abstract Iterator> entryIterator(); - - Set> createEntrySet() { - @WeakOuter - class EntrySetImpl extends EntrySet { - @Override - Map map() { - return DescendingMap.this; - } - - @Override - public Iterator> iterator() { - return entryIterator(); - } - } - return new EntrySetImpl(); - } - - @Override - public Set keySet() { - return navigableKeySet(); - } - - private transient NavigableSet navigableKeySet; - - @Override - public NavigableSet navigableKeySet() { - NavigableSet result = navigableKeySet; - return (result == null) ? navigableKeySet = new NavigableKeySet(this) : result; - } - - @Override - public NavigableSet descendingKeySet() { - return forward().navigableKeySet(); - } - - @Override - public NavigableMap subMap( - K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { - return forward().subMap(toKey, toInclusive, fromKey, fromInclusive).descendingMap(); - } - - @Override - public NavigableMap headMap(K toKey, boolean inclusive) { - return forward().tailMap(toKey, inclusive).descendingMap(); - } - - @Override - public NavigableMap tailMap(K fromKey, boolean inclusive) { - return forward().headMap(fromKey, inclusive).descendingMap(); - } - - @Override - public SortedMap subMap(K fromKey, K toKey) { - return subMap(fromKey, true, toKey, false); - } - - @Override - public SortedMap headMap(K toKey) { - return headMap(toKey, false); - } - - @Override - public SortedMap tailMap(K fromKey) { - return tailMap(fromKey, true); - } - - @Override - public Collection values() { - return new Values(this); - } - - @Override - public String toString() { - return standardToString(); - } - } - - /** - * Returns a map from the ith element of list to i. - */ - static ImmutableMap indexMap(Collection list) { - ImmutableMap.Builder builder = new ImmutableMap.Builder(list.size()); - int i = 0; - for (E e : list) { - builder.put(e, i++); - } - return builder.build(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/MinMaxPriorityQueue.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/MinMaxPriorityQueue.java deleted file mode 100644 index 451eec8c0c7c..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/MinMaxPriorityQueue.java +++ /dev/null @@ -1,960 +0,0 @@ -/* - * Copyright (C) 2010 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkPositionIndex; -import static com.google.common.base.Preconditions.checkState; -import static com.google.common.collect.CollectPreconditions.checkRemove; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.math.IntMath; -import com.google.j2objc.annotations.Weak; -import com.google.j2objc.annotations.WeakOuter; - -import java.util.AbstractQueue; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.ConcurrentModificationException; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.PriorityQueue; -import java.util.Queue; - -/** - * A double-ended priority queue, which provides constant-time access to both - * its least element and its greatest element, as determined by the queue's - * specified comparator. If no comparator is given at creation time, the - * natural order of elements is used. If no maximum size is given at creation time, - * the queue is unbounded. - * - *

Usage example:

   {@code
- *
- *   MinMaxPriorityQueue users = MinMaxPriorityQueue.orderedBy(userComparator)
- *       .maximumSize(1000)
- *       .create();}
- * - *

As a {@link Queue} it functions exactly as a {@link PriorityQueue}: its - * head element -- the implicit target of the methods {@link #peek()}, {@link - * #poll()} and {@link #remove()} -- is defined as the least element in - * the queue according to the queue's comparator. But unlike a regular priority - * queue, the methods {@link #peekLast}, {@link #pollLast} and - * {@link #removeLast} are also provided, to act on the greatest element - * in the queue instead. - * - *

A min-max priority queue can be configured with a maximum size. If so, - * each time the size of the queue exceeds that value, the queue automatically - * removes its greatest element according to its comparator (which might be the - * element that was just added). This is different from conventional bounded - * queues, which either block or reject new elements when full. - * - *

This implementation is based on the - * min-max heap - * developed by Atkinson, et al. Unlike many other double-ended priority queues, - * it stores elements in a single array, as compact as the traditional heap data - * structure used in {@link PriorityQueue}. - * - *

This class is not thread-safe, and does not accept null elements. - * - *

Performance notes: - * - *

    - *
  • If you only access one end of the queue, and do use a maximum size, - * this class will perform significantly worse than a {@code PriorityQueue} - * with manual eviction above the maximum size. In many cases - * {@link Ordering#leastOf} may work for your use case with significantly - * improved (and asymptotically superior) performance. - *
  • The retrieval operations {@link #peek}, {@link #peekFirst}, {@link - * #peekLast}, {@link #element}, and {@link #size} are constant-time. - *
  • The enqueing and dequeing operations ({@link #offer}, {@link #add}, and - * all the forms of {@link #poll} and {@link #remove()}) run in {@code - * O(log n) time}. - *
  • The {@link #remove(Object)} and {@link #contains} operations require - * linear ({@code O(n)}) time. - *
  • If you only access one end of the queue, and don't use a maximum size, - * this class is functionally equivalent to {@link PriorityQueue}, but - * significantly slower. - *
- * - * @author Sverre Sundsdal - * @author Torbjorn Gannholm - * @since 8.0 - */ -// TODO(kevinb): GWT compatibility -@Beta -public final class MinMaxPriorityQueue extends AbstractQueue { - - /** - * Creates a new min-max priority queue with default settings: natural order, - * no maximum size, no initial contents, and an initial expected size of 11. - */ - public static > MinMaxPriorityQueue create() { - return new Builder(Ordering.natural()).create(); - } - - /** - * Creates a new min-max priority queue using natural order, no maximum size, - * and initially containing the given elements. - */ - public static > MinMaxPriorityQueue create( - Iterable initialContents) { - return new Builder(Ordering.natural()).create(initialContents); - } - - /** - * Creates and returns a new builder, configured to build {@code - * MinMaxPriorityQueue} instances that use {@code comparator} to determine the - * least and greatest elements. - */ - public static Builder orderedBy(Comparator comparator) { - return new Builder(comparator); - } - - /** - * Creates and returns a new builder, configured to build {@code - * MinMaxPriorityQueue} instances sized appropriately to hold {@code - * expectedSize} elements. - */ - public static Builder expectedSize(int expectedSize) { - return new Builder(Ordering.natural()).expectedSize(expectedSize); - } - - /** - * Creates and returns a new builder, configured to build {@code - * MinMaxPriorityQueue} instances that are limited to {@code maximumSize} - * elements. Each time a queue grows beyond this bound, it immediately - * removes its greatest element (according to its comparator), which might be - * the element that was just added. - */ - public static Builder maximumSize(int maximumSize) { - return new Builder(Ordering.natural()).maximumSize(maximumSize); - } - - /** - * The builder class used in creation of min-max priority queues. Instead of - * constructing one directly, use {@link - * MinMaxPriorityQueue#orderedBy(Comparator)}, {@link - * MinMaxPriorityQueue#expectedSize(int)} or {@link - * MinMaxPriorityQueue#maximumSize(int)}. - * - * @param the upper bound on the eventual type that can be produced by - * this builder (for example, a {@code Builder} can produce a - * {@code Queue} or {@code Queue} but not a {@code - * Queue}). - * @since 8.0 - */ - @Beta - public static final class Builder { - /* - * TODO(kevinb): when the dust settles, see if we still need this or can - * just default to DEFAULT_CAPACITY. - */ - private static final int UNSET_EXPECTED_SIZE = -1; - - private final Comparator comparator; - private int expectedSize = UNSET_EXPECTED_SIZE; - private int maximumSize = Integer.MAX_VALUE; - - private Builder(Comparator comparator) { - this.comparator = checkNotNull(comparator); - } - - /** - * Configures this builder to build min-max priority queues with an initial - * expected size of {@code expectedSize}. - */ - public Builder expectedSize(int expectedSize) { - checkArgument(expectedSize >= 0); - this.expectedSize = expectedSize; - return this; - } - - /** - * Configures this builder to build {@code MinMaxPriorityQueue} instances - * that are limited to {@code maximumSize} elements. Each time a queue grows - * beyond this bound, it immediately removes its greatest element (according - * to its comparator), which might be the element that was just added. - */ - public Builder maximumSize(int maximumSize) { - checkArgument(maximumSize > 0); - this.maximumSize = maximumSize; - return this; - } - - /** - * Builds a new min-max priority queue using the previously specified - * options, and having no initial contents. - */ - public MinMaxPriorityQueue create() { - return create(Collections.emptySet()); - } - - /** - * Builds a new min-max priority queue using the previously specified - * options, and having the given initial elements. - */ - public MinMaxPriorityQueue create(Iterable initialContents) { - MinMaxPriorityQueue queue = - new MinMaxPriorityQueue( - this, initialQueueSize(expectedSize, maximumSize, initialContents)); - for (T element : initialContents) { - queue.offer(element); - } - return queue; - } - - @SuppressWarnings("unchecked") // safe "contravariant cast" - private Ordering ordering() { - return Ordering.from((Comparator) comparator); - } - } - - private final Heap minHeap; - private final Heap maxHeap; - @VisibleForTesting final int maximumSize; - private Object[] queue; - private int size; - private int modCount; - - private MinMaxPriorityQueue(Builder builder, int queueSize) { - Ordering ordering = builder.ordering(); - this.minHeap = new Heap(ordering); - this.maxHeap = new Heap(ordering.reverse()); - minHeap.otherHeap = maxHeap; - maxHeap.otherHeap = minHeap; - - this.maximumSize = builder.maximumSize; - // TODO(kevinb): pad? - this.queue = new Object[queueSize]; - } - - @Override - public int size() { - return size; - } - - /** - * Adds the given element to this queue. If this queue has a maximum size, - * after adding {@code element} the queue will automatically evict its - * greatest element (according to its comparator), which may be {@code - * element} itself. - * - * @return {@code true} always - */ - @Override - public boolean add(E element) { - offer(element); - return true; - } - - @Override - public boolean addAll(Collection newElements) { - boolean modified = false; - for (E element : newElements) { - offer(element); - modified = true; - } - return modified; - } - - /** - * Adds the given element to this queue. If this queue has a maximum size, - * after adding {@code element} the queue will automatically evict its - * greatest element (according to its comparator), which may be {@code - * element} itself. - */ - @Override - public boolean offer(E element) { - checkNotNull(element); - modCount++; - int insertIndex = size++; - - growIfNeeded(); - - // Adds the element to the end of the heap and bubbles it up to the correct - // position. - heapForIndex(insertIndex).bubbleUp(insertIndex, element); - return size <= maximumSize || pollLast() != element; - } - - @Override - public E poll() { - return isEmpty() ? null : removeAndGet(0); - } - - @SuppressWarnings("unchecked") // we must carefully only allow Es to get in - E elementData(int index) { - return (E) queue[index]; - } - - @Override - public E peek() { - return isEmpty() ? null : elementData(0); - } - - /** - * Returns the index of the max element. - */ - private int getMaxElementIndex() { - switch (size) { - case 1: - return 0; // The lone element in the queue is the maximum. - case 2: - return 1; // The lone element in the maxHeap is the maximum. - default: - // The max element must sit on the first level of the maxHeap. It is - // actually the *lesser* of the two from the maxHeap's perspective. - return (maxHeap.compareElements(1, 2) <= 0) ? 1 : 2; - } - } - - /** - * Removes and returns the least element of this queue, or returns {@code - * null} if the queue is empty. - */ - public E pollFirst() { - return poll(); - } - - /** - * Removes and returns the least element of this queue. - * - * @throws NoSuchElementException if the queue is empty - */ - public E removeFirst() { - return remove(); - } - - /** - * Retrieves, but does not remove, the least element of this queue, or returns - * {@code null} if the queue is empty. - */ - public E peekFirst() { - return peek(); - } - - /** - * Removes and returns the greatest element of this queue, or returns {@code - * null} if the queue is empty. - */ - public E pollLast() { - return isEmpty() ? null : removeAndGet(getMaxElementIndex()); - } - - /** - * Removes and returns the greatest element of this queue. - * - * @throws NoSuchElementException if the queue is empty - */ - public E removeLast() { - if (isEmpty()) { - throw new NoSuchElementException(); - } - return removeAndGet(getMaxElementIndex()); - } - - /** - * Retrieves, but does not remove, the greatest element of this queue, or - * returns {@code null} if the queue is empty. - */ - public E peekLast() { - return isEmpty() ? null : elementData(getMaxElementIndex()); - } - - /** - * Removes the element at position {@code index}. - * - *

Normally this method leaves the elements at up to {@code index - 1}, - * inclusive, untouched. Under these circumstances, it returns {@code null}. - * - *

Occasionally, in order to maintain the heap invariant, it must swap a - * later element of the list with one before {@code index}. Under these - * circumstances it returns a pair of elements as a {@link MoveDesc}. The - * first one is the element that was previously at the end of the heap and is - * now at some position before {@code index}. The second element is the one - * that was swapped down to replace the element at {@code index}. This fact is - * used by iterator.remove so as to visit elements during a traversal once and - * only once. - */ - @VisibleForTesting - MoveDesc removeAt(int index) { - checkPositionIndex(index, size); - modCount++; - size--; - if (size == index) { - queue[size] = null; - return null; - } - E actualLastElement = elementData(size); - int lastElementAt = heapForIndex(size).getCorrectLastElement(actualLastElement); - E toTrickle = elementData(size); - queue[size] = null; - MoveDesc changes = fillHole(index, toTrickle); - if (lastElementAt < index) { - // Last element is moved to before index, swapped with trickled element. - if (changes == null) { - // The trickled element is still after index. - return new MoveDesc(actualLastElement, toTrickle); - } else { - // The trickled element is back before index, but the replaced element - // has now been moved after index. - return new MoveDesc(actualLastElement, changes.replaced); - } - } - // Trickled element was after index to begin with, no adjustment needed. - return changes; - } - - private MoveDesc fillHole(int index, E toTrickle) { - Heap heap = heapForIndex(index); - // We consider elementData(index) a "hole", and we want to fill it - // with the last element of the heap, toTrickle. - // Since the last element of the heap is from the bottom level, we - // optimistically fill index position with elements from lower levels, - // moving the hole down. In most cases this reduces the number of - // comparisons with toTrickle, but in some cases we will need to bubble it - // all the way up again. - int vacated = heap.fillHoleAt(index); - // Try to see if toTrickle can be bubbled up min levels. - int bubbledTo = heap.bubbleUpAlternatingLevels(vacated, toTrickle); - if (bubbledTo == vacated) { - // Could not bubble toTrickle up min levels, try moving - // it from min level to max level (or max to min level) and bubble up - // there. - return heap.tryCrossOverAndBubbleUp(index, vacated, toTrickle); - } else { - return (bubbledTo < index) ? new MoveDesc(toTrickle, elementData(index)) : null; - } - } - - // Returned from removeAt() to iterator.remove() - static class MoveDesc { - final E toTrickle; - final E replaced; - - MoveDesc(E toTrickle, E replaced) { - this.toTrickle = toTrickle; - this.replaced = replaced; - } - } - - /** - * Removes and returns the value at {@code index}. - */ - private E removeAndGet(int index) { - E value = elementData(index); - removeAt(index); - return value; - } - - private Heap heapForIndex(int i) { - return isEvenLevel(i) ? minHeap : maxHeap; - } - - private static final int EVEN_POWERS_OF_TWO = 0x55555555; - private static final int ODD_POWERS_OF_TWO = 0xaaaaaaaa; - - @VisibleForTesting - static boolean isEvenLevel(int index) { - int oneBased = index + 1; - checkState(oneBased > 0, "negative index"); - return (oneBased & EVEN_POWERS_OF_TWO) > (oneBased & ODD_POWERS_OF_TWO); - } - - /** - * Returns {@code true} if the MinMax heap structure holds. This is only used - * in testing. - * - * TODO(kevinb): move to the test class? - */ - @VisibleForTesting - boolean isIntact() { - for (int i = 1; i < size; i++) { - if (!heapForIndex(i).verifyIndex(i)) { - return false; - } - } - return true; - } - - /** - * Each instance of MinMaxPriortyQueue encapsulates two instances of Heap: - * a min-heap and a max-heap. Conceptually, these might each have their own - * array for storage, but for efficiency's sake they are stored interleaved on - * alternate heap levels in the same array (MMPQ.queue). - */ - @WeakOuter - private class Heap { - final Ordering ordering; - @Weak Heap otherHeap; - - Heap(Ordering ordering) { - this.ordering = ordering; - } - - int compareElements(int a, int b) { - return ordering.compare(elementData(a), elementData(b)); - } - - /** - * Tries to move {@code toTrickle} from a min to a max level and - * bubble up there. If it moved before {@code removeIndex} this method - * returns a pair as described in {@link #removeAt}. - */ - MoveDesc tryCrossOverAndBubbleUp(int removeIndex, int vacated, E toTrickle) { - int crossOver = crossOver(vacated, toTrickle); - if (crossOver == vacated) { - return null; - } - // Successfully crossed over from min to max. - // Bubble up max levels. - E parent; - // If toTrickle is moved up to a parent of removeIndex, the parent is - // placed in removeIndex position. We must return that to the iterator so - // that it knows to skip it. - if (crossOver < removeIndex) { - // We crossed over to the parent level in crossOver, so the parent - // has already been moved. - parent = elementData(removeIndex); - } else { - parent = elementData(getParentIndex(removeIndex)); - } - // bubble it up the opposite heap - if (otherHeap.bubbleUpAlternatingLevels(crossOver, toTrickle) < removeIndex) { - return new MoveDesc(toTrickle, parent); - } else { - return null; - } - } - - /** - * Bubbles a value from {@code index} up the appropriate heap if required. - */ - void bubbleUp(int index, E x) { - int crossOver = crossOverUp(index, x); - - Heap heap; - if (crossOver == index) { - heap = this; - } else { - index = crossOver; - heap = otherHeap; - } - heap.bubbleUpAlternatingLevels(index, x); - } - - /** - * Bubbles a value from {@code index} up the levels of this heap, and - * returns the index the element ended up at. - */ - int bubbleUpAlternatingLevels(int index, E x) { - while (index > 2) { - int grandParentIndex = getGrandparentIndex(index); - E e = elementData(grandParentIndex); - if (ordering.compare(e, x) <= 0) { - break; - } - queue[index] = e; - index = grandParentIndex; - } - queue[index] = x; - return index; - } - - /** - * Returns the index of minimum value between {@code index} and - * {@code index + len}, or {@code -1} if {@code index} is greater than - * {@code size}. - */ - int findMin(int index, int len) { - if (index >= size) { - return -1; - } - checkState(index > 0); - int limit = Math.min(index, size - len) + len; - int minIndex = index; - for (int i = index + 1; i < limit; i++) { - if (compareElements(i, minIndex) < 0) { - minIndex = i; - } - } - return minIndex; - } - - /** - * Returns the minimum child or {@code -1} if no child exists. - */ - int findMinChild(int index) { - return findMin(getLeftChildIndex(index), 2); - } - - /** - * Returns the minimum grand child or -1 if no grand child exists. - */ - int findMinGrandChild(int index) { - int leftChildIndex = getLeftChildIndex(index); - if (leftChildIndex < 0) { - return -1; - } - return findMin(getLeftChildIndex(leftChildIndex), 4); - } - - /** - * Moves an element one level up from a min level to a max level - * (or vice versa). - * Returns the new position of the element. - */ - int crossOverUp(int index, E x) { - if (index == 0) { - queue[0] = x; - return 0; - } - int parentIndex = getParentIndex(index); - E parentElement = elementData(parentIndex); - if (parentIndex != 0) { - // This is a guard for the case of the childless uncle. - // Since the end of the array is actually the middle of the heap, - // a smaller childless uncle can become a child of x when we - // bubble up alternate levels, violating the invariant. - int grandparentIndex = getParentIndex(parentIndex); - int uncleIndex = getRightChildIndex(grandparentIndex); - if (uncleIndex != parentIndex && getLeftChildIndex(uncleIndex) >= size) { - E uncleElement = elementData(uncleIndex); - if (ordering.compare(uncleElement, parentElement) < 0) { - parentIndex = uncleIndex; - parentElement = uncleElement; - } - } - } - if (ordering.compare(parentElement, x) < 0) { - queue[index] = parentElement; - queue[parentIndex] = x; - return parentIndex; - } - queue[index] = x; - return index; - } - - /** - * Returns the conceptually correct last element of the heap. - * - *

Since the last element of the array is actually in the - * middle of the sorted structure, a childless uncle node could be - * smaller, which would corrupt the invariant if this element - * becomes the new parent of the uncle. In that case, we first - * switch the last element with its uncle, before returning. - */ - int getCorrectLastElement(E actualLastElement) { - int parentIndex = getParentIndex(size); - if (parentIndex != 0) { - int grandparentIndex = getParentIndex(parentIndex); - int uncleIndex = getRightChildIndex(grandparentIndex); - if (uncleIndex != parentIndex && getLeftChildIndex(uncleIndex) >= size) { - E uncleElement = elementData(uncleIndex); - if (ordering.compare(uncleElement, actualLastElement) < 0) { - queue[uncleIndex] = actualLastElement; - queue[size] = uncleElement; - return uncleIndex; - } - } - } - return size; - } - - /** - * Crosses an element over to the opposite heap by moving it one level down - * (or up if there are no elements below it). - * - * Returns the new position of the element. - */ - int crossOver(int index, E x) { - int minChildIndex = findMinChild(index); - // TODO(kevinb): split the && into two if's and move crossOverUp so it's - // only called when there's no child. - if ((minChildIndex > 0) && (ordering.compare(elementData(minChildIndex), x) < 0)) { - queue[index] = elementData(minChildIndex); - queue[minChildIndex] = x; - return minChildIndex; - } - return crossOverUp(index, x); - } - - /** - * Fills the hole at {@code index} by moving in the least of its - * grandchildren to this position, then recursively filling the new hole - * created. - * - * @return the position of the new hole (where the lowest grandchild moved - * from, that had no grandchild to replace it) - */ - int fillHoleAt(int index) { - int minGrandchildIndex; - while ((minGrandchildIndex = findMinGrandChild(index)) > 0) { - queue[index] = elementData(minGrandchildIndex); - index = minGrandchildIndex; - } - return index; - } - - private boolean verifyIndex(int i) { - if ((getLeftChildIndex(i) < size) && (compareElements(i, getLeftChildIndex(i)) > 0)) { - return false; - } - if ((getRightChildIndex(i) < size) && (compareElements(i, getRightChildIndex(i)) > 0)) { - return false; - } - if ((i > 0) && (compareElements(i, getParentIndex(i)) > 0)) { - return false; - } - if ((i > 2) && (compareElements(getGrandparentIndex(i), i) > 0)) { - return false; - } - return true; - } - - // These would be static if inner classes could have static members. - - private int getLeftChildIndex(int i) { - return i * 2 + 1; - } - - private int getRightChildIndex(int i) { - return i * 2 + 2; - } - - private int getParentIndex(int i) { - return (i - 1) / 2; - } - - private int getGrandparentIndex(int i) { - return getParentIndex(getParentIndex(i)); // (i - 3) / 4 - } - } - - /** - * Iterates the elements of the queue in no particular order. - * - * If the underlying queue is modified during iteration an exception will be - * thrown. - */ - private class QueueIterator implements Iterator { - private int cursor = -1; - private int expectedModCount = modCount; - private Queue forgetMeNot; - private List skipMe; - private E lastFromForgetMeNot; - private boolean canRemove; - - @Override - public boolean hasNext() { - checkModCount(); - return (nextNotInSkipMe(cursor + 1) < size()) - || ((forgetMeNot != null) && !forgetMeNot.isEmpty()); - } - - @Override - public E next() { - checkModCount(); - int tempCursor = nextNotInSkipMe(cursor + 1); - if (tempCursor < size()) { - cursor = tempCursor; - canRemove = true; - return elementData(cursor); - } else if (forgetMeNot != null) { - cursor = size(); - lastFromForgetMeNot = forgetMeNot.poll(); - if (lastFromForgetMeNot != null) { - canRemove = true; - return lastFromForgetMeNot; - } - } - throw new NoSuchElementException("iterator moved past last element in queue."); - } - - @Override - public void remove() { - checkRemove(canRemove); - checkModCount(); - canRemove = false; - expectedModCount++; - if (cursor < size()) { - MoveDesc moved = removeAt(cursor); - if (moved != null) { - if (forgetMeNot == null) { - forgetMeNot = new ArrayDeque(); - skipMe = new ArrayList(3); - } - forgetMeNot.add(moved.toTrickle); - skipMe.add(moved.replaced); - } - cursor--; - } else { // we must have set lastFromForgetMeNot in next() - checkState(removeExact(lastFromForgetMeNot)); - lastFromForgetMeNot = null; - } - } - - // Finds only this exact instance, not others that are equals() - private boolean containsExact(Iterable elements, E target) { - for (E element : elements) { - if (element == target) { - return true; - } - } - return false; - } - - // Removes only this exact instance, not others that are equals() - boolean removeExact(Object target) { - for (int i = 0; i < size; i++) { - if (queue[i] == target) { - removeAt(i); - return true; - } - } - return false; - } - - void checkModCount() { - if (modCount != expectedModCount) { - throw new ConcurrentModificationException(); - } - } - - /** - * Returns the index of the first element after {@code c} that is not in - * {@code skipMe} and returns {@code size()} if there is no such element. - */ - private int nextNotInSkipMe(int c) { - if (skipMe != null) { - while (c < size() && containsExact(skipMe, elementData(c))) { - c++; - } - } - return c; - } - } - - /** - * Returns an iterator over the elements contained in this collection, - * in no particular order. - * - *

The iterator is fail-fast: If the MinMaxPriorityQueue is modified - * at any time after the iterator is created, in any way except through the - * iterator's own remove method, the iterator will generally throw a - * {@link ConcurrentModificationException}. Thus, in the face of concurrent - * modification, the iterator fails quickly and cleanly, rather than risking - * arbitrary, non-deterministic behavior at an undetermined time in the - * future. - * - *

Note that the fail-fast behavior of an iterator cannot be guaranteed - * as it is, generally speaking, impossible to make any hard guarantees in the - * presence of unsynchronized concurrent modification. Fail-fast iterators - * throw {@code ConcurrentModificationException} on a best-effort basis. - * Therefore, it would be wrong to write a program that depended on this - * exception for its correctness: the fail-fast behavior of iterators - * should be used only to detect bugs. - * - * @return an iterator over the elements contained in this collection - */ - @Override - public Iterator iterator() { - return new QueueIterator(); - } - - @Override - public void clear() { - for (int i = 0; i < size; i++) { - queue[i] = null; - } - size = 0; - } - - @Override - public Object[] toArray() { - Object[] copyTo = new Object[size]; - System.arraycopy(queue, 0, copyTo, 0, size); - return copyTo; - } - - /** - * Returns the comparator used to order the elements in this queue. Obeys the - * general contract of {@link PriorityQueue#comparator}, but returns {@link - * Ordering#natural} instead of {@code null} to indicate natural ordering. - */ - public Comparator comparator() { - return minHeap.ordering; - } - - @VisibleForTesting - int capacity() { - return queue.length; - } - - // Size/capacity-related methods - - private static final int DEFAULT_CAPACITY = 11; - - @VisibleForTesting - static int initialQueueSize( - int configuredExpectedSize, int maximumSize, Iterable initialContents) { - // Start with what they said, if they said it, otherwise DEFAULT_CAPACITY - int result = - (configuredExpectedSize == Builder.UNSET_EXPECTED_SIZE) - ? DEFAULT_CAPACITY - : configuredExpectedSize; - - // Enlarge to contain initial contents - if (initialContents instanceof Collection) { - int initialSize = ((Collection) initialContents).size(); - result = Math.max(result, initialSize); - } - - // Now cap it at maxSize + 1 - return capAtMaximumSize(result, maximumSize); - } - - private void growIfNeeded() { - if (size > queue.length) { - int newCapacity = calculateNewCapacity(); - Object[] newQueue = new Object[newCapacity]; - System.arraycopy(queue, 0, newQueue, 0, queue.length); - queue = newQueue; - } - } - - /** Returns ~2x the old capacity if small; ~1.5x otherwise. */ - private int calculateNewCapacity() { - int oldCapacity = queue.length; - int newCapacity = - (oldCapacity < 64) - ? (oldCapacity + 1) * 2 - : IntMath.checkedMultiply(oldCapacity / 2, 3); - return capAtMaximumSize(newCapacity, maximumSize); - } - - /** There's no reason for the queueSize to ever be more than maxSize + 1 */ - private static int capAtMaximumSize(int queueSize, int maximumSize) { - return Math.min(queueSize - 1, maximumSize) + 1; // don't overflow - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Multimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Multimap.java deleted file mode 100644 index 9924dd1e78f8..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Multimap.java +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * A collection that maps keys to values, similar to {@link Map}, but in which - * each key may be associated with multiple values. You can visualize the - * contents of a multimap either as a map from keys to nonempty - * collections of values: - * - *

    - *
  • a → 1, 2 - *
  • b → 3 - *
- * - * ... or as a single "flattened" collection of key-value pairs: - * - *
    - *
  • a → 1 - *
  • a → 2 - *
  • b → 3 - *
- * - *

Important: although the first interpretation resembles how most - * multimaps are implemented, the design of the {@code Multimap} API is - * based on the second form. So, using the multimap shown above as an - * example, the {@link #size} is {@code 3}, not {@code 2}, and the {@link - * #values} collection is {@code [1, 2, 3]}, not {@code [[1, 2], [3]]}. For - * those times when the first style is more useful, use the multimap's {@link - * #asMap} view (or create a {@code Map>} in the first place). - * - *

Example

- * - *

The following code:

   {@code
- *
- *   ListMultimap multimap = ArrayListMultimap.create();
- *   for (President pres : US_PRESIDENTS_IN_ORDER) {
- *     multimap.put(pres.firstName(), pres.lastName());
- *   }
- *   for (String firstName : multimap.keySet()) {
- *     List lastNames = multimap.get(firstName);
- *     out.println(firstName + ": " + lastNames);
- *   }}
- * - * ... produces output such as:
   {@code
- *
- *   Zachary: [Taylor]
- *   John: [Adams, Adams, Tyler, Kennedy]  // Remember, Quincy!
- *   George: [Washington, Bush, Bush]
- *   Grover: [Cleveland, Cleveland]        // Two, non-consecutive terms, rep'ing NJ!
- *   ...}
- * - *

Views

- * - *

Much of the power of the multimap API comes from the view - * collections it provides. These always reflect the latest state of the - * multimap itself. When they support modification, the changes are - * write-through (they automatically update the backing multimap). These - * view collections are: - * - *

    - *
  • {@link #asMap}, mentioned above
  • - *
  • {@link #keys}, {@link #keySet}, {@link #values}, {@link #entries}, which - * are similar to the corresponding view collections of {@link Map} - *
  • and, notably, even the collection returned by {@link #get get(key)} is an - * active view of the values corresponding to {@code key} - *
- * - *

The collections returned by the {@link #replaceValues replaceValues} and - * {@link #removeAll removeAll} methods, which contain values that have just - * been removed from the multimap, are naturally not views. - * - *

Subinterfaces

- * - *

Instead of using the {@code Multimap} interface directly, prefer the - * subinterfaces {@link ListMultimap} and {@link SetMultimap}. These take their - * names from the fact that the collections they return from {@code get} behave - * like (and, of course, implement) {@link List} and {@link Set}, respectively. - * - *

For example, the "presidents" code snippet above used a {@code - * ListMultimap}; if it had used a {@code SetMultimap} instead, two presidents - * would have vanished, and last names might or might not appear in - * chronological order. - * - *

Warning: instances of type {@code Multimap} may not implement - * {@link Object#equals} in the way you expect. Multimaps containing the same - * key-value pairs, even in the same order, may or may not be equal and may or - * may not have the same {@code hashCode}. The recommended subinterfaces - * provide much stronger guarantees. - * - *

Comparison to a map of collections

- * - *

Multimaps are commonly used in places where a {@code Map>} would otherwise have appeared. The differences include: - * - *

    - *
  • There is no need to populate an empty collection before adding an entry - * with {@link #put put}. - *
  • {@code get} never returns {@code null}, only an empty collection. - *
  • A key is contained in the multimap if and only if it maps to at least - * one value. Any operation that causes a key to have zero associated - * values has the effect of removing that key from the multimap. - *
  • The total entry count is available as {@link #size}. - *
  • Many complex operations become easier; for example, {@code - * Collections.min(multimap.values())} finds the smallest value across all - * keys. - *
- * - *

Implementations

- * - *

As always, prefer the immutable implementations, {@link - * ImmutableListMultimap} and {@link ImmutableSetMultimap}. General-purpose - * mutable implementations are listed above under "All Known Implementing - * Classes". You can also create a custom multimap, backed by any {@code - * Map} and {@link Collection} types, using the {@link Multimaps#newMultimap - * Multimaps.newMultimap} family of methods. Finally, another popular way to - * obtain a multimap is using {@link Multimaps#index Multimaps.index}. See - * the {@link Multimaps} class for these and other static utilities related - * to multimaps. - * - *

Other Notes

- * - *

As with {@code Map}, the behavior of a {@code Multimap} is not specified - * if key objects already present in the multimap change in a manner that - * affects {@code equals} comparisons. Use caution if mutable objects are used - * as keys in a {@code Multimap}. - * - *

All methods that modify the multimap are optional. The view collections - * returned by the multimap may or may not be modifiable. Any modification - * method that is not supported will throw {@link - * UnsupportedOperationException}. - * - *

See the Guava User Guide article on - * {@code Multimap}. - * - * @author Jared Levy - * @since 2.0 - */ -@GwtCompatible -public interface Multimap { - // Query Operations - - /** - * Returns the number of key-value pairs in this multimap. - * - *

Note: this method does not return the number of distinct - * keys in the multimap, which is given by {@code keySet().size()} or - * {@code asMap().size()}. See the opening section of the {@link Multimap} - * class documentation for clarification. - */ - int size(); - - /** - * Returns {@code true} if this multimap contains no key-value pairs. - * Equivalent to {@code size() == 0}, but can in some cases be more efficient. - */ - boolean isEmpty(); - - /** - * Returns {@code true} if this multimap contains at least one key-value pair - * with the key {@code key}. - */ - boolean containsKey(@Nullable Object key); - - /** - * Returns {@code true} if this multimap contains at least one key-value pair - * with the value {@code value}. - */ - boolean containsValue(@Nullable Object value); - - /** - * Returns {@code true} if this multimap contains at least one key-value pair - * with the key {@code key} and the value {@code value}. - */ - boolean containsEntry(@Nullable Object key, @Nullable Object value); - - // Modification Operations - - /** - * Stores a key-value pair in this multimap. - * - *

Some multimap implementations allow duplicate key-value pairs, in which - * case {@code put} always adds a new key-value pair and increases the - * multimap size by 1. Other implementations prohibit duplicates, and storing - * a key-value pair that's already in the multimap has no effect. - * - * @return {@code true} if the method increased the size of the multimap, or - * {@code false} if the multimap already contained the key-value pair and - * doesn't allow duplicates - */ - boolean put(@Nullable K key, @Nullable V value); - - /** - * Removes a single key-value pair with the key {@code key} and the value - * {@code value} from this multimap, if such exists. If multiple key-value - * pairs in the multimap fit this description, which one is removed is - * unspecified. - * - * @return {@code true} if the multimap changed - */ - boolean remove(@Nullable Object key, @Nullable Object value); - - // Bulk Operations - - /** - * Stores a key-value pair in this multimap for each of {@code values}, all - * using the same key, {@code key}. Equivalent to (but expected to be more - * efficient than):

   {@code
-   *
-   *   for (V value : values) {
-   *     put(key, value);
-   *   }}
- * - *

In particular, this is a no-op if {@code values} is empty. - * - * @return {@code true} if the multimap changed - */ - boolean putAll(@Nullable K key, Iterable values); - - /** - * Stores all key-value pairs of {@code multimap} in this multimap, in the - * order returned by {@code multimap.entries()}. - * - * @return {@code true} if the multimap changed - */ - boolean putAll(Multimap multimap); - - /** - * Stores a collection of values with the same key, replacing any existing - * values for that key. - * - *

If {@code values} is empty, this is equivalent to - * {@link #removeAll(Object) removeAll(key)}. - * - * @return the collection of replaced values, or an empty collection if no - * values were previously associated with the key. The collection - * may be modifiable, but updating it will have no effect on the - * multimap. - */ - Collection replaceValues(@Nullable K key, Iterable values); - - /** - * Removes all values associated with the key {@code key}. - * - *

Once this method returns, {@code key} will not be mapped to any values, - * so it will not appear in {@link #keySet()}, {@link #asMap()}, or any other - * views. - * - * @return the values that were removed (possibly empty). The returned - * collection may be modifiable, but updating it will have no - * effect on the multimap. - */ - Collection removeAll(@Nullable Object key); - - /** - * Removes all key-value pairs from the multimap, leaving it {@linkplain - * #isEmpty empty}. - */ - void clear(); - - // Views - - /** - * Returns a view collection of the values associated with {@code key} in this - * multimap, if any. Note that when {@code containsKey(key)} is false, this - * returns an empty collection, not {@code null}. - * - *

Changes to the returned collection will update the underlying multimap, - * and vice versa. - */ - Collection get(@Nullable K key); - - /** - * Returns a view collection of all distinct keys contained in this - * multimap. Note that the key set contains a key if and only if this multimap - * maps that key to at least one value. - * - *

Changes to the returned set will update the underlying multimap, and - * vice versa. However, adding to the returned set is not possible. - */ - Set keySet(); - - /** - * Returns a view collection containing the key from each key-value pair in - * this multimap, without collapsing duplicates. This collection has - * the same size as this multimap, and {@code keys().count(k) == - * get(k).size()} for all {@code k}. - * - *

Changes to the returned multiset will update the underlying multimap, - * and vice versa. However, adding to the returned collection is not - * possible. - */ - Multiset keys(); - - /** - * Returns a view collection containing the value from each key-value - * pair contained in this multimap, without collapsing duplicates (so {@code - * values().size() == size()}). - * - *

Changes to the returned collection will update the underlying multimap, - * and vice versa. However, adding to the returned collection is not - * possible. - */ - Collection values(); - - /** - * Returns a view collection of all key-value pairs contained in this - * multimap, as {@link Map.Entry} instances. - * - *

Changes to the returned collection or the entries it contains will - * update the underlying multimap, and vice versa. However, adding to - * the returned collection is not possible. - */ - Collection> entries(); - - /** - * Returns a view of this multimap as a {@code Map} from each distinct key - * to the nonempty collection of that key's associated values. Note that - * {@code this.asMap().get(k)} is equivalent to {@code this.get(k)} only when - * {@code k} is a key contained in the multimap; otherwise it returns {@code - * null} as opposed to an empty collection. - * - *

Changes to the returned map or the collections that serve as its values - * will update the underlying multimap, and vice versa. The map does not - * support {@code put} or {@code putAll}, nor do its entries support {@link - * Map.Entry#setValue setValue}. - */ - Map> asMap(); - - // Comparison and hashing - - /** - * Compares the specified object with this multimap for equality. Two - * multimaps are equal when their map views, as returned by {@link #asMap}, - * are also equal. - * - *

In general, two multimaps with identical key-value mappings may or may - * not be equal, depending on the implementation. For example, two - * {@link SetMultimap} instances with the same key-value mappings are equal, - * but equality of two {@link ListMultimap} instances depends on the ordering - * of the values for each key. - * - *

A non-empty {@link SetMultimap} cannot be equal to a non-empty - * {@link ListMultimap}, since their {@link #asMap} views contain unequal - * collections as values. However, any two empty multimaps are equal, because - * they both have empty {@link #asMap} views. - */ - @Override - boolean equals(@Nullable Object obj); - - /** - * Returns the hash code for this multimap. - * - *

The hash code of a multimap is defined as the hash code of the map view, - * as returned by {@link Multimap#asMap}. - * - *

In general, two multimaps with identical key-value mappings may or may - * not have the same hash codes, depending on the implementation. For - * example, two {@link SetMultimap} instances with the same key-value - * mappings will have the same {@code hashCode}, but the {@code hashCode} - * of {@link ListMultimap} instances depends on the ordering of the values - * for each key. - */ - @Override - int hashCode(); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/MultimapBuilder.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/MultimapBuilder.java deleted file mode 100644 index 97738efb7590..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/MultimapBuilder.java +++ /dev/null @@ -1,485 +0,0 @@ -/* - * Copyright (C) 2013 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.CollectPreconditions.checkNonnegative; -import static com.google.common.collect.Maps.newLinkedHashMapWithExpectedSize; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Supplier; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Comparator; -import java.util.EnumMap; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeMap; -import java.util.TreeSet; - -import javax.annotation.CheckReturnValue; - -/** - * A builder for a multimap implementation that allows customization of the backing map and value - * collection implementations used in a particular multimap. - * - *

This can be used to easily configure multimap data structure implementations not provided - * explicitly in {@code com.google.common.collect}, for example: - * - *

   {@code
- *   ListMultimap treeListMultimap =
- *       MultimapBuilder.treeKeys().arrayListValues().build();
- *   SetMultimap hashEnumMultimap =
- *       MultimapBuilder.hashKeys().enumSetValues(MyEnum.class).build();}
- * - *

{@code MultimapBuilder} instances are immutable. Invoking a configuration method has no - * effect on the receiving instance; you must store and use the new builder instance it returns - * instead. - * - *

The generated multimaps are serializable if the key and value types are serializable, - * unless stated otherwise in one of the configuration methods. - * - * @author Louis Wasserman - * @param An upper bound on the key type of the generated multimap. - * @param An upper bound on the value type of the generated multimap. - * @since 16.0 - */ -@Beta -@GwtCompatible -@CheckReturnValue -public abstract class MultimapBuilder { - /* - * Leaving K and V as upper bounds rather than the actual key and value types allows type - * parameters to be left implicit more often. CacheBuilder uses the same technique. - */ - - private MultimapBuilder() {} - - private static final int DEFAULT_EXPECTED_KEYS = 8; - - /** - * Uses a {@link HashMap} to map keys to value collections. - */ - public static MultimapBuilderWithKeys hashKeys() { - return hashKeys(DEFAULT_EXPECTED_KEYS); - } - - /** - * Uses a {@link HashMap} to map keys to value collections, initialized to expect the specified - * number of keys. - * - * @throws IllegalArgumentException if {@code expectedKeys < 0} - */ - public static MultimapBuilderWithKeys hashKeys(final int expectedKeys) { - checkNonnegative(expectedKeys, "expectedKeys"); - return new MultimapBuilderWithKeys() { - @Override - Map> createMap() { - return Maps.newHashMapWithExpectedSize(expectedKeys); - } - }; - } - - /** - * Uses a {@link LinkedHashMap} to map keys to value collections. - * - *

The collections returned by {@link Multimap#keySet()}, {@link Multimap#keys()}, and - * {@link Multimap#asMap()} will iterate through the keys in the order that they were first added - * to the multimap, save that if all values associated with a key are removed and then the key is - * added back into the multimap, that key will come last in the key iteration order. - */ - public static MultimapBuilderWithKeys linkedHashKeys() { - return linkedHashKeys(DEFAULT_EXPECTED_KEYS); - } - - /** - * Uses a {@link LinkedHashMap} to map keys to value collections, initialized to expect the - * specified number of keys. - * - *

The collections returned by {@link Multimap#keySet()}, {@link Multimap#keys()}, and - * {@link Multimap#asMap()} will iterate through the keys in the order that they were first added - * to the multimap, save that if all values associated with a key are removed and then the key is - * added back into the multimap, that key will come last in the key iteration order. - */ - public static MultimapBuilderWithKeys linkedHashKeys(final int expectedKeys) { - checkNonnegative(expectedKeys, "expectedKeys"); - return new MultimapBuilderWithKeys() { - @Override - Map> createMap() { - return newLinkedHashMapWithExpectedSize(expectedKeys); - } - }; - } - - /** - * Uses a naturally-ordered {@link TreeMap} to map keys to value collections. - * - *

The collections returned by {@link Multimap#keySet()}, {@link Multimap#keys()}, and - * {@link Multimap#asMap()} will iterate through the keys in sorted order. - * - *

For all multimaps generated by the resulting builder, the {@link Multimap#keySet()} can be - * safely cast to a {@link java.util.SortedSet}, and the {@link Multimap#asMap()} can safely be - * cast to a {@link java.util.SortedMap}. - */ - @SuppressWarnings("rawtypes") - public static MultimapBuilderWithKeys treeKeys() { - return treeKeys(Ordering.natural()); - } - - /** - * Uses a {@link TreeMap} sorted by the specified comparator to map keys to value collections. - * - *

The collections returned by {@link Multimap#keySet()}, {@link Multimap#keys()}, and - * {@link Multimap#asMap()} will iterate through the keys in sorted order. - * - *

For all multimaps generated by the resulting builder, the {@link Multimap#keySet()} can be - * safely cast to a {@link java.util.SortedSet}, and the {@link Multimap#asMap()} can safely be - * cast to a {@link java.util.SortedMap}. - * - *

Multimaps generated by the resulting builder will not be serializable if {@code comparator} - * is not serializable. - */ - public static MultimapBuilderWithKeys treeKeys(final Comparator comparator) { - checkNotNull(comparator); - return new MultimapBuilderWithKeys() { - @Override - Map> createMap() { - return new TreeMap>(comparator); - } - }; - } - - /** - * Uses an {@link EnumMap} to map keys to value collections. - */ - public static > MultimapBuilderWithKeys enumKeys( - final Class keyClass) { - checkNotNull(keyClass); - return new MultimapBuilderWithKeys() { - @SuppressWarnings("unchecked") - @Override - Map> createMap() { - // K must actually be K0, since enums are effectively final - // (their subclasses are inaccessible) - return (Map>) new EnumMap>(keyClass); - } - }; - } - - private static final class ArrayListSupplier implements Supplier>, Serializable { - private final int expectedValuesPerKey; - - ArrayListSupplier(int expectedValuesPerKey) { - this.expectedValuesPerKey = checkNonnegative(expectedValuesPerKey, "expectedValuesPerKey"); - } - - @Override - public List get() { - return new ArrayList(expectedValuesPerKey); - } - } - - private enum LinkedListSupplier implements Supplier> { - INSTANCE; - - public static Supplier> instance() { - // Each call generates a fresh LinkedList, which can serve as a List for any V. - @SuppressWarnings({"rawtypes", "unchecked"}) - Supplier> result = (Supplier) INSTANCE; - return result; - } - - @Override - public List get() { - return new LinkedList(); - } - } - - private static final class HashSetSupplier implements Supplier>, Serializable { - private final int expectedValuesPerKey; - - HashSetSupplier(int expectedValuesPerKey) { - this.expectedValuesPerKey = checkNonnegative(expectedValuesPerKey, "expectedValuesPerKey"); - } - - @Override - public Set get() { - return Sets.newHashSetWithExpectedSize(expectedValuesPerKey); - } - } - - private static final class LinkedHashSetSupplier implements Supplier>, Serializable { - private final int expectedValuesPerKey; - - LinkedHashSetSupplier(int expectedValuesPerKey) { - this.expectedValuesPerKey = checkNonnegative(expectedValuesPerKey, "expectedValuesPerKey"); - } - - @Override - public Set get() { - return Sets.newLinkedHashSetWithExpectedSize(expectedValuesPerKey); - } - } - - private static final class TreeSetSupplier implements Supplier>, Serializable { - private final Comparator comparator; - - TreeSetSupplier(Comparator comparator) { - this.comparator = checkNotNull(comparator); - } - - @Override - public SortedSet get() { - return new TreeSet(comparator); - } - } - - private static final class EnumSetSupplier> - implements Supplier>, Serializable { - private final Class clazz; - - EnumSetSupplier(Class clazz) { - this.clazz = checkNotNull(clazz); - } - - @Override - public Set get() { - return EnumSet.noneOf(clazz); - } - } - - /** - * An intermediate stage in a {@link MultimapBuilder} in which the key-value collection map - * implementation has been specified, but the value collection implementation has not. - * - * @param The upper bound on the key type of the generated multimap. - */ - public abstract static class MultimapBuilderWithKeys { - - private static final int DEFAULT_EXPECTED_VALUES_PER_KEY = 2; - - MultimapBuilderWithKeys() {} - - abstract Map> createMap(); - - /** - * Uses an {@link ArrayList} to store value collections. - */ - public ListMultimapBuilder arrayListValues() { - return arrayListValues(DEFAULT_EXPECTED_VALUES_PER_KEY); - } - - /** - * Uses an {@link ArrayList} to store value collections, initialized to expect the specified - * number of values per key. - * - * @throws IllegalArgumentException if {@code expectedValuesPerKey < 0} - */ - public ListMultimapBuilder arrayListValues(final int expectedValuesPerKey) { - checkNonnegative(expectedValuesPerKey, "expectedValuesPerKey"); - return new ListMultimapBuilder() { - @Override - public ListMultimap build() { - return Multimaps.newListMultimap( - MultimapBuilderWithKeys.this.createMap(), - new ArrayListSupplier(expectedValuesPerKey)); - } - }; - } - - /** - * Uses a {@link LinkedList} to store value collections. - */ - public ListMultimapBuilder linkedListValues() { - return new ListMultimapBuilder() { - @Override - public ListMultimap build() { - return Multimaps.newListMultimap( - MultimapBuilderWithKeys.this.createMap(), LinkedListSupplier.instance()); - } - }; - } - - /** - * Uses a {@link HashSet} to store value collections. - */ - public SetMultimapBuilder hashSetValues() { - return hashSetValues(DEFAULT_EXPECTED_VALUES_PER_KEY); - } - - /** - * Uses a {@link HashSet} to store value collections, initialized to expect the specified number - * of values per key. - * - * @throws IllegalArgumentException if {@code expectedValuesPerKey < 0} - */ - public SetMultimapBuilder hashSetValues(final int expectedValuesPerKey) { - checkNonnegative(expectedValuesPerKey, "expectedValuesPerKey"); - return new SetMultimapBuilder() { - @Override - public SetMultimap build() { - return Multimaps.newSetMultimap( - MultimapBuilderWithKeys.this.createMap(), - new HashSetSupplier(expectedValuesPerKey)); - } - }; - } - - /** - * Uses a {@link LinkedHashSet} to store value collections. - */ - public SetMultimapBuilder linkedHashSetValues() { - return linkedHashSetValues(DEFAULT_EXPECTED_VALUES_PER_KEY); - } - - /** - * Uses a {@link LinkedHashSet} to store value collections, initialized to expect the specified - * number of values per key. - * - * @throws IllegalArgumentException if {@code expectedValuesPerKey < 0} - */ - public SetMultimapBuilder linkedHashSetValues(final int expectedValuesPerKey) { - checkNonnegative(expectedValuesPerKey, "expectedValuesPerKey"); - return new SetMultimapBuilder() { - @Override - public SetMultimap build() { - return Multimaps.newSetMultimap( - MultimapBuilderWithKeys.this.createMap(), - new LinkedHashSetSupplier(expectedValuesPerKey)); - } - }; - } - - /** - * Uses a naturally-ordered {@link TreeSet} to store value collections. - */ - @SuppressWarnings("rawtypes") - public SortedSetMultimapBuilder treeSetValues() { - return treeSetValues(Ordering.natural()); - } - - /** - * Uses a {@link TreeSet} ordered by the specified comparator to store value collections. - * - *

Multimaps generated by the resulting builder will not be serializable if - * {@code comparator} is not serializable. - */ - public SortedSetMultimapBuilder treeSetValues(final Comparator comparator) { - checkNotNull(comparator, "comparator"); - return new SortedSetMultimapBuilder() { - @Override - public SortedSetMultimap build() { - return Multimaps.newSortedSetMultimap( - MultimapBuilderWithKeys.this.createMap(), new TreeSetSupplier(comparator)); - } - }; - } - - /** - * Uses an {@link EnumSet} to store value collections. - */ - public > SetMultimapBuilder enumSetValues( - final Class valueClass) { - checkNotNull(valueClass, "valueClass"); - return new SetMultimapBuilder() { - @Override - public SetMultimap build() { - // V must actually be V0, since enums are effectively final - // (their subclasses are inaccessible) - @SuppressWarnings({"unchecked", "rawtypes"}) - Supplier> factory = (Supplier) new EnumSetSupplier(valueClass); - return Multimaps.newSetMultimap(MultimapBuilderWithKeys.this.createMap(), factory); - } - }; - } - } - - /** - * Returns a new, empty {@code Multimap} with the specified implementation. - */ - public abstract Multimap build(); - - /** - * Returns a {@code Multimap} with the specified implementation, initialized with the entries of - * {@code multimap}. - */ - public Multimap build( - Multimap multimap) { - Multimap result = build(); - result.putAll(multimap); - return result; - } - - /** - * A specialization of {@link MultimapBuilder} that generates {@link ListMultimap} instances. - */ - public abstract static class ListMultimapBuilder extends MultimapBuilder { - ListMultimapBuilder() {} - - @Override - public abstract ListMultimap build(); - - @Override - public ListMultimap build( - Multimap multimap) { - return (ListMultimap) super.build(multimap); - } - } - - /** - * A specialization of {@link MultimapBuilder} that generates {@link SetMultimap} instances. - */ - public abstract static class SetMultimapBuilder extends MultimapBuilder { - SetMultimapBuilder() {} - - @Override - public abstract SetMultimap build(); - - @Override - public SetMultimap build( - Multimap multimap) { - return (SetMultimap) super.build(multimap); - } - } - - /** - * A specialization of {@link MultimapBuilder} that generates {@link SortedSetMultimap} instances. - */ - public abstract static class SortedSetMultimapBuilder extends SetMultimapBuilder { - SortedSetMultimapBuilder() {} - - @Override - public abstract SortedSetMultimap build(); - - @Override - public SortedSetMultimap build( - Multimap multimap) { - return (SortedSetMultimap) super.build(multimap); - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Multimaps.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Multimaps.java deleted file mode 100644 index 62cd1f391383..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Multimaps.java +++ /dev/null @@ -1,2134 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.CollectPreconditions.checkNonnegative; -import static com.google.common.collect.CollectPreconditions.checkRemove; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.base.Function; -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import com.google.common.base.Supplier; -import com.google.common.collect.Maps.EntryTransformer; -import com.google.j2objc.annotations.Weak; -import com.google.j2objc.annotations.WeakOuter; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.util.AbstractCollection; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.NoSuchElementException; -import java.util.Set; -import java.util.SortedSet; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * Provides static methods acting on or generating a {@code Multimap}. - * - *

See the Guava User Guide article on - * {@code Multimaps}. - * - * @author Jared Levy - * @author Robert Konigsberg - * @author Mike Bostock - * @author Louis Wasserman - * @since 2.0 - */ -@GwtCompatible(emulated = true) -public final class Multimaps { - private Multimaps() {} - - /** - * Creates a new {@code Multimap} backed by {@code map}, whose internal value - * collections are generated by {@code factory}. - * - * Warning: do not use this method when the collections returned by - * {@code factory} implement either {@link List} or {@code Set}! Use the more - * specific method {@link #newListMultimap}, {@link #newSetMultimap} or {@link - * #newSortedSetMultimap} instead, to avoid very surprising behavior from - * {@link Multimap#equals}. - * - *

The {@code factory}-generated and {@code map} classes determine the - * multimap iteration order. They also specify the behavior of the - * {@code equals}, {@code hashCode}, and {@code toString} methods for the - * multimap and its returned views. However, the multimap's {@code get} - * method returns instances of a different class than {@code factory.get()} - * does. - * - *

The multimap is serializable if {@code map}, {@code factory}, the - * collections generated by {@code factory}, and the multimap contents are all - * serializable. - * - *

The multimap is not threadsafe when any concurrent operations update the - * multimap, even if {@code map} and the instances generated by - * {@code factory} are. Concurrent read operations will work correctly. To - * allow concurrent update operations, wrap the multimap with a call to - * {@link #synchronizedMultimap}. - * - *

Call this method only when the simpler methods - * {@link ArrayListMultimap#create()}, {@link HashMultimap#create()}, - * {@link LinkedHashMultimap#create()}, {@link LinkedListMultimap#create()}, - * {@link TreeMultimap#create()}, and - * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice. - * - *

Note: the multimap assumes complete ownership over of {@code map} and - * the collections returned by {@code factory}. Those objects should not be - * manually updated and they should not use soft, weak, or phantom references. - * - * @param map place to store the mapping from each key to its corresponding - * values - * @param factory supplier of new, empty collections that will each hold all - * values for a given key - * @throws IllegalArgumentException if {@code map} is not empty - */ - public static Multimap newMultimap( - Map> map, final Supplier> factory) { - return new CustomMultimap(map, factory); - } - - private static class CustomMultimap extends AbstractMapBasedMultimap { - transient Supplier> factory; - - CustomMultimap(Map> map, Supplier> factory) { - super(map); - this.factory = checkNotNull(factory); - } - - @Override - protected Collection createCollection() { - return factory.get(); - } - - // can't use Serialization writeMultimap and populateMultimap methods since - // there's no way to generate the empty backing map. - - /** @serialData the factory and the backing map */ - @GwtIncompatible("java.io.ObjectOutputStream") - private void writeObject(ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); - stream.writeObject(factory); - stream.writeObject(backingMap()); - } - - @GwtIncompatible("java.io.ObjectInputStream") - @SuppressWarnings("unchecked") // reading data stored by writeObject - private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - factory = (Supplier>) stream.readObject(); - Map> map = (Map>) stream.readObject(); - setMap(map); - } - - @GwtIncompatible("java serialization not supported") - private static final long serialVersionUID = 0; - } - - /** - * Creates a new {@code ListMultimap} that uses the provided map and factory. - * It can generate a multimap based on arbitrary {@link Map} and {@link List} - * classes. - * - *

The {@code factory}-generated and {@code map} classes determine the - * multimap iteration order. They also specify the behavior of the - * {@code equals}, {@code hashCode}, and {@code toString} methods for the - * multimap and its returned views. The multimap's {@code get}, {@code - * removeAll}, and {@code replaceValues} methods return {@code RandomAccess} - * lists if the factory does. However, the multimap's {@code get} method - * returns instances of a different class than does {@code factory.get()}. - * - *

The multimap is serializable if {@code map}, {@code factory}, the - * lists generated by {@code factory}, and the multimap contents are all - * serializable. - * - *

The multimap is not threadsafe when any concurrent operations update the - * multimap, even if {@code map} and the instances generated by - * {@code factory} are. Concurrent read operations will work correctly. To - * allow concurrent update operations, wrap the multimap with a call to - * {@link #synchronizedListMultimap}. - * - *

Call this method only when the simpler methods - * {@link ArrayListMultimap#create()} and {@link LinkedListMultimap#create()} - * won't suffice. - * - *

Note: the multimap assumes complete ownership over of {@code map} and - * the lists returned by {@code factory}. Those objects should not be manually - * updated, they should be empty when provided, and they should not use soft, - * weak, or phantom references. - * - * @param map place to store the mapping from each key to its corresponding - * values - * @param factory supplier of new, empty lists that will each hold all values - * for a given key - * @throws IllegalArgumentException if {@code map} is not empty - */ - public static ListMultimap newListMultimap( - Map> map, final Supplier> factory) { - return new CustomListMultimap(map, factory); - } - - private static class CustomListMultimap extends AbstractListMultimap { - transient Supplier> factory; - - CustomListMultimap(Map> map, Supplier> factory) { - super(map); - this.factory = checkNotNull(factory); - } - - @Override - protected List createCollection() { - return factory.get(); - } - - /** @serialData the factory and the backing map */ - @GwtIncompatible("java.io.ObjectOutputStream") - private void writeObject(ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); - stream.writeObject(factory); - stream.writeObject(backingMap()); - } - - @GwtIncompatible("java.io.ObjectInputStream") - @SuppressWarnings("unchecked") // reading data stored by writeObject - private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - factory = (Supplier>) stream.readObject(); - Map> map = (Map>) stream.readObject(); - setMap(map); - } - - @GwtIncompatible("java serialization not supported") - private static final long serialVersionUID = 0; - } - - /** - * Creates a new {@code SetMultimap} that uses the provided map and factory. - * It can generate a multimap based on arbitrary {@link Map} and {@link Set} - * classes. - * - *

The {@code factory}-generated and {@code map} classes determine the - * multimap iteration order. They also specify the behavior of the - * {@code equals}, {@code hashCode}, and {@code toString} methods for the - * multimap and its returned views. However, the multimap's {@code get} - * method returns instances of a different class than {@code factory.get()} - * does. - * - *

The multimap is serializable if {@code map}, {@code factory}, the - * sets generated by {@code factory}, and the multimap contents are all - * serializable. - * - *

The multimap is not threadsafe when any concurrent operations update the - * multimap, even if {@code map} and the instances generated by - * {@code factory} are. Concurrent read operations will work correctly. To - * allow concurrent update operations, wrap the multimap with a call to - * {@link #synchronizedSetMultimap}. - * - *

Call this method only when the simpler methods - * {@link HashMultimap#create()}, {@link LinkedHashMultimap#create()}, - * {@link TreeMultimap#create()}, and - * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice. - * - *

Note: the multimap assumes complete ownership over of {@code map} and - * the sets returned by {@code factory}. Those objects should not be manually - * updated and they should not use soft, weak, or phantom references. - * - * @param map place to store the mapping from each key to its corresponding - * values - * @param factory supplier of new, empty sets that will each hold all values - * for a given key - * @throws IllegalArgumentException if {@code map} is not empty - */ - public static SetMultimap newSetMultimap( - Map> map, final Supplier> factory) { - return new CustomSetMultimap(map, factory); - } - - private static class CustomSetMultimap extends AbstractSetMultimap { - transient Supplier> factory; - - CustomSetMultimap(Map> map, Supplier> factory) { - super(map); - this.factory = checkNotNull(factory); - } - - @Override - protected Set createCollection() { - return factory.get(); - } - - /** @serialData the factory and the backing map */ - @GwtIncompatible("java.io.ObjectOutputStream") - private void writeObject(ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); - stream.writeObject(factory); - stream.writeObject(backingMap()); - } - - @GwtIncompatible("java.io.ObjectInputStream") - @SuppressWarnings("unchecked") // reading data stored by writeObject - private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - factory = (Supplier>) stream.readObject(); - Map> map = (Map>) stream.readObject(); - setMap(map); - } - - @GwtIncompatible("not needed in emulated source") - private static final long serialVersionUID = 0; - } - - /** - * Creates a new {@code SortedSetMultimap} that uses the provided map and - * factory. It can generate a multimap based on arbitrary {@link Map} and - * {@link SortedSet} classes. - * - *

The {@code factory}-generated and {@code map} classes determine the - * multimap iteration order. They also specify the behavior of the - * {@code equals}, {@code hashCode}, and {@code toString} methods for the - * multimap and its returned views. However, the multimap's {@code get} - * method returns instances of a different class than {@code factory.get()} - * does. - * - *

The multimap is serializable if {@code map}, {@code factory}, the - * sets generated by {@code factory}, and the multimap contents are all - * serializable. - * - *

The multimap is not threadsafe when any concurrent operations update the - * multimap, even if {@code map} and the instances generated by - * {@code factory} are. Concurrent read operations will work correctly. To - * allow concurrent update operations, wrap the multimap with a call to - * {@link #synchronizedSortedSetMultimap}. - * - *

Call this method only when the simpler methods - * {@link TreeMultimap#create()} and - * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice. - * - *

Note: the multimap assumes complete ownership over of {@code map} and - * the sets returned by {@code factory}. Those objects should not be manually - * updated and they should not use soft, weak, or phantom references. - * - * @param map place to store the mapping from each key to its corresponding - * values - * @param factory supplier of new, empty sorted sets that will each hold - * all values for a given key - * @throws IllegalArgumentException if {@code map} is not empty - */ - public static SortedSetMultimap newSortedSetMultimap( - Map> map, final Supplier> factory) { - return new CustomSortedSetMultimap(map, factory); - } - - private static class CustomSortedSetMultimap extends AbstractSortedSetMultimap { - transient Supplier> factory; - transient Comparator valueComparator; - - CustomSortedSetMultimap(Map> map, Supplier> factory) { - super(map); - this.factory = checkNotNull(factory); - valueComparator = factory.get().comparator(); - } - - @Override - protected SortedSet createCollection() { - return factory.get(); - } - - @Override - public Comparator valueComparator() { - return valueComparator; - } - - /** @serialData the factory and the backing map */ - @GwtIncompatible("java.io.ObjectOutputStream") - private void writeObject(ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); - stream.writeObject(factory); - stream.writeObject(backingMap()); - } - - @GwtIncompatible("java.io.ObjectInputStream") - @SuppressWarnings("unchecked") // reading data stored by writeObject - private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - factory = (Supplier>) stream.readObject(); - valueComparator = factory.get().comparator(); - Map> map = (Map>) stream.readObject(); - setMap(map); - } - - @GwtIncompatible("not needed in emulated source") - private static final long serialVersionUID = 0; - } - - /** - * Copies each key-value mapping in {@code source} into {@code dest}, with - * its key and value reversed. - * - *

If {@code source} is an {@link ImmutableMultimap}, consider using - * {@link ImmutableMultimap#inverse} instead. - * - * @param source any multimap - * @param dest the multimap to copy into; usually empty - * @return {@code dest} - */ - public static > M invertFrom( - Multimap source, M dest) { - checkNotNull(dest); - for (Map.Entry entry : source.entries()) { - dest.put(entry.getValue(), entry.getKey()); - } - return dest; - } - - /** - * Returns a synchronized (thread-safe) multimap backed by the specified - * multimap. In order to guarantee serial access, it is critical that - * all access to the backing multimap is accomplished through the - * returned multimap. - * - *

It is imperative that the user manually synchronize on the returned - * multimap when accessing any of its collection views:

   {@code
-   *
-   *   Multimap multimap = Multimaps.synchronizedMultimap(
-   *       HashMultimap.create());
-   *   ...
-   *   Collection values = multimap.get(key);  // Needn't be in synchronized block
-   *   ...
-   *   synchronized (multimap) {  // Synchronizing on multimap, not values!
-   *     Iterator i = values.iterator(); // Must be in synchronized block
-   *     while (i.hasNext()) {
-   *       foo(i.next());
-   *     }
-   *   }}
- * - *

Failure to follow this advice may result in non-deterministic behavior. - * - *

Note that the generated multimap's {@link Multimap#removeAll} and - * {@link Multimap#replaceValues} methods return collections that aren't - * synchronized. - * - *

The returned multimap will be serializable if the specified multimap is - * serializable. - * - * @param multimap the multimap to be wrapped in a synchronized view - * @return a synchronized view of the specified multimap - */ - public static Multimap synchronizedMultimap(Multimap multimap) { - return Synchronized.multimap(multimap, null); - } - - /** - * Returns an unmodifiable view of the specified multimap. Query operations on - * the returned multimap "read through" to the specified multimap, and - * attempts to modify the returned multimap, either directly or through the - * multimap's views, result in an {@code UnsupportedOperationException}. - * - *

Note that the generated multimap's {@link Multimap#removeAll} and - * {@link Multimap#replaceValues} methods return collections that are - * modifiable. - * - *

The returned multimap will be serializable if the specified multimap is - * serializable. - * - * @param delegate the multimap for which an unmodifiable view is to be - * returned - * @return an unmodifiable view of the specified multimap - */ - public static Multimap unmodifiableMultimap(Multimap delegate) { - if (delegate instanceof UnmodifiableMultimap || delegate instanceof ImmutableMultimap) { - return delegate; - } - return new UnmodifiableMultimap(delegate); - } - - /** - * Simply returns its argument. - * - * @deprecated no need to use this - * @since 10.0 - */ - @Deprecated - public static Multimap unmodifiableMultimap(ImmutableMultimap delegate) { - return checkNotNull(delegate); - } - - private static class UnmodifiableMultimap extends ForwardingMultimap - implements Serializable { - final Multimap delegate; - transient Collection> entries; - transient Multiset keys; - transient Set keySet; - transient Collection values; - transient Map> map; - - UnmodifiableMultimap(final Multimap delegate) { - this.delegate = checkNotNull(delegate); - } - - @Override - protected Multimap delegate() { - return delegate; - } - - @Override - public void clear() { - throw new UnsupportedOperationException(); - } - - @Override - public Map> asMap() { - Map> result = map; - if (result == null) { - result = map = - Collections.unmodifiableMap( - Maps.transformValues( - delegate.asMap(), - new Function, Collection>() { - @Override - public Collection apply(Collection collection) { - return unmodifiableValueCollection(collection); - } - })); - } - return result; - } - - @Override - public Collection> entries() { - Collection> result = entries; - if (result == null) { - entries = result = unmodifiableEntries(delegate.entries()); - } - return result; - } - - @Override - public Collection get(K key) { - return unmodifiableValueCollection(delegate.get(key)); - } - - @Override - public Multiset keys() { - Multiset result = keys; - if (result == null) { - keys = result = Multisets.unmodifiableMultiset(delegate.keys()); - } - return result; - } - - @Override - public Set keySet() { - Set result = keySet; - if (result == null) { - keySet = result = Collections.unmodifiableSet(delegate.keySet()); - } - return result; - } - - @Override - public boolean put(K key, V value) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean putAll(K key, Iterable values) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean putAll(Multimap multimap) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean remove(Object key, Object value) { - throw new UnsupportedOperationException(); - } - - @Override - public Collection removeAll(Object key) { - throw new UnsupportedOperationException(); - } - - @Override - public Collection replaceValues(K key, Iterable values) { - throw new UnsupportedOperationException(); - } - - @Override - public Collection values() { - Collection result = values; - if (result == null) { - values = result = Collections.unmodifiableCollection(delegate.values()); - } - return result; - } - - private static final long serialVersionUID = 0; - } - - private static class UnmodifiableListMultimap extends UnmodifiableMultimap - implements ListMultimap { - UnmodifiableListMultimap(ListMultimap delegate) { - super(delegate); - } - - @Override - public ListMultimap delegate() { - return (ListMultimap) super.delegate(); - } - - @Override - public List get(K key) { - return Collections.unmodifiableList(delegate().get(key)); - } - - @Override - public List removeAll(Object key) { - throw new UnsupportedOperationException(); - } - - @Override - public List replaceValues(K key, Iterable values) { - throw new UnsupportedOperationException(); - } - - private static final long serialVersionUID = 0; - } - - private static class UnmodifiableSetMultimap extends UnmodifiableMultimap - implements SetMultimap { - UnmodifiableSetMultimap(SetMultimap delegate) { - super(delegate); - } - - @Override - public SetMultimap delegate() { - return (SetMultimap) super.delegate(); - } - - @Override - public Set get(K key) { - /* - * Note that this doesn't return a SortedSet when delegate is a - * SortedSetMultiset, unlike (SortedSet) super.get(). - */ - return Collections.unmodifiableSet(delegate().get(key)); - } - - @Override - public Set> entries() { - return Maps.unmodifiableEntrySet(delegate().entries()); - } - - @Override - public Set removeAll(Object key) { - throw new UnsupportedOperationException(); - } - - @Override - public Set replaceValues(K key, Iterable values) { - throw new UnsupportedOperationException(); - } - - private static final long serialVersionUID = 0; - } - - private static class UnmodifiableSortedSetMultimap extends UnmodifiableSetMultimap - implements SortedSetMultimap { - UnmodifiableSortedSetMultimap(SortedSetMultimap delegate) { - super(delegate); - } - - @Override - public SortedSetMultimap delegate() { - return (SortedSetMultimap) super.delegate(); - } - - @Override - public SortedSet get(K key) { - return Collections.unmodifiableSortedSet(delegate().get(key)); - } - - @Override - public SortedSet removeAll(Object key) { - throw new UnsupportedOperationException(); - } - - @Override - public SortedSet replaceValues(K key, Iterable values) { - throw new UnsupportedOperationException(); - } - - @Override - public Comparator valueComparator() { - return delegate().valueComparator(); - } - - private static final long serialVersionUID = 0; - } - - /** - * Returns a synchronized (thread-safe) {@code SetMultimap} backed by the - * specified multimap. - * - *

You must follow the warnings described in {@link #synchronizedMultimap}. - * - *

The returned multimap will be serializable if the specified multimap is - * serializable. - * - * @param multimap the multimap to be wrapped - * @return a synchronized view of the specified multimap - */ - public static SetMultimap synchronizedSetMultimap(SetMultimap multimap) { - return Synchronized.setMultimap(multimap, null); - } - - /** - * Returns an unmodifiable view of the specified {@code SetMultimap}. Query - * operations on the returned multimap "read through" to the specified - * multimap, and attempts to modify the returned multimap, either directly or - * through the multimap's views, result in an - * {@code UnsupportedOperationException}. - * - *

Note that the generated multimap's {@link Multimap#removeAll} and - * {@link Multimap#replaceValues} methods return collections that are - * modifiable. - * - *

The returned multimap will be serializable if the specified multimap is - * serializable. - * - * @param delegate the multimap for which an unmodifiable view is to be - * returned - * @return an unmodifiable view of the specified multimap - */ - public static SetMultimap unmodifiableSetMultimap(SetMultimap delegate) { - if (delegate instanceof UnmodifiableSetMultimap || delegate instanceof ImmutableSetMultimap) { - return delegate; - } - return new UnmodifiableSetMultimap(delegate); - } - - /** - * Simply returns its argument. - * - * @deprecated no need to use this - * @since 10.0 - */ - @Deprecated - public static SetMultimap unmodifiableSetMultimap( - ImmutableSetMultimap delegate) { - return checkNotNull(delegate); - } - - /** - * Returns a synchronized (thread-safe) {@code SortedSetMultimap} backed by - * the specified multimap. - * - *

You must follow the warnings described in {@link #synchronizedMultimap}. - * - *

The returned multimap will be serializable if the specified multimap is - * serializable. - * - * @param multimap the multimap to be wrapped - * @return a synchronized view of the specified multimap - */ - public static SortedSetMultimap synchronizedSortedSetMultimap( - SortedSetMultimap multimap) { - return Synchronized.sortedSetMultimap(multimap, null); - } - - /** - * Returns an unmodifiable view of the specified {@code SortedSetMultimap}. - * Query operations on the returned multimap "read through" to the specified - * multimap, and attempts to modify the returned multimap, either directly or - * through the multimap's views, result in an - * {@code UnsupportedOperationException}. - * - *

Note that the generated multimap's {@link Multimap#removeAll} and - * {@link Multimap#replaceValues} methods return collections that are - * modifiable. - * - *

The returned multimap will be serializable if the specified multimap is - * serializable. - * - * @param delegate the multimap for which an unmodifiable view is to be - * returned - * @return an unmodifiable view of the specified multimap - */ - public static SortedSetMultimap unmodifiableSortedSetMultimap( - SortedSetMultimap delegate) { - if (delegate instanceof UnmodifiableSortedSetMultimap) { - return delegate; - } - return new UnmodifiableSortedSetMultimap(delegate); - } - - /** - * Returns a synchronized (thread-safe) {@code ListMultimap} backed by the - * specified multimap. - * - *

You must follow the warnings described in {@link #synchronizedMultimap}. - * - * @param multimap the multimap to be wrapped - * @return a synchronized view of the specified multimap - */ - public static ListMultimap synchronizedListMultimap(ListMultimap multimap) { - return Synchronized.listMultimap(multimap, null); - } - - /** - * Returns an unmodifiable view of the specified {@code ListMultimap}. Query - * operations on the returned multimap "read through" to the specified - * multimap, and attempts to modify the returned multimap, either directly or - * through the multimap's views, result in an - * {@code UnsupportedOperationException}. - * - *

Note that the generated multimap's {@link Multimap#removeAll} and - * {@link Multimap#replaceValues} methods return collections that are - * modifiable. - * - *

The returned multimap will be serializable if the specified multimap is - * serializable. - * - * @param delegate the multimap for which an unmodifiable view is to be - * returned - * @return an unmodifiable view of the specified multimap - */ - public static ListMultimap unmodifiableListMultimap(ListMultimap delegate) { - if (delegate instanceof UnmodifiableListMultimap || delegate instanceof ImmutableListMultimap) { - return delegate; - } - return new UnmodifiableListMultimap(delegate); - } - - /** - * Simply returns its argument. - * - * @deprecated no need to use this - * @since 10.0 - */ - @Deprecated - public static ListMultimap unmodifiableListMultimap( - ImmutableListMultimap delegate) { - return checkNotNull(delegate); - } - - /** - * Returns an unmodifiable view of the specified collection, preserving the - * interface for instances of {@code SortedSet}, {@code Set}, {@code List} and - * {@code Collection}, in that order of preference. - * - * @param collection the collection for which to return an unmodifiable view - * @return an unmodifiable view of the collection - */ - private static Collection unmodifiableValueCollection(Collection collection) { - if (collection instanceof SortedSet) { - return Collections.unmodifiableSortedSet((SortedSet) collection); - } else if (collection instanceof Set) { - return Collections.unmodifiableSet((Set) collection); - } else if (collection instanceof List) { - return Collections.unmodifiableList((List) collection); - } - return Collections.unmodifiableCollection(collection); - } - - /** - * Returns an unmodifiable view of the specified collection of entries. The - * {@link Entry#setValue} operation throws an {@link - * UnsupportedOperationException}. If the specified collection is a {@code - * Set}, the returned collection is also a {@code Set}. - * - * @param entries the entries for which to return an unmodifiable view - * @return an unmodifiable view of the entries - */ - private static Collection> unmodifiableEntries( - Collection> entries) { - if (entries instanceof Set) { - return Maps.unmodifiableEntrySet((Set>) entries); - } - return new Maps.UnmodifiableEntries(Collections.unmodifiableCollection(entries)); - } - - /** - * Returns {@link ListMultimap#asMap multimap.asMap()}, with its type - * corrected from {@code Map>} to {@code Map>}. - * - * @since 15.0 - */ - @Beta - @SuppressWarnings("unchecked") - // safe by specification of ListMultimap.asMap() - public static Map> asMap(ListMultimap multimap) { - return (Map>) (Map) multimap.asMap(); - } - - /** - * Returns {@link SetMultimap#asMap multimap.asMap()}, with its type corrected - * from {@code Map>} to {@code Map>}. - * - * @since 15.0 - */ - @Beta - @SuppressWarnings("unchecked") - // safe by specification of SetMultimap.asMap() - public static Map> asMap(SetMultimap multimap) { - return (Map>) (Map) multimap.asMap(); - } - - /** - * Returns {@link SortedSetMultimap#asMap multimap.asMap()}, with its type - * corrected from {@code Map>} to - * {@code Map>}. - * - * @since 15.0 - */ - @Beta - @SuppressWarnings("unchecked") - // safe by specification of SortedSetMultimap.asMap() - public static Map> asMap(SortedSetMultimap multimap) { - return (Map>) (Map) multimap.asMap(); - } - - /** - * Returns {@link Multimap#asMap multimap.asMap()}. This is provided for - * parity with the other more strongly-typed {@code asMap()} implementations. - * - * @since 15.0 - */ - @Beta - public static Map> asMap(Multimap multimap) { - return multimap.asMap(); - } - - /** - * Returns a multimap view of the specified map. The multimap is backed by the - * map, so changes to the map are reflected in the multimap, and vice versa. - * If the map is modified while an iteration over one of the multimap's - * collection views is in progress (except through the iterator's own {@code - * remove} operation, or through the {@code setValue} operation on a map entry - * returned by the iterator), the results of the iteration are undefined. - * - *

The multimap supports mapping removal, which removes the corresponding - * mapping from the map. It does not support any operations which might add - * mappings, such as {@code put}, {@code putAll} or {@code replaceValues}. - * - *

The returned multimap will be serializable if the specified map is - * serializable. - * - * @param map the backing map for the returned multimap view - */ - public static SetMultimap forMap(Map map) { - return new MapMultimap(map); - } - - /** @see Multimaps#forMap */ - private static class MapMultimap extends AbstractMultimap - implements SetMultimap, Serializable { - final Map map; - - MapMultimap(Map map) { - this.map = checkNotNull(map); - } - - @Override - public int size() { - return map.size(); - } - - @Override - public boolean containsKey(Object key) { - return map.containsKey(key); - } - - @Override - public boolean containsValue(Object value) { - return map.containsValue(value); - } - - @Override - public boolean containsEntry(Object key, Object value) { - return map.entrySet().contains(Maps.immutableEntry(key, value)); - } - - @Override - public Set get(final K key) { - return new Sets.ImprovedAbstractSet() { - @Override - public Iterator iterator() { - return new Iterator() { - int i; - - @Override - public boolean hasNext() { - return (i == 0) && map.containsKey(key); - } - - @Override - public V next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - i++; - return map.get(key); - } - - @Override - public void remove() { - checkRemove(i == 1); - i = -1; - map.remove(key); - } - }; - } - - @Override - public int size() { - return map.containsKey(key) ? 1 : 0; - } - }; - } - - @Override - public boolean put(K key, V value) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean putAll(K key, Iterable values) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean putAll(Multimap multimap) { - throw new UnsupportedOperationException(); - } - - @Override - public Set replaceValues(K key, Iterable values) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean remove(Object key, Object value) { - return map.entrySet().remove(Maps.immutableEntry(key, value)); - } - - @Override - public Set removeAll(Object key) { - Set values = new HashSet(2); - if (!map.containsKey(key)) { - return values; - } - values.add(map.remove(key)); - return values; - } - - @Override - public void clear() { - map.clear(); - } - - @Override - public Set keySet() { - return map.keySet(); - } - - @Override - public Collection values() { - return map.values(); - } - - @Override - public Set> entries() { - return map.entrySet(); - } - - @Override - Iterator> entryIterator() { - return map.entrySet().iterator(); - } - - @Override - Map> createAsMap() { - return new AsMap(this); - } - - @Override - public int hashCode() { - return map.hashCode(); - } - - private static final long serialVersionUID = 7845222491160860175L; - } - - /** - * Returns a view of a multimap where each value is transformed by a function. - * All other properties of the multimap, such as iteration order, are left - * intact. For example, the code:

   {@code
-   *
-   * Multimap multimap =
-   *     ImmutableSetMultimap.of("a", 2, "b", -3, "b", -3, "a", 4, "c", 6);
-   * Function square = new Function() {
-   *     public String apply(Integer in) {
-   *       return Integer.toString(in * in);
-   *     }
-   * };
-   * Multimap transformed =
-   *     Multimaps.transformValues(multimap, square);
-   *   System.out.println(transformed);}
- * - * ... prints {@code {a=[4, 16], b=[9, 9], c=[36]}}. - * - *

Changes in the underlying multimap are reflected in this view. - * Conversely, this view supports removal operations, and these are reflected - * in the underlying multimap. - * - *

It's acceptable for the underlying multimap to contain null keys, and - * even null values provided that the function is capable of accepting null - * input. The transformed multimap might contain null values, if the function - * sometimes gives a null result. - * - *

The returned multimap is not thread-safe or serializable, even if the - * underlying multimap is. The {@code equals} and {@code hashCode} methods - * of the returned multimap are meaningless, since there is not a definition - * of {@code equals} or {@code hashCode} for general collections, and - * {@code get()} will return a general {@code Collection} as opposed to a - * {@code List} or a {@code Set}. - * - *

The function is applied lazily, invoked when needed. This is necessary - * for the returned multimap to be a view, but it means that the function will - * be applied many times for bulk operations like - * {@link Multimap#containsValue} and {@code Multimap.toString()}. For this to - * perform well, {@code function} should be fast. To avoid lazy evaluation - * when the returned multimap doesn't need to be a view, copy the returned - * multimap into a new multimap of your choosing. - * - * @since 7.0 - */ - public static Multimap transformValues( - Multimap fromMultimap, final Function function) { - checkNotNull(function); - EntryTransformer transformer = Maps.asEntryTransformer(function); - return transformEntries(fromMultimap, transformer); - } - - /** - * Returns a view of a multimap whose values are derived from the original - * multimap's entries. In contrast to {@link #transformValues}, this method's - * entry-transformation logic may depend on the key as well as the value. - * - *

All other properties of the transformed multimap, such as iteration - * order, are left intact. For example, the code:

   {@code
-   *
-   *   SetMultimap multimap =
-   *       ImmutableSetMultimap.of("a", 1, "a", 4, "b", -6);
-   *   EntryTransformer transformer =
-   *       new EntryTransformer() {
-   *         public String transformEntry(String key, Integer value) {
-   *            return (value >= 0) ? key : "no" + key;
-   *         }
-   *       };
-   *   Multimap transformed =
-   *       Multimaps.transformEntries(multimap, transformer);
-   *   System.out.println(transformed);}
- * - * ... prints {@code {a=[a, a], b=[nob]}}. - * - *

Changes in the underlying multimap are reflected in this view. - * Conversely, this view supports removal operations, and these are reflected - * in the underlying multimap. - * - *

It's acceptable for the underlying multimap to contain null keys and - * null values provided that the transformer is capable of accepting null - * inputs. The transformed multimap might contain null values if the - * transformer sometimes gives a null result. - * - *

The returned multimap is not thread-safe or serializable, even if the - * underlying multimap is. The {@code equals} and {@code hashCode} methods - * of the returned multimap are meaningless, since there is not a definition - * of {@code equals} or {@code hashCode} for general collections, and - * {@code get()} will return a general {@code Collection} as opposed to a - * {@code List} or a {@code Set}. - * - *

The transformer is applied lazily, invoked when needed. This is - * necessary for the returned multimap to be a view, but it means that the - * transformer will be applied many times for bulk operations like {@link - * Multimap#containsValue} and {@link Object#toString}. For this to perform - * well, {@code transformer} should be fast. To avoid lazy evaluation when the - * returned multimap doesn't need to be a view, copy the returned multimap - * into a new multimap of your choosing. - * - *

Warning: This method assumes that for any instance {@code k} of - * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies - * that {@code k2} is also of type {@code K}. Using an {@code - * EntryTransformer} key type for which this may not hold, such as {@code - * ArrayList}, may risk a {@code ClassCastException} when calling methods on - * the transformed multimap. - * - * @since 7.0 - */ - public static Multimap transformEntries( - Multimap fromMap, EntryTransformer transformer) { - return new TransformedEntriesMultimap(fromMap, transformer); - } - - private static class TransformedEntriesMultimap extends AbstractMultimap { - final Multimap fromMultimap; - final EntryTransformer transformer; - - TransformedEntriesMultimap( - Multimap fromMultimap, - final EntryTransformer transformer) { - this.fromMultimap = checkNotNull(fromMultimap); - this.transformer = checkNotNull(transformer); - } - - Collection transform(K key, Collection values) { - Function function = Maps.asValueToValueFunction(transformer, key); - if (values instanceof List) { - return Lists.transform((List) values, function); - } else { - return Collections2.transform(values, function); - } - } - - @Override - Map> createAsMap() { - return Maps.transformEntries( - fromMultimap.asMap(), - new EntryTransformer, Collection>() { - @Override - public Collection transformEntry(K key, Collection value) { - return transform(key, value); - } - }); - } - - @Override - public void clear() { - fromMultimap.clear(); - } - - @Override - public boolean containsKey(Object key) { - return fromMultimap.containsKey(key); - } - - @Override - Iterator> entryIterator() { - return Iterators.transform( - fromMultimap.entries().iterator(), Maps.asEntryToEntryFunction(transformer)); - } - - @Override - public Collection get(final K key) { - return transform(key, fromMultimap.get(key)); - } - - @Override - public boolean isEmpty() { - return fromMultimap.isEmpty(); - } - - @Override - public Set keySet() { - return fromMultimap.keySet(); - } - - @Override - public Multiset keys() { - return fromMultimap.keys(); - } - - @Override - public boolean put(K key, V2 value) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean putAll(K key, Iterable values) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean putAll(Multimap multimap) { - throw new UnsupportedOperationException(); - } - - @SuppressWarnings("unchecked") - @Override - public boolean remove(Object key, Object value) { - return get((K) key).remove(value); - } - - @SuppressWarnings("unchecked") - @Override - public Collection removeAll(Object key) { - return transform((K) key, fromMultimap.removeAll(key)); - } - - @Override - public Collection replaceValues(K key, Iterable values) { - throw new UnsupportedOperationException(); - } - - @Override - public int size() { - return fromMultimap.size(); - } - - @Override - Collection createValues() { - return Collections2.transform( - fromMultimap.entries(), Maps.asEntryToValueFunction(transformer)); - } - } - - /** - * Returns a view of a {@code ListMultimap} where each value is transformed by - * a function. All other properties of the multimap, such as iteration order, - * are left intact. For example, the code:

   {@code
-   *
-   *   ListMultimap multimap
-   *        = ImmutableListMultimap.of("a", 4, "a", 16, "b", 9);
-   *   Function sqrt =
-   *       new Function() {
-   *         public Double apply(Integer in) {
-   *           return Math.sqrt((int) in);
-   *         }
-   *       };
-   *   ListMultimap transformed = Multimaps.transformValues(map,
-   *       sqrt);
-   *   System.out.println(transformed);}
- * - * ... prints {@code {a=[2.0, 4.0], b=[3.0]}}. - * - *

Changes in the underlying multimap are reflected in this view. - * Conversely, this view supports removal operations, and these are reflected - * in the underlying multimap. - * - *

It's acceptable for the underlying multimap to contain null keys, and - * even null values provided that the function is capable of accepting null - * input. The transformed multimap might contain null values, if the function - * sometimes gives a null result. - * - *

The returned multimap is not thread-safe or serializable, even if the - * underlying multimap is. - * - *

The function is applied lazily, invoked when needed. This is necessary - * for the returned multimap to be a view, but it means that the function will - * be applied many times for bulk operations like - * {@link Multimap#containsValue} and {@code Multimap.toString()}. For this to - * perform well, {@code function} should be fast. To avoid lazy evaluation - * when the returned multimap doesn't need to be a view, copy the returned - * multimap into a new multimap of your choosing. - * - * @since 7.0 - */ - public static ListMultimap transformValues( - ListMultimap fromMultimap, final Function function) { - checkNotNull(function); - EntryTransformer transformer = Maps.asEntryTransformer(function); - return transformEntries(fromMultimap, transformer); - } - - /** - * Returns a view of a {@code ListMultimap} whose values are derived from the - * original multimap's entries. In contrast to - * {@link #transformValues(ListMultimap, Function)}, this method's - * entry-transformation logic may depend on the key as well as the value. - * - *

All other properties of the transformed multimap, such as iteration - * order, are left intact. For example, the code:

   {@code
-   *
-   *   Multimap multimap =
-   *       ImmutableMultimap.of("a", 1, "a", 4, "b", 6);
-   *   EntryTransformer transformer =
-   *       new EntryTransformer() {
-   *         public String transformEntry(String key, Integer value) {
-   *           return key + value;
-   *         }
-   *       };
-   *   Multimap transformed =
-   *       Multimaps.transformEntries(multimap, transformer);
-   *   System.out.println(transformed);}
- * - * ... prints {@code {"a"=["a1", "a4"], "b"=["b6"]}}. - * - *

Changes in the underlying multimap are reflected in this view. - * Conversely, this view supports removal operations, and these are reflected - * in the underlying multimap. - * - *

It's acceptable for the underlying multimap to contain null keys and - * null values provided that the transformer is capable of accepting null - * inputs. The transformed multimap might contain null values if the - * transformer sometimes gives a null result. - * - *

The returned multimap is not thread-safe or serializable, even if the - * underlying multimap is. - * - *

The transformer is applied lazily, invoked when needed. This is - * necessary for the returned multimap to be a view, but it means that the - * transformer will be applied many times for bulk operations like {@link - * Multimap#containsValue} and {@link Object#toString}. For this to perform - * well, {@code transformer} should be fast. To avoid lazy evaluation when the - * returned multimap doesn't need to be a view, copy the returned multimap - * into a new multimap of your choosing. - * - *

Warning: This method assumes that for any instance {@code k} of - * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies - * that {@code k2} is also of type {@code K}. Using an {@code - * EntryTransformer} key type for which this may not hold, such as {@code - * ArrayList}, may risk a {@code ClassCastException} when calling methods on - * the transformed multimap. - * - * @since 7.0 - */ - public static ListMultimap transformEntries( - ListMultimap fromMap, EntryTransformer transformer) { - return new TransformedEntriesListMultimap(fromMap, transformer); - } - - private static final class TransformedEntriesListMultimap - extends TransformedEntriesMultimap implements ListMultimap { - - TransformedEntriesListMultimap( - ListMultimap fromMultimap, EntryTransformer transformer) { - super(fromMultimap, transformer); - } - - @Override - List transform(K key, Collection values) { - return Lists.transform((List) values, Maps.asValueToValueFunction(transformer, key)); - } - - @Override - public List get(K key) { - return transform(key, fromMultimap.get(key)); - } - - @SuppressWarnings("unchecked") - @Override - public List removeAll(Object key) { - return transform((K) key, fromMultimap.removeAll(key)); - } - - @Override - public List replaceValues(K key, Iterable values) { - throw new UnsupportedOperationException(); - } - } - - /** - * Creates an index {@code ImmutableListMultimap} that contains the results of - * applying a specified function to each item in an {@code Iterable} of - * values. Each value will be stored as a value in the resulting multimap, - * yielding a multimap with the same size as the input iterable. The key used - * to store that value in the multimap will be the result of calling the - * function on that value. The resulting multimap is created as an immutable - * snapshot. In the returned multimap, keys appear in the order they are first - * encountered, and the values corresponding to each key appear in the same - * order as they are encountered. - * - *

For example,

   {@code
-   *
-   *   List badGuys =
-   *       Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde");
-   *   Function stringLengthFunction = ...;
-   *   Multimap index =
-   *       Multimaps.index(badGuys, stringLengthFunction);
-   *   System.out.println(index);}
- * - *

prints

   {@code
-   *
-   *   {4=[Inky], 6=[Blinky], 5=[Pinky, Pinky, Clyde]}}
- * - *

The returned multimap is serializable if its keys and values are all - * serializable. - * - * @param values the values to use when constructing the {@code - * ImmutableListMultimap} - * @param keyFunction the function used to produce the key for each value - * @return {@code ImmutableListMultimap} mapping the result of evaluating the - * function {@code keyFunction} on each value in the input collection to - * that value - * @throws NullPointerException if any of the following cases is true: - *

    - *
  • {@code values} is null - *
  • {@code keyFunction} is null - *
  • An element in {@code values} is null - *
  • {@code keyFunction} returns {@code null} for any element of {@code - * values} - *
- */ - public static ImmutableListMultimap index( - Iterable values, Function keyFunction) { - return index(values.iterator(), keyFunction); - } - - /** - * Creates an index {@code ImmutableListMultimap} that contains the results of - * applying a specified function to each item in an {@code Iterator} of - * values. Each value will be stored as a value in the resulting multimap, - * yielding a multimap with the same size as the input iterator. The key used - * to store that value in the multimap will be the result of calling the - * function on that value. The resulting multimap is created as an immutable - * snapshot. In the returned multimap, keys appear in the order they are first - * encountered, and the values corresponding to each key appear in the same - * order as they are encountered. - * - *

For example,

   {@code
-   *
-   *   List badGuys =
-   *       Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde");
-   *   Function stringLengthFunction = ...;
-   *   Multimap index =
-   *       Multimaps.index(badGuys.iterator(), stringLengthFunction);
-   *   System.out.println(index);}
- * - *

prints

   {@code
-   *
-   *   {4=[Inky], 6=[Blinky], 5=[Pinky, Pinky, Clyde]}}
- * - *

The returned multimap is serializable if its keys and values are all - * serializable. - * - * @param values the values to use when constructing the {@code - * ImmutableListMultimap} - * @param keyFunction the function used to produce the key for each value - * @return {@code ImmutableListMultimap} mapping the result of evaluating the - * function {@code keyFunction} on each value in the input collection to - * that value - * @throws NullPointerException if any of the following cases is true: - *

    - *
  • {@code values} is null - *
  • {@code keyFunction} is null - *
  • An element in {@code values} is null - *
  • {@code keyFunction} returns {@code null} for any element of {@code - * values} - *
- * @since 10.0 - */ - public static ImmutableListMultimap index( - Iterator values, Function keyFunction) { - checkNotNull(keyFunction); - ImmutableListMultimap.Builder builder = ImmutableListMultimap.builder(); - while (values.hasNext()) { - V value = values.next(); - checkNotNull(value, values); - builder.put(keyFunction.apply(value), value); - } - return builder.build(); - } - - static class Keys extends AbstractMultiset { - @Weak final Multimap multimap; - - Keys(Multimap multimap) { - this.multimap = multimap; - } - - @Override - Iterator> entryIterator() { - return new TransformedIterator>, Multiset.Entry>( - multimap.asMap().entrySet().iterator()) { - @Override - Multiset.Entry transform(final Map.Entry> backingEntry) { - return new Multisets.AbstractEntry() { - @Override - public K getElement() { - return backingEntry.getKey(); - } - - @Override - public int getCount() { - return backingEntry.getValue().size(); - } - }; - } - }; - } - - @Override - int distinctElements() { - return multimap.asMap().size(); - } - - @Override - Set> createEntrySet() { - return new KeysEntrySet(); - } - - @WeakOuter - class KeysEntrySet extends Multisets.EntrySet { - @Override - Multiset multiset() { - return Keys.this; - } - - @Override - public Iterator> iterator() { - return entryIterator(); - } - - @Override - public int size() { - return distinctElements(); - } - - @Override - public boolean isEmpty() { - return multimap.isEmpty(); - } - - @Override - public boolean contains(@Nullable Object o) { - if (o instanceof Multiset.Entry) { - Multiset.Entry entry = (Multiset.Entry) o; - Collection collection = multimap.asMap().get(entry.getElement()); - return collection != null && collection.size() == entry.getCount(); - } - return false; - } - - @Override - public boolean remove(@Nullable Object o) { - if (o instanceof Multiset.Entry) { - Multiset.Entry entry = (Multiset.Entry) o; - Collection collection = multimap.asMap().get(entry.getElement()); - if (collection != null && collection.size() == entry.getCount()) { - collection.clear(); - return true; - } - } - return false; - } - } - - @Override - public boolean contains(@Nullable Object element) { - return multimap.containsKey(element); - } - - @Override - public Iterator iterator() { - return Maps.keyIterator(multimap.entries().iterator()); - } - - @Override - public int count(@Nullable Object element) { - Collection values = Maps.safeGet(multimap.asMap(), element); - return (values == null) ? 0 : values.size(); - } - - @Override - public int remove(@Nullable Object element, int occurrences) { - checkNonnegative(occurrences, "occurrences"); - if (occurrences == 0) { - return count(element); - } - - Collection values = Maps.safeGet(multimap.asMap(), element); - - if (values == null) { - return 0; - } - - int oldCount = values.size(); - if (occurrences >= oldCount) { - values.clear(); - } else { - Iterator iterator = values.iterator(); - for (int i = 0; i < occurrences; i++) { - iterator.next(); - iterator.remove(); - } - } - return oldCount; - } - - @Override - public void clear() { - multimap.clear(); - } - - @Override - public Set elementSet() { - return multimap.keySet(); - } - } - - /** - * A skeleton implementation of {@link Multimap#entries()}. - */ - abstract static class Entries extends AbstractCollection> { - abstract Multimap multimap(); - - @Override - public int size() { - return multimap().size(); - } - - @Override - public boolean contains(@Nullable Object o) { - if (o instanceof Map.Entry) { - Map.Entry entry = (Map.Entry) o; - return multimap().containsEntry(entry.getKey(), entry.getValue()); - } - return false; - } - - @Override - public boolean remove(@Nullable Object o) { - if (o instanceof Map.Entry) { - Map.Entry entry = (Map.Entry) o; - return multimap().remove(entry.getKey(), entry.getValue()); - } - return false; - } - - @Override - public void clear() { - multimap().clear(); - } - } - - /** - * A skeleton implementation of {@link Multimap#asMap()}. - */ - static final class AsMap extends Maps.ViewCachingAbstractMap> { - @Weak private final Multimap multimap; - - AsMap(Multimap multimap) { - this.multimap = checkNotNull(multimap); - } - - @Override - public int size() { - return multimap.keySet().size(); - } - - @Override - protected Set>> createEntrySet() { - return new EntrySet(); - } - - void removeValuesForKey(Object key) { - multimap.keySet().remove(key); - } - - @WeakOuter - class EntrySet extends Maps.EntrySet> { - @Override - Map> map() { - return AsMap.this; - } - - @Override - public Iterator>> iterator() { - return Maps.asMapEntryIterator( - multimap.keySet(), - new Function>() { - @Override - public Collection apply(K key) { - return multimap.get(key); - } - }); - } - - @Override - public boolean remove(Object o) { - if (!contains(o)) { - return false; - } - Map.Entry entry = (Map.Entry) o; - removeValuesForKey(entry.getKey()); - return true; - } - } - - @SuppressWarnings("unchecked") - @Override - public Collection get(Object key) { - return containsKey(key) ? multimap.get((K) key) : null; - } - - @Override - public Collection remove(Object key) { - return containsKey(key) ? multimap.removeAll(key) : null; - } - - @Override - public Set keySet() { - return multimap.keySet(); - } - - @Override - public boolean isEmpty() { - return multimap.isEmpty(); - } - - @Override - public boolean containsKey(Object key) { - return multimap.containsKey(key); - } - - @Override - public void clear() { - multimap.clear(); - } - } - - /** - * Returns a multimap containing the mappings in {@code unfiltered} whose keys - * satisfy a predicate. The returned multimap is a live view of - * {@code unfiltered}; changes to one affect the other. - * - *

The resulting multimap's views have iterators that don't support - * {@code remove()}, but all other methods are supported by the multimap and - * its views. When adding a key that doesn't satisfy the predicate, the - * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()} - * methods throw an {@link IllegalArgumentException}. - * - *

When methods such as {@code removeAll()} and {@code clear()} are called on - * the filtered multimap or its views, only mappings whose keys satisfy the - * filter will be removed from the underlying multimap. - * - *

The returned multimap isn't threadsafe or serializable, even if - * {@code unfiltered} is. - * - *

Many of the filtered multimap's methods, such as {@code size()}, iterate - * across every key/value mapping in the underlying multimap and determine - * which satisfy the filter. When a live view is not needed, it may be - * faster to copy the filtered multimap and use the copy. - * - *

Warning: {@code keyPredicate} must be consistent with equals, - * as documented at {@link Predicate#apply}. Do not provide a predicate such - * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent - * with equals. - * - * @since 11.0 - */ - @CheckReturnValue - public static Multimap filterKeys( - Multimap unfiltered, final Predicate keyPredicate) { - if (unfiltered instanceof SetMultimap) { - return filterKeys((SetMultimap) unfiltered, keyPredicate); - } else if (unfiltered instanceof ListMultimap) { - return filterKeys((ListMultimap) unfiltered, keyPredicate); - } else if (unfiltered instanceof FilteredKeyMultimap) { - FilteredKeyMultimap prev = (FilteredKeyMultimap) unfiltered; - return new FilteredKeyMultimap( - prev.unfiltered, Predicates.and(prev.keyPredicate, keyPredicate)); - } else if (unfiltered instanceof FilteredMultimap) { - FilteredMultimap prev = (FilteredMultimap) unfiltered; - return filterFiltered(prev, Maps.keyPredicateOnEntries(keyPredicate)); - } else { - return new FilteredKeyMultimap(unfiltered, keyPredicate); - } - } - - /** - * Returns a multimap containing the mappings in {@code unfiltered} whose keys - * satisfy a predicate. The returned multimap is a live view of - * {@code unfiltered}; changes to one affect the other. - * - *

The resulting multimap's views have iterators that don't support - * {@code remove()}, but all other methods are supported by the multimap and - * its views. When adding a key that doesn't satisfy the predicate, the - * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()} - * methods throw an {@link IllegalArgumentException}. - * - *

When methods such as {@code removeAll()} and {@code clear()} are called on - * the filtered multimap or its views, only mappings whose keys satisfy the - * filter will be removed from the underlying multimap. - * - *

The returned multimap isn't threadsafe or serializable, even if - * {@code unfiltered} is. - * - *

Many of the filtered multimap's methods, such as {@code size()}, iterate - * across every key/value mapping in the underlying multimap and determine - * which satisfy the filter. When a live view is not needed, it may be - * faster to copy the filtered multimap and use the copy. - * - *

Warning: {@code keyPredicate} must be consistent with equals, - * as documented at {@link Predicate#apply}. Do not provide a predicate such - * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent - * with equals. - * - * @since 14.0 - */ - @CheckReturnValue - public static SetMultimap filterKeys( - SetMultimap unfiltered, final Predicate keyPredicate) { - if (unfiltered instanceof FilteredKeySetMultimap) { - FilteredKeySetMultimap prev = (FilteredKeySetMultimap) unfiltered; - return new FilteredKeySetMultimap( - prev.unfiltered(), Predicates.and(prev.keyPredicate, keyPredicate)); - } else if (unfiltered instanceof FilteredSetMultimap) { - FilteredSetMultimap prev = (FilteredSetMultimap) unfiltered; - return filterFiltered(prev, Maps.keyPredicateOnEntries(keyPredicate)); - } else { - return new FilteredKeySetMultimap(unfiltered, keyPredicate); - } - } - - /** - * Returns a multimap containing the mappings in {@code unfiltered} whose keys - * satisfy a predicate. The returned multimap is a live view of - * {@code unfiltered}; changes to one affect the other. - * - *

The resulting multimap's views have iterators that don't support - * {@code remove()}, but all other methods are supported by the multimap and - * its views. When adding a key that doesn't satisfy the predicate, the - * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()} - * methods throw an {@link IllegalArgumentException}. - * - *

When methods such as {@code removeAll()} and {@code clear()} are called on - * the filtered multimap or its views, only mappings whose keys satisfy the - * filter will be removed from the underlying multimap. - * - *

The returned multimap isn't threadsafe or serializable, even if - * {@code unfiltered} is. - * - *

Many of the filtered multimap's methods, such as {@code size()}, iterate - * across every key/value mapping in the underlying multimap and determine - * which satisfy the filter. When a live view is not needed, it may be - * faster to copy the filtered multimap and use the copy. - * - *

Warning: {@code keyPredicate} must be consistent with equals, - * as documented at {@link Predicate#apply}. Do not provide a predicate such - * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent - * with equals. - * - * @since 14.0 - */ - @CheckReturnValue - public static ListMultimap filterKeys( - ListMultimap unfiltered, final Predicate keyPredicate) { - if (unfiltered instanceof FilteredKeyListMultimap) { - FilteredKeyListMultimap prev = (FilteredKeyListMultimap) unfiltered; - return new FilteredKeyListMultimap( - prev.unfiltered(), Predicates.and(prev.keyPredicate, keyPredicate)); - } else { - return new FilteredKeyListMultimap(unfiltered, keyPredicate); - } - } - - /** - * Returns a multimap containing the mappings in {@code unfiltered} whose values - * satisfy a predicate. The returned multimap is a live view of - * {@code unfiltered}; changes to one affect the other. - * - *

The resulting multimap's views have iterators that don't support - * {@code remove()}, but all other methods are supported by the multimap and - * its views. When adding a value that doesn't satisfy the predicate, the - * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()} - * methods throw an {@link IllegalArgumentException}. - * - *

When methods such as {@code removeAll()} and {@code clear()} are called on - * the filtered multimap or its views, only mappings whose value satisfy the - * filter will be removed from the underlying multimap. - * - *

The returned multimap isn't threadsafe or serializable, even if - * {@code unfiltered} is. - * - *

Many of the filtered multimap's methods, such as {@code size()}, iterate - * across every key/value mapping in the underlying multimap and determine - * which satisfy the filter. When a live view is not needed, it may be - * faster to copy the filtered multimap and use the copy. - * - *

Warning: {@code valuePredicate} must be consistent with - * equals, as documented at {@link Predicate#apply}. Do not provide a - * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is - * inconsistent with equals. - * - * @since 11.0 - */ - @CheckReturnValue - public static Multimap filterValues( - Multimap unfiltered, final Predicate valuePredicate) { - return filterEntries(unfiltered, Maps.valuePredicateOnEntries(valuePredicate)); - } - - /** - * Returns a multimap containing the mappings in {@code unfiltered} whose values - * satisfy a predicate. The returned multimap is a live view of - * {@code unfiltered}; changes to one affect the other. - * - *

The resulting multimap's views have iterators that don't support - * {@code remove()}, but all other methods are supported by the multimap and - * its views. When adding a value that doesn't satisfy the predicate, the - * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()} - * methods throw an {@link IllegalArgumentException}. - * - *

When methods such as {@code removeAll()} and {@code clear()} are called on - * the filtered multimap or its views, only mappings whose value satisfy the - * filter will be removed from the underlying multimap. - * - *

The returned multimap isn't threadsafe or serializable, even if - * {@code unfiltered} is. - * - *

Many of the filtered multimap's methods, such as {@code size()}, iterate - * across every key/value mapping in the underlying multimap and determine - * which satisfy the filter. When a live view is not needed, it may be - * faster to copy the filtered multimap and use the copy. - * - *

Warning: {@code valuePredicate} must be consistent with - * equals, as documented at {@link Predicate#apply}. Do not provide a - * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is - * inconsistent with equals. - * - * @since 14.0 - */ - @CheckReturnValue - public static SetMultimap filterValues( - SetMultimap unfiltered, final Predicate valuePredicate) { - return filterEntries(unfiltered, Maps.valuePredicateOnEntries(valuePredicate)); - } - - /** - * Returns a multimap containing the mappings in {@code unfiltered} that - * satisfy a predicate. The returned multimap is a live view of - * {@code unfiltered}; changes to one affect the other. - * - *

The resulting multimap's views have iterators that don't support - * {@code remove()}, but all other methods are supported by the multimap and - * its views. When adding a key/value pair that doesn't satisfy the predicate, - * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()} - * methods throw an {@link IllegalArgumentException}. - * - *

When methods such as {@code removeAll()} and {@code clear()} are called on - * the filtered multimap or its views, only mappings whose keys satisfy the - * filter will be removed from the underlying multimap. - * - *

The returned multimap isn't threadsafe or serializable, even if - * {@code unfiltered} is. - * - *

Many of the filtered multimap's methods, such as {@code size()}, iterate - * across every key/value mapping in the underlying multimap and determine - * which satisfy the filter. When a live view is not needed, it may be - * faster to copy the filtered multimap and use the copy. - * - *

Warning: {@code entryPredicate} must be consistent with - * equals, as documented at {@link Predicate#apply}. - * - * @since 11.0 - */ - @CheckReturnValue - public static Multimap filterEntries( - Multimap unfiltered, Predicate> entryPredicate) { - checkNotNull(entryPredicate); - if (unfiltered instanceof SetMultimap) { - return filterEntries((SetMultimap) unfiltered, entryPredicate); - } - return (unfiltered instanceof FilteredMultimap) - ? filterFiltered((FilteredMultimap) unfiltered, entryPredicate) - : new FilteredEntryMultimap(checkNotNull(unfiltered), entryPredicate); - } - - /** - * Returns a multimap containing the mappings in {@code unfiltered} that - * satisfy a predicate. The returned multimap is a live view of - * {@code unfiltered}; changes to one affect the other. - * - *

The resulting multimap's views have iterators that don't support - * {@code remove()}, but all other methods are supported by the multimap and - * its views. When adding a key/value pair that doesn't satisfy the predicate, - * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()} - * methods throw an {@link IllegalArgumentException}. - * - *

When methods such as {@code removeAll()} and {@code clear()} are called on - * the filtered multimap or its views, only mappings whose keys satisfy the - * filter will be removed from the underlying multimap. - * - *

The returned multimap isn't threadsafe or serializable, even if - * {@code unfiltered} is. - * - *

Many of the filtered multimap's methods, such as {@code size()}, iterate - * across every key/value mapping in the underlying multimap and determine - * which satisfy the filter. When a live view is not needed, it may be - * faster to copy the filtered multimap and use the copy. - * - *

Warning: {@code entryPredicate} must be consistent with - * equals, as documented at {@link Predicate#apply}. - * - * @since 14.0 - */ - @CheckReturnValue - public static SetMultimap filterEntries( - SetMultimap unfiltered, Predicate> entryPredicate) { - checkNotNull(entryPredicate); - return (unfiltered instanceof FilteredSetMultimap) - ? filterFiltered((FilteredSetMultimap) unfiltered, entryPredicate) - : new FilteredEntrySetMultimap(checkNotNull(unfiltered), entryPredicate); - } - - /** - * Support removal operations when filtering a filtered multimap. Since a - * filtered multimap has iterators that don't support remove, passing one to - * the FilteredEntryMultimap constructor would lead to a multimap whose removal - * operations would fail. This method combines the predicates to avoid that - * problem. - */ - private static Multimap filterFiltered( - FilteredMultimap multimap, Predicate> entryPredicate) { - Predicate> predicate = Predicates.and(multimap.entryPredicate(), entryPredicate); - return new FilteredEntryMultimap(multimap.unfiltered(), predicate); - } - - /** - * Support removal operations when filtering a filtered multimap. Since a filtered multimap has - * iterators that don't support remove, passing one to the FilteredEntryMultimap constructor would - * lead to a multimap whose removal operations would fail. This method combines the predicates to - * avoid that problem. - */ - private static SetMultimap filterFiltered( - FilteredSetMultimap multimap, Predicate> entryPredicate) { - Predicate> predicate = Predicates.and(multimap.entryPredicate(), entryPredicate); - return new FilteredEntrySetMultimap(multimap.unfiltered(), predicate); - } - - static boolean equalsImpl(Multimap multimap, @Nullable Object object) { - if (object == multimap) { - return true; - } - if (object instanceof Multimap) { - Multimap that = (Multimap) object; - return multimap.asMap().equals(that.asMap()); - } - return false; - } - - // TODO(jlevy): Create methods that filter a SortedSetMultimap. -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Multiset.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Multiset.java deleted file mode 100644 index 940a216036ec..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Multiset.java +++ /dev/null @@ -1,446 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * A collection that supports order-independent equality, like {@link Set}, but - * may have duplicate elements. A multiset is also sometimes called a - * bag. - * - *

Elements of a multiset that are equal to one another are referred to as - * occurrences of the same single element. The total number of - * occurrences of an element in a multiset is called the count of that - * element (the terms "frequency" and "multiplicity" are equivalent, but not - * used in this API). Since the count of an element is represented as an {@code - * int}, a multiset may never contain more than {@link Integer#MAX_VALUE} - * occurrences of any one element. - * - *

{@code Multiset} refines the specifications of several methods from - * {@code Collection}. It also defines an additional query operation, {@link - * #count}, which returns the count of an element. There are five new - * bulk-modification operations, for example {@link #add(Object, int)}, to add - * or remove multiple occurrences of an element at once, or to set the count of - * an element to a specific value. These modification operations are optional, - * but implementations which support the standard collection operations {@link - * #add(Object)} or {@link #remove(Object)} are encouraged to implement the - * related methods as well. Finally, two collection views are provided: {@link - * #elementSet} contains the distinct elements of the multiset "with duplicates - * collapsed", and {@link #entrySet} is similar but contains {@link Entry - * Multiset.Entry} instances, each providing both a distinct element and the - * count of that element. - * - *

In addition to these required methods, implementations of {@code - * Multiset} are expected to provide two {@code static} creation methods: - * {@code create()}, returning an empty multiset, and {@code - * create(Iterable)}, returning a multiset containing the - * given initial elements. This is simply a refinement of {@code Collection}'s - * constructor recommendations, reflecting the new developments of Java 5. - * - *

As with other collection types, the modification operations are optional, - * and should throw {@link UnsupportedOperationException} when they are not - * implemented. Most implementations should support either all add operations - * or none of them, all removal operations or none of them, and if and only if - * all of these are supported, the {@code setCount} methods as well. - * - *

A multiset uses {@link Object#equals} to determine whether two instances - * should be considered "the same," unless specified otherwise by the - * implementation. - * - *

Common implementations include {@link ImmutableMultiset}, {@link - * HashMultiset}, and {@link ConcurrentHashMultiset}. - * - *

If your values may be zero, negative, or outside the range of an int, you - * may wish to use {@link com.google.common.util.concurrent.AtomicLongMap} - * instead. Note, however, that unlike {@code Multiset}, {@code AtomicLongMap} - * does not automatically remove zeros. - * - *

See the Guava User Guide article on - * {@code Multiset}. - * - * @author Kevin Bourrillion - * @since 2.0 - */ -@GwtCompatible -public interface Multiset extends Collection { - // Query Operations - - /** - * Returns the number of occurrences of an element in this multiset (the - * count of the element). Note that for an {@link Object#equals}-based - * multiset, this gives the same result as {@link Collections#frequency} - * (which would presumably perform more poorly). - * - *

Note: the utility method {@link Iterables#frequency} generalizes - * this operation; it correctly delegates to this method when dealing with a - * multiset, but it can also accept any other iterable type. - * - * @param element the element to count occurrences of - * @return the number of occurrences of the element in this multiset; possibly - * zero but never negative - */ - int count(@Nullable Object element); - - // Bulk Operations - - /** - * Adds a number of occurrences of an element to this multiset. Note that if - * {@code occurrences == 1}, this method has the identical effect to {@link - * #add(Object)}. This method is functionally equivalent (except in the case - * of overflow) to the call {@code addAll(Collections.nCopies(element, - * occurrences))}, which would presumably perform much more poorly. - * - * @param element the element to add occurrences of; may be null only if - * explicitly allowed by the implementation - * @param occurrences the number of occurrences of the element to add. May be - * zero, in which case no change will be made. - * @return the count of the element before the operation; possibly zero - * @throws IllegalArgumentException if {@code occurrences} is negative, or if - * this operation would result in more than {@link Integer#MAX_VALUE} - * occurrences of the element - * @throws NullPointerException if {@code element} is null and this - * implementation does not permit null elements. Note that if {@code - * occurrences} is zero, the implementation may opt to return normally. - */ - int add(@Nullable E element, int occurrences); - - /** - * Removes a number of occurrences of the specified element from this - * multiset. If the multiset contains fewer than this number of occurrences to - * begin with, all occurrences will be removed. Note that if - * {@code occurrences == 1}, this is functionally equivalent to the call - * {@code remove(element)}. - * - * @param element the element to conditionally remove occurrences of - * @param occurrences the number of occurrences of the element to remove. May - * be zero, in which case no change will be made. - * @return the count of the element before the operation; possibly zero - * @throws IllegalArgumentException if {@code occurrences} is negative - */ - int remove(@Nullable Object element, int occurrences); - - /** - * Adds or removes the necessary occurrences of an element such that the - * element attains the desired count. - * - * @param element the element to add or remove occurrences of; may be null - * only if explicitly allowed by the implementation - * @param count the desired count of the element in this multiset - * @return the count of the element before the operation; possibly zero - * @throws IllegalArgumentException if {@code count} is negative - * @throws NullPointerException if {@code element} is null and this - * implementation does not permit null elements. Note that if {@code - * count} is zero, the implementor may optionally return zero instead. - */ - int setCount(E element, int count); - - /** - * Conditionally sets the count of an element to a new value, as described in - * {@link #setCount(Object, int)}, provided that the element has the expected - * current count. If the current count is not {@code oldCount}, no change is - * made. - * - * @param element the element to conditionally set the count of; may be null - * only if explicitly allowed by the implementation - * @param oldCount the expected present count of the element in this multiset - * @param newCount the desired count of the element in this multiset - * @return {@code true} if the condition for modification was met. This - * implies that the multiset was indeed modified, unless - * {@code oldCount == newCount}. - * @throws IllegalArgumentException if {@code oldCount} or {@code newCount} is - * negative - * @throws NullPointerException if {@code element} is null and the - * implementation does not permit null elements. Note that if {@code - * oldCount} and {@code newCount} are both zero, the implementor may - * optionally return {@code true} instead. - */ - boolean setCount(E element, int oldCount, int newCount); - - // Views - - /** - * Returns the set of distinct elements contained in this multiset. The - * element set is backed by the same data as the multiset, so any change to - * either is immediately reflected in the other. The order of the elements in - * the element set is unspecified. - * - *

If the element set supports any removal operations, these necessarily - * cause all occurrences of the removed element(s) to be removed from - * the multiset. Implementations are not expected to support the add - * operations, although this is possible. - * - *

A common use for the element set is to find the number of distinct - * elements in the multiset: {@code elementSet().size()}. - * - * @return a view of the set of distinct elements in this multiset - */ - Set elementSet(); - - /** - * Returns a view of the contents of this multiset, grouped into {@code - * Multiset.Entry} instances, each providing an element of the multiset and - * the count of that element. This set contains exactly one entry for each - * distinct element in the multiset (thus it always has the same size as the - * {@link #elementSet}). The order of the elements in the element set is - * unspecified. - * - *

The entry set is backed by the same data as the multiset, so any change - * to either is immediately reflected in the other. However, multiset changes - * may or may not be reflected in any {@code Entry} instances already - * retrieved from the entry set (this is implementation-dependent). - * Furthermore, implementations are not required to support modifications to - * the entry set at all, and the {@code Entry} instances themselves don't - * even have methods for modification. See the specific implementation class - * for more details on how its entry set handles modifications. - * - * @return a set of entries representing the data of this multiset - */ - Set> entrySet(); - - /** - * An unmodifiable element-count pair for a multiset. The {@link - * Multiset#entrySet} method returns a view of the multiset whose elements - * are of this class. A multiset implementation may return Entry instances - * that are either live "read-through" views to the Multiset, or immutable - * snapshots. Note that this type is unrelated to the similarly-named type - * {@code Map.Entry}. - * - * @since 2.0 - */ - interface Entry { - - /** - * Returns the multiset element corresponding to this entry. Multiple calls - * to this method always return the same instance. - * - * @return the element corresponding to this entry - */ - E getElement(); - - /** - * Returns the count of the associated element in the underlying multiset. - * This count may either be an unchanging snapshot of the count at the time - * the entry was retrieved, or a live view of the current count of the - * element in the multiset, depending on the implementation. Note that in - * the former case, this method can never return zero, while in the latter, - * it will return zero if all occurrences of the element were since removed - * from the multiset. - * - * @return the count of the element; never negative - */ - int getCount(); - - /** - * {@inheritDoc} - * - *

Returns {@code true} if the given object is also a multiset entry and - * the two entries represent the same element and count. That is, two - * entries {@code a} and {@code b} are equal if:

   {@code
-     *
-     *   Objects.equal(a.getElement(), b.getElement())
-     *       && a.getCount() == b.getCount()}
- */ - @Override - // TODO(kevinb): check this wrt TreeMultiset? - boolean equals(Object o); - - /** - * {@inheritDoc} - * - *

The hash code of a multiset entry for element {@code element} and - * count {@code count} is defined as:

   {@code
-     *
-     *   ((element == null) ? 0 : element.hashCode()) ^ count}
- */ - @Override - int hashCode(); - - /** - * Returns the canonical string representation of this entry, defined as - * follows. If the count for this entry is one, this is simply the string - * representation of the corresponding element. Otherwise, it is the string - * representation of the element, followed by the three characters {@code - * " x "} (space, letter x, space), followed by the count. - */ - @Override - String toString(); - } - - // Comparison and hashing - - /** - * Compares the specified object with this multiset for equality. Returns - * {@code true} if the given object is also a multiset and contains equal - * elements with equal counts, regardless of order. - */ - @Override - // TODO(kevinb): caveats about equivalence-relation? - boolean equals(@Nullable Object object); - - /** - * Returns the hash code for this multiset. This is defined as the sum of - *
   {@code
-   *
-   *   ((element == null) ? 0 : element.hashCode()) ^ count(element)}
- * - *

over all distinct elements in the multiset. It follows that a multiset and - * its entry set always have the same hash code. - */ - @Override - int hashCode(); - - /** - * {@inheritDoc} - * - *

It is recommended, though not mandatory, that this method return the - * result of invoking {@link #toString} on the {@link #entrySet}, yielding a - * result such as {@code [a x 3, c, d x 2, e]}. - */ - @Override - String toString(); - - // Refined Collection Methods - - /** - * {@inheritDoc} - * - *

Elements that occur multiple times in the multiset will appear - * multiple times in this iterator, though not necessarily sequentially. - */ - @Override - Iterator iterator(); - - /** - * Determines whether this multiset contains the specified element. - * - *

This method refines {@link Collection#contains} to further specify that - * it may not throw an exception in response to {@code element} being - * null or of the wrong type. - * - * @param element the element to check for - * @return {@code true} if this multiset contains at least one occurrence of - * the element - */ - @Override - boolean contains(@Nullable Object element); - - /** - * Returns {@code true} if this multiset contains at least one occurrence of - * each element in the specified collection. - * - *

This method refines {@link Collection#containsAll} to further specify - * that it may not throw an exception in response to any of {@code - * elements} being null or of the wrong type. - * - *

Note: this method does not take into account the occurrence - * count of an element in the two collections; it may still return {@code - * true} even if {@code elements} contains several occurrences of an element - * and this multiset contains only one. This is no different than any other - * collection type like {@link List}, but it may be unexpected to the user of - * a multiset. - * - * @param elements the collection of elements to be checked for containment in - * this multiset - * @return {@code true} if this multiset contains at least one occurrence of - * each element contained in {@code elements} - * @throws NullPointerException if {@code elements} is null - */ - @Override - boolean containsAll(Collection elements); - - /** - * Adds a single occurrence of the specified element to this multiset. - * - *

This method refines {@link Collection#add}, which only ensures - * the presence of the element, to further specify that a successful call must - * always increment the count of the element, and the overall size of the - * collection, by one. - * - *

To both add the element and obtain the previous count of that element, - * use {@link #add(E, int) add}{@code (element, 1)} instead. - * - * @param element the element to add one occurrence of; may be null only if - * explicitly allowed by the implementation - * @return {@code true} always, since this call is required to modify the - * multiset, unlike other {@link Collection} types - * @throws NullPointerException if {@code element} is null and this - * implementation does not permit null elements - * @throws IllegalArgumentException if {@link Integer#MAX_VALUE} occurrences - * of {@code element} are already contained in this multiset - */ - @Override - boolean add(E element); - - /** - * Removes a single occurrence of the specified element from this - * multiset, if present. - * - *

This method refines {@link Collection#remove} to further specify that it - * may not throw an exception in response to {@code element} being null - * or of the wrong type. - * - *

To both remove the element and obtain the previous count of that element, - * use {@link #remove(E, int) remove}{@code (element, 1)} instead. - * - * @param element the element to remove one occurrence of - * @return {@code true} if an occurrence was found and removed - */ - @Override - boolean remove(@Nullable Object element); - - /** - * {@inheritDoc} - * - *

Note: This method ignores how often any element might appear in - * {@code c}, and only cares whether or not an element appears at all. - * If you wish to remove one occurrence in this multiset for every occurrence - * in {@code c}, see {@link Multisets#removeOccurrences(Multiset, Multiset)}. - * - *

This method refines {@link Collection#removeAll} to further specify that - * it may not throw an exception in response to any of {@code elements} - * being null or of the wrong type. - */ - @Override - boolean removeAll(Collection c); - - /** - * {@inheritDoc} - * - *

Note: This method ignores how often any element might appear in - * {@code c}, and only cares whether or not an element appears at all. - * If you wish to remove one occurrence in this multiset for every occurrence - * in {@code c}, see {@link Multisets#retainOccurrences(Multiset, Multiset)}. - * - *

This method refines {@link Collection#retainAll} to further specify that - * it may not throw an exception in response to any of {@code elements} - * being null or of the wrong type. - * - * @see Multisets#retainOccurrences(Multiset, Multiset) - */ - @Override - boolean retainAll(Collection c); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Multisets.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Multisets.java deleted file mode 100644 index 2f4d184c3659..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Multisets.java +++ /dev/null @@ -1,1128 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.CollectPreconditions.checkNonnegative; -import static com.google.common.collect.CollectPreconditions.checkRemove; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Objects; -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import com.google.common.collect.Multiset.Entry; -import com.google.common.primitives.Ints; - -import java.io.Serializable; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.Set; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * Provides static utility methods for creating and working with {@link - * Multiset} instances. - * - *

See the Guava User Guide article on - * {@code Multisets}. - * - * @author Kevin Bourrillion - * @author Mike Bostock - * @author Louis Wasserman - * @since 2.0 - */ -@GwtCompatible -public final class Multisets { - private Multisets() {} - - /** - * Returns an unmodifiable view of the specified multiset. Query operations on - * the returned multiset "read through" to the specified multiset, and - * attempts to modify the returned multiset result in an - * {@link UnsupportedOperationException}. - * - *

The returned multiset will be serializable if the specified multiset is - * serializable. - * - * @param multiset the multiset for which an unmodifiable view is to be - * generated - * @return an unmodifiable view of the multiset - */ - public static Multiset unmodifiableMultiset(Multiset multiset) { - if (multiset instanceof UnmodifiableMultiset || multiset instanceof ImmutableMultiset) { - // Since it's unmodifiable, the covariant cast is safe - @SuppressWarnings("unchecked") - Multiset result = (Multiset) multiset; - return result; - } - return new UnmodifiableMultiset(checkNotNull(multiset)); - } - - /** - * Simply returns its argument. - * - * @deprecated no need to use this - * @since 10.0 - */ - @Deprecated - public static Multiset unmodifiableMultiset(ImmutableMultiset multiset) { - return checkNotNull(multiset); - } - - static class UnmodifiableMultiset extends ForwardingMultiset implements Serializable { - final Multiset delegate; - - UnmodifiableMultiset(Multiset delegate) { - this.delegate = delegate; - } - - @SuppressWarnings("unchecked") - @Override - protected Multiset delegate() { - // This is safe because all non-covariant methods are overriden - return (Multiset) delegate; - } - - transient Set elementSet; - - Set createElementSet() { - return Collections.unmodifiableSet(delegate.elementSet()); - } - - @Override - public Set elementSet() { - Set es = elementSet; - return (es == null) ? elementSet = createElementSet() : es; - } - - transient Set> entrySet; - - @SuppressWarnings("unchecked") - @Override - public Set> entrySet() { - Set> es = entrySet; - return (es == null) - // Safe because the returned set is made unmodifiable and Entry - // itself is readonly - ? entrySet = (Set) Collections.unmodifiableSet(delegate.entrySet()) - : es; - } - - @SuppressWarnings("unchecked") - @Override - public Iterator iterator() { - // Safe because the returned Iterator is made unmodifiable - return (Iterator) Iterators.unmodifiableIterator(delegate.iterator()); - } - - @Override - public boolean add(E element) { - throw new UnsupportedOperationException(); - } - - @Override - public int add(E element, int occurences) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean addAll(Collection elementsToAdd) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean remove(Object element) { - throw new UnsupportedOperationException(); - } - - @Override - public int remove(Object element, int occurrences) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean removeAll(Collection elementsToRemove) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean retainAll(Collection elementsToRetain) { - throw new UnsupportedOperationException(); - } - - @Override - public void clear() { - throw new UnsupportedOperationException(); - } - - @Override - public int setCount(E element, int count) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean setCount(E element, int oldCount, int newCount) { - throw new UnsupportedOperationException(); - } - - private static final long serialVersionUID = 0; - } - - /** - * Returns an unmodifiable view of the specified sorted multiset. Query - * operations on the returned multiset "read through" to the specified - * multiset, and attempts to modify the returned multiset result in an {@link - * UnsupportedOperationException}. - * - *

The returned multiset will be serializable if the specified multiset is - * serializable. - * - * @param sortedMultiset the sorted multiset for which an unmodifiable view is - * to be generated - * @return an unmodifiable view of the multiset - * @since 11.0 - */ - @Beta - public static SortedMultiset unmodifiableSortedMultiset(SortedMultiset sortedMultiset) { - // it's in its own file so it can be emulated for GWT - return new UnmodifiableSortedMultiset(checkNotNull(sortedMultiset)); - } - - /** - * Returns an immutable multiset entry with the specified element and count. - * The entry will be serializable if {@code e} is. - * - * @param e the element to be associated with the returned entry - * @param n the count to be associated with the returned entry - * @throws IllegalArgumentException if {@code n} is negative - */ - public static Multiset.Entry immutableEntry(@Nullable E e, int n) { - return new ImmutableEntry(e, n); - } - - static class ImmutableEntry extends AbstractEntry implements Serializable { - @Nullable private final E element; - private final int count; - - ImmutableEntry(@Nullable E element, int count) { - this.element = element; - this.count = count; - checkNonnegative(count, "count"); - } - - @Override - @Nullable - public final E getElement() { - return element; - } - - @Override - public final int getCount() { - return count; - } - - public ImmutableEntry nextInBucket() { - return null; - } - - private static final long serialVersionUID = 0; - } - - /** - * Returns a view of the elements of {@code unfiltered} that satisfy a predicate. The returned - * multiset is a live view of {@code unfiltered}; changes to one affect the other. - * - *

The resulting multiset's iterators, and those of its {@code entrySet()} and - * {@code elementSet()}, do not support {@code remove()}. However, all other multiset methods - * supported by {@code unfiltered} are supported by the returned multiset. When given an element - * that doesn't satisfy the predicate, the multiset's {@code add()} and {@code addAll()} methods - * throw an {@link IllegalArgumentException}. When methods such as {@code removeAll()} and - * {@code clear()} are called on the filtered multiset, only elements that satisfy the filter - * will be removed from the underlying multiset. - * - *

The returned multiset isn't threadsafe or serializable, even if {@code unfiltered} is. - * - *

Many of the filtered multiset's methods, such as {@code size()}, iterate across every - * element in the underlying multiset and determine which elements satisfy the filter. When a - * live view is not needed, it may be faster to copy the returned multiset and use the - * copy. - * - *

Warning: {@code predicate} must be consistent with equals, as documented at - * {@link Predicate#apply}. Do not provide a predicate such as - * {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent with equals. (See - * {@link Iterables#filter(Iterable, Class)} for related functionality.) - * - * @since 14.0 - */ - @Beta - @CheckReturnValue - public static Multiset filter(Multiset unfiltered, Predicate predicate) { - if (unfiltered instanceof FilteredMultiset) { - // Support clear(), removeAll(), and retainAll() when filtering a filtered - // collection. - FilteredMultiset filtered = (FilteredMultiset) unfiltered; - Predicate combinedPredicate = Predicates.and(filtered.predicate, predicate); - return new FilteredMultiset(filtered.unfiltered, combinedPredicate); - } - return new FilteredMultiset(unfiltered, predicate); - } - - private static final class FilteredMultiset extends AbstractMultiset { - final Multiset unfiltered; - final Predicate predicate; - - FilteredMultiset(Multiset unfiltered, Predicate predicate) { - this.unfiltered = checkNotNull(unfiltered); - this.predicate = checkNotNull(predicate); - } - - @Override - public UnmodifiableIterator iterator() { - return Iterators.filter(unfiltered.iterator(), predicate); - } - - @Override - Set createElementSet() { - return Sets.filter(unfiltered.elementSet(), predicate); - } - - @Override - Set> createEntrySet() { - return Sets.filter( - unfiltered.entrySet(), - new Predicate>() { - @Override - public boolean apply(Entry entry) { - return predicate.apply(entry.getElement()); - } - }); - } - - @Override - Iterator> entryIterator() { - throw new AssertionError("should never be called"); - } - - @Override - int distinctElements() { - return elementSet().size(); - } - - @Override - public int count(@Nullable Object element) { - int count = unfiltered.count(element); - if (count > 0) { - @SuppressWarnings("unchecked") // element is equal to an E - E e = (E) element; - return predicate.apply(e) ? count : 0; - } - return 0; - } - - @Override - public int add(@Nullable E element, int occurrences) { - checkArgument( - predicate.apply(element), "Element %s does not match predicate %s", element, predicate); - return unfiltered.add(element, occurrences); - } - - @Override - public int remove(@Nullable Object element, int occurrences) { - checkNonnegative(occurrences, "occurrences"); - if (occurrences == 0) { - return count(element); - } else { - return contains(element) ? unfiltered.remove(element, occurrences) : 0; - } - } - - @Override - public void clear() { - elementSet().clear(); - } - } - - /** - * Returns the expected number of distinct elements given the specified - * elements. The number of distinct elements is only computed if {@code - * elements} is an instance of {@code Multiset}; otherwise the default value - * of 11 is returned. - */ - static int inferDistinctElements(Iterable elements) { - if (elements instanceof Multiset) { - return ((Multiset) elements).elementSet().size(); - } - return 11; // initial capacity will be rounded up to 16 - } - - /** - * Returns an unmodifiable view of the union of two multisets. - * In the returned multiset, the count of each element is the maximum - * of its counts in the two backing multisets. The iteration order of the - * returned multiset matches that of the element set of {@code multiset1} - * followed by the members of the element set of {@code multiset2} that are - * not contained in {@code multiset1}, with repeated occurrences of the same - * element appearing consecutively. - * - *

Results are undefined if {@code multiset1} and {@code multiset2} are - * based on different equivalence relations (as {@code HashMultiset} and - * {@code TreeMultiset} are). - * - * @since 14.0 - */ - @Beta - public static Multiset union( - final Multiset multiset1, final Multiset multiset2) { - checkNotNull(multiset1); - checkNotNull(multiset2); - - return new AbstractMultiset() { - @Override - public boolean contains(@Nullable Object element) { - return multiset1.contains(element) || multiset2.contains(element); - } - - @Override - public boolean isEmpty() { - return multiset1.isEmpty() && multiset2.isEmpty(); - } - - @Override - public int count(Object element) { - return Math.max(multiset1.count(element), multiset2.count(element)); - } - - @Override - Set createElementSet() { - return Sets.union(multiset1.elementSet(), multiset2.elementSet()); - } - - @Override - Iterator> entryIterator() { - final Iterator> iterator1 = multiset1.entrySet().iterator(); - final Iterator> iterator2 = multiset2.entrySet().iterator(); - // TODO(lowasser): consider making the entries live views - return new AbstractIterator>() { - @Override - protected Entry computeNext() { - if (iterator1.hasNext()) { - Entry entry1 = iterator1.next(); - E element = entry1.getElement(); - int count = Math.max(entry1.getCount(), multiset2.count(element)); - return immutableEntry(element, count); - } - while (iterator2.hasNext()) { - Entry entry2 = iterator2.next(); - E element = entry2.getElement(); - if (!multiset1.contains(element)) { - return immutableEntry(element, entry2.getCount()); - } - } - return endOfData(); - } - }; - } - - @Override - int distinctElements() { - return elementSet().size(); - } - }; - } - - /** - * Returns an unmodifiable view of the intersection of two multisets. - * In the returned multiset, the count of each element is the minimum - * of its counts in the two backing multisets, with elements that would have - * a count of 0 not included. The iteration order of the returned multiset - * matches that of the element set of {@code multiset1}, with repeated - * occurrences of the same element appearing consecutively. - * - *

Results are undefined if {@code multiset1} and {@code multiset2} are - * based on different equivalence relations (as {@code HashMultiset} and - * {@code TreeMultiset} are). - * - * @since 2.0 - */ - public static Multiset intersection( - final Multiset multiset1, final Multiset multiset2) { - checkNotNull(multiset1); - checkNotNull(multiset2); - - return new AbstractMultiset() { - @Override - public int count(Object element) { - int count1 = multiset1.count(element); - return (count1 == 0) ? 0 : Math.min(count1, multiset2.count(element)); - } - - @Override - Set createElementSet() { - return Sets.intersection(multiset1.elementSet(), multiset2.elementSet()); - } - - @Override - Iterator> entryIterator() { - final Iterator> iterator1 = multiset1.entrySet().iterator(); - // TODO(lowasser): consider making the entries live views - return new AbstractIterator>() { - @Override - protected Entry computeNext() { - while (iterator1.hasNext()) { - Entry entry1 = iterator1.next(); - E element = entry1.getElement(); - int count = Math.min(entry1.getCount(), multiset2.count(element)); - if (count > 0) { - return immutableEntry(element, count); - } - } - return endOfData(); - } - }; - } - - @Override - int distinctElements() { - return elementSet().size(); - } - }; - } - - /** - * Returns an unmodifiable view of the sum of two multisets. - * In the returned multiset, the count of each element is the sum of - * its counts in the two backing multisets. The iteration order of the - * returned multiset matches that of the element set of {@code multiset1} - * followed by the members of the element set of {@code multiset2} that - * are not contained in {@code multiset1}, with repeated occurrences of the - * same element appearing consecutively. - * - *

Results are undefined if {@code multiset1} and {@code multiset2} are - * based on different equivalence relations (as {@code HashMultiset} and - * {@code TreeMultiset} are). - * - * @since 14.0 - */ - @Beta - public static Multiset sum( - final Multiset multiset1, final Multiset multiset2) { - checkNotNull(multiset1); - checkNotNull(multiset2); - - // TODO(lowasser): consider making the entries live views - return new AbstractMultiset() { - @Override - public boolean contains(@Nullable Object element) { - return multiset1.contains(element) || multiset2.contains(element); - } - - @Override - public boolean isEmpty() { - return multiset1.isEmpty() && multiset2.isEmpty(); - } - - @Override - public int size() { - return multiset1.size() + multiset2.size(); - } - - @Override - public int count(Object element) { - return multiset1.count(element) + multiset2.count(element); - } - - @Override - Set createElementSet() { - return Sets.union(multiset1.elementSet(), multiset2.elementSet()); - } - - @Override - Iterator> entryIterator() { - final Iterator> iterator1 = multiset1.entrySet().iterator(); - final Iterator> iterator2 = multiset2.entrySet().iterator(); - return new AbstractIterator>() { - @Override - protected Entry computeNext() { - if (iterator1.hasNext()) { - Entry entry1 = iterator1.next(); - E element = entry1.getElement(); - int count = entry1.getCount() + multiset2.count(element); - return immutableEntry(element, count); - } - while (iterator2.hasNext()) { - Entry entry2 = iterator2.next(); - E element = entry2.getElement(); - if (!multiset1.contains(element)) { - return immutableEntry(element, entry2.getCount()); - } - } - return endOfData(); - } - }; - } - - @Override - int distinctElements() { - return elementSet().size(); - } - }; - } - - /** - * Returns an unmodifiable view of the difference of two multisets. - * In the returned multiset, the count of each element is the result of the - * zero-truncated subtraction of its count in the second multiset from - * its count in the first multiset, with elements that would have a count of - * 0 not included. The iteration order of the returned multiset matches that - * of the element set of {@code multiset1}, with repeated occurrences of the - * same element appearing consecutively. - * - *

Results are undefined if {@code multiset1} and {@code multiset2} are - * based on different equivalence relations (as {@code HashMultiset} and - * {@code TreeMultiset} are). - * - * @since 14.0 - */ - @Beta - public static Multiset difference( - final Multiset multiset1, final Multiset multiset2) { - checkNotNull(multiset1); - checkNotNull(multiset2); - - // TODO(lowasser): consider making the entries live views - return new AbstractMultiset() { - @Override - public int count(@Nullable Object element) { - int count1 = multiset1.count(element); - return (count1 == 0) ? 0 : Math.max(0, count1 - multiset2.count(element)); - } - - @Override - Iterator> entryIterator() { - final Iterator> iterator1 = multiset1.entrySet().iterator(); - return new AbstractIterator>() { - @Override - protected Entry computeNext() { - while (iterator1.hasNext()) { - Entry entry1 = iterator1.next(); - E element = entry1.getElement(); - int count = entry1.getCount() - multiset2.count(element); - if (count > 0) { - return immutableEntry(element, count); - } - } - return endOfData(); - } - }; - } - - @Override - int distinctElements() { - return Iterators.size(entryIterator()); - } - }; - } - - /** - * Returns {@code true} if {@code subMultiset.count(o) <= - * superMultiset.count(o)} for all {@code o}. - * - * @since 10.0 - */ - public static boolean containsOccurrences(Multiset superMultiset, Multiset subMultiset) { - checkNotNull(superMultiset); - checkNotNull(subMultiset); - for (Entry entry : subMultiset.entrySet()) { - int superCount = superMultiset.count(entry.getElement()); - if (superCount < entry.getCount()) { - return false; - } - } - return true; - } - - /** - * Modifies {@code multisetToModify} so that its count for an element - * {@code e} is at most {@code multisetToRetain.count(e)}. - * - *

To be precise, {@code multisetToModify.count(e)} is set to - * {@code Math.min(multisetToModify.count(e), - * multisetToRetain.count(e))}. This is similar to - * {@link #intersection(Multiset, Multiset) intersection} - * {@code (multisetToModify, multisetToRetain)}, but mutates - * {@code multisetToModify} instead of returning a view. - * - *

In contrast, {@code multisetToModify.retainAll(multisetToRetain)} keeps - * all occurrences of elements that appear at all in {@code - * multisetToRetain}, and deletes all occurrences of all other elements. - * - * @return {@code true} if {@code multisetToModify} was changed as a result - * of this operation - * @since 10.0 - */ - public static boolean retainOccurrences( - Multiset multisetToModify, Multiset multisetToRetain) { - return retainOccurrencesImpl(multisetToModify, multisetToRetain); - } - - /** - * Delegate implementation which cares about the element type. - */ - private static boolean retainOccurrencesImpl( - Multiset multisetToModify, Multiset occurrencesToRetain) { - checkNotNull(multisetToModify); - checkNotNull(occurrencesToRetain); - // Avoiding ConcurrentModificationExceptions is tricky. - Iterator> entryIterator = multisetToModify.entrySet().iterator(); - boolean changed = false; - while (entryIterator.hasNext()) { - Entry entry = entryIterator.next(); - int retainCount = occurrencesToRetain.count(entry.getElement()); - if (retainCount == 0) { - entryIterator.remove(); - changed = true; - } else if (retainCount < entry.getCount()) { - multisetToModify.setCount(entry.getElement(), retainCount); - changed = true; - } - } - return changed; - } - - /** - * For each occurrence of an element {@code e} in {@code occurrencesToRemove}, - * removes one occurrence of {@code e} in {@code multisetToModify}. - * - *

Equivalently, this method modifies {@code multisetToModify} so that - * {@code multisetToModify.count(e)} is set to - * {@code Math.max(0, multisetToModify.count(e) - - * Iterables.frequency(occurrencesToRemove, e))}. - * - *

This is not the same as {@code multisetToModify.} - * {@link Multiset#removeAll removeAll}{@code (occurrencesToRemove)}, which - * removes all occurrences of elements that appear in - * {@code occurrencesToRemove}. However, this operation is equivalent - * to, albeit sometimes more efficient than, the following:

   {@code
-   *
-   *   for (E e : occurrencesToRemove) {
-   *     multisetToModify.remove(e);
-   *   }}
- * - * @return {@code true} if {@code multisetToModify} was changed as a result of - * this operation - * @since 18.0 (present in 10.0 with a requirement that the second parameter - * be a {@code Multiset}) - */ - public static boolean removeOccurrences( - Multiset multisetToModify, Iterable occurrencesToRemove) { - if (occurrencesToRemove instanceof Multiset) { - return removeOccurrences(multisetToModify, (Multiset) occurrencesToRemove); - } else { - checkNotNull(multisetToModify); - checkNotNull(occurrencesToRemove); - boolean changed = false; - for (Object o : occurrencesToRemove) { - changed |= multisetToModify.remove(o); - } - return changed; - } - } - - /** - * For each occurrence of an element {@code e} in {@code occurrencesToRemove}, - * removes one occurrence of {@code e} in {@code multisetToModify}. - * - *

Equivalently, this method modifies {@code multisetToModify} so that - * {@code multisetToModify.count(e)} is set to - * {@code Math.max(0, multisetToModify.count(e) - - * occurrencesToRemove.count(e))}. - * - *

This is not the same as {@code multisetToModify.} - * {@link Multiset#removeAll removeAll}{@code (occurrencesToRemove)}, which - * removes all occurrences of elements that appear in - * {@code occurrencesToRemove}. However, this operation is equivalent - * to, albeit sometimes more efficient than, the following:

   {@code
-   *
-   *   for (E e : occurrencesToRemove) {
-   *     multisetToModify.remove(e);
-   *   }}
- * - * @return {@code true} if {@code multisetToModify} was changed as a result of - * this operation - * @since 10.0 (missing in 18.0 when only the overload taking an {@code Iterable} was present) - */ - public static boolean removeOccurrences( - Multiset multisetToModify, Multiset occurrencesToRemove) { - checkNotNull(multisetToModify); - checkNotNull(occurrencesToRemove); - - boolean changed = false; - Iterator> entryIterator = multisetToModify.entrySet().iterator(); - while (entryIterator.hasNext()) { - Entry entry = entryIterator.next(); - int removeCount = occurrencesToRemove.count(entry.getElement()); - if (removeCount >= entry.getCount()) { - entryIterator.remove(); - changed = true; - } else if (removeCount > 0) { - multisetToModify.remove(entry.getElement(), removeCount); - changed = true; - } - } - return changed; - } - - /** - * Implementation of the {@code equals}, {@code hashCode}, and - * {@code toString} methods of {@link Multiset.Entry}. - */ - abstract static class AbstractEntry implements Multiset.Entry { - /** - * Indicates whether an object equals this entry, following the behavior - * specified in {@link Multiset.Entry#equals}. - */ - @Override - public boolean equals(@Nullable Object object) { - if (object instanceof Multiset.Entry) { - Multiset.Entry that = (Multiset.Entry) object; - return this.getCount() == that.getCount() - && Objects.equal(this.getElement(), that.getElement()); - } - return false; - } - - /** - * Return this entry's hash code, following the behavior specified in - * {@link Multiset.Entry#hashCode}. - */ - @Override - public int hashCode() { - E e = getElement(); - return ((e == null) ? 0 : e.hashCode()) ^ getCount(); - } - - /** - * Returns a string representation of this multiset entry. The string - * representation consists of the associated element if the associated count - * is one, and otherwise the associated element followed by the characters - * " x " (space, x and space) followed by the count. Elements and counts are - * converted to strings as by {@code String.valueOf}. - */ - @Override - public String toString() { - String text = String.valueOf(getElement()); - int n = getCount(); - return (n == 1) ? text : (text + " x " + n); - } - } - - /** - * An implementation of {@link Multiset#equals}. - */ - static boolean equalsImpl(Multiset multiset, @Nullable Object object) { - if (object == multiset) { - return true; - } - if (object instanceof Multiset) { - Multiset that = (Multiset) object; - /* - * We can't simply check whether the entry sets are equal, since that - * approach fails when a TreeMultiset has a comparator that returns 0 - * when passed unequal elements. - */ - - if (multiset.size() != that.size() || multiset.entrySet().size() != that.entrySet().size()) { - return false; - } - for (Entry entry : that.entrySet()) { - if (multiset.count(entry.getElement()) != entry.getCount()) { - return false; - } - } - return true; - } - return false; - } - - /** - * An implementation of {@link Multiset#addAll}. - */ - static boolean addAllImpl(Multiset self, Collection elements) { - if (elements.isEmpty()) { - return false; - } - if (elements instanceof Multiset) { - Multiset that = cast(elements); - for (Entry entry : that.entrySet()) { - self.add(entry.getElement(), entry.getCount()); - } - } else { - Iterators.addAll(self, elements.iterator()); - } - return true; - } - - /** - * An implementation of {@link Multiset#removeAll}. - */ - static boolean removeAllImpl(Multiset self, Collection elementsToRemove) { - Collection collection = - (elementsToRemove instanceof Multiset) - ? ((Multiset) elementsToRemove).elementSet() - : elementsToRemove; - - return self.elementSet().removeAll(collection); - } - - /** - * An implementation of {@link Multiset#retainAll}. - */ - static boolean retainAllImpl(Multiset self, Collection elementsToRetain) { - checkNotNull(elementsToRetain); - Collection collection = - (elementsToRetain instanceof Multiset) - ? ((Multiset) elementsToRetain).elementSet() - : elementsToRetain; - - return self.elementSet().retainAll(collection); - } - - /** - * An implementation of {@link Multiset#setCount(Object, int)}. - */ - static int setCountImpl(Multiset self, E element, int count) { - checkNonnegative(count, "count"); - - int oldCount = self.count(element); - - int delta = count - oldCount; - if (delta > 0) { - self.add(element, delta); - } else if (delta < 0) { - self.remove(element, -delta); - } - - return oldCount; - } - - /** - * An implementation of {@link Multiset#setCount(Object, int, int)}. - */ - static boolean setCountImpl(Multiset self, E element, int oldCount, int newCount) { - checkNonnegative(oldCount, "oldCount"); - checkNonnegative(newCount, "newCount"); - - if (self.count(element) == oldCount) { - self.setCount(element, newCount); - return true; - } else { - return false; - } - } - - abstract static class ElementSet extends Sets.ImprovedAbstractSet { - abstract Multiset multiset(); - - @Override - public void clear() { - multiset().clear(); - } - - @Override - public boolean contains(Object o) { - return multiset().contains(o); - } - - @Override - public boolean containsAll(Collection c) { - return multiset().containsAll(c); - } - - @Override - public boolean isEmpty() { - return multiset().isEmpty(); - } - - @Override - public Iterator iterator() { - return new TransformedIterator, E>(multiset().entrySet().iterator()) { - @Override - E transform(Entry entry) { - return entry.getElement(); - } - }; - } - - @Override - public boolean remove(Object o) { - return multiset().remove(o, Integer.MAX_VALUE) > 0; - } - - @Override - public int size() { - return multiset().entrySet().size(); - } - } - - abstract static class EntrySet extends Sets.ImprovedAbstractSet> { - abstract Multiset multiset(); - - @Override - public boolean contains(@Nullable Object o) { - if (o instanceof Entry) { - /* - * The GWT compiler wrongly issues a warning here. - */ - @SuppressWarnings("cast") - Entry entry = (Entry) o; - if (entry.getCount() <= 0) { - return false; - } - int count = multiset().count(entry.getElement()); - return count == entry.getCount(); - } - return false; - } - - // GWT compiler warning; see contains(). - @SuppressWarnings("cast") - @Override - public boolean remove(Object object) { - if (object instanceof Multiset.Entry) { - Entry entry = (Entry) object; - Object element = entry.getElement(); - int entryCount = entry.getCount(); - if (entryCount != 0) { - // Safe as long as we never add a new entry, which we won't. - @SuppressWarnings("unchecked") - Multiset multiset = (Multiset) multiset(); - return multiset.setCount(element, entryCount, 0); - } - } - return false; - } - - @Override - public void clear() { - multiset().clear(); - } - } - - /** - * An implementation of {@link Multiset#iterator}. - */ - static Iterator iteratorImpl(Multiset multiset) { - return new MultisetIteratorImpl(multiset, multiset.entrySet().iterator()); - } - - static final class MultisetIteratorImpl implements Iterator { - private final Multiset multiset; - private final Iterator> entryIterator; - private Entry currentEntry; - - /** Count of subsequent elements equal to current element */ - private int laterCount; - - /** Count of all elements equal to current element */ - private int totalCount; - - private boolean canRemove; - - MultisetIteratorImpl(Multiset multiset, Iterator> entryIterator) { - this.multiset = multiset; - this.entryIterator = entryIterator; - } - - @Override - public boolean hasNext() { - return laterCount > 0 || entryIterator.hasNext(); - } - - @Override - public E next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - if (laterCount == 0) { - currentEntry = entryIterator.next(); - totalCount = laterCount = currentEntry.getCount(); - } - laterCount--; - canRemove = true; - return currentEntry.getElement(); - } - - @Override - public void remove() { - checkRemove(canRemove); - if (totalCount == 1) { - entryIterator.remove(); - } else { - multiset.remove(currentEntry.getElement()); - } - totalCount--; - canRemove = false; - } - } - - /** - * An implementation of {@link Multiset#size}. - */ - static int sizeImpl(Multiset multiset) { - long size = 0; - for (Entry entry : multiset.entrySet()) { - size += entry.getCount(); - } - return Ints.saturatedCast(size); - } - - /** - * Used to avoid http://bugs.sun.com/view_bug.do?bug_id=6558557 - */ - static Multiset cast(Iterable iterable) { - return (Multiset) iterable; - } - - private static final Ordering> DECREASING_COUNT_ORDERING = - new Ordering>() { - @Override - public int compare(Entry entry1, Entry entry2) { - return Ints.compare(entry2.getCount(), entry1.getCount()); - } - }; - - /** - * Returns a copy of {@code multiset} as an {@link ImmutableMultiset} whose iteration order is - * highest count first, with ties broken by the iteration order of the original multiset. - * - * @since 11.0 - */ - @Beta - public static ImmutableMultiset copyHighestCountFirst(Multiset multiset) { - List> sortedEntries = - Multisets.DECREASING_COUNT_ORDERING.immutableSortedCopy(multiset.entrySet()); - return ImmutableMultiset.copyFromEntries(sortedEntries); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/MutableClassToInstanceMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/MutableClassToInstanceMap.java deleted file mode 100644 index 4b4d771441ba..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/MutableClassToInstanceMap.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.collect.MapConstraints.ConstrainedMap; -import com.google.common.primitives.Primitives; - -import java.util.HashMap; -import java.util.Map; - -/** - * A mutable class-to-instance map backed by an arbitrary user-provided map. - * See also {@link ImmutableClassToInstanceMap}. - * - *

See the Guava User Guide article on - * {@code ClassToInstanceMap}. - * - * @author Kevin Bourrillion - * @since 2.0 - */ -public final class MutableClassToInstanceMap extends ConstrainedMap, B> - implements ClassToInstanceMap { - - /** - * Returns a new {@code MutableClassToInstanceMap} instance backed by a {@link - * HashMap} using the default initial capacity and load factor. - */ - public static MutableClassToInstanceMap create() { - return new MutableClassToInstanceMap(new HashMap, B>()); - } - - /** - * Returns a new {@code MutableClassToInstanceMap} instance backed by a given - * empty {@code backingMap}. The caller surrenders control of the backing map, - * and thus should not allow any direct references to it to remain accessible. - */ - public static MutableClassToInstanceMap create(Map, B> backingMap) { - return new MutableClassToInstanceMap(backingMap); - } - - private MutableClassToInstanceMap(Map, B> delegate) { - super(delegate, VALUE_CAN_BE_CAST_TO_KEY); - } - - private static final MapConstraint, Object> VALUE_CAN_BE_CAST_TO_KEY = - new MapConstraint, Object>() { - @Override - public void checkKeyValue(Class key, Object value) { - cast(key, value); - } - }; - - @Override - public T putInstance(Class type, T value) { - return cast(type, put(type, value)); - } - - @Override - public T getInstance(Class type) { - return cast(type, get(type)); - } - - private static T cast(Class type, B value) { - return Primitives.wrap(type).cast(value); - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/NaturalOrdering.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/NaturalOrdering.java deleted file mode 100644 index fbacf0186204..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/NaturalOrdering.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; - -/** An ordering that uses the natural order of the values. */ -@GwtCompatible(serializable = true) -@SuppressWarnings("unchecked") // TODO(kevinb): the right way to explain this?? -final class NaturalOrdering extends Ordering implements Serializable { - static final NaturalOrdering INSTANCE = new NaturalOrdering(); - - @Override - public int compare(Comparable left, Comparable right) { - checkNotNull(left); // for GWT - checkNotNull(right); - return left.compareTo(right); - } - - @Override - public Ordering reverse() { - return (Ordering) ReverseNaturalOrdering.INSTANCE; - } - - // preserving singleton-ness gives equals()/hashCode() for free - private Object readResolve() { - return INSTANCE; - } - - @Override - public String toString() { - return "Ordering.natural()"; - } - - private NaturalOrdering() {} - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/NullsFirstOrdering.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/NullsFirstOrdering.java deleted file mode 100644 index 28d8fece483e..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/NullsFirstOrdering.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; - -import javax.annotation.Nullable; - -/** An ordering that treats {@code null} as less than all other values. */ -@GwtCompatible(serializable = true) -final class NullsFirstOrdering extends Ordering implements Serializable { - final Ordering ordering; - - NullsFirstOrdering(Ordering ordering) { - this.ordering = ordering; - } - - @Override - public int compare(@Nullable T left, @Nullable T right) { - if (left == right) { - return 0; - } - if (left == null) { - return RIGHT_IS_GREATER; - } - if (right == null) { - return LEFT_IS_GREATER; - } - return ordering.compare(left, right); - } - - @Override - public Ordering reverse() { - // ordering.reverse() might be optimized, so let it do its thing - return ordering.reverse().nullsLast(); - } - - @SuppressWarnings("unchecked") // still need the right way to explain this - @Override - public Ordering nullsFirst() { - return (Ordering) this; - } - - @Override - public Ordering nullsLast() { - return ordering.nullsLast(); - } - - @Override - public boolean equals(@Nullable Object object) { - if (object == this) { - return true; - } - if (object instanceof NullsFirstOrdering) { - NullsFirstOrdering that = (NullsFirstOrdering) object; - return this.ordering.equals(that.ordering); - } - return false; - } - - @Override - public int hashCode() { - return ordering.hashCode() ^ 957692532; // meaningless - } - - @Override - public String toString() { - return ordering + ".nullsFirst()"; - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/NullsLastOrdering.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/NullsLastOrdering.java deleted file mode 100644 index a4b39db52521..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/NullsLastOrdering.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; - -import javax.annotation.Nullable; - -/** An ordering that treats {@code null} as greater than all other values. */ -@GwtCompatible(serializable = true) -final class NullsLastOrdering extends Ordering implements Serializable { - final Ordering ordering; - - NullsLastOrdering(Ordering ordering) { - this.ordering = ordering; - } - - @Override - public int compare(@Nullable T left, @Nullable T right) { - if (left == right) { - return 0; - } - if (left == null) { - return LEFT_IS_GREATER; - } - if (right == null) { - return RIGHT_IS_GREATER; - } - return ordering.compare(left, right); - } - - @Override - public Ordering reverse() { - // ordering.reverse() might be optimized, so let it do its thing - return ordering.reverse().nullsFirst(); - } - - @Override - public Ordering nullsFirst() { - return ordering.nullsFirst(); - } - - @SuppressWarnings("unchecked") // still need the right way to explain this - @Override - public Ordering nullsLast() { - return (Ordering) this; - } - - @Override - public boolean equals(@Nullable Object object) { - if (object == this) { - return true; - } - if (object instanceof NullsLastOrdering) { - NullsLastOrdering that = (NullsLastOrdering) object; - return this.ordering.equals(that.ordering); - } - return false; - } - - @Override - public int hashCode() { - return ordering.hashCode() ^ -921210296; // meaningless - } - - @Override - public String toString() { - return ordering + ".nullsLast()"; - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ObjectArrays.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ObjectArrays.java deleted file mode 100644 index 23280025f1d4..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ObjectArrays.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkPositionIndexes; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; - -import java.lang.reflect.Array; -import java.util.Collection; - -import javax.annotation.Nullable; - -/** - * Static utility methods pertaining to object arrays. - * - * @author Kevin Bourrillion - * @since 2.0 - */ -@GwtCompatible(emulated = true) -public final class ObjectArrays { - static final Object[] EMPTY_ARRAY = new Object[0]; - - private ObjectArrays() {} - - /** - * Returns a new array of the given length with the specified component type. - * - * @param type the component type - * @param length the length of the new array - */ - @GwtIncompatible("Array.newInstance(Class, int)") - @SuppressWarnings("unchecked") - public static T[] newArray(Class type, int length) { - return (T[]) Array.newInstance(type, length); - } - - /** - * Returns a new array of the given length with the same type as a reference - * array. - * - * @param reference any array of the desired type - * @param length the length of the new array - */ - public static T[] newArray(T[] reference, int length) { - return Platform.newArray(reference, length); - } - - /** - * Returns a new array that contains the concatenated contents of two arrays. - * - * @param first the first array of elements to concatenate - * @param second the second array of elements to concatenate - * @param type the component type of the returned array - */ - @GwtIncompatible("Array.newInstance(Class, int)") - public static T[] concat(T[] first, T[] second, Class type) { - T[] result = newArray(type, first.length + second.length); - System.arraycopy(first, 0, result, 0, first.length); - System.arraycopy(second, 0, result, first.length, second.length); - return result; - } - - /** - * Returns a new array that prepends {@code element} to {@code array}. - * - * @param element the element to prepend to the front of {@code array} - * @param array the array of elements to append - * @return an array whose size is one larger than {@code array}, with - * {@code element} occupying the first position, and the - * elements of {@code array} occupying the remaining elements. - */ - public static T[] concat(@Nullable T element, T[] array) { - T[] result = newArray(array, array.length + 1); - result[0] = element; - System.arraycopy(array, 0, result, 1, array.length); - return result; - } - - /** - * Returns a new array that appends {@code element} to {@code array}. - * - * @param array the array of elements to prepend - * @param element the element to append to the end - * @return an array whose size is one larger than {@code array}, with - * the same contents as {@code array}, plus {@code element} occupying the - * last position. - */ - public static T[] concat(T[] array, @Nullable T element) { - T[] result = arraysCopyOf(array, array.length + 1); - result[array.length] = element; - return result; - } - - /** GWT safe version of Arrays.copyOf. */ - static T[] arraysCopyOf(T[] original, int newLength) { - T[] copy = newArray(original, newLength); - System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); - return copy; - } - - /** - * Returns an array containing all of the elements in the specified - * collection; the runtime type of the returned array is that of the specified - * array. If the collection fits in the specified array, it is returned - * therein. Otherwise, a new array is allocated with the runtime type of the - * specified array and the size of the specified collection. - * - *

If the collection fits in the specified array with room to spare (i.e., - * the array has more elements than the collection), the element in the array - * immediately following the end of the collection is set to {@code null}. - * This is useful in determining the length of the collection only if - * the caller knows that the collection does not contain any null elements. - * - *

This method returns the elements in the order they are returned by the - * collection's iterator. - * - *

TODO(kevinb): support concurrently modified collections? - * - * @param c the collection for which to return an array of elements - * @param array the array in which to place the collection elements - * @throws ArrayStoreException if the runtime type of the specified array is - * not a supertype of the runtime type of every element in the specified - * collection - */ - static T[] toArrayImpl(Collection c, T[] array) { - int size = c.size(); - if (array.length < size) { - array = newArray(array, size); - } - fillArray(c, array); - if (array.length > size) { - array[size] = null; - } - return array; - } - - /** - * Implementation of {@link Collection#toArray(Object[])} for collections backed by an object - * array. the runtime type of the returned array is that of the specified array. If the collection - * fits in the specified array, it is returned therein. Otherwise, a new array is allocated with - * the runtime type of the specified array and the size of the specified collection. - * - *

If the collection fits in the specified array with room to spare (i.e., the array has more - * elements than the collection), the element in the array immediately following the end of the - * collection is set to {@code null}. This is useful in determining the length of the collection - * only if the caller knows that the collection does not contain any null elements. - */ - static T[] toArrayImpl(Object[] src, int offset, int len, T[] dst) { - checkPositionIndexes(offset, offset + len, src.length); - if (dst.length < len) { - dst = newArray(dst, len); - } else if (dst.length > len) { - dst[len] = null; - } - System.arraycopy(src, offset, dst, 0, len); - return dst; - } - - /** - * Returns an array containing all of the elements in the specified - * collection. This method returns the elements in the order they are returned - * by the collection's iterator. The returned array is "safe" in that no - * references to it are maintained by the collection. The caller is thus free - * to modify the returned array. - * - *

This method assumes that the collection size doesn't change while the - * method is running. - * - *

TODO(kevinb): support concurrently modified collections? - * - * @param c the collection for which to return an array of elements - */ - static Object[] toArrayImpl(Collection c) { - return fillArray(c, new Object[c.size()]); - } - - /** - * Returns a copy of the specified subrange of the specified array that is literally an Object[], - * and not e.g. a {@code String[]}. - */ - static Object[] copyAsObjectArray(Object[] elements, int offset, int length) { - checkPositionIndexes(offset, offset + length, elements.length); - if (length == 0) { - return EMPTY_ARRAY; - } - Object[] result = new Object[length]; - System.arraycopy(elements, offset, result, 0, length); - return result; - } - - private static Object[] fillArray(Iterable elements, Object[] array) { - int i = 0; - for (Object element : elements) { - array[i++] = element; - } - return array; - } - - /** - * Swaps {@code array[i]} with {@code array[j]}. - */ - static void swap(Object[] array, int i, int j) { - Object temp = array[i]; - array[i] = array[j]; - array[j] = temp; - } - - static Object[] checkElementsNotNull(Object... array) { - return checkElementsNotNull(array, array.length); - } - - static Object[] checkElementsNotNull(Object[] array, int length) { - for (int i = 0; i < length; i++) { - checkElementNotNull(array[i], i); - } - return array; - } - - // We do this instead of Preconditions.checkNotNull to save boxing and array - // creation cost. - static Object checkElementNotNull(Object element, int index) { - if (element == null) { - throw new NullPointerException("at index " + index); - } - return element; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Ordering.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Ordering.java deleted file mode 100644 index f31a422e2cb0..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Ordering.java +++ /dev/null @@ -1,968 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.CollectPreconditions.checkNonnegative; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Function; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.SortedMap; -import java.util.SortedSet; -import java.util.TreeSet; -import java.util.concurrent.atomic.AtomicInteger; - -import javax.annotation.Nullable; - -/** - * A comparator, with additional methods to support common operations. This is an "enriched" - * version of {@code Comparator}, in the same sense that {@link FluentIterable} is an enriched - * {@link Iterable}. - * - *

Three types of methods

- * - * Like other fluent types, there are three types of methods present: methods for acquiring, - * chaining, and using. - * - *

Acquiring

- * - *

The common ways to get an instance of {@code Ordering} are: - * - *

    - *
  • Subclass it and implement {@link #compare} instead of implementing {@link Comparator} - * directly - *
  • Pass a pre-existing {@link Comparator} instance to {@link #from(Comparator)} - *
  • Use the natural ordering, {@link Ordering#natural} - *
- * - *

Chaining

- * - *

Then you can use the chaining methods to get an altered version of that {@code - * Ordering}, including: - * - *

    - *
  • {@link #reverse} - *
  • {@link #compound(Comparator)} - *
  • {@link #onResultOf(Function)} - *
  • {@link #nullsFirst} / {@link #nullsLast} - *
- * - *

Using

- * - *

Finally, use the resulting {@code Ordering} anywhere a {@link Comparator} is required, or use - * any of its special operations, such as:

- * - *
    - *
  • {@link #immutableSortedCopy} - *
  • {@link #isOrdered} / {@link #isStrictlyOrdered} - *
  • {@link #min} / {@link #max} - *
- * - *

Understanding complex orderings

- * - *

Complex chained orderings like the following example can be challenging to understand. - *

   {@code
- *
- *   Ordering ordering =
- *       Ordering.natural()
- *           .nullsFirst()
- *           .onResultOf(getBarFunction)
- *           .nullsLast();}
- * - * Note that each chaining method returns a new ordering instance which is backed by the previous - * instance, but has the chance to act on values before handing off to that backing - * instance. As a result, it usually helps to read chained ordering expressions backwards. - * For example, when {@code compare} is called on the above ordering: - * - *
    - *
  1. First, if only one {@code Foo} is null, that null value is treated as greater - *
  2. Next, non-null {@code Foo} values are passed to {@code getBarFunction} (we will be - * comparing {@code Bar} values from now on) - *
  3. Next, if only one {@code Bar} is null, that null value is treated as lesser - *
  4. Finally, natural ordering is used (i.e. the result of {@code Bar.compareTo(Bar)} is - * returned) - *
- * - *

Alas, {@link #reverse} is a little different. As you read backwards through a chain and - * encounter a call to {@code reverse}, continue working backwards until a result is determined, - * and then reverse that result. - * - *

Additional notes

- * - *

Except as noted, the orderings returned by the factory methods of this - * class are serializable if and only if the provided instances that back them - * are. For example, if {@code ordering} and {@code function} can themselves be - * serialized, then {@code ordering.onResultOf(function)} can as well. - * - *

See the Guava User Guide article on - * {@code Ordering}. - * - * @author Jesse Wilson - * @author Kevin Bourrillion - * @since 2.0 - */ -@GwtCompatible -public abstract class Ordering implements Comparator { - // Natural order - - /** - * Returns a serializable ordering that uses the natural order of the values. - * The ordering throws a {@link NullPointerException} when passed a null - * parameter. - * - *

The type specification is {@code }, instead of - * the technically correct {@code >}, to - * support legacy types from before Java 5. - */ - @GwtCompatible(serializable = true) - @SuppressWarnings("unchecked") // TODO(kevinb): right way to explain this?? - public static Ordering natural() { - return (Ordering) NaturalOrdering.INSTANCE; - } - - // Static factories - - /** - * Returns an ordering based on an existing comparator instance. Note - * that it is unnecessary to create a new anonymous inner class - * implementing {@code Comparator} just to pass it in here. Instead, simply - * subclass {@code Ordering} and implement its {@code compare} method - * directly. - * - * @param comparator the comparator that defines the order - * @return comparator itself if it is already an {@code Ordering}; otherwise - * an ordering that wraps that comparator - */ - @GwtCompatible(serializable = true) - public static Ordering from(Comparator comparator) { - return (comparator instanceof Ordering) - ? (Ordering) comparator - : new ComparatorOrdering(comparator); - } - - /** - * Simply returns its argument. - * - * @deprecated no need to use this - */ - @GwtCompatible(serializable = true) - @Deprecated - public static Ordering from(Ordering ordering) { - return checkNotNull(ordering); - } - - /** - * Returns an ordering that compares objects according to the order in - * which they appear in the given list. Only objects present in the list - * (according to {@link Object#equals}) may be compared. This comparator - * imposes a "partial ordering" over the type {@code T}. Subsequent changes - * to the {@code valuesInOrder} list will have no effect on the returned - * comparator. Null values in the list are not supported. - * - *

The returned comparator throws an {@link ClassCastException} when it - * receives an input parameter that isn't among the provided values. - * - *

The generated comparator is serializable if all the provided values are - * serializable. - * - * @param valuesInOrder the values that the returned comparator will be able - * to compare, in the order the comparator should induce - * @return the comparator described above - * @throws NullPointerException if any of the provided values is null - * @throws IllegalArgumentException if {@code valuesInOrder} contains any - * duplicate values (according to {@link Object#equals}) - */ - @GwtCompatible(serializable = true) - public static Ordering explicit(List valuesInOrder) { - return new ExplicitOrdering(valuesInOrder); - } - - /** - * Returns an ordering that compares objects according to the order in - * which they are given to this method. Only objects present in the argument - * list (according to {@link Object#equals}) may be compared. This comparator - * imposes a "partial ordering" over the type {@code T}. Null values in the - * argument list are not supported. - * - *

The returned comparator throws a {@link ClassCastException} when it - * receives an input parameter that isn't among the provided values. - * - *

The generated comparator is serializable if all the provided values are - * serializable. - * - * @param leastValue the value which the returned comparator should consider - * the "least" of all values - * @param remainingValuesInOrder the rest of the values that the returned - * comparator will be able to compare, in the order the comparator should - * follow - * @return the comparator described above - * @throws NullPointerException if any of the provided values is null - * @throws IllegalArgumentException if any duplicate values (according to - * {@link Object#equals(Object)}) are present among the method arguments - */ - @GwtCompatible(serializable = true) - public static Ordering explicit(T leastValue, T... remainingValuesInOrder) { - return explicit(Lists.asList(leastValue, remainingValuesInOrder)); - } - - // Ordering singletons - - /** - * Returns an ordering which treats all values as equal, indicating "no - * ordering." Passing this ordering to any stable sort algorithm - * results in no change to the order of elements. Note especially that {@link - * #sortedCopy} and {@link #immutableSortedCopy} are stable, and in the - * returned instance these are implemented by simply copying the source list. - * - *

Example:

   {@code
-   *
-   *   Ordering.allEqual().nullsLast().sortedCopy(
-   *       asList(t, null, e, s, null, t, null))}
- * - *

Assuming {@code t}, {@code e} and {@code s} are non-null, this returns - * {@code [t, e, s, t, null, null, null]} regardlesss of the true comparison - * order of those three values (which might not even implement {@link - * Comparable} at all). - * - *

Warning: by definition, this comparator is not consistent with - * equals (as defined {@linkplain Comparator here}). Avoid its use in - * APIs, such as {@link TreeSet#TreeSet(Comparator)}, where such consistency - * is expected. - * - *

The returned comparator is serializable. - * - * @since 13.0 - */ - @GwtCompatible(serializable = true) - @SuppressWarnings("unchecked") - public static Ordering allEqual() { - return AllEqualOrdering.INSTANCE; - } - - /** - * Returns an ordering that compares objects by the natural ordering of their - * string representations as returned by {@code toString()}. It does not - * support null values. - * - *

The comparator is serializable. - */ - @GwtCompatible(serializable = true) - public static Ordering usingToString() { - return UsingToStringOrdering.INSTANCE; - } - - /** - * Returns an arbitrary ordering over all objects, for which {@code compare(a, - * b) == 0} implies {@code a == b} (identity equality). There is no meaning - * whatsoever to the order imposed, but it is constant for the life of the VM. - * - *

Because the ordering is identity-based, it is not "consistent with - * {@link Object#equals(Object)}" as defined by {@link Comparator}. Use - * caution when building a {@link SortedSet} or {@link SortedMap} from it, as - * the resulting collection will not behave exactly according to spec. - * - *

This ordering is not serializable, as its implementation relies on - * {@link System#identityHashCode(Object)}, so its behavior cannot be - * preserved across serialization. - * - * @since 2.0 - */ - public static Ordering arbitrary() { - return ArbitraryOrderingHolder.ARBITRARY_ORDERING; - } - - private static class ArbitraryOrderingHolder { - static final Ordering ARBITRARY_ORDERING = new ArbitraryOrdering(); - } - - @VisibleForTesting - static class ArbitraryOrdering extends Ordering { - - @SuppressWarnings("deprecation") // TODO(kevinb): ? - private Map uids = - Platform.tryWeakKeys(new MapMaker()) - .makeComputingMap( - new Function() { - final AtomicInteger counter = new AtomicInteger(0); - - @Override - public Integer apply(Object from) { - return counter.getAndIncrement(); - } - }); - - @Override - public int compare(Object left, Object right) { - if (left == right) { - return 0; - } else if (left == null) { - return -1; - } else if (right == null) { - return 1; - } - int leftCode = identityHashCode(left); - int rightCode = identityHashCode(right); - if (leftCode != rightCode) { - return leftCode < rightCode ? -1 : 1; - } - - // identityHashCode collision (rare, but not as rare as you'd think) - int result = uids.get(left).compareTo(uids.get(right)); - if (result == 0) { - throw new AssertionError(); // extremely, extremely unlikely. - } - return result; - } - - @Override - public String toString() { - return "Ordering.arbitrary()"; - } - - /* - * We need to be able to mock identityHashCode() calls for tests, because it - * can take 1-10 seconds to find colliding objects. Mocking frameworks that - * can do magic to mock static method calls still can't do so for a system - * class, so we need the indirection. In production, Hotspot should still - * recognize that the call is 1-morphic and should still be willing to - * inline it if necessary. - */ - int identityHashCode(Object object) { - return System.identityHashCode(object); - } - } - - // Constructor - - /** - * Constructs a new instance of this class (only invokable by the subclass - * constructor, typically implicit). - */ - protected Ordering() {} - - // Instance-based factories (and any static equivalents) - - /** - * Returns the reverse of this ordering; the {@code Ordering} equivalent to - * {@link Collections#reverseOrder(Comparator)}. - */ - // type parameter lets us avoid the extra in statements like: - // Ordering o = Ordering.natural().reverse(); - @GwtCompatible(serializable = true) - public Ordering reverse() { - return new ReverseOrdering(this); - } - - /** - * Returns an ordering that treats {@code null} as less than all other values - * and uses {@code this} to compare non-null values. - */ - // type parameter lets us avoid the extra in statements like: - // Ordering o = Ordering.natural().nullsFirst(); - @GwtCompatible(serializable = true) - public Ordering nullsFirst() { - return new NullsFirstOrdering(this); - } - - /** - * Returns an ordering that treats {@code null} as greater than all other - * values and uses this ordering to compare non-null values. - */ - // type parameter lets us avoid the extra in statements like: - // Ordering o = Ordering.natural().nullsLast(); - @GwtCompatible(serializable = true) - public Ordering nullsLast() { - return new NullsLastOrdering(this); - } - - /** - * Returns a new ordering on {@code F} which orders elements by first applying - * a function to them, then comparing those results using {@code this}. For - * example, to compare objects by their string forms, in a case-insensitive - * manner, use:
   {@code
-   *
-   *   Ordering.from(String.CASE_INSENSITIVE_ORDER)
-   *       .onResultOf(Functions.toStringFunction())}
- */ - @GwtCompatible(serializable = true) - public Ordering onResultOf(Function function) { - return new ByFunctionOrdering(function, this); - } - - Ordering> onKeys() { - return onResultOf(Maps.keyFunction()); - } - - /** - * Returns an ordering which first uses the ordering {@code this}, but which - * in the event of a "tie", then delegates to {@code secondaryComparator}. - * For example, to sort a bug list first by status and second by priority, you - * might use {@code byStatus.compound(byPriority)}. For a compound ordering - * with three or more components, simply chain multiple calls to this method. - * - *

An ordering produced by this method, or a chain of calls to this method, - * is equivalent to one created using {@link Ordering#compound(Iterable)} on - * the same component comparators. - */ - @GwtCompatible(serializable = true) - public Ordering compound(Comparator secondaryComparator) { - return new CompoundOrdering(this, checkNotNull(secondaryComparator)); - } - - /** - * Returns an ordering which tries each given comparator in order until a - * non-zero result is found, returning that result, and returning zero only if - * all comparators return zero. The returned ordering is based on the state of - * the {@code comparators} iterable at the time it was provided to this - * method. - * - *

The returned ordering is equivalent to that produced using {@code - * Ordering.from(comp1).compound(comp2).compound(comp3) . . .}. - * - *

Warning: Supplying an argument with undefined iteration order, - * such as a {@link HashSet}, will produce non-deterministic results. - * - * @param comparators the comparators to try in order - */ - @GwtCompatible(serializable = true) - public static Ordering compound(Iterable> comparators) { - return new CompoundOrdering(comparators); - } - - /** - * Returns a new ordering which sorts iterables by comparing corresponding - * elements pairwise until a nonzero result is found; imposes "dictionary - * order". If the end of one iterable is reached, but not the other, the - * shorter iterable is considered to be less than the longer one. For example, - * a lexicographical natural ordering over integers considers {@code - * [] < [1] < [1, 1] < [1, 2] < [2]}. - * - *

Note that {@code ordering.lexicographical().reverse()} is not - * equivalent to {@code ordering.reverse().lexicographical()} (consider how - * each would order {@code [1]} and {@code [1, 1]}). - * - * @since 2.0 - */ - @GwtCompatible(serializable = true) - // type parameter lets us avoid the extra in statements like: - // Ordering> o = - // Ordering.natural().lexicographical(); - public Ordering> lexicographical() { - /* - * Note that technically the returned ordering should be capable of - * handling not just {@code Iterable} instances, but also any {@code - * Iterable}. However, the need for this comes up so rarely - * that it doesn't justify making everyone else deal with the very ugly - * wildcard. - */ - return new LexicographicalOrdering(this); - } - - // Regular instance methods - - // Override to add @Nullable - @Override - public abstract int compare(@Nullable T left, @Nullable T right); - - /** - * Returns the least of the specified values according to this ordering. If - * there are multiple least values, the first of those is returned. The - * iterator will be left exhausted: its {@code hasNext()} method will return - * {@code false}. - * - * @param iterator the iterator whose minimum element is to be determined - * @throws NoSuchElementException if {@code iterator} is empty - * @throws ClassCastException if the parameters are not mutually - * comparable under this ordering. - * - * @since 11.0 - */ - public E min(Iterator iterator) { - // let this throw NoSuchElementException as necessary - E minSoFar = iterator.next(); - - while (iterator.hasNext()) { - minSoFar = min(minSoFar, iterator.next()); - } - - return minSoFar; - } - - /** - * Returns the least of the specified values according to this ordering. If - * there are multiple least values, the first of those is returned. - * - * @param iterable the iterable whose minimum element is to be determined - * @throws NoSuchElementException if {@code iterable} is empty - * @throws ClassCastException if the parameters are not mutually - * comparable under this ordering. - */ - public E min(Iterable iterable) { - return min(iterable.iterator()); - } - - /** - * Returns the lesser of the two values according to this ordering. If the - * values compare as 0, the first is returned. - * - *

Implementation note: this method is invoked by the default - * implementations of the other {@code min} overloads, so overriding it will - * affect their behavior. - * - * @param a value to compare, returned if less than or equal to b. - * @param b value to compare. - * @throws ClassCastException if the parameters are not mutually - * comparable under this ordering. - */ - public E min(@Nullable E a, @Nullable E b) { - return (compare(a, b) <= 0) ? a : b; - } - - /** - * Returns the least of the specified values according to this ordering. If - * there are multiple least values, the first of those is returned. - * - * @param a value to compare, returned if less than or equal to the rest. - * @param b value to compare - * @param c value to compare - * @param rest values to compare - * @throws ClassCastException if the parameters are not mutually - * comparable under this ordering. - */ - public E min(@Nullable E a, @Nullable E b, @Nullable E c, E... rest) { - E minSoFar = min(min(a, b), c); - - for (E r : rest) { - minSoFar = min(minSoFar, r); - } - - return minSoFar; - } - - /** - * Returns the greatest of the specified values according to this ordering. If - * there are multiple greatest values, the first of those is returned. The - * iterator will be left exhausted: its {@code hasNext()} method will return - * {@code false}. - * - * @param iterator the iterator whose maximum element is to be determined - * @throws NoSuchElementException if {@code iterator} is empty - * @throws ClassCastException if the parameters are not mutually - * comparable under this ordering. - * - * @since 11.0 - */ - public E max(Iterator iterator) { - // let this throw NoSuchElementException as necessary - E maxSoFar = iterator.next(); - - while (iterator.hasNext()) { - maxSoFar = max(maxSoFar, iterator.next()); - } - - return maxSoFar; - } - - /** - * Returns the greatest of the specified values according to this ordering. If - * there are multiple greatest values, the first of those is returned. - * - * @param iterable the iterable whose maximum element is to be determined - * @throws NoSuchElementException if {@code iterable} is empty - * @throws ClassCastException if the parameters are not mutually - * comparable under this ordering. - */ - public E max(Iterable iterable) { - return max(iterable.iterator()); - } - - /** - * Returns the greater of the two values according to this ordering. If the - * values compare as 0, the first is returned. - * - *

Implementation note: this method is invoked by the default - * implementations of the other {@code max} overloads, so overriding it will - * affect their behavior. - * - * @param a value to compare, returned if greater than or equal to b. - * @param b value to compare. - * @throws ClassCastException if the parameters are not mutually - * comparable under this ordering. - */ - public E max(@Nullable E a, @Nullable E b) { - return (compare(a, b) >= 0) ? a : b; - } - - /** - * Returns the greatest of the specified values according to this ordering. If - * there are multiple greatest values, the first of those is returned. - * - * @param a value to compare, returned if greater than or equal to the rest. - * @param b value to compare - * @param c value to compare - * @param rest values to compare - * @throws ClassCastException if the parameters are not mutually - * comparable under this ordering. - */ - public E max(@Nullable E a, @Nullable E b, @Nullable E c, E... rest) { - E maxSoFar = max(max(a, b), c); - - for (E r : rest) { - maxSoFar = max(maxSoFar, r); - } - - return maxSoFar; - } - - /** - * Returns the {@code k} least elements of the given iterable according to - * this ordering, in order from least to greatest. If there are fewer than - * {@code k} elements present, all will be included. - * - *

The implementation does not necessarily use a stable sorting - * algorithm; when multiple elements are equivalent, it is undefined which - * will come first. - * - * @return an immutable {@code RandomAccess} list of the {@code k} least - * elements in ascending order - * @throws IllegalArgumentException if {@code k} is negative - * @since 8.0 - */ - public List leastOf(Iterable iterable, int k) { - if (iterable instanceof Collection) { - Collection collection = (Collection) iterable; - if (collection.size() <= 2L * k) { - // In this case, just dumping the collection to an array and sorting is - // faster than using the implementation for Iterator, which is - // specialized for k much smaller than n. - - @SuppressWarnings("unchecked") // c only contains E's and doesn't escape - E[] array = (E[]) collection.toArray(); - Arrays.sort(array, this); - if (array.length > k) { - array = ObjectArrays.arraysCopyOf(array, k); - } - return Collections.unmodifiableList(Arrays.asList(array)); - } - } - return leastOf(iterable.iterator(), k); - } - - /** - * Returns the {@code k} least elements from the given iterator according to - * this ordering, in order from least to greatest. If there are fewer than - * {@code k} elements present, all will be included. - * - *

The implementation does not necessarily use a stable sorting - * algorithm; when multiple elements are equivalent, it is undefined which - * will come first. - * - * @return an immutable {@code RandomAccess} list of the {@code k} least - * elements in ascending order - * @throws IllegalArgumentException if {@code k} is negative - * @since 14.0 - */ - public List leastOf(Iterator elements, int k) { - checkNotNull(elements); - checkNonnegative(k, "k"); - - if (k == 0 || !elements.hasNext()) { - return ImmutableList.of(); - } else if (k >= Integer.MAX_VALUE / 2) { - // k is really large; just do a straightforward sorted-copy-and-sublist - ArrayList list = Lists.newArrayList(elements); - Collections.sort(list, this); - if (list.size() > k) { - list.subList(k, list.size()).clear(); - } - list.trimToSize(); - return Collections.unmodifiableList(list); - } - - /* - * Our goal is an O(n) algorithm using only one pass and O(k) additional - * memory. - * - * We use the following algorithm: maintain a buffer of size 2*k. Every time - * the buffer gets full, find the median and partition around it, keeping - * only the lowest k elements. This requires n/k find-median-and-partition - * steps, each of which take O(k) time with a traditional quickselect. - * - * After sorting the output, the whole algorithm is O(n + k log k). It - * degrades gracefully for worst-case input (descending order), performs - * competitively or wins outright for randomly ordered input, and doesn't - * require the whole collection to fit into memory. - */ - int bufferCap = k * 2; - @SuppressWarnings("unchecked") // we'll only put E's in - E[] buffer = (E[]) new Object[bufferCap]; - E threshold = elements.next(); - buffer[0] = threshold; - int bufferSize = 1; - // threshold is the kth smallest element seen so far. Once bufferSize >= k, - // anything larger than threshold can be ignored immediately. - - while (bufferSize < k && elements.hasNext()) { - E e = elements.next(); - buffer[bufferSize++] = e; - threshold = max(threshold, e); - } - - while (elements.hasNext()) { - E e = elements.next(); - if (compare(e, threshold) >= 0) { - continue; - } - - buffer[bufferSize++] = e; - if (bufferSize == bufferCap) { - // We apply the quickselect algorithm to partition about the median, - // and then ignore the last k elements. - int left = 0; - int right = bufferCap - 1; - - int minThresholdPosition = 0; - // The leftmost position at which the greatest of the k lower elements - // -- the new value of threshold -- might be found. - - while (left < right) { - int pivotIndex = (left + right + 1) >>> 1; - int pivotNewIndex = partition(buffer, left, right, pivotIndex); - if (pivotNewIndex > k) { - right = pivotNewIndex - 1; - } else if (pivotNewIndex < k) { - left = Math.max(pivotNewIndex, left + 1); - minThresholdPosition = pivotNewIndex; - } else { - break; - } - } - bufferSize = k; - - threshold = buffer[minThresholdPosition]; - for (int i = minThresholdPosition + 1; i < bufferSize; i++) { - threshold = max(threshold, buffer[i]); - } - } - } - - Arrays.sort(buffer, 0, bufferSize, this); - - bufferSize = Math.min(bufferSize, k); - return Collections.unmodifiableList( - Arrays.asList(ObjectArrays.arraysCopyOf(buffer, bufferSize))); - // We can't use ImmutableList; we have to be null-friendly! - } - - private int partition(E[] values, int left, int right, int pivotIndex) { - E pivotValue = values[pivotIndex]; - - values[pivotIndex] = values[right]; - values[right] = pivotValue; - - int storeIndex = left; - for (int i = left; i < right; i++) { - if (compare(values[i], pivotValue) < 0) { - ObjectArrays.swap(values, storeIndex, i); - storeIndex++; - } - } - ObjectArrays.swap(values, right, storeIndex); - return storeIndex; - } - - /** - * Returns the {@code k} greatest elements of the given iterable according to - * this ordering, in order from greatest to least. If there are fewer than - * {@code k} elements present, all will be included. - * - *

The implementation does not necessarily use a stable sorting - * algorithm; when multiple elements are equivalent, it is undefined which - * will come first. - * - * @return an immutable {@code RandomAccess} list of the {@code k} greatest - * elements in descending order - * @throws IllegalArgumentException if {@code k} is negative - * @since 8.0 - */ - public List greatestOf(Iterable iterable, int k) { - // TODO(kevinb): see if delegation is hurting performance noticeably - // TODO(kevinb): if we change this implementation, add full unit tests. - return reverse().leastOf(iterable, k); - } - - /** - * Returns the {@code k} greatest elements from the given iterator according to - * this ordering, in order from greatest to least. If there are fewer than - * {@code k} elements present, all will be included. - * - *

The implementation does not necessarily use a stable sorting - * algorithm; when multiple elements are equivalent, it is undefined which - * will come first. - * - * @return an immutable {@code RandomAccess} list of the {@code k} greatest - * elements in descending order - * @throws IllegalArgumentException if {@code k} is negative - * @since 14.0 - */ - public List greatestOf(Iterator iterator, int k) { - return reverse().leastOf(iterator, k); - } - - /** - * Returns a mutable list containing {@code elements} sorted by this - * ordering; use this only when the resulting list may need further - * modification, or may contain {@code null}. The input is not modified. The - * returned list is serializable and has random access. - * - *

Unlike {@link Sets#newTreeSet(Iterable)}, this method does not discard - * elements that are duplicates according to the comparator. The sort - * performed is stable, meaning that such elements will appear in the - * returned list in the same order they appeared in {@code elements}. - * - *

Performance note: According to our - * benchmarking - * on Open JDK 7, {@link #immutableSortedCopy} generally performs better (in - * both time and space) than this method, and this method in turn generally - * performs better than copying the list and calling {@link - * Collections#sort(List)}. - */ - public List sortedCopy(Iterable elements) { - @SuppressWarnings("unchecked") // does not escape, and contains only E's - E[] array = (E[]) Iterables.toArray(elements); - Arrays.sort(array, this); - return Lists.newArrayList(Arrays.asList(array)); - } - - /** - * Returns an immutable list containing {@code elements} sorted by this - * ordering. The input is not modified. - * - *

Unlike {@link Sets#newTreeSet(Iterable)}, this method does not discard - * elements that are duplicates according to the comparator. The sort - * performed is stable, meaning that such elements will appear in the - * returned list in the same order they appeared in {@code elements}. - * - *

Performance note: According to our - * benchmarking - * on Open JDK 7, this method is the most efficient way to make a sorted copy - * of a collection. - * - * @throws NullPointerException if any of {@code elements} (or {@code - * elements} itself) is null - * @since 3.0 - */ - public ImmutableList immutableSortedCopy(Iterable elements) { - @SuppressWarnings("unchecked") // we'll only ever have E's in here - E[] array = (E[]) Iterables.toArray(elements); - for (E e : array) { - checkNotNull(e); - } - Arrays.sort(array, this); - return ImmutableList.asImmutableList(array); - } - - /** - * Returns {@code true} if each element in {@code iterable} after the first is - * greater than or equal to the element that preceded it, according to this - * ordering. Note that this is always true when the iterable has fewer than - * two elements. - */ - public boolean isOrdered(Iterable iterable) { - Iterator it = iterable.iterator(); - if (it.hasNext()) { - T prev = it.next(); - while (it.hasNext()) { - T next = it.next(); - if (compare(prev, next) > 0) { - return false; - } - prev = next; - } - } - return true; - } - - /** - * Returns {@code true} if each element in {@code iterable} after the first is - * strictly greater than the element that preceded it, according to - * this ordering. Note that this is always true when the iterable has fewer - * than two elements. - */ - public boolean isStrictlyOrdered(Iterable iterable) { - Iterator it = iterable.iterator(); - if (it.hasNext()) { - T prev = it.next(); - while (it.hasNext()) { - T next = it.next(); - if (compare(prev, next) >= 0) { - return false; - } - prev = next; - } - } - return true; - } - - /** - * {@link Collections#binarySearch(List, Object, Comparator) Searches} - * {@code sortedList} for {@code key} using the binary search algorithm. The - * list must be sorted using this ordering. - * - * @param sortedList the list to be searched - * @param key the key to be searched for - */ - public int binarySearch(List sortedList, @Nullable T key) { - return Collections.binarySearch(sortedList, key, this); - } - - /** - * Exception thrown by a {@link Ordering#explicit(List)} or {@link - * Ordering#explicit(Object, Object[])} comparator when comparing a value - * outside the set of values it can compare. Extending {@link - * ClassCastException} may seem odd, but it is required. - */ - // TODO(kevinb): make this public, document it right - @VisibleForTesting - static class IncomparableValueException extends ClassCastException { - final Object value; - - IncomparableValueException(Object value) { - super("Cannot compare value: " + value); - this.value = value; - } - - private static final long serialVersionUID = 0; - } - - // Never make these public - static final int LEFT_IS_GREATER = 1; - static final int RIGHT_IS_GREATER = -1; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/PeekingIterator.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/PeekingIterator.java deleted file mode 100644 index 13442a9cc404..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/PeekingIterator.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * An iterator that supports a one-element lookahead while iterating. - * - *

See the Guava User Guide article on - * {@code PeekingIterator}. - * - * @author Mick Killianey - * @since 2.0 - */ -@GwtCompatible -public interface PeekingIterator extends Iterator { - /** - * Returns the next element in the iteration, without advancing the iteration. - * - *

Calls to {@code peek()} should not change the state of the iteration, - * except that it may prevent removal of the most recent element via - * {@link #remove()}. - * - * @throws NoSuchElementException if the iteration has no more elements - * according to {@link #hasNext()} - */ - E peek(); - - /** - * {@inheritDoc} - * - *

The objects returned by consecutive calls to {@link #peek()} then {@link - * #next()} are guaranteed to be equal to each other. - */ - @Override - E next(); - - /** - * {@inheritDoc} - * - *

Implementations may or may not support removal when a call to {@link - * #peek()} has occurred since the most recent call to {@link #next()}. - * - * @throws IllegalStateException if there has been a call to {@link #peek()} - * since the most recent call to {@link #next()} and this implementation - * does not support this sequence of calls (optional) - */ - @Override - void remove(); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Platform.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Platform.java deleted file mode 100644 index 6e350b89ee4c..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Platform.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Function; -import com.google.common.base.Predicate; -import com.google.common.collect.Maps.EntryTransformer; - -import java.lang.reflect.Array; -import java.util.ArrayDeque; -import java.util.Collections; -import java.util.Map; -import java.util.NavigableMap; -import java.util.NavigableSet; -import java.util.Queue; -import java.util.Set; -import java.util.SortedMap; -import java.util.SortedSet; - -/** - * Methods factored out so that they can be emulated differently in GWT. - * - * @author Hayward Chan - */ -@GwtCompatible(emulated = true) -final class Platform { - /** - * Returns a new array of the given length with the same type as a reference - * array. - * - * @param reference any array of the desired type - * @param length the length of the new array - */ - static T[] newArray(T[] reference, int length) { - Class type = reference.getClass().getComponentType(); - - // the cast is safe because - // result.getClass() == reference.getClass().getComponentType() - @SuppressWarnings("unchecked") - T[] result = (T[]) Array.newInstance(type, length); - return result; - } - - static Set newSetFromMap(Map map) { - return Collections.newSetFromMap(map); - } - - /** - * Configures the given map maker to use weak keys, if possible; does nothing - * otherwise (i.e., in GWT). This is sometimes acceptable, when only - * server-side code could generate enough volume that reclamation becomes - * important. - */ - static MapMaker tryWeakKeys(MapMaker mapMaker) { - return mapMaker.weakKeys(); - } - - static SortedMap mapsTransformEntriesSortedMap( - SortedMap fromMap, EntryTransformer transformer) { - return (fromMap instanceof NavigableMap) - ? Maps.transformEntries((NavigableMap) fromMap, transformer) - : Maps.transformEntriesIgnoreNavigable(fromMap, transformer); - } - - static SortedMap mapsAsMapSortedSet( - SortedSet set, Function function) { - return (set instanceof NavigableSet) - ? Maps.asMap((NavigableSet) set, function) - : Maps.asMapSortedIgnoreNavigable(set, function); - } - - static SortedSet setsFilterSortedSet(SortedSet set, Predicate predicate) { - return (set instanceof NavigableSet) - ? Sets.filter((NavigableSet) set, predicate) - : Sets.filterSortedIgnoreNavigable(set, predicate); - } - - static SortedMap mapsFilterSortedMap( - SortedMap map, Predicate> predicate) { - return (map instanceof NavigableMap) - ? Maps.filterEntries((NavigableMap) map, predicate) - : Maps.filterSortedIgnoreNavigable(map, predicate); - } - - static Queue newFastestQueue(int initialCapacity) { - return new ArrayDeque(initialCapacity); - } - - private Platform() {} -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Queues.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Queues.java deleted file mode 100644 index bc8c0de12a92..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Queues.java +++ /dev/null @@ -1,406 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.Beta; -import com.google.common.base.Preconditions; - -import java.util.ArrayDeque; -import java.util.Collection; -import java.util.Deque; -import java.util.PriorityQueue; -import java.util.Queue; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.LinkedBlockingDeque; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.PriorityBlockingQueue; -import java.util.concurrent.SynchronousQueue; -import java.util.concurrent.TimeUnit; - -/** - * Static utility methods pertaining to {@link Queue} and {@link Deque} instances. - * Also see this class's counterparts {@link Lists}, {@link Sets}, and {@link Maps}. - * - * @author Kurt Alfred Kluever - * @since 11.0 - */ -public final class Queues { - private Queues() {} - - // ArrayBlockingQueue - - /** - * Creates an empty {@code ArrayBlockingQueue} with the given (fixed) capacity - * and nonfair access policy. - */ - public static ArrayBlockingQueue newArrayBlockingQueue(int capacity) { - return new ArrayBlockingQueue(capacity); - } - - // ArrayDeque - - /** - * Creates an empty {@code ArrayDeque}. - * - * @since 12.0 - */ - public static ArrayDeque newArrayDeque() { - return new ArrayDeque(); - } - - /** - * Creates an {@code ArrayDeque} containing the elements of the specified iterable, - * in the order they are returned by the iterable's iterator. - * - * @since 12.0 - */ - public static ArrayDeque newArrayDeque(Iterable elements) { - if (elements instanceof Collection) { - return new ArrayDeque(Collections2.cast(elements)); - } - ArrayDeque deque = new ArrayDeque(); - Iterables.addAll(deque, elements); - return deque; - } - - // ConcurrentLinkedQueue - - /** - * Creates an empty {@code ConcurrentLinkedQueue}. - */ - public static ConcurrentLinkedQueue newConcurrentLinkedQueue() { - return new ConcurrentLinkedQueue(); - } - - /** - * Creates a {@code ConcurrentLinkedQueue} containing the elements of the specified iterable, - * in the order they are returned by the iterable's iterator. - */ - public static ConcurrentLinkedQueue newConcurrentLinkedQueue( - Iterable elements) { - if (elements instanceof Collection) { - return new ConcurrentLinkedQueue(Collections2.cast(elements)); - } - ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue(); - Iterables.addAll(queue, elements); - return queue; - } - - // LinkedBlockingDeque - - /** - * Creates an empty {@code LinkedBlockingDeque} with a capacity of {@link Integer#MAX_VALUE}. - * - * @since 12.0 - */ - public static LinkedBlockingDeque newLinkedBlockingDeque() { - return new LinkedBlockingDeque(); - } - - /** - * Creates an empty {@code LinkedBlockingDeque} with the given (fixed) capacity. - * - * @throws IllegalArgumentException if {@code capacity} is less than 1 - * @since 12.0 - */ - public static LinkedBlockingDeque newLinkedBlockingDeque(int capacity) { - return new LinkedBlockingDeque(capacity); - } - - /** - * Creates a {@code LinkedBlockingDeque} with a capacity of {@link Integer#MAX_VALUE}, - * containing the elements of the specified iterable, - * in the order they are returned by the iterable's iterator. - * - * @since 12.0 - */ - public static LinkedBlockingDeque newLinkedBlockingDeque(Iterable elements) { - if (elements instanceof Collection) { - return new LinkedBlockingDeque(Collections2.cast(elements)); - } - LinkedBlockingDeque deque = new LinkedBlockingDeque(); - Iterables.addAll(deque, elements); - return deque; - } - - // LinkedBlockingQueue - - /** - * Creates an empty {@code LinkedBlockingQueue} with a capacity of {@link Integer#MAX_VALUE}. - */ - public static LinkedBlockingQueue newLinkedBlockingQueue() { - return new LinkedBlockingQueue(); - } - - /** - * Creates an empty {@code LinkedBlockingQueue} with the given (fixed) capacity. - * - * @throws IllegalArgumentException if {@code capacity} is less than 1 - */ - public static LinkedBlockingQueue newLinkedBlockingQueue(int capacity) { - return new LinkedBlockingQueue(capacity); - } - - /** - * Creates a {@code LinkedBlockingQueue} with a capacity of {@link Integer#MAX_VALUE}, - * containing the elements of the specified iterable, - * in the order they are returned by the iterable's iterator. - * - * @param elements the elements that the queue should contain, in order - * @return a new {@code LinkedBlockingQueue} containing those elements - */ - public static LinkedBlockingQueue newLinkedBlockingQueue(Iterable elements) { - if (elements instanceof Collection) { - return new LinkedBlockingQueue(Collections2.cast(elements)); - } - LinkedBlockingQueue queue = new LinkedBlockingQueue(); - Iterables.addAll(queue, elements); - return queue; - } - - // LinkedList: see {@link com.google.common.collect.Lists} - - // PriorityBlockingQueue - - /** - * Creates an empty {@code PriorityBlockingQueue} with the ordering given by its - * elements' natural ordering. - * - * @since 11.0 (requires that {@code E} be {@code Comparable} since 15.0). - */ - public static PriorityBlockingQueue newPriorityBlockingQueue() { - return new PriorityBlockingQueue(); - } - - /** - * Creates a {@code PriorityBlockingQueue} containing the given elements. - * - * Note: If the specified iterable is a {@code SortedSet} or a {@code PriorityQueue}, - * this priority queue will be ordered according to the same ordering. - * - * @since 11.0 (requires that {@code E} be {@code Comparable} since 15.0). - */ - public static PriorityBlockingQueue newPriorityBlockingQueue( - Iterable elements) { - if (elements instanceof Collection) { - return new PriorityBlockingQueue(Collections2.cast(elements)); - } - PriorityBlockingQueue queue = new PriorityBlockingQueue(); - Iterables.addAll(queue, elements); - return queue; - } - - // PriorityQueue - - /** - * Creates an empty {@code PriorityQueue} with the ordering given by its - * elements' natural ordering. - * - * @since 11.0 (requires that {@code E} be {@code Comparable} since 15.0). - */ - public static PriorityQueue newPriorityQueue() { - return new PriorityQueue(); - } - - /** - * Creates a {@code PriorityQueue} containing the given elements. - * - * Note: If the specified iterable is a {@code SortedSet} or a {@code PriorityQueue}, - * this priority queue will be ordered according to the same ordering. - * - * @since 11.0 (requires that {@code E} be {@code Comparable} since 15.0). - */ - public static PriorityQueue newPriorityQueue( - Iterable elements) { - if (elements instanceof Collection) { - return new PriorityQueue(Collections2.cast(elements)); - } - PriorityQueue queue = new PriorityQueue(); - Iterables.addAll(queue, elements); - return queue; - } - - // SynchronousQueue - - /** - * Creates an empty {@code SynchronousQueue} with nonfair access policy. - */ - public static SynchronousQueue newSynchronousQueue() { - return new SynchronousQueue(); - } - - /** - * Drains the queue as {@link BlockingQueue#drainTo(Collection, int)}, but if the requested - * {@code numElements} elements are not available, it will wait for them up to the specified - * timeout. - * - * @param q the blocking queue to be drained - * @param buffer where to add the transferred elements - * @param numElements the number of elements to be waited for - * @param timeout how long to wait before giving up, in units of {@code unit} - * @param unit a {@code TimeUnit} determining how to interpret the timeout parameter - * @return the number of elements transferred - * @throws InterruptedException if interrupted while waiting - */ - @Beta - public static int drain( - BlockingQueue q, - Collection buffer, - int numElements, - long timeout, - TimeUnit unit) - throws InterruptedException { - Preconditions.checkNotNull(buffer); - /* - * This code performs one System.nanoTime() more than necessary, and in return, the time to - * execute Queue#drainTo is not added *on top* of waiting for the timeout (which could make - * the timeout arbitrarily inaccurate, given a queue that is slow to drain). - */ - long deadline = System.nanoTime() + unit.toNanos(timeout); - int added = 0; - while (added < numElements) { - // we could rely solely on #poll, but #drainTo might be more efficient when there are multiple - // elements already available (e.g. LinkedBlockingQueue#drainTo locks only once) - added += q.drainTo(buffer, numElements - added); - if (added < numElements) { // not enough elements immediately available; will have to poll - E e = q.poll(deadline - System.nanoTime(), TimeUnit.NANOSECONDS); - if (e == null) { - break; // we already waited enough, and there are no more elements in sight - } - buffer.add(e); - added++; - } - } - return added; - } - - /** - * Drains the queue as {@linkplain #drain(BlockingQueue, Collection, int, long, TimeUnit)}, - * but with a different behavior in case it is interrupted while waiting. In that case, the - * operation will continue as usual, and in the end the thread's interruption status will be set - * (no {@code InterruptedException} is thrown). - * - * @param q the blocking queue to be drained - * @param buffer where to add the transferred elements - * @param numElements the number of elements to be waited for - * @param timeout how long to wait before giving up, in units of {@code unit} - * @param unit a {@code TimeUnit} determining how to interpret the timeout parameter - * @return the number of elements transferred - */ - @Beta - public static int drainUninterruptibly( - BlockingQueue q, - Collection buffer, - int numElements, - long timeout, - TimeUnit unit) { - Preconditions.checkNotNull(buffer); - long deadline = System.nanoTime() + unit.toNanos(timeout); - int added = 0; - boolean interrupted = false; - try { - while (added < numElements) { - // we could rely solely on #poll, but #drainTo might be more efficient when there are - // multiple elements already available (e.g. LinkedBlockingQueue#drainTo locks only once) - added += q.drainTo(buffer, numElements - added); - if (added < numElements) { // not enough elements immediately available; will have to poll - E e; // written exactly once, by a successful (uninterrupted) invocation of #poll - while (true) { - try { - e = q.poll(deadline - System.nanoTime(), TimeUnit.NANOSECONDS); - break; - } catch (InterruptedException ex) { - interrupted = true; // note interruption and retry - } - } - if (e == null) { - break; // we already waited enough, and there are no more elements in sight - } - buffer.add(e); - added++; - } - } - } finally { - if (interrupted) { - Thread.currentThread().interrupt(); - } - } - return added; - } - - /** - * Returns a synchronized (thread-safe) queue backed by the specified queue. In order to - * guarantee serial access, it is critical that all access to the backing queue is - * accomplished through the returned queue. - * - *

It is imperative that the user manually synchronize on the returned queue when accessing - * the queue's iterator:

   {@code
-   *
-   *   Queue queue = Queues.synchronizedQueue(MinMaxPriorityQueue.create());
-   *   ...
-   *   queue.add(element);  // Needn't be in synchronized block
-   *   ...
-   *   synchronized (queue) {  // Must synchronize on queue!
-   *     Iterator i = queue.iterator(); // Must be in synchronized block
-   *     while (i.hasNext()) {
-   *       foo(i.next());
-   *     }
-   *   }}
- * - *

Failure to follow this advice may result in non-deterministic behavior. - * - *

The returned queue will be serializable if the specified queue is serializable. - * - * @param queue the queue to be wrapped in a synchronized view - * @return a synchronized view of the specified queue - * @since 14.0 - */ - public static Queue synchronizedQueue(Queue queue) { - return Synchronized.queue(queue, null); - } - - /** - * Returns a synchronized (thread-safe) deque backed by the specified deque. In order to - * guarantee serial access, it is critical that all access to the backing deque is - * accomplished through the returned deque. - * - *

It is imperative that the user manually synchronize on the returned deque when accessing - * any of the deque's iterators:

   {@code
-   *
-   *   Deque deque = Queues.synchronizedDeque(Queues.newArrayDeque());
-   *   ...
-   *   deque.add(element);  // Needn't be in synchronized block
-   *   ...
-   *   synchronized (deque) {  // Must synchronize on deque!
-   *     Iterator i = deque.iterator(); // Must be in synchronized block
-   *     while (i.hasNext()) {
-   *       foo(i.next());
-   *     }
-   *   }}
- * - *

Failure to follow this advice may result in non-deterministic behavior. - * - *

The returned deque will be serializable if the specified deque is serializable. - * - * @param deque the deque to be wrapped in a synchronized view - * @return a synchronized view of the specified deque - * @since 15.0 - */ - public static Deque synchronizedDeque(Deque deque) { - return Synchronized.deque(deque, null); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Range.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Range.java deleted file mode 100644 index f967633db1ac..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Range.java +++ /dev/null @@ -1,692 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Equivalence; -import com.google.common.base.Function; -import com.google.common.base.Predicate; - -import java.io.Serializable; -import java.util.Comparator; -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.SortedSet; - -import javax.annotation.Nullable; - -/** - * A range (or "interval") defines the boundaries around a contiguous span of values of some - * {@code Comparable} type; for example, "integers from 1 to 100 inclusive." Note that it is not - * possible to iterate over these contained values. To do so, pass this range instance and - * an appropriate {@link DiscreteDomain} to {@link ContiguousSet#create}. - * - *

Types of ranges

- * - *

Each end of the range may be bounded or unbounded. If bounded, there is an associated - * endpoint value, and the range is considered to be either open (does not include the - * endpoint) or closed (includes the endpoint) on that side. With three possibilities on each - * side, this yields nine basic types of ranges, enumerated below. (Notation: a square bracket - * ({@code [ ]}) indicates that the range is closed on that side; a parenthesis ({@code ( )}) means - * it is either open or unbounded. The construct {@code {x | statement}} is read "the set of all - * x such that statement.") - * - *

- *
Notation Definition Factory method - *
{@code (a..b)} {@code {x | a < x < b}} {@link Range#open open} - *
{@code [a..b]} {@code {x | a <= x <= b}}{@link Range#closed closed} - *
{@code (a..b]} {@code {x | a < x <= b}} {@link Range#openClosed openClosed} - *
{@code [a..b)} {@code {x | a <= x < b}} {@link Range#closedOpen closedOpen} - *
{@code (a..+∞)} {@code {x | x > a}} {@link Range#greaterThan greaterThan} - *
{@code [a..+∞)} {@code {x | x >= a}} {@link Range#atLeast atLeast} - *
{@code (-∞..b)} {@code {x | x < b}} {@link Range#lessThan lessThan} - *
{@code (-∞..b]} {@code {x | x <= b}} {@link Range#atMost atMost} - *
{@code (-∞..+∞)}{@code {x}} {@link Range#all all} - *
- * - *

When both endpoints exist, the upper endpoint may not be less than the lower. The endpoints - * may be equal only if at least one of the bounds is closed: - * - *

    - *
  • {@code [a..a]} : a singleton range - *
  • {@code [a..a); (a..a]} : {@linkplain #isEmpty empty} ranges; also valid - *
  • {@code (a..a)} : invalid; an exception will be thrown - *
- * - *

Warnings

- * - *
    - *
  • Use immutable value types only, if at all possible. If you must use a mutable type, do - * not allow the endpoint instances to mutate after the range is created! - *
  • Your value type's comparison method should be {@linkplain Comparable consistent with equals} - * if at all possible. Otherwise, be aware that concepts used throughout this documentation such - * as "equal", "same", "unique" and so on actually refer to whether {@link Comparable#compareTo - * compareTo} returns zero, not whether {@link Object#equals equals} returns {@code true}. - *
  • A class which implements {@code Comparable} is very broken, and will cause - * undefined horrible things to happen in {@code Range}. For now, the Range API does not prevent - * its use, because this would also rule out all ungenerified (pre-JDK1.5) data types. This - * may change in the future. - *
- * - *

Other notes

- * - *
    - *
  • Instances of this type are obtained using the static factory methods in this class. - *
  • Ranges are convex: whenever two values are contained, all values in between them must - * also be contained. More formally, for any {@code c1 <= c2 <= c3} of type {@code C}, {@code - * r.contains(c1) && r.contains(c3)} implies {@code r.contains(c2)}). This means that a {@code - * Range} can never be used to represent, say, "all prime numbers from 1 to - * 100." - *
  • When evaluated as a {@link Predicate}, a range yields the same result as invoking {@link - * #contains}. - *
  • Terminology note: a range {@code a} is said to be the maximal range having property - * P if, for all ranges {@code b} also having property P, {@code a.encloses(b)}. - * Likewise, {@code a} is minimal when {@code b.encloses(a)} for all {@code b} having - * property P. See, for example, the definition of {@link #intersection intersection}. - *
- * - *

Further reading

- * - *

See the Guava User Guide article on - * {@code Range}. - * - * @author Kevin Bourrillion - * @author Gregory Kick - * @since 10.0 - */ -@GwtCompatible -@SuppressWarnings("rawtypes") -public final class Range implements Predicate, Serializable { - - private static final Function LOWER_BOUND_FN = - new Function() { - @Override - public Cut apply(Range range) { - return range.lowerBound; - } - }; - - @SuppressWarnings("unchecked") - static > Function, Cut> lowerBoundFn() { - return (Function) LOWER_BOUND_FN; - } - - private static final Function UPPER_BOUND_FN = - new Function() { - @Override - public Cut apply(Range range) { - return range.upperBound; - } - }; - - @SuppressWarnings("unchecked") - static > Function, Cut> upperBoundFn() { - return (Function) UPPER_BOUND_FN; - } - - static final Ordering> RANGE_LEX_ORDERING = new RangeLexOrdering(); - - static > Range create(Cut lowerBound, Cut upperBound) { - return new Range(lowerBound, upperBound); - } - - /** - * Returns a range that contains all values strictly greater than {@code - * lower} and strictly less than {@code upper}. - * - * @throws IllegalArgumentException if {@code lower} is greater than or - * equal to {@code upper} - * @since 14.0 - */ - public static > Range open(C lower, C upper) { - return create(Cut.aboveValue(lower), Cut.belowValue(upper)); - } - - /** - * Returns a range that contains all values greater than or equal to - * {@code lower} and less than or equal to {@code upper}. - * - * @throws IllegalArgumentException if {@code lower} is greater than {@code - * upper} - * @since 14.0 - */ - public static > Range closed(C lower, C upper) { - return create(Cut.belowValue(lower), Cut.aboveValue(upper)); - } - - /** - * Returns a range that contains all values greater than or equal to - * {@code lower} and strictly less than {@code upper}. - * - * @throws IllegalArgumentException if {@code lower} is greater than {@code - * upper} - * @since 14.0 - */ - public static > Range closedOpen(C lower, C upper) { - return create(Cut.belowValue(lower), Cut.belowValue(upper)); - } - - /** - * Returns a range that contains all values strictly greater than {@code - * lower} and less than or equal to {@code upper}. - * - * @throws IllegalArgumentException if {@code lower} is greater than {@code - * upper} - * @since 14.0 - */ - public static > Range openClosed(C lower, C upper) { - return create(Cut.aboveValue(lower), Cut.aboveValue(upper)); - } - - /** - * Returns a range that contains any value from {@code lower} to {@code - * upper}, where each endpoint may be either inclusive (closed) or exclusive - * (open). - * - * @throws IllegalArgumentException if {@code lower} is greater than {@code - * upper} - * @since 14.0 - */ - public static > Range range( - C lower, BoundType lowerType, C upper, BoundType upperType) { - checkNotNull(lowerType); - checkNotNull(upperType); - - Cut lowerBound = - (lowerType == BoundType.OPEN) ? Cut.aboveValue(lower) : Cut.belowValue(lower); - Cut upperBound = - (upperType == BoundType.OPEN) ? Cut.belowValue(upper) : Cut.aboveValue(upper); - return create(lowerBound, upperBound); - } - - /** - * Returns a range that contains all values strictly less than {@code - * endpoint}. - * - * @since 14.0 - */ - public static > Range lessThan(C endpoint) { - return create(Cut.belowAll(), Cut.belowValue(endpoint)); - } - - /** - * Returns a range that contains all values less than or equal to - * {@code endpoint}. - * - * @since 14.0 - */ - public static > Range atMost(C endpoint) { - return create(Cut.belowAll(), Cut.aboveValue(endpoint)); - } - - /** - * Returns a range with no lower bound up to the given endpoint, which may be - * either inclusive (closed) or exclusive (open). - * - * @since 14.0 - */ - public static > Range upTo(C endpoint, BoundType boundType) { - switch (boundType) { - case OPEN: - return lessThan(endpoint); - case CLOSED: - return atMost(endpoint); - default: - throw new AssertionError(); - } - } - - /** - * Returns a range that contains all values strictly greater than {@code - * endpoint}. - * - * @since 14.0 - */ - public static > Range greaterThan(C endpoint) { - return create(Cut.aboveValue(endpoint), Cut.aboveAll()); - } - - /** - * Returns a range that contains all values greater than or equal to - * {@code endpoint}. - * - * @since 14.0 - */ - public static > Range atLeast(C endpoint) { - return create(Cut.belowValue(endpoint), Cut.aboveAll()); - } - - /** - * Returns a range from the given endpoint, which may be either inclusive - * (closed) or exclusive (open), with no upper bound. - * - * @since 14.0 - */ - public static > Range downTo(C endpoint, BoundType boundType) { - switch (boundType) { - case OPEN: - return greaterThan(endpoint); - case CLOSED: - return atLeast(endpoint); - default: - throw new AssertionError(); - } - } - - private static final Range ALL = - new Range(Cut.belowAll(), Cut.aboveAll()); - - /** - * Returns a range that contains every value of type {@code C}. - * - * @since 14.0 - */ - @SuppressWarnings("unchecked") - public static > Range all() { - return (Range) ALL; - } - - /** - * Returns a range that {@linkplain Range#contains(Comparable) contains} only - * the given value. The returned range is {@linkplain BoundType#CLOSED closed} - * on both ends. - * - * @since 14.0 - */ - public static > Range singleton(C value) { - return closed(value, value); - } - - /** - * Returns the minimal range that - * {@linkplain Range#contains(Comparable) contains} all of the given values. - * The returned range is {@linkplain BoundType#CLOSED closed} on both ends. - * - * @throws ClassCastException if the parameters are not mutually - * comparable - * @throws NoSuchElementException if {@code values} is empty - * @throws NullPointerException if any of {@code values} is null - * @since 14.0 - */ - public static > Range encloseAll(Iterable values) { - checkNotNull(values); - if (values instanceof ContiguousSet) { - return ((ContiguousSet) values).range(); - } - Iterator valueIterator = values.iterator(); - C min = checkNotNull(valueIterator.next()); - C max = min; - while (valueIterator.hasNext()) { - C value = checkNotNull(valueIterator.next()); - min = Ordering.natural().min(min, value); - max = Ordering.natural().max(max, value); - } - return closed(min, max); - } - - final Cut lowerBound; - final Cut upperBound; - - private Range(Cut lowerBound, Cut upperBound) { - this.lowerBound = checkNotNull(lowerBound); - this.upperBound = checkNotNull(upperBound); - if (lowerBound.compareTo(upperBound) > 0 - || lowerBound == Cut.aboveAll() - || upperBound == Cut.belowAll()) { - throw new IllegalArgumentException("Invalid range: " + toString(lowerBound, upperBound)); - } - } - - /** - * Returns {@code true} if this range has a lower endpoint. - */ - public boolean hasLowerBound() { - return lowerBound != Cut.belowAll(); - } - - /** - * Returns the lower endpoint of this range. - * - * @throws IllegalStateException if this range is unbounded below (that is, {@link - * #hasLowerBound()} returns {@code false}) - */ - public C lowerEndpoint() { - return lowerBound.endpoint(); - } - - /** - * Returns the type of this range's lower bound: {@link BoundType#CLOSED} if the range includes - * its lower endpoint, {@link BoundType#OPEN} if it does not. - * - * @throws IllegalStateException if this range is unbounded below (that is, {@link - * #hasLowerBound()} returns {@code false}) - */ - public BoundType lowerBoundType() { - return lowerBound.typeAsLowerBound(); - } - - /** - * Returns {@code true} if this range has an upper endpoint. - */ - public boolean hasUpperBound() { - return upperBound != Cut.aboveAll(); - } - - /** - * Returns the upper endpoint of this range. - * - * @throws IllegalStateException if this range is unbounded above (that is, {@link - * #hasUpperBound()} returns {@code false}) - */ - public C upperEndpoint() { - return upperBound.endpoint(); - } - - /** - * Returns the type of this range's upper bound: {@link BoundType#CLOSED} if the range includes - * its upper endpoint, {@link BoundType#OPEN} if it does not. - * - * @throws IllegalStateException if this range is unbounded above (that is, {@link - * #hasUpperBound()} returns {@code false}) - */ - public BoundType upperBoundType() { - return upperBound.typeAsUpperBound(); - } - - /** - * Returns {@code true} if this range is of the form {@code [v..v)} or {@code (v..v]}. (This does - * not encompass ranges of the form {@code (v..v)}, because such ranges are invalid and - * can't be constructed at all.) - * - *

Note that certain discrete ranges such as the integer range {@code (3..4)} are not - * considered empty, even though they contain no actual values. In these cases, it may be - * helpful to preprocess ranges with {@link #canonical(DiscreteDomain)}. - */ - public boolean isEmpty() { - return lowerBound.equals(upperBound); - } - - /** - * Returns {@code true} if {@code value} is within the bounds of this range. For example, on the - * range {@code [0..2)}, {@code contains(1)} returns {@code true}, while {@code contains(2)} - * returns {@code false}. - */ - public boolean contains(C value) { - checkNotNull(value); - // let this throw CCE if there is some trickery going on - return lowerBound.isLessThan(value) && !upperBound.isLessThan(value); - } - - /** - * @deprecated Provided only to satisfy the {@link Predicate} interface; use {@link #contains} - * instead. - */ - @Deprecated - @Override - public boolean apply(C input) { - return contains(input); - } - - /** - * Returns {@code true} if every element in {@code values} is {@linkplain #contains contained} in - * this range. - */ - public boolean containsAll(Iterable values) { - if (Iterables.isEmpty(values)) { - return true; - } - - // this optimizes testing equality of two range-backed sets - if (values instanceof SortedSet) { - SortedSet set = cast(values); - Comparator comparator = set.comparator(); - if (Ordering.natural().equals(comparator) || comparator == null) { - return contains(set.first()) && contains(set.last()); - } - } - - for (C value : values) { - if (!contains(value)) { - return false; - } - } - return true; - } - - /** - * Returns {@code true} if the bounds of {@code other} do not extend outside the bounds of this - * range. Examples: - * - *

    - *
  • {@code [3..6]} encloses {@code [4..5]} - *
  • {@code (3..6)} encloses {@code (3..6)} - *
  • {@code [3..6]} encloses {@code [4..4)} (even though the latter is empty) - *
  • {@code (3..6]} does not enclose {@code [3..6]} - *
  • {@code [4..5]} does not enclose {@code (3..6)} (even though it contains every value - * contained by the latter range) - *
  • {@code [3..6]} does not enclose {@code (1..1]} (even though it contains every value - * contained by the latter range) - *
- * - *

Note that if {@code a.encloses(b)}, then {@code b.contains(v)} implies - * {@code a.contains(v)}, but as the last two examples illustrate, the converse is not always - * true. - * - *

Being reflexive, antisymmetric and transitive, the {@code encloses} relation defines a - * partial order over ranges. There exists a unique {@linkplain Range#all maximal} range - * according to this relation, and also numerous {@linkplain #isEmpty minimal} ranges. Enclosure - * also implies {@linkplain #isConnected connectedness}. - */ - public boolean encloses(Range other) { - return lowerBound.compareTo(other.lowerBound) <= 0 - && upperBound.compareTo(other.upperBound) >= 0; - } - - /** - * Returns {@code true} if there exists a (possibly empty) range which is {@linkplain #encloses - * enclosed} by both this range and {@code other}. - * - *

For example, - *

    - *
  • {@code [2, 4)} and {@code [5, 7)} are not connected - *
  • {@code [2, 4)} and {@code [3, 5)} are connected, because both enclose {@code [3, 4)} - *
  • {@code [2, 4)} and {@code [4, 6)} are connected, because both enclose the empty range - * {@code [4, 4)} - *
- * - *

Note that this range and {@code other} have a well-defined {@linkplain #span union} and - * {@linkplain #intersection intersection} (as a single, possibly-empty range) if and only if this - * method returns {@code true}. - * - *

The connectedness relation is both reflexive and symmetric, but does not form an {@linkplain - * Equivalence equivalence relation} as it is not transitive. - * - *

Note that certain discrete ranges are not considered connected, even though there are no - * elements "between them." For example, {@code [3, 5]} is not considered connected to {@code - * [6, 10]}. In these cases, it may be desirable for both input ranges to be preprocessed with - * {@link #canonical(DiscreteDomain)} before testing for connectedness. - */ - public boolean isConnected(Range other) { - return lowerBound.compareTo(other.upperBound) <= 0 - && other.lowerBound.compareTo(upperBound) <= 0; - } - - /** - * Returns the maximal range {@linkplain #encloses enclosed} by both this range and {@code - * connectedRange}, if such a range exists. - * - *

For example, the intersection of {@code [1..5]} and {@code (3..7)} is {@code (3..5]}. The - * resulting range may be empty; for example, {@code [1..5)} intersected with {@code [5..7)} - * yields the empty range {@code [5..5)}. - * - *

The intersection exists if and only if the two ranges are {@linkplain #isConnected - * connected}. - * - *

The intersection operation is commutative, associative and idempotent, and its identity - * element is {@link Range#all}). - * - * @throws IllegalArgumentException if {@code isConnected(connectedRange)} is {@code false} - */ - public Range intersection(Range connectedRange) { - int lowerCmp = lowerBound.compareTo(connectedRange.lowerBound); - int upperCmp = upperBound.compareTo(connectedRange.upperBound); - if (lowerCmp >= 0 && upperCmp <= 0) { - return this; - } else if (lowerCmp <= 0 && upperCmp >= 0) { - return connectedRange; - } else { - Cut newLower = (lowerCmp >= 0) ? lowerBound : connectedRange.lowerBound; - Cut newUpper = (upperCmp <= 0) ? upperBound : connectedRange.upperBound; - return create(newLower, newUpper); - } - } - - /** - * Returns the minimal range that {@linkplain #encloses encloses} both this range and {@code - * other}. For example, the span of {@code [1..3]} and {@code (5..7)} is {@code [1..7)}. - * - *

If the input ranges are {@linkplain #isConnected connected}, the returned range can - * also be called their union. If they are not, note that the span might contain values - * that are not contained in either input range. - * - *

Like {@link #intersection(Range) intersection}, this operation is commutative, associative - * and idempotent. Unlike it, it is always well-defined for any two input ranges. - */ - public Range span(Range other) { - int lowerCmp = lowerBound.compareTo(other.lowerBound); - int upperCmp = upperBound.compareTo(other.upperBound); - if (lowerCmp <= 0 && upperCmp >= 0) { - return this; - } else if (lowerCmp >= 0 && upperCmp <= 0) { - return other; - } else { - Cut newLower = (lowerCmp <= 0) ? lowerBound : other.lowerBound; - Cut newUpper = (upperCmp >= 0) ? upperBound : other.upperBound; - return create(newLower, newUpper); - } - } - - /** - * Returns the canonical form of this range in the given domain. The canonical form has the - * following properties: - * - *

    - *
  • equivalence: {@code a.canonical().contains(v) == a.contains(v)} for all {@code v} (in other - * words, {@code ContiguousSet.create(a.canonical(domain), domain).equals( - * ContiguousSet.create(a, domain))} - *
  • uniqueness: unless {@code a.isEmpty()}, - * {@code ContiguousSet.create(a, domain).equals(ContiguousSet.create(b, domain))} implies - * {@code a.canonical(domain).equals(b.canonical(domain))} - *
  • idempotence: {@code a.canonical(domain).canonical(domain).equals(a.canonical(domain))} - *
- * - *

Furthermore, this method guarantees that the range returned will be one of the following - * canonical forms: - * - *

    - *
  • [start..end) - *
  • [start..+∞) - *
  • (-∞..end) (only if type {@code C} is unbounded below) - *
  • (-∞..+∞) (only if type {@code C} is unbounded below) - *
- */ - public Range canonical(DiscreteDomain domain) { - checkNotNull(domain); - Cut lower = lowerBound.canonical(domain); - Cut upper = upperBound.canonical(domain); - return (lower == lowerBound && upper == upperBound) ? this : create(lower, upper); - } - - /** - * Returns {@code true} if {@code object} is a range having the same endpoints and bound types as - * this range. Note that discrete ranges such as {@code (1..4)} and {@code [2..3]} are not - * equal to one another, despite the fact that they each contain precisely the same set of values. - * Similarly, empty ranges are not equal unless they have exactly the same representation, so - * {@code [3..3)}, {@code (3..3]}, {@code (4..4]} are all unequal. - */ - @Override - public boolean equals(@Nullable Object object) { - if (object instanceof Range) { - Range other = (Range) object; - return lowerBound.equals(other.lowerBound) && upperBound.equals(other.upperBound); - } - return false; - } - - /** Returns a hash code for this range. */ - @Override - public int hashCode() { - return lowerBound.hashCode() * 31 + upperBound.hashCode(); - } - - /** - * Returns a string representation of this range, such as {@code "[3..5)"} (other examples are - * listed in the class documentation). - */ - @Override - public String toString() { - return toString(lowerBound, upperBound); - } - - private static String toString(Cut lowerBound, Cut upperBound) { - StringBuilder sb = new StringBuilder(16); - lowerBound.describeAsLowerBound(sb); - sb.append('\u2025'); - upperBound.describeAsUpperBound(sb); - return sb.toString(); - } - - /** - * Used to avoid http://bugs.sun.com/view_bug.do?bug_id=6558557 - */ - private static SortedSet cast(Iterable iterable) { - return (SortedSet) iterable; - } - - Object readResolve() { - if (this.equals(ALL)) { - return all(); - } else { - return this; - } - } - - @SuppressWarnings("unchecked") // this method may throw CCE - static int compareOrThrow(Comparable left, Comparable right) { - return left.compareTo(right); - } - - /** - * Needed to serialize sorted collections of Ranges. - */ - private static class RangeLexOrdering extends Ordering> implements Serializable { - - @Override - public int compare(Range left, Range right) { - return ComparisonChain.start() - .compare(left.lowerBound, right.lowerBound) - .compare(left.upperBound, right.upperBound) - .result(); - } - - private static final long serialVersionUID = 0; - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/RangeMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/RangeMap.java deleted file mode 100644 index ce41e6d077d0..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/RangeMap.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.Beta; - -import java.util.Map; - -import javax.annotation.Nullable; - -/** - * A mapping from disjoint nonempty ranges to non-null values. Queries look up the value - * associated with the range (if any) that contains a specified key. - * - *

In contrast to {@link RangeSet}, no "coalescing" is done of {@linkplain - * Range#isConnected(Range) connected} ranges, even if they are mapped to the same value. - * - * @author Louis Wasserman - * @since 14.0 - */ -@Beta -public interface RangeMap { - /** - * Returns the value associated with the specified key, or {@code null} if there is no - * such value. - * - *

Specifically, if any range in this range map contains the specified key, the value - * associated with that range is returned. - */ - @Nullable - V get(K key); - - /** - * Returns the range containing this key and its associated value, if such a range is present - * in the range map, or {@code null} otherwise. - */ - @Nullable - Map.Entry, V> getEntry(K key); - - /** - * Returns the minimal range {@linkplain Range#encloses(Range) enclosing} the ranges - * in this {@code RangeMap}. - * - * @throws NoSuchElementException if this range map is empty - */ - Range span(); - - /** - * Maps a range to a specified value (optional operation). - * - *

Specifically, after a call to {@code put(range, value)}, if - * {@link Range#contains(Comparable) range.contains(k)}, then {@link #get(Comparable) get(k)} - * will return {@code value}. - * - *

If {@code range} {@linkplain Range#isEmpty() is empty}, then this is a no-op. - */ - void put(Range range, V value); - - /** - * Puts all the associations from {@code rangeMap} into this range map (optional operation). - */ - void putAll(RangeMap rangeMap); - - /** - * Removes all associations from this range map (optional operation). - */ - void clear(); - - /** - * Removes all associations from this range map in the specified range (optional operation). - * - *

If {@code !range.contains(k)}, {@link #get(Comparable) get(k)} will return the same result - * before and after a call to {@code remove(range)}. If {@code range.contains(k)}, then - * after a call to {@code remove(range)}, {@code get(k)} will return {@code null}. - */ - void remove(Range range); - - /** - * Returns a view of this range map as an unmodifiable {@code Map, V>}. - * Modifications to this range map are guaranteed to read through to the returned {@code Map}. - * - *

The returned {@code Map} iterates over entries in ascending order of the bounds of the - * {@code Range} entries. - * - *

It is guaranteed that no empty ranges will be in the returned {@code Map}. - */ - Map, V> asMapOfRanges(); - - /** - * Returns a view of this range map as an unmodifiable {@code Map, V>}. - * Modifications to this range map are guaranteed to read through to the returned {@code Map}. - * - *

The returned {@code Map} iterates over entries in descending order of the bounds of the - * {@code Range} entries. - * - *

It is guaranteed that no empty ranges will be in the returned {@code Map}. - * - * @since 19.0 - */ - Map, V> asDescendingMapOfRanges(); - - /** - * Returns a view of the part of this range map that intersects with {@code range}. - * - *

For example, if {@code rangeMap} had the entries - * {@code [1, 5] => "foo", (6, 8) => "bar", (10, \u2025) => "baz"} - * then {@code rangeMap.subRangeMap(Range.open(3, 12))} would return a range map - * with the entries {@code (3, 5) => "foo", (6, 8) => "bar", (10, 12) => "baz"}. - * - *

The returned range map supports all optional operations that this range map supports, - * except for {@code asMapOfRanges().iterator().remove()}. - * - *

The returned range map will throw an {@link IllegalArgumentException} on an attempt to - * insert a range not {@linkplain Range#encloses(Range) enclosed} by {@code range}. - */ - RangeMap subRangeMap(Range range); - - /** - * Returns {@code true} if {@code obj} is another {@code RangeMap} that has an equivalent - * {@link #asMapOfRanges()}. - */ - @Override - boolean equals(@Nullable Object o); - - /** - * Returns {@code asMapOfRanges().hashCode()}. - */ - @Override - int hashCode(); - - /** - * Returns a readable string representation of this range map. - */ - @Override - String toString(); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/RangeSet.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/RangeSet.java deleted file mode 100644 index 4d2523ec431d..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/RangeSet.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.Beta; - -import java.util.NoSuchElementException; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * A set comprising zero or more {@linkplain Range#isEmpty nonempty}, - * {@linkplain Range#isConnected(Range) disconnected} ranges of type {@code C}. - * - *

Implementations that choose to support the {@link #add(Range)} operation are required to - * ignore empty ranges and coalesce connected ranges. For example:

   {@code
- *
- *   RangeSet rangeSet = TreeRangeSet.create();
- *   rangeSet.add(Range.closed(1, 10)); // {[1, 10]}
- *   rangeSet.add(Range.closedOpen(11, 15)); // disconnected range; {[1, 10], [11, 15)}
- *   rangeSet.add(Range.closedOpen(15, 20)); // connected range; {[1, 10], [11, 20)}
- *   rangeSet.add(Range.openClosed(0, 0)); // empty range; {[1, 10], [11, 20)}
- *   rangeSet.remove(Range.open(5, 10)); // splits [1, 10]; {[1, 5], [10, 10], [11, 20)}}
- * - *

Note that the behavior of {@link Range#isEmpty()} and {@link Range#isConnected(Range)} may - * not be as expected on discrete ranges. See the Javadoc of those methods for details. - * - *

For a {@link Set} whose contents are specified by a {@link Range}, see {@link ContiguousSet}. - * - * @author Kevin Bourrillion - * @author Louis Wasserman - * @since 14.0 - */ -@Beta -public interface RangeSet { - - // Query methods - - /** - * Determines whether any of this range set's member ranges contains {@code value}. - */ - boolean contains(C value); - - /** - * Returns the unique range from this range set that {@linkplain Range#contains contains} - * {@code value}, or {@code null} if this range set does not contain {@code value}. - */ - Range rangeContaining(C value); - - /** - * Returns {@code true} if there exists a member range in this range set which - * {@linkplain Range#encloses encloses} the specified range. - */ - boolean encloses(Range otherRange); - - /** - * Returns {@code true} if for each member range in {@code other} there exists a member range in - * this range set which {@linkplain Range#encloses encloses} it. It follows that - * {@code this.contains(value)} whenever {@code other.contains(value)}. Returns {@code true} if - * {@code other} is empty. - * - *

This is equivalent to checking if this range set {@link #encloses} each of the ranges in - * {@code other}. - */ - boolean enclosesAll(RangeSet other); - - /** - * Returns {@code true} if this range set contains no ranges. - */ - boolean isEmpty(); - - /** - * Returns the minimal range which {@linkplain Range#encloses(Range) encloses} all ranges - * in this range set. - * - * @throws NoSuchElementException if this range set is {@linkplain #isEmpty() empty} - */ - Range span(); - - // Views - - /** - * Returns a view of the {@linkplain Range#isConnected disconnected} ranges that make up this - * range set. The returned set may be empty. The iterators returned by its - * {@link Iterable#iterator} method return the ranges in increasing order of lower bound - * (equivalently, of upper bound). - */ - Set> asRanges(); - - /** - * Returns a descending view of the {@linkplain Range#isConnected disconnected} ranges that - * make up this range set. The returned set may be empty. The iterators returned by its - * {@link Iterable#iterator} method return the ranges in decreasing order of lower bound - * (equivalently, of upper bound). - * - * @since 19.0 - */ - Set> asDescendingSetOfRanges(); - - /** - * Returns a view of the complement of this {@code RangeSet}. - * - *

The returned view supports the {@link #add} operation if this {@code RangeSet} supports - * {@link #remove}, and vice versa. - */ - RangeSet complement(); - - /** - * Returns a view of the intersection of this {@code RangeSet} with the specified range. - * - *

The returned view supports all optional operations supported by this {@code RangeSet}, with - * the caveat that an {@link IllegalArgumentException} is thrown on an attempt to - * {@linkplain #add(Range) add} any range not {@linkplain Range#encloses(Range) enclosed} by - * {@code view}. - */ - RangeSet subRangeSet(Range view); - - // Modification - - /** - * Adds the specified range to this {@code RangeSet} (optional operation). That is, for equal - * range sets a and b, the result of {@code a.add(range)} is that {@code a} will be the minimal - * range set for which both {@code a.enclosesAll(b)} and {@code a.encloses(range)}. - * - *

Note that {@code range} will be {@linkplain Range#span(Range) coalesced} with any ranges in - * the range set that are {@linkplain Range#isConnected(Range) connected} with it. Moreover, - * if {@code range} is empty, this is a no-op. - * - * @throws UnsupportedOperationException if this range set does not support the {@code add} - * operation - */ - void add(Range range); - - /** - * Removes the specified range from this {@code RangeSet} (optional operation). After this - * operation, if {@code range.contains(c)}, {@code this.contains(c)} will return {@code false}. - * - *

If {@code range} is empty, this is a no-op. - * - * @throws UnsupportedOperationException if this range set does not support the {@code remove} - * operation - */ - void remove(Range range); - - /** - * Removes all ranges from this {@code RangeSet} (optional operation). After this operation, - * {@code this.contains(c)} will return false for all {@code c}. - * - *

This is equivalent to {@code remove(Range.all())}. - * - * @throws UnsupportedOperationException if this range set does not support the {@code clear} - * operation - */ - void clear(); - - /** - * Adds all of the ranges from the specified range set to this range set (optional operation). - * After this operation, this range set is the minimal range set that - * {@linkplain #enclosesAll(RangeSet) encloses} both the original range set and {@code other}. - * - *

This is equivalent to calling {@link #add} on each of the ranges in {@code other} in turn. - * - * @throws UnsupportedOperationException if this range set does not support the {@code addAll} - * operation - */ - void addAll(RangeSet other); - - /** - * Removes all of the ranges from the specified range set from this range set (optional - * operation). After this operation, if {@code other.contains(c)}, {@code this.contains(c)} will - * return {@code false}. - * - *

This is equivalent to calling {@link #remove} on each of the ranges in {@code other} in - * turn. - * - * @throws UnsupportedOperationException if this range set does not support the {@code removeAll} - * operation - */ - void removeAll(RangeSet other); - - // Object methods - - /** - * Returns {@code true} if {@code obj} is another {@code RangeSet} that contains the same ranges - * according to {@link Range#equals(Object)}. - */ - @Override - boolean equals(@Nullable Object obj); - - /** - * Returns {@code asRanges().hashCode()}. - */ - @Override - int hashCode(); - - /** - * Returns a readable string representation of this range set. For example, if this - * {@code RangeSet} consisted of {@code Range.closed(1, 3)} and {@code Range.greaterThan(4)}, - * this might return {@code " [1‥3](4‥+∞)}"}. - */ - @Override - String toString(); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularContiguousSet.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularContiguousSet.java deleted file mode 100644 index 428377ff9bd4..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularContiguousSet.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.BoundType.CLOSED; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; - -import java.io.Serializable; -import java.util.Collection; - -import javax.annotation.Nullable; - -/** - * An implementation of {@link ContiguousSet} that contains one or more elements. - * - * @author Gregory Kick - */ -@GwtCompatible(emulated = true) -@SuppressWarnings("unchecked") // allow ungenerified Comparable types -final class RegularContiguousSet extends ContiguousSet { - private final Range range; - - RegularContiguousSet(Range range, DiscreteDomain domain) { - super(domain); - this.range = range; - } - - private ContiguousSet intersectionInCurrentDomain(Range other) { - return (range.isConnected(other)) - ? ContiguousSet.create(range.intersection(other), domain) - : new EmptyContiguousSet(domain); - } - - @Override - ContiguousSet headSetImpl(C toElement, boolean inclusive) { - return intersectionInCurrentDomain(Range.upTo(toElement, BoundType.forBoolean(inclusive))); - } - - @Override - ContiguousSet subSetImpl( - C fromElement, boolean fromInclusive, C toElement, boolean toInclusive) { - if (fromElement.compareTo(toElement) == 0 && !fromInclusive && !toInclusive) { - // Range would reject our attempt to create (x, x). - return new EmptyContiguousSet(domain); - } - return intersectionInCurrentDomain( - Range.range( - fromElement, BoundType.forBoolean(fromInclusive), - toElement, BoundType.forBoolean(toInclusive))); - } - - @Override - ContiguousSet tailSetImpl(C fromElement, boolean inclusive) { - return intersectionInCurrentDomain(Range.downTo(fromElement, BoundType.forBoolean(inclusive))); - } - - @GwtIncompatible("not used by GWT emulation") - @Override - int indexOf(Object target) { - return contains(target) ? (int) domain.distance(first(), (C) target) : -1; - } - - @Override - public UnmodifiableIterator iterator() { - return new AbstractSequentialIterator(first()) { - final C last = last(); - - @Override - protected C computeNext(C previous) { - return equalsOrThrow(previous, last) ? null : domain.next(previous); - } - }; - } - - @GwtIncompatible("NavigableSet") - @Override - public UnmodifiableIterator descendingIterator() { - return new AbstractSequentialIterator(last()) { - final C first = first(); - - @Override - protected C computeNext(C previous) { - return equalsOrThrow(previous, first) ? null : domain.previous(previous); - } - }; - } - - private static boolean equalsOrThrow(Comparable left, @Nullable Comparable right) { - return right != null && Range.compareOrThrow(left, right) == 0; - } - - @Override - boolean isPartialView() { - return false; - } - - @Override - public C first() { - return range.lowerBound.leastValueAbove(domain); - } - - @Override - public C last() { - return range.upperBound.greatestValueBelow(domain); - } - - @Override - public int size() { - long distance = domain.distance(first(), last()); - return (distance >= Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) distance + 1; - } - - @Override - public boolean contains(@Nullable Object object) { - if (object == null) { - return false; - } - try { - return range.contains((C) object); - } catch (ClassCastException e) { - return false; - } - } - - @Override - public boolean containsAll(Collection targets) { - return Collections2.containsAllImpl(this, targets); - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public ContiguousSet intersection(ContiguousSet other) { - checkNotNull(other); - checkArgument(this.domain.equals(other.domain)); - if (other.isEmpty()) { - return other; - } else { - C lowerEndpoint = Ordering.natural().max(this.first(), other.first()); - C upperEndpoint = Ordering.natural().min(this.last(), other.last()); - return (lowerEndpoint.compareTo(upperEndpoint) < 0) - ? ContiguousSet.create(Range.closed(lowerEndpoint, upperEndpoint), domain) - : new EmptyContiguousSet(domain); - } - } - - @Override - public Range range() { - return range(CLOSED, CLOSED); - } - - @Override - public Range range(BoundType lowerBoundType, BoundType upperBoundType) { - return Range.create( - range.lowerBound.withLowerBoundType(lowerBoundType, domain), - range.upperBound.withUpperBoundType(upperBoundType, domain)); - } - - @Override - public boolean equals(@Nullable Object object) { - if (object == this) { - return true; - } else if (object instanceof RegularContiguousSet) { - RegularContiguousSet that = (RegularContiguousSet) object; - if (this.domain.equals(that.domain)) { - return this.first().equals(that.first()) && this.last().equals(that.last()); - } - } - return super.equals(object); - } - - // copied to make sure not to use the GWT-emulated version - @Override - public int hashCode() { - return Sets.hashCodeImpl(this); - } - - @GwtIncompatible("serialization") - private static final class SerializedForm implements Serializable { - final Range range; - final DiscreteDomain domain; - - private SerializedForm(Range range, DiscreteDomain domain) { - this.range = range; - this.domain = domain; - } - - private Object readResolve() { - return new RegularContiguousSet(range, domain); - } - } - - @GwtIncompatible("serialization") - @Override - Object writeReplace() { - return new SerializedForm(range, domain); - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableAsList.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableAsList.java deleted file mode 100644 index 49c4c4d00ba5..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableAsList.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.j2objc.annotations.Weak; - -/** - * An {@link ImmutableAsList} implementation specialized for when the delegate collection is - * already backed by an {@code ImmutableList} or array. - * - * @author Louis Wasserman - */ -@GwtCompatible(emulated = true) -@SuppressWarnings("serial") // uses writeReplace, not default serialization -class RegularImmutableAsList extends ImmutableAsList { - @Weak private final ImmutableCollection delegate; - private final ImmutableList delegateList; - - RegularImmutableAsList(ImmutableCollection delegate, ImmutableList delegateList) { - this.delegate = delegate; - this.delegateList = delegateList; - } - - RegularImmutableAsList(ImmutableCollection delegate, Object[] array) { - this(delegate, ImmutableList.asImmutableList(array)); - } - - @Override - ImmutableCollection delegateCollection() { - return delegate; - } - - ImmutableList delegateList() { - return delegateList; - } - - @SuppressWarnings("unchecked") // safe covariant cast! - @Override - public UnmodifiableListIterator listIterator(int index) { - return (UnmodifiableListIterator) delegateList.listIterator(index); - } - - @GwtIncompatible("not present in emulated superclass") - @Override - int copyIntoArray(Object[] dst, int offset) { - return delegateList.copyIntoArray(dst, offset); - } - - @Override - public E get(int index) { - return delegateList.get(index); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableBiMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableBiMap.java deleted file mode 100644 index b405c91a7fce..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableBiMap.java +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkPositionIndex; -import static com.google.common.collect.CollectPreconditions.checkEntryNotNull; -import static com.google.common.collect.ImmutableMapEntry.createEntryArray; -import static com.google.common.collect.RegularImmutableMap.checkNoConflictInKeyBucket; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.collect.ImmutableMapEntry.NonTerminalImmutableBiMapEntry; -import com.google.j2objc.annotations.WeakOuter; - -import java.io.Serializable; - -import javax.annotation.Nullable; - -/** - * Bimap with zero or more mappings. - * - * @author Louis Wasserman - */ -@GwtCompatible(serializable = true, emulated = true) -@SuppressWarnings("serial") // uses writeReplace(), not default serialization -class RegularImmutableBiMap extends ImmutableBiMap { - static final RegularImmutableBiMap EMPTY = - new RegularImmutableBiMap( - null, null, (Entry[]) ImmutableMap.EMPTY_ENTRY_ARRAY, 0, 0); - - static final double MAX_LOAD_FACTOR = 1.2; - - private final transient ImmutableMapEntry[] keyTable; - private final transient ImmutableMapEntry[] valueTable; - private final transient Entry[] entries; - private final transient int mask; - private final transient int hashCode; - - static RegularImmutableBiMap fromEntries(Entry... entries) { - return fromEntryArray(entries.length, entries); - } - - static RegularImmutableBiMap fromEntryArray(int n, Entry[] entryArray) { - checkPositionIndex(n, entryArray.length); - int tableSize = Hashing.closedTableSize(n, MAX_LOAD_FACTOR); - int mask = tableSize - 1; - ImmutableMapEntry[] keyTable = createEntryArray(tableSize); - ImmutableMapEntry[] valueTable = createEntryArray(tableSize); - Entry[] entries; - if (n == entryArray.length) { - entries = entryArray; - } else { - entries = createEntryArray(n); - } - int hashCode = 0; - - for (int i = 0; i < n; i++) { - @SuppressWarnings("unchecked") - Entry entry = entryArray[i]; - K key = entry.getKey(); - V value = entry.getValue(); - checkEntryNotNull(key, value); - int keyHash = key.hashCode(); - int valueHash = value.hashCode(); - int keyBucket = Hashing.smear(keyHash) & mask; - int valueBucket = Hashing.smear(valueHash) & mask; - - ImmutableMapEntry nextInKeyBucket = keyTable[keyBucket]; - checkNoConflictInKeyBucket(key, entry, nextInKeyBucket); - ImmutableMapEntry nextInValueBucket = valueTable[valueBucket]; - checkNoConflictInValueBucket(value, entry, nextInValueBucket); - ImmutableMapEntry newEntry; - if (nextInValueBucket == null && nextInKeyBucket == null) { - /* - * TODO(lowasser): consider using a NonTerminalImmutableMapEntry when nextInKeyBucket is - * nonnull but nextInValueBucket is null. This may save a few bytes on some platforms, but - * 2-morphic call sites are often optimized much better than 3-morphic, so it'd require - * benchmarking. - */ - boolean reusable = - entry instanceof ImmutableMapEntry && ((ImmutableMapEntry) entry).isReusable(); - newEntry = reusable - ? (ImmutableMapEntry) entry - : new ImmutableMapEntry(key, value); - } else { - newEntry = new NonTerminalImmutableBiMapEntry( - key, value, nextInKeyBucket, nextInValueBucket); - } - keyTable[keyBucket] = newEntry; - valueTable[valueBucket] = newEntry; - entries[i] = newEntry; - hashCode += keyHash ^ valueHash; - } - return new RegularImmutableBiMap(keyTable, valueTable, entries, mask, hashCode); - } - - private RegularImmutableBiMap( - ImmutableMapEntry[] keyTable, - ImmutableMapEntry[] valueTable, - Entry[] entries, - int mask, - int hashCode) { - this.keyTable = keyTable; - this.valueTable = valueTable; - this.entries = entries; - this.mask = mask; - this.hashCode = hashCode; - } - - // checkNoConflictInKeyBucket is static imported from RegularImmutableMap - - private static void checkNoConflictInValueBucket( - Object value, Entry entry, @Nullable ImmutableMapEntry valueBucketHead) { - for (; valueBucketHead != null; valueBucketHead = valueBucketHead.getNextInValueBucket()) { - checkNoConflict(!value.equals(valueBucketHead.getValue()), "value", entry, valueBucketHead); - } - } - - @Override - @Nullable - public V get(@Nullable Object key) { - return (keyTable == null) ? null : RegularImmutableMap.get(key, keyTable, mask); - } - - @Override - ImmutableSet> createEntrySet() { - return isEmpty() - ? ImmutableSet.>of() - : new ImmutableMapEntrySet.RegularEntrySet(this, entries); - } - - @Override - boolean isHashCodeFast() { - return true; - } - - @Override - public int hashCode() { - return hashCode; - } - - @Override - boolean isPartialView() { - return false; - } - - @Override - public int size() { - return entries.length; - } - - private transient ImmutableBiMap inverse; - - @Override - public ImmutableBiMap inverse() { - if (isEmpty()) { - return ImmutableBiMap.of(); - } - ImmutableBiMap result = inverse; - return (result == null) ? inverse = new Inverse() : result; - } - - private final class Inverse extends ImmutableBiMap { - - @Override - public int size() { - return inverse().size(); - } - - @Override - public ImmutableBiMap inverse() { - return RegularImmutableBiMap.this; - } - - @Override - public K get(@Nullable Object value) { - if (value == null || valueTable == null) { - return null; - } - int bucket = Hashing.smear(value.hashCode()) & mask; - for (ImmutableMapEntry entry = valueTable[bucket]; - entry != null; - entry = entry.getNextInValueBucket()) { - if (value.equals(entry.getValue())) { - return entry.getKey(); - } - } - return null; - } - - @Override - ImmutableSet> createEntrySet() { - return new InverseEntrySet(); - } - - @WeakOuter - final class InverseEntrySet extends ImmutableMapEntrySet { - @Override - ImmutableMap map() { - return Inverse.this; - } - - @Override - boolean isHashCodeFast() { - return true; - } - - @Override - public int hashCode() { - return hashCode; - } - - @Override - public UnmodifiableIterator> iterator() { - return asList().iterator(); - } - - @Override - ImmutableList> createAsList() { - return new ImmutableAsList>() { - @Override - public Entry get(int index) { - Entry entry = entries[index]; - return Maps.immutableEntry(entry.getValue(), entry.getKey()); - } - - @Override - ImmutableCollection> delegateCollection() { - return InverseEntrySet.this; - } - }; - } - } - - @Override - boolean isPartialView() { - return false; - } - - @Override - Object writeReplace() { - return new InverseSerializedForm(RegularImmutableBiMap.this); - } - } - - private static class InverseSerializedForm implements Serializable { - private final ImmutableBiMap forward; - - InverseSerializedForm(ImmutableBiMap forward) { - this.forward = forward; - } - - Object readResolve() { - return forward.inverse(); - } - - private static final long serialVersionUID = 1; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableList.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableList.java deleted file mode 100644 index 9436f098dc8b..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableList.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Preconditions; - -/** - * Implementation of {@link ImmutableList} used for 0 or 2+ elements (not 1). - * - * @author Kevin Bourrillion - */ -@GwtCompatible(serializable = true, emulated = true) -@SuppressWarnings("serial") // uses writeReplace(), not default serialization -class RegularImmutableList extends ImmutableList { - static final ImmutableList EMPTY = - new RegularImmutableList(ObjectArrays.EMPTY_ARRAY); - - private final transient int offset; - private final transient int size; - private final transient Object[] array; - - RegularImmutableList(Object[] array, int offset, int size) { - this.offset = offset; - this.size = size; - this.array = array; - } - - RegularImmutableList(Object[] array) { - this(array, 0, array.length); - } - - @Override - public int size() { - return size; - } - - @Override - boolean isPartialView() { - return size != array.length; - } - - @Override - int copyIntoArray(Object[] dst, int dstOff) { - System.arraycopy(array, offset, dst, dstOff, size); - return dstOff + size; - } - - // The fake cast to E is safe because the creation methods only allow E's - @Override - @SuppressWarnings("unchecked") - public E get(int index) { - Preconditions.checkElementIndex(index, size); - return (E) array[index + offset]; - } - - @Override - ImmutableList subListUnchecked(int fromIndex, int toIndex) { - return new RegularImmutableList(array, offset + fromIndex, toIndex - fromIndex); - } - - @SuppressWarnings("unchecked") - @Override - public UnmodifiableListIterator listIterator(int index) { - // for performance - // The fake cast to E is safe because the creation methods only allow E's - return (UnmodifiableListIterator) Iterators.forArray(array, offset, size, index); - } - - // TODO(lowasser): benchmark optimizations for equals() and see if they're worthwhile -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableMap.java deleted file mode 100644 index 4c2cdfacb3c9..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableMap.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkPositionIndex; -import static com.google.common.collect.CollectPreconditions.checkEntryNotNull; -import static com.google.common.collect.ImmutableMapEntry.createEntryArray; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.collect.ImmutableMapEntry.NonTerminalImmutableMapEntry; - -import javax.annotation.Nullable; - -/** - * Implementation of {@link ImmutableMap} with two or more entries. - * - * @author Jesse Wilson - * @author Kevin Bourrillion - * @author Gregory Kick - */ -@GwtCompatible(serializable = true, emulated = true) -final class RegularImmutableMap extends ImmutableMap { - - // entries in insertion order - private final transient Entry[] entries; - // array of linked lists of entries - private final transient ImmutableMapEntry[] table; - // 'and' with an int to get a table index - private final transient int mask; - - static RegularImmutableMap fromEntries(Entry... entries) { - return fromEntryArray(entries.length, entries); - } - - /** - * Creates a RegularImmutableMap from the first n entries in entryArray. This implementation - * may replace the entries in entryArray with its own entry objects (though they will have the - * same key/value contents), and may take ownership of entryArray. - */ - static RegularImmutableMap fromEntryArray(int n, Entry[] entryArray) { - checkPositionIndex(n, entryArray.length); - Entry[] entries; - if (n == entryArray.length) { - entries = entryArray; - } else { - entries = createEntryArray(n); - } - int tableSize = Hashing.closedTableSize(n, MAX_LOAD_FACTOR); - ImmutableMapEntry[] table = createEntryArray(tableSize); - int mask = tableSize - 1; - for (int entryIndex = 0; entryIndex < n; entryIndex++) { - Entry entry = entryArray[entryIndex]; - K key = entry.getKey(); - V value = entry.getValue(); - checkEntryNotNull(key, value); - int tableIndex = Hashing.smear(key.hashCode()) & mask; - @Nullable ImmutableMapEntry existing = table[tableIndex]; - // prepend, not append, so the entries can be immutable - ImmutableMapEntry newEntry; - if (existing == null) { - boolean reusable = - entry instanceof ImmutableMapEntry && ((ImmutableMapEntry) entry).isReusable(); - newEntry = - reusable ? (ImmutableMapEntry) entry : new ImmutableMapEntry(key, value); - } else { - newEntry = new NonTerminalImmutableMapEntry(key, value, existing); - } - table[tableIndex] = newEntry; - entries[entryIndex] = newEntry; - checkNoConflictInKeyBucket(key, newEntry, existing); - } - return new RegularImmutableMap(entries, table, mask); - } - - private RegularImmutableMap(Entry[] entries, ImmutableMapEntry[] table, int mask) { - this.entries = entries; - this.table = table; - this.mask = mask; - } - - static void checkNoConflictInKeyBucket( - Object key, Entry entry, @Nullable ImmutableMapEntry keyBucketHead) { - for (; keyBucketHead != null; keyBucketHead = keyBucketHead.getNextInKeyBucket()) { - checkNoConflict(!key.equals(keyBucketHead.getKey()), "key", entry, keyBucketHead); - } - } - - /** - * Closed addressing tends to perform well even with high load factors. - * Being conservative here ensures that the table is still likely to be - * relatively sparse (hence it misses fast) while saving space. - */ - private static final double MAX_LOAD_FACTOR = 1.2; - - @Override - public V get(@Nullable Object key) { - return get(key, table, mask); - } - - @Nullable - static V get(@Nullable Object key, ImmutableMapEntry[] keyTable, int mask) { - if (key == null) { - return null; - } - int index = Hashing.smear(key.hashCode()) & mask; - for (ImmutableMapEntry entry = keyTable[index]; - entry != null; - entry = entry.getNextInKeyBucket()) { - Object candidateKey = entry.getKey(); - - /* - * Assume that equals uses the == optimization when appropriate, and that - * it would check hash codes as an optimization when appropriate. If we - * did these things, it would just make things worse for the most - * performance-conscious users. - */ - if (key.equals(candidateKey)) { - return entry.getValue(); - } - } - return null; - } - - @Override - public int size() { - return entries.length; - } - - @Override - boolean isPartialView() { - return false; - } - - @Override - ImmutableSet> createEntrySet() { - return new ImmutableMapEntrySet.RegularEntrySet(this, entries); - } - - // This class is never actually serialized directly, but we have to make the - // warning go away (and suppressing would suppress for all nested classes too) - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableMultiset.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableMultiset.java deleted file mode 100644 index 5181f5718669..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableMultiset.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Objects; -import com.google.common.collect.Multisets.ImmutableEntry; -import com.google.common.primitives.Ints; -import com.google.j2objc.annotations.WeakOuter; - -import java.util.Collection; - -import javax.annotation.Nullable; - -/** - * Implementation of {@link ImmutableMultiset} with zero or more elements. - * - * @author Jared Levy - * @author Louis Wasserman - */ -@GwtCompatible(serializable = true) -@SuppressWarnings("serial") // uses writeReplace(), not default serialization -class RegularImmutableMultiset extends ImmutableMultiset { - static final RegularImmutableMultiset EMPTY = - new RegularImmutableMultiset(ImmutableList.>of()); - - private final transient Multisets.ImmutableEntry[] entries; - private final transient Multisets.ImmutableEntry[] hashTable; - private final transient int size; - private final transient int hashCode; - - private transient ImmutableSet elementSet; - - RegularImmutableMultiset(Collection> entries) { - int distinct = entries.size(); - @SuppressWarnings("unchecked") - Multisets.ImmutableEntry[] entryArray = new Multisets.ImmutableEntry[distinct]; - if (distinct == 0) { - this.entries = entryArray; - this.hashTable = null; - this.size = 0; - this.hashCode = 0; - this.elementSet = ImmutableSet.of(); - } else { - int tableSize = Hashing.closedTableSize(distinct, 1.0); - int mask = tableSize - 1; - @SuppressWarnings("unchecked") - Multisets.ImmutableEntry[] hashTable = new Multisets.ImmutableEntry[tableSize]; - - int index = 0; - int hashCode = 0; - long size = 0; - for (Entry entry : entries) { - E element = checkNotNull(entry.getElement()); - int count = entry.getCount(); - int hash = element.hashCode(); - int bucket = Hashing.smear(hash) & mask; - Multisets.ImmutableEntry bucketHead = hashTable[bucket]; - Multisets.ImmutableEntry newEntry; - if (bucketHead == null) { - boolean canReuseEntry = - entry instanceof Multisets.ImmutableEntry && !(entry instanceof NonTerminalEntry); - newEntry = - canReuseEntry - ? (Multisets.ImmutableEntry) entry - : new Multisets.ImmutableEntry(element, count); - } else { - newEntry = new NonTerminalEntry(element, count, bucketHead); - } - hashCode += hash ^ count; - entryArray[index++] = newEntry; - hashTable[bucket] = newEntry; - size += count; - } - this.entries = entryArray; - this.hashTable = hashTable; - this.size = Ints.saturatedCast(size); - this.hashCode = hashCode; - } - } - - private static final class NonTerminalEntry extends Multisets.ImmutableEntry { - private final Multisets.ImmutableEntry nextInBucket; - - NonTerminalEntry(E element, int count, ImmutableEntry nextInBucket) { - super(element, count); - this.nextInBucket = nextInBucket; - } - - @Override - public ImmutableEntry nextInBucket() { - return nextInBucket; - } - } - - @Override - boolean isPartialView() { - return false; - } - - @Override - public int count(@Nullable Object element) { - Multisets.ImmutableEntry[] hashTable = this.hashTable; - if (element == null || hashTable == null) { - return 0; - } - int hash = Hashing.smearedHash(element); - int mask = hashTable.length - 1; - for (Multisets.ImmutableEntry entry = hashTable[hash & mask]; - entry != null; - entry = entry.nextInBucket()) { - if (Objects.equal(element, entry.getElement())) { - return entry.getCount(); - } - } - return 0; - } - - @Override - public int size() { - return size; - } - - @Override - public ImmutableSet elementSet() { - ImmutableSet result = elementSet; - return (result == null) ? elementSet = new ElementSet() : result; - } - - @WeakOuter - private final class ElementSet extends ImmutableSet.Indexed { - - @Override - E get(int index) { - return entries[index].getElement(); - } - - @Override - public boolean contains(@Nullable Object object) { - return RegularImmutableMultiset.this.contains(object); - } - - @Override - boolean isPartialView() { - return true; - } - - @Override - public int size() { - return entries.length; - } - } - - @Override - Entry getEntry(int index) { - return entries[index]; - } - - @Override - public int hashCode() { - return hashCode; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableSet.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableSet.java deleted file mode 100644 index 9bf70d7df7b1..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableSet.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.VisibleForTesting; - -import javax.annotation.Nullable; - -/** - * Implementation of {@link ImmutableSet} with two or more elements. - * - * @author Kevin Bourrillion - */ -@GwtCompatible(serializable = true, emulated = true) -@SuppressWarnings("serial") // uses writeReplace(), not default serialization -final class RegularImmutableSet extends ImmutableSet { - static final RegularImmutableSet EMPTY = - new RegularImmutableSet(ObjectArrays.EMPTY_ARRAY, 0, null, 0); - - private final transient Object[] elements; - // the same elements in hashed positions (plus nulls) - @VisibleForTesting final transient Object[] table; - // 'and' with an int to get a valid table index. - private final transient int mask; - private final transient int hashCode; - - RegularImmutableSet(Object[] elements, int hashCode, Object[] table, int mask) { - this.elements = elements; - this.table = table; - this.mask = mask; - this.hashCode = hashCode; - } - - @Override - public boolean contains(@Nullable Object target) { - Object[] table = this.table; - if (target == null || table == null) { - return false; - } - for (int i = Hashing.smearedHash(target); ; i++) { - i &= mask; - Object candidate = table[i]; - if (candidate == null) { - return false; - } else if (candidate.equals(target)) { - return true; - } - } - } - - @Override - public int size() { - return elements.length; - } - - @SuppressWarnings("unchecked") // all elements are E's - @Override - public UnmodifiableIterator iterator() { - return (UnmodifiableIterator) Iterators.forArray(elements); - } - - @Override - int copyIntoArray(Object[] dst, int offset) { - System.arraycopy(elements, 0, dst, offset, elements.length); - return offset + elements.length; - } - - @Override - ImmutableList createAsList() { - return (table == null) ? ImmutableList.of() : new RegularImmutableAsList(this, elements); - } - - @Override - boolean isPartialView() { - return false; - } - - @Override - public int hashCode() { - return hashCode; - } - - @Override - boolean isHashCodeFast() { - return true; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableSortedMultiset.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableSortedMultiset.java deleted file mode 100644 index bf39c07ba1df..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableSortedMultiset.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkPositionIndexes; -import static com.google.common.collect.BoundType.CLOSED; - -import com.google.common.primitives.Ints; - -import java.util.Comparator; - -import javax.annotation.Nullable; - -/** - * An immutable sorted multiset with one or more distinct elements. - * - * @author Louis Wasserman - */ -@SuppressWarnings("serial") // uses writeReplace, not default serialization -final class RegularImmutableSortedMultiset extends ImmutableSortedMultiset { - private static final long[] ZERO_CUMULATIVE_COUNTS = {0}; - - private final transient RegularImmutableSortedSet elementSet; - private final transient long[] cumulativeCounts; - private final transient int offset; - private final transient int length; - - RegularImmutableSortedMultiset(Comparator comparator) { - this.elementSet = ImmutableSortedSet.emptySet(comparator); - this.cumulativeCounts = ZERO_CUMULATIVE_COUNTS; - this.offset = 0; - this.length = 0; - } - - RegularImmutableSortedMultiset( - RegularImmutableSortedSet elementSet, long[] cumulativeCounts, int offset, int length) { - this.elementSet = elementSet; - this.cumulativeCounts = cumulativeCounts; - this.offset = offset; - this.length = length; - } - - private int getCount(int index) { - return (int) (cumulativeCounts[offset + index + 1] - cumulativeCounts[offset + index]); - } - - @Override - Entry getEntry(int index) { - return Multisets.immutableEntry(elementSet.asList().get(index), getCount(index)); - } - - @Override - public Entry firstEntry() { - return isEmpty() ? null : getEntry(0); - } - - @Override - public Entry lastEntry() { - return isEmpty() ? null : getEntry(length - 1); - } - - @Override - public int count(@Nullable Object element) { - int index = elementSet.indexOf(element); - return (index >= 0) ? getCount(index) : 0; - } - - @Override - public int size() { - long size = cumulativeCounts[offset + length] - cumulativeCounts[offset]; - return Ints.saturatedCast(size); - } - - @Override - public ImmutableSortedSet elementSet() { - return elementSet; - } - - @Override - public ImmutableSortedMultiset headMultiset(E upperBound, BoundType boundType) { - return getSubMultiset(0, elementSet.headIndex(upperBound, checkNotNull(boundType) == CLOSED)); - } - - @Override - public ImmutableSortedMultiset tailMultiset(E lowerBound, BoundType boundType) { - return getSubMultiset( - elementSet.tailIndex(lowerBound, checkNotNull(boundType) == CLOSED), length); - } - - ImmutableSortedMultiset getSubMultiset(int from, int to) { - checkPositionIndexes(from, to, length); - if (from == to) { - return emptyMultiset(comparator()); - } else if (from == 0 && to == length) { - return this; - } else { - RegularImmutableSortedSet subElementSet = - (RegularImmutableSortedSet) elementSet.getSubSet(from, to); - return new RegularImmutableSortedMultiset( - subElementSet, cumulativeCounts, offset + from, to - from); - } - } - - @Override - boolean isPartialView() { - return offset > 0 || length < cumulativeCounts.length - 1; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableSortedSet.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableSortedSet.java deleted file mode 100644 index 32883b0e6a09..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableSortedSet.java +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.SortedLists.KeyAbsentBehavior.INVERTED_INSERTION_INDEX; -import static com.google.common.collect.SortedLists.KeyAbsentBehavior.NEXT_HIGHER; -import static com.google.common.collect.SortedLists.KeyPresentBehavior.ANY_PRESENT; -import static com.google.common.collect.SortedLists.KeyPresentBehavior.FIRST_AFTER; -import static com.google.common.collect.SortedLists.KeyPresentBehavior.FIRST_PRESENT; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; - -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * An immutable sorted set with one or more elements. TODO(jlevy): Consider - * separate class for a single-element sorted set. - * - * @author Jared Levy - * @author Louis Wasserman - */ -@GwtCompatible(serializable = true, emulated = true) -@SuppressWarnings("serial") -final class RegularImmutableSortedSet extends ImmutableSortedSet { - - private transient final ImmutableList elements; - - RegularImmutableSortedSet(ImmutableList elements, Comparator comparator) { - super(comparator); - this.elements = elements; - } - - @Override - public UnmodifiableIterator iterator() { - return elements.iterator(); - } - - @GwtIncompatible("NavigableSet") - @Override - public UnmodifiableIterator descendingIterator() { - return elements.reverse().iterator(); - } - - @Override - public int size() { - return elements.size(); - } - - @Override - public boolean contains(@Nullable Object o) { - try { - return o != null && unsafeBinarySearch(o) >= 0; - } catch (ClassCastException e) { - return false; - } - } - - @Override - public boolean containsAll(Collection targets) { - // TODO(jlevy): For optimal performance, use a binary search when - // targets.size() < size() / log(size()) - // TODO(kevinb): see if we can share code with OrderedIterator after it - // graduates from labs. - if (targets instanceof Multiset) { - targets = ((Multiset) targets).elementSet(); - } - if (!SortedIterables.hasSameComparator(comparator(), targets) || (targets.size() <= 1)) { - return super.containsAll(targets); - } - - /* - * If targets is a sorted set with the same comparator, containsAll can run - * in O(n) time stepping through the two collections. - */ - PeekingIterator thisIterator = Iterators.peekingIterator(iterator()); - Iterator thatIterator = targets.iterator(); - Object target = thatIterator.next(); - - try { - - while (thisIterator.hasNext()) { - - int cmp = unsafeCompare(thisIterator.peek(), target); - - if (cmp < 0) { - thisIterator.next(); - } else if (cmp == 0) { - - if (!thatIterator.hasNext()) { - - return true; - } - - target = thatIterator.next(); - - } else if (cmp > 0) { - return false; - } - } - } catch (NullPointerException e) { - return false; - } catch (ClassCastException e) { - return false; - } - - return false; - } - - private int unsafeBinarySearch(Object key) throws ClassCastException { - return Collections.binarySearch(elements, key, unsafeComparator()); - } - - @Override - boolean isPartialView() { - return elements.isPartialView(); - } - - @Override - int copyIntoArray(Object[] dst, int offset) { - return elements.copyIntoArray(dst, offset); - } - - @Override - public boolean equals(@Nullable Object object) { - if (object == this) { - return true; - } - if (!(object instanceof Set)) { - return false; - } - - Set that = (Set) object; - if (size() != that.size()) { - return false; - } else if (isEmpty()) { - return true; - } - - if (SortedIterables.hasSameComparator(comparator, that)) { - Iterator otherIterator = that.iterator(); - try { - Iterator iterator = iterator(); - while (iterator.hasNext()) { - Object element = iterator.next(); - Object otherElement = otherIterator.next(); - if (otherElement == null || unsafeCompare(element, otherElement) != 0) { - return false; - } - } - return true; - } catch (ClassCastException e) { - return false; - } catch (NoSuchElementException e) { - return false; // concurrent change to other set - } - } - return this.containsAll(that); - } - - @Override - public E first() { - if (isEmpty()) { - throw new NoSuchElementException(); - } - return elements.get(0); - } - - @Override - public E last() { - if (isEmpty()) { - throw new NoSuchElementException(); - } - return elements.get(size() - 1); - } - - @Override - public E lower(E element) { - int index = headIndex(element, false) - 1; - return (index == -1) ? null : elements.get(index); - } - - @Override - public E floor(E element) { - int index = headIndex(element, true) - 1; - return (index == -1) ? null : elements.get(index); - } - - @Override - public E ceiling(E element) { - int index = tailIndex(element, true); - return (index == size()) ? null : elements.get(index); - } - - @Override - public E higher(E element) { - int index = tailIndex(element, false); - return (index == size()) ? null : elements.get(index); - } - - @Override - ImmutableSortedSet headSetImpl(E toElement, boolean inclusive) { - return getSubSet(0, headIndex(toElement, inclusive)); - } - - int headIndex(E toElement, boolean inclusive) { - return SortedLists.binarySearch( - elements, - checkNotNull(toElement), - comparator(), - inclusive ? FIRST_AFTER : FIRST_PRESENT, - NEXT_HIGHER); - } - - @Override - ImmutableSortedSet subSetImpl( - E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { - return tailSetImpl(fromElement, fromInclusive).headSetImpl(toElement, toInclusive); - } - - @Override - ImmutableSortedSet tailSetImpl(E fromElement, boolean inclusive) { - return getSubSet(tailIndex(fromElement, inclusive), size()); - } - - int tailIndex(E fromElement, boolean inclusive) { - return SortedLists.binarySearch( - elements, - checkNotNull(fromElement), - comparator(), - inclusive ? FIRST_PRESENT : FIRST_AFTER, - NEXT_HIGHER); - } - - // Pretend the comparator can compare anything. If it turns out it can't - // compare two elements, it'll throw a CCE. Only methods that are specified to - // throw CCE should call this. - @SuppressWarnings("unchecked") - Comparator unsafeComparator() { - return (Comparator) comparator; - } - - RegularImmutableSortedSet getSubSet(int newFromIndex, int newToIndex) { - if (newFromIndex == 0 && newToIndex == size()) { - return this; - } else if (newFromIndex < newToIndex) { - return new RegularImmutableSortedSet( - elements.subList(newFromIndex, newToIndex), comparator); - } else { - return emptySet(comparator); - } - } - - @Override - int indexOf(@Nullable Object target) { - if (target == null) { - return -1; - } - int position; - try { - position = SortedLists.binarySearch( - elements, target, unsafeComparator(), ANY_PRESENT, INVERTED_INSERTION_INDEX); - } catch (ClassCastException e) { - return -1; - } - return (position >= 0) ? position : -1; - } - - @Override - ImmutableList createAsList() { - return (size() <= 1) ? elements : new ImmutableSortedAsList(this, elements); - } - - @Override - ImmutableSortedSet createDescendingSet() { - Ordering reversedOrder = Ordering.from(comparator).reverse(); - return isEmpty() - ? emptySet(reversedOrder) - : new RegularImmutableSortedSet(elements.reverse(), reversedOrder); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableTable.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableTable.java deleted file mode 100644 index 0bbbe39d783b..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/RegularImmutableTable.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.collect.Table.Cell; -import com.google.j2objc.annotations.WeakOuter; - -import java.util.Collections; -import java.util.Comparator; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * An implementation of {@link ImmutableTable} holding an arbitrary number of - * cells. - * - * @author Gregory Kick - */ -@GwtCompatible -abstract class RegularImmutableTable extends ImmutableTable { - RegularImmutableTable() {} - - abstract Cell getCell(int iterationIndex); - - @Override - final ImmutableSet> createCellSet() { - return isEmpty() ? ImmutableSet.>of() : new CellSet(); - } - - @WeakOuter - private final class CellSet extends ImmutableSet.Indexed> { - @Override - public int size() { - return RegularImmutableTable.this.size(); - } - - @Override - Cell get(int index) { - return getCell(index); - } - - @Override - public boolean contains(@Nullable Object object) { - if (object instanceof Cell) { - Cell cell = (Cell) object; - Object value = RegularImmutableTable.this.get(cell.getRowKey(), cell.getColumnKey()); - return value != null && value.equals(cell.getValue()); - } - return false; - } - - @Override - boolean isPartialView() { - return false; - } - } - - abstract V getValue(int iterationIndex); - - @Override - final ImmutableCollection createValues() { - return isEmpty() ? ImmutableList.of() : new Values(); - } - - @WeakOuter - private final class Values extends ImmutableList { - @Override - public int size() { - return RegularImmutableTable.this.size(); - } - - @Override - public V get(int index) { - return getValue(index); - } - - @Override - boolean isPartialView() { - return true; - } - } - - static RegularImmutableTable forCells( - List> cells, - @Nullable final Comparator rowComparator, - @Nullable final Comparator columnComparator) { - checkNotNull(cells); - if (rowComparator != null || columnComparator != null) { - /* - * This sorting logic leads to a cellSet() ordering that may not be expected and that isn't - * documented in the Javadoc. If a row Comparator is provided, cellSet() iterates across the - * columns in the first row, the columns in the second row, etc. If a column Comparator is - * provided but a row Comparator isn't, cellSet() iterates across the rows in the first - * column, the rows in the second column, etc. - */ - Comparator> comparator = - new Comparator>() { - @Override - public int compare(Cell cell1, Cell cell2) { - int rowCompare = - (rowComparator == null) - ? 0 - : rowComparator.compare(cell1.getRowKey(), cell2.getRowKey()); - if (rowCompare != 0) { - return rowCompare; - } - return (columnComparator == null) - ? 0 - : columnComparator.compare(cell1.getColumnKey(), cell2.getColumnKey()); - } - }; - Collections.sort(cells, comparator); - } - return forCellsInternal(cells, rowComparator, columnComparator); - } - - static RegularImmutableTable forCells(Iterable> cells) { - return forCellsInternal(cells, null, null); - } - - /** - * A factory that chooses the most space-efficient representation of the - * table. - */ - private static final RegularImmutableTable forCellsInternal( - Iterable> cells, - @Nullable Comparator rowComparator, - @Nullable Comparator columnComparator) { - Set rowSpaceBuilder = new LinkedHashSet(); - Set columnSpaceBuilder = new LinkedHashSet(); - ImmutableList> cellList = ImmutableList.copyOf(cells); - for (Cell cell : cells) { - rowSpaceBuilder.add(cell.getRowKey()); - columnSpaceBuilder.add(cell.getColumnKey()); - } - - ImmutableSet rowSpace = - (rowComparator == null) - ? ImmutableSet.copyOf(rowSpaceBuilder) - : ImmutableSet.copyOf( - Ordering.from(rowComparator).immutableSortedCopy(rowSpaceBuilder)); - ImmutableSet columnSpace = - (columnComparator == null) - ? ImmutableSet.copyOf(columnSpaceBuilder) - : ImmutableSet.copyOf( - Ordering.from(columnComparator).immutableSortedCopy(columnSpaceBuilder)); - - // use a dense table if more than half of the cells have values - // TODO(gak): tune this condition based on empirical evidence - return (cellList.size() > (((long) rowSpace.size() * columnSpace.size()) / 2)) - ? new DenseImmutableTable(cellList, rowSpace, columnSpace) - : new SparseImmutableTable(cellList, rowSpace, columnSpace); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ReverseNaturalOrdering.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ReverseNaturalOrdering.java deleted file mode 100644 index d94fc0cb62a8..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ReverseNaturalOrdering.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; -import java.util.Iterator; - -/** An ordering that uses the reverse of the natural order of the values. */ -@GwtCompatible(serializable = true) -@SuppressWarnings("unchecked") // TODO(kevinb): the right way to explain this?? -final class ReverseNaturalOrdering extends Ordering implements Serializable { - static final ReverseNaturalOrdering INSTANCE = new ReverseNaturalOrdering(); - - @Override - public int compare(Comparable left, Comparable right) { - checkNotNull(left); // right null is caught later - if (left == right) { - return 0; - } - - return right.compareTo(left); - } - - @Override - public Ordering reverse() { - return Ordering.natural(); - } - - // Override the min/max methods to "hoist" delegation outside loops - - @Override - public E min(E a, E b) { - return NaturalOrdering.INSTANCE.max(a, b); - } - - @Override - public E min(E a, E b, E c, E... rest) { - return NaturalOrdering.INSTANCE.max(a, b, c, rest); - } - - @Override - public E min(Iterator iterator) { - return NaturalOrdering.INSTANCE.max(iterator); - } - - @Override - public E min(Iterable iterable) { - return NaturalOrdering.INSTANCE.max(iterable); - } - - @Override - public E max(E a, E b) { - return NaturalOrdering.INSTANCE.min(a, b); - } - - @Override - public E max(E a, E b, E c, E... rest) { - return NaturalOrdering.INSTANCE.min(a, b, c, rest); - } - - @Override - public E max(Iterator iterator) { - return NaturalOrdering.INSTANCE.min(iterator); - } - - @Override - public E max(Iterable iterable) { - return NaturalOrdering.INSTANCE.min(iterable); - } - - // preserving singleton-ness gives equals()/hashCode() for free - private Object readResolve() { - return INSTANCE; - } - - @Override - public String toString() { - return "Ordering.natural().reverse()"; - } - - private ReverseNaturalOrdering() {} - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/ReverseOrdering.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/ReverseOrdering.java deleted file mode 100644 index 30ffbf898aa8..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/ReverseOrdering.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; -import java.util.Iterator; - -import javax.annotation.Nullable; - -/** An ordering that uses the reverse of a given order. */ -@GwtCompatible(serializable = true) -final class ReverseOrdering extends Ordering implements Serializable { - final Ordering forwardOrder; - - ReverseOrdering(Ordering forwardOrder) { - this.forwardOrder = checkNotNull(forwardOrder); - } - - @Override - public int compare(T a, T b) { - return forwardOrder.compare(b, a); - } - - @SuppressWarnings("unchecked") // how to explain? - @Override - public Ordering reverse() { - return (Ordering) forwardOrder; - } - - // Override the min/max methods to "hoist" delegation outside loops - - @Override - public E min(E a, E b) { - return forwardOrder.max(a, b); - } - - @Override - public E min(E a, E b, E c, E... rest) { - return forwardOrder.max(a, b, c, rest); - } - - @Override - public E min(Iterator iterator) { - return forwardOrder.max(iterator); - } - - @Override - public E min(Iterable iterable) { - return forwardOrder.max(iterable); - } - - @Override - public E max(E a, E b) { - return forwardOrder.min(a, b); - } - - @Override - public E max(E a, E b, E c, E... rest) { - return forwardOrder.min(a, b, c, rest); - } - - @Override - public E max(Iterator iterator) { - return forwardOrder.min(iterator); - } - - @Override - public E max(Iterable iterable) { - return forwardOrder.min(iterable); - } - - @Override - public int hashCode() { - return -forwardOrder.hashCode(); - } - - @Override - public boolean equals(@Nullable Object object) { - if (object == this) { - return true; - } - if (object instanceof ReverseOrdering) { - ReverseOrdering that = (ReverseOrdering) object; - return this.forwardOrder.equals(that.forwardOrder); - } - return false; - } - - @Override - public String toString() { - return forwardOrder + ".reverse()"; - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/RowSortedTable.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/RowSortedTable.java deleted file mode 100644 index 76d8ad6908ee..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/RowSortedTable.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2010 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; -import java.util.SortedSet; - -/** - * Interface that extends {@code Table} and whose rows are sorted. - * - *

The {@link #rowKeySet} method returns a {@link SortedSet} and the {@link - * #rowMap} method returns a {@link SortedMap}, instead of the {@link Set} and - * {@link Map} specified by the {@link Table} interface. - * - * @author Warren Dukes - * @since 8.0 - */ -@GwtCompatible -@Beta -public interface RowSortedTable extends Table { - /** - * {@inheritDoc} - * - *

This method returns a {@link SortedSet}, instead of the {@code Set} - * specified in the {@link Table} interface. - */ - @Override - SortedSet rowKeySet(); - - /** - * {@inheritDoc} - * - *

This method returns a {@link SortedMap}, instead of the {@code Map} - * specified in the {@link Table} interface. - */ - @Override - SortedMap> rowMap(); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Serialization.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Serialization.java deleted file mode 100644 index 6f57fdc74a59..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Serialization.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.lang.reflect.Field; -import java.util.Collection; -import java.util.Map; - -/** - * Provides static methods for serializing collection classes. - * - *

This class assists the implementation of collection classes. Do not use - * this class to serialize collections that are defined elsewhere. - * - * @author Jared Levy - */ -final class Serialization { - private Serialization() {} - - /** - * Reads a count corresponding to a serialized map, multiset, or multimap. It - * returns the size of a map serialized by {@link - * #writeMap(Map, ObjectOutputStream)}, the number of distinct elements in a - * multiset serialized by {@link - * #writeMultiset(Multiset, ObjectOutputStream)}, or the number of distinct - * keys in a multimap serialized by {@link - * #writeMultimap(Multimap, ObjectOutputStream)}. - */ - static int readCount(ObjectInputStream stream) throws IOException { - return stream.readInt(); - } - - /** - * Stores the contents of a map in an output stream, as part of serialization. - * It does not support concurrent maps whose content may change while the - * method is running. - * - *

The serialized output consists of the number of entries, first key, - * first value, second key, second value, and so on. - */ - static void writeMap(Map map, ObjectOutputStream stream) throws IOException { - stream.writeInt(map.size()); - for (Map.Entry entry : map.entrySet()) { - stream.writeObject(entry.getKey()); - stream.writeObject(entry.getValue()); - } - } - - /** - * Populates a map by reading an input stream, as part of deserialization. - * See {@link #writeMap} for the data format. - */ - static void populateMap(Map map, ObjectInputStream stream) - throws IOException, ClassNotFoundException { - int size = stream.readInt(); - populateMap(map, stream, size); - } - - /** - * Populates a map by reading an input stream, as part of deserialization. - * See {@link #writeMap} for the data format. The size is determined by a - * prior call to {@link #readCount}. - */ - static void populateMap(Map map, ObjectInputStream stream, int size) - throws IOException, ClassNotFoundException { - for (int i = 0; i < size; i++) { - @SuppressWarnings("unchecked") // reading data stored by writeMap - K key = (K) stream.readObject(); - @SuppressWarnings("unchecked") // reading data stored by writeMap - V value = (V) stream.readObject(); - map.put(key, value); - } - } - - /** - * Stores the contents of a multiset in an output stream, as part of - * serialization. It does not support concurrent multisets whose content may - * change while the method is running. - * - *

The serialized output consists of the number of distinct elements, the - * first element, its count, the second element, its count, and so on. - */ - static void writeMultiset(Multiset multiset, ObjectOutputStream stream) - throws IOException { - int entryCount = multiset.entrySet().size(); - stream.writeInt(entryCount); - for (Multiset.Entry entry : multiset.entrySet()) { - stream.writeObject(entry.getElement()); - stream.writeInt(entry.getCount()); - } - } - - /** - * Populates a multiset by reading an input stream, as part of - * deserialization. See {@link #writeMultiset} for the data format. - */ - static void populateMultiset(Multiset multiset, ObjectInputStream stream) - throws IOException, ClassNotFoundException { - int distinctElements = stream.readInt(); - populateMultiset(multiset, stream, distinctElements); - } - - /** - * Populates a multiset by reading an input stream, as part of - * deserialization. See {@link #writeMultiset} for the data format. The number - * of distinct elements is determined by a prior call to {@link #readCount}. - */ - static void populateMultiset( - Multiset multiset, ObjectInputStream stream, int distinctElements) - throws IOException, ClassNotFoundException { - for (int i = 0; i < distinctElements; i++) { - @SuppressWarnings("unchecked") // reading data stored by writeMultiset - E element = (E) stream.readObject(); - int count = stream.readInt(); - multiset.add(element, count); - } - } - - /** - * Stores the contents of a multimap in an output stream, as part of - * serialization. It does not support concurrent multimaps whose content may - * change while the method is running. The {@link Multimap#asMap} view - * determines the ordering in which data is written to the stream. - * - *

The serialized output consists of the number of distinct keys, and then - * for each distinct key: the key, the number of values for that key, and the - * key's values. - */ - static void writeMultimap(Multimap multimap, ObjectOutputStream stream) - throws IOException { - stream.writeInt(multimap.asMap().size()); - for (Map.Entry> entry : multimap.asMap().entrySet()) { - stream.writeObject(entry.getKey()); - stream.writeInt(entry.getValue().size()); - for (V value : entry.getValue()) { - stream.writeObject(value); - } - } - } - - /** - * Populates a multimap by reading an input stream, as part of - * deserialization. See {@link #writeMultimap} for the data format. - */ - static void populateMultimap(Multimap multimap, ObjectInputStream stream) - throws IOException, ClassNotFoundException { - int distinctKeys = stream.readInt(); - populateMultimap(multimap, stream, distinctKeys); - } - - /** - * Populates a multimap by reading an input stream, as part of - * deserialization. See {@link #writeMultimap} for the data format. The number - * of distinct keys is determined by a prior call to {@link #readCount}. - */ - static void populateMultimap( - Multimap multimap, ObjectInputStream stream, int distinctKeys) - throws IOException, ClassNotFoundException { - for (int i = 0; i < distinctKeys; i++) { - @SuppressWarnings("unchecked") // reading data stored by writeMultimap - K key = (K) stream.readObject(); - Collection values = multimap.get(key); - int valueCount = stream.readInt(); - for (int j = 0; j < valueCount; j++) { - @SuppressWarnings("unchecked") // reading data stored by writeMultimap - V value = (V) stream.readObject(); - values.add(value); - } - } - } - - // Secret sauce for setting final fields; don't make it public. - static FieldSetter getFieldSetter(final Class clazz, String fieldName) { - try { - Field field = clazz.getDeclaredField(fieldName); - return new FieldSetter(field); - } catch (NoSuchFieldException e) { - throw new AssertionError(e); // programmer error - } - } - - // Secret sauce for setting final fields; don't make it public. - static final class FieldSetter { - private final Field field; - - private FieldSetter(Field field) { - this.field = field; - field.setAccessible(true); - } - - void set(T instance, Object value) { - try { - field.set(instance, value); - } catch (IllegalAccessException impossible) { - throw new AssertionError(impossible); - } - } - - void set(T instance, int value) { - try { - field.set(instance, value); - } catch (IllegalAccessException impossible) { - throw new AssertionError(impossible); - } - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/SetMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/SetMultimap.java deleted file mode 100644 index 46ae17ac0442..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/SetMultimap.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Collection; -import java.util.Map; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * A {@code Multimap} that cannot hold duplicate key-value pairs. Adding a - * key-value pair that's already in the multimap has no effect. See the {@link - * Multimap} documentation for information common to all multimaps. - * - *

The {@link #get}, {@link #removeAll}, and {@link #replaceValues} methods - * each return a {@link Set} of values, while {@link #entries} returns a {@code - * Set} of map entries. Though the method signature doesn't say so explicitly, - * the map returned by {@link #asMap} has {@code Set} values. - * - *

If the values corresponding to a single key should be ordered according to - * a {@link java.util.Comparator} (or the natural order), see the - * {@link SortedSetMultimap} subinterface. - * - *

Since the value collections are sets, the behavior of a {@code SetMultimap} - * is not specified if key or value objects already present in the - * multimap change in a manner that affects {@code equals} comparisons. - * Use caution if mutable objects are used as keys or values in a - * {@code SetMultimap}. - * - *

See the Guava User Guide article on - * {@code Multimap}. - * - * @author Jared Levy - * @since 2.0 - */ -@GwtCompatible -public interface SetMultimap extends Multimap { - /** - * {@inheritDoc} - * - *

Because a {@code SetMultimap} has unique values for a given key, this - * method returns a {@link Set}, instead of the {@link java.util.Collection} - * specified in the {@link Multimap} interface. - */ - @Override - Set get(@Nullable K key); - - /** - * {@inheritDoc} - * - *

Because a {@code SetMultimap} has unique values for a given key, this - * method returns a {@link Set}, instead of the {@link java.util.Collection} - * specified in the {@link Multimap} interface. - */ - @Override - Set removeAll(@Nullable Object key); - - /** - * {@inheritDoc} - * - *

Because a {@code SetMultimap} has unique values for a given key, this - * method returns a {@link Set}, instead of the {@link java.util.Collection} - * specified in the {@link Multimap} interface. - * - *

Any duplicates in {@code values} will be stored in the multimap once. - */ - @Override - Set replaceValues(K key, Iterable values); - - /** - * {@inheritDoc} - * - *

Because a {@code SetMultimap} has unique values for a given key, this - * method returns a {@link Set}, instead of the {@link java.util.Collection} - * specified in the {@link Multimap} interface. - */ - @Override - Set> entries(); - - /** - * {@inheritDoc} - * - *

Note: The returned map's values are guaranteed to be of type - * {@link Set}. To obtain this map with the more specific generic type - * {@code Map>}, call {@link Multimaps#asMap(SetMultimap)} instead. - */ - @Override - Map> asMap(); - - /** - * Compares the specified object to this multimap for equality. - * - *

Two {@code SetMultimap} instances are equal if, for each key, they - * contain the same values. Equality does not depend on the ordering of keys - * or values. - * - *

An empty {@code SetMultimap} is equal to any other empty {@code - * Multimap}, including an empty {@code ListMultimap}. - */ - @Override - boolean equals(@Nullable Object obj); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Sets.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Sets.java deleted file mode 100644 index 5d0142cebc35..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Sets.java +++ /dev/null @@ -1,1735 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import com.google.common.collect.Collections2.FilteredCollection; - -import java.io.Serializable; -import java.util.AbstractSet; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.EnumSet; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.NavigableSet; -import java.util.NoSuchElementException; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArraySet; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * Static utility methods pertaining to {@link Set} instances. Also see this - * class's counterparts {@link Lists}, {@link Maps} and {@link Queues}. - * - *

See the Guava User Guide article on - * {@code Sets}. - * - * @author Kevin Bourrillion - * @author Jared Levy - * @author Chris Povirk - * @since 2.0 - */ -@GwtCompatible(emulated = true) -public final class Sets { - private Sets() {} - - /** - * {@link AbstractSet} substitute without the potentially-quadratic - * {@code removeAll} implementation. - */ - abstract static class ImprovedAbstractSet extends AbstractSet { - @Override - public boolean removeAll(Collection c) { - return removeAllImpl(this, c); - } - - @Override - public boolean retainAll(Collection c) { - return super.retainAll(checkNotNull(c)); // GWT compatibility - } - } - - /** - * Returns an immutable set instance containing the given enum elements. - * Internally, the returned set will be backed by an {@link EnumSet}. - * - *

The iteration order of the returned set follows the enum's iteration - * order, not the order in which the elements are provided to the method. - * - * @param anElement one of the elements the set should contain - * @param otherElements the rest of the elements the set should contain - * @return an immutable set containing those elements, minus duplicates - */ - // http://code.google.com/p/google-web-toolkit/issues/detail?id=3028 - @GwtCompatible(serializable = true) - public static > ImmutableSet immutableEnumSet( - E anElement, E... otherElements) { - return ImmutableEnumSet.asImmutable(EnumSet.of(anElement, otherElements)); - } - - /** - * Returns an immutable set instance containing the given enum elements. - * Internally, the returned set will be backed by an {@link EnumSet}. - * - *

The iteration order of the returned set follows the enum's iteration - * order, not the order in which the elements appear in the given collection. - * - * @param elements the elements, all of the same {@code enum} type, that the - * set should contain - * @return an immutable set containing those elements, minus duplicates - */ - // http://code.google.com/p/google-web-toolkit/issues/detail?id=3028 - @GwtCompatible(serializable = true) - public static > ImmutableSet immutableEnumSet(Iterable elements) { - if (elements instanceof ImmutableEnumSet) { - return (ImmutableEnumSet) elements; - } else if (elements instanceof Collection) { - Collection collection = (Collection) elements; - if (collection.isEmpty()) { - return ImmutableSet.of(); - } else { - return ImmutableEnumSet.asImmutable(EnumSet.copyOf(collection)); - } - } else { - Iterator itr = elements.iterator(); - if (itr.hasNext()) { - EnumSet enumSet = EnumSet.of(itr.next()); - Iterators.addAll(enumSet, itr); - return ImmutableEnumSet.asImmutable(enumSet); - } else { - return ImmutableSet.of(); - } - } - } - - /** - * Returns a new, mutable {@code EnumSet} instance containing the given elements in their - * natural order. This method behaves identically to {@link EnumSet#copyOf(Collection)}, but also - * accepts non-{@code Collection} iterables and empty iterables. - */ - public static > EnumSet newEnumSet( - Iterable iterable, Class elementType) { - EnumSet set = EnumSet.noneOf(elementType); - Iterables.addAll(set, iterable); - return set; - } - - // HashSet - - /** - * Creates a mutable, initially empty {@code HashSet} instance. - * - *

Note: if mutability is not required, use {@link ImmutableSet#of()} instead. If - * {@code E} is an {@link Enum} type, use {@link EnumSet#noneOf} instead. Otherwise, strongly - * consider using a {@code LinkedHashSet} instead, at the cost of increased memory footprint, to - * get deterministic iteration behavior. - * - *

Note for Java 7 and later: this method is now unnecessary and should be treated as - * deprecated. Instead, use the {@code HashSet} constructor directly, taking advantage of the new - * "diamond" syntax. - */ - public static HashSet newHashSet() { - return new HashSet(); - } - - /** - * Creates a mutable {@code HashSet} instance initially containing the given elements. - * - *

Note: if elements are non-null and won't be added or removed after this point, use - * {@link ImmutableSet#of()} or {@link ImmutableSet#copyOf(Object[])} instead. If {@code E} is an - * {@link Enum} type, use {@link EnumSet#of(Enum, Enum[])} instead. Otherwise, strongly consider - * using a {@code LinkedHashSet} instead, at the cost of increased memory footprint, to get - * deterministic iteration behavior. - * - *

This method is just a small convenience, either for {@code newHashSet(}{@link Arrays#asList - * asList}{@code (...))}, or for creating an empty set then calling {@link Collections#addAll}. - * This method is not actually very useful and will likely be deprecated in the future. - */ - public static HashSet newHashSet(E... elements) { - HashSet set = newHashSetWithExpectedSize(elements.length); - Collections.addAll(set, elements); - return set; - } - - /** - * Creates a {@code HashSet} instance, with a high enough initial table size that it should - * hold {@code expectedSize} elements without resizing. This behavior cannot be broadly - * guaranteed, but it is observed to be true for OpenJDK 1.7. It also can't be guaranteed that the - * method isn't inadvertently oversizing the returned set. - * - * @param expectedSize the number of elements you expect to add to the - * returned set - * @return a new, empty {@code HashSet} with enough capacity to hold {@code - * expectedSize} elements without resizing - * @throws IllegalArgumentException if {@code expectedSize} is negative - */ - public static HashSet newHashSetWithExpectedSize(int expectedSize) { - return new HashSet(Maps.capacity(expectedSize)); - } - - /** - * Creates a mutable {@code HashSet} instance containing the given elements. A very thin - * convenience for creating an empty set then calling {@link Collection#addAll} or {@link - * Iterables#addAll}. - * - *

Note: if mutability is not required and the elements are non-null, use {@link - * ImmutableSet#copyOf(Iterable)} instead. (Or, change {@code elements} to be a {@link - * FluentIterable} and call {@code elements.toSet()}.) - * - *

Note: if {@code E} is an {@link Enum} type, use {@link #newEnumSet(Iterable, Class)} - * instead. - * - *

Note for Java 7 and later: if {@code elements} is a {@link Collection}, you don't - * need this method. Instead, use the {@code HashSet} constructor directly, taking advantage of - * the new "diamond" syntax. - * - *

Overall, this method is not very useful and will likely be deprecated in the future. - */ - public static HashSet newHashSet(Iterable elements) { - return (elements instanceof Collection) - ? new HashSet(Collections2.cast(elements)) - : newHashSet(elements.iterator()); - } - - /** - * Creates a mutable {@code HashSet} instance containing the given elements. A very thin - * convenience for creating an empty set and then calling {@link Iterators#addAll}. - * - *

Note: if mutability is not required and the elements are non-null, use {@link - * ImmutableSet#copyOf(Iterator)} instead. - * - *

Note: if {@code E} is an {@link Enum} type, you should create an {@link EnumSet} - * instead. - * - *

Overall, this method is not very useful and will likely be deprecated in the future. - */ - public static HashSet newHashSet(Iterator elements) { - HashSet set = newHashSet(); - Iterators.addAll(set, elements); - return set; - } - - /** - * Creates a thread-safe set backed by a hash map. The set is backed by a - * {@link ConcurrentHashMap} instance, and thus carries the same concurrency - * guarantees. - * - *

Unlike {@code HashSet}, this class does NOT allow {@code null} to be - * used as an element. The set is serializable. - * - * @return a new, empty thread-safe {@code Set} - * @since 15.0 - */ - public static Set newConcurrentHashSet() { - return newSetFromMap(new ConcurrentHashMap()); - } - - /** - * Creates a thread-safe set backed by a hash map and containing the given - * elements. The set is backed by a {@link ConcurrentHashMap} instance, and - * thus carries the same concurrency guarantees. - * - *

Unlike {@code HashSet}, this class does NOT allow {@code null} to be - * used as an element. The set is serializable. - * - * @param elements the elements that the set should contain - * @return a new thread-safe set containing those elements (minus duplicates) - * @throws NullPointerException if {@code elements} or any of its contents is - * null - * @since 15.0 - */ - public static Set newConcurrentHashSet(Iterable elements) { - Set set = newConcurrentHashSet(); - Iterables.addAll(set, elements); - return set; - } - - // LinkedHashSet - - /** - * Creates a mutable, empty {@code LinkedHashSet} instance. - * - *

Note: if mutability is not required, use {@link - * ImmutableSet#of()} instead. - * - * @return a new, empty {@code LinkedHashSet} - */ - public static LinkedHashSet newLinkedHashSet() { - return new LinkedHashSet(); - } - - /** - * Creates a {@code LinkedHashSet} instance, with a high enough "initial - * capacity" that it should hold {@code expectedSize} elements without - * growth. This behavior cannot be broadly guaranteed, but it is observed to - * be true for OpenJDK 1.6. It also can't be guaranteed that the method isn't - * inadvertently oversizing the returned set. - * - * @param expectedSize the number of elements you expect to add to the - * returned set - * @return a new, empty {@code LinkedHashSet} with enough capacity to hold - * {@code expectedSize} elements without resizing - * @throws IllegalArgumentException if {@code expectedSize} is negative - * @since 11.0 - */ - public static LinkedHashSet newLinkedHashSetWithExpectedSize(int expectedSize) { - return new LinkedHashSet(Maps.capacity(expectedSize)); - } - - /** - * Creates a mutable {@code LinkedHashSet} instance containing the - * given elements in order. - * - *

Note: if mutability is not required and the elements are - * non-null, use {@link ImmutableSet#copyOf(Iterable)} instead. - * - * @param elements the elements that the set should contain, in order - * @return a new {@code LinkedHashSet} containing those elements (minus - * duplicates) - */ - public static LinkedHashSet newLinkedHashSet(Iterable elements) { - if (elements instanceof Collection) { - return new LinkedHashSet(Collections2.cast(elements)); - } - LinkedHashSet set = newLinkedHashSet(); - Iterables.addAll(set, elements); - return set; - } - - // TreeSet - - /** - * Creates a mutable, empty {@code TreeSet} instance sorted by the - * natural sort ordering of its elements. - * - *

Note: if mutability is not required, use {@link - * ImmutableSortedSet#of()} instead. - * - * @return a new, empty {@code TreeSet} - */ - public static TreeSet newTreeSet() { - return new TreeSet(); - } - - /** - * Creates a mutable {@code TreeSet} instance containing the given - * elements sorted by their natural ordering. - * - *

Note: if mutability is not required, use {@link - * ImmutableSortedSet#copyOf(Iterable)} instead. - * - *

Note: If {@code elements} is a {@code SortedSet} with an explicit - * comparator, this method has different behavior than - * {@link TreeSet#TreeSet(SortedSet)}, which returns a {@code TreeSet} with - * that comparator. - * - * @param elements the elements that the set should contain - * @return a new {@code TreeSet} containing those elements (minus duplicates) - */ - public static TreeSet newTreeSet(Iterable elements) { - TreeSet set = newTreeSet(); - Iterables.addAll(set, elements); - return set; - } - - /** - * Creates a mutable, empty {@code TreeSet} instance with the given - * comparator. - * - *

Note: if mutability is not required, use {@code - * ImmutableSortedSet.orderedBy(comparator).build()} instead. - * - * @param comparator the comparator to use to sort the set - * @return a new, empty {@code TreeSet} - * @throws NullPointerException if {@code comparator} is null - */ - public static TreeSet newTreeSet(Comparator comparator) { - return new TreeSet(checkNotNull(comparator)); - } - - /** - * Creates an empty {@code Set} that uses identity to determine equality. It - * compares object references, instead of calling {@code equals}, to - * determine whether a provided object matches an element in the set. For - * example, {@code contains} returns {@code false} when passed an object that - * equals a set member, but isn't the same instance. This behavior is similar - * to the way {@code IdentityHashMap} handles key lookups. - * - * @since 8.0 - */ - public static Set newIdentityHashSet() { - return Sets.newSetFromMap(Maps.newIdentityHashMap()); - } - - /** - * Creates an empty {@code CopyOnWriteArraySet} instance. - * - *

Note: if you need an immutable empty {@link Set}, use - * {@link Collections#emptySet} instead. - * - * @return a new, empty {@code CopyOnWriteArraySet} - * @since 12.0 - */ - @GwtIncompatible("CopyOnWriteArraySet") - public static CopyOnWriteArraySet newCopyOnWriteArraySet() { - return new CopyOnWriteArraySet(); - } - - /** - * Creates a {@code CopyOnWriteArraySet} instance containing the given elements. - * - * @param elements the elements that the set should contain, in order - * @return a new {@code CopyOnWriteArraySet} containing those elements - * @since 12.0 - */ - @GwtIncompatible("CopyOnWriteArraySet") - public static CopyOnWriteArraySet newCopyOnWriteArraySet(Iterable elements) { - // We copy elements to an ArrayList first, rather than incurring the - // quadratic cost of adding them to the COWAS directly. - Collection elementsCollection = - (elements instanceof Collection) - ? Collections2.cast(elements) - : Lists.newArrayList(elements); - return new CopyOnWriteArraySet(elementsCollection); - } - - /** - * Creates an {@code EnumSet} consisting of all enum values that are not in - * the specified collection. If the collection is an {@link EnumSet}, this - * method has the same behavior as {@link EnumSet#complementOf}. Otherwise, - * the specified collection must contain at least one element, in order to - * determine the element type. If the collection could be empty, use - * {@link #complementOf(Collection, Class)} instead of this method. - * - * @param collection the collection whose complement should be stored in the - * enum set - * @return a new, modifiable {@code EnumSet} containing all values of the enum - * that aren't present in the given collection - * @throws IllegalArgumentException if {@code collection} is not an - * {@code EnumSet} instance and contains no elements - */ - public static > EnumSet complementOf(Collection collection) { - if (collection instanceof EnumSet) { - return EnumSet.complementOf((EnumSet) collection); - } - checkArgument( - !collection.isEmpty(), "collection is empty; use the other version of this method"); - Class type = collection.iterator().next().getDeclaringClass(); - return makeComplementByHand(collection, type); - } - - /** - * Creates an {@code EnumSet} consisting of all enum values that are not in - * the specified collection. This is equivalent to - * {@link EnumSet#complementOf}, but can act on any input collection, as long - * as the elements are of enum type. - * - * @param collection the collection whose complement should be stored in the - * {@code EnumSet} - * @param type the type of the elements in the set - * @return a new, modifiable {@code EnumSet} initially containing all the - * values of the enum not present in the given collection - */ - public static > EnumSet complementOf( - Collection collection, Class type) { - checkNotNull(collection); - return (collection instanceof EnumSet) - ? EnumSet.complementOf((EnumSet) collection) - : makeComplementByHand(collection, type); - } - - private static > EnumSet makeComplementByHand( - Collection collection, Class type) { - EnumSet result = EnumSet.allOf(type); - result.removeAll(collection); - return result; - } - - /** - * Returns a set backed by the specified map. The resulting set displays - * the same ordering, concurrency, and performance characteristics as the - * backing map. In essence, this factory method provides a {@link Set} - * implementation corresponding to any {@link Map} implementation. There is no - * need to use this method on a {@link Map} implementation that already has a - * corresponding {@link Set} implementation (such as {@link java.util.HashMap} - * or {@link java.util.TreeMap}). - * - *

Each method invocation on the set returned by this method results in - * exactly one method invocation on the backing map or its {@code keySet} - * view, with one exception. The {@code addAll} method is implemented as a - * sequence of {@code put} invocations on the backing map. - * - *

The specified map must be empty at the time this method is invoked, - * and should not be accessed directly after this method returns. These - * conditions are ensured if the map is created empty, passed directly - * to this method, and no reference to the map is retained, as illustrated - * in the following code fragment:

  {@code
-   *
-   *   Set identityHashSet = Sets.newSetFromMap(
-   *       new IdentityHashMap());}
-   *
-   * 

The returned set is serializable if the backing map is. - * - * @param map the backing map - * @return the set backed by the map - * @throws IllegalArgumentException if {@code map} is not empty - * @deprecated Use {@link Collections#newSetFromMap} instead. This method - * will be removed in August 2017. - */ - @Deprecated - public static Set newSetFromMap(Map map) { - return Platform.newSetFromMap(map); - } - - /** - * An unmodifiable view of a set which may be backed by other sets; this view - * will change as the backing sets do. Contains methods to copy the data into - * a new set which will then remain stable. There is usually no reason to - * retain a reference of type {@code SetView}; typically, you either use it - * as a plain {@link Set}, or immediately invoke {@link #immutableCopy} or - * {@link #copyInto} and forget the {@code SetView} itself. - * - * @since 2.0 - */ - public abstract static class SetView extends AbstractSet { - private SetView() {} // no subclasses but our own - - /** - * Returns an immutable copy of the current contents of this set view. - * Does not support null elements. - * - *

Warning: this may have unexpected results if a backing set of - * this view uses a nonstandard notion of equivalence, for example if it is - * a {@link TreeSet} using a comparator that is inconsistent with {@link - * Object#equals(Object)}. - */ - public ImmutableSet immutableCopy() { - return ImmutableSet.copyOf(this); - } - - /** - * Copies the current contents of this set view into an existing set. This - * method has equivalent behavior to {@code set.addAll(this)}, assuming that - * all the sets involved are based on the same notion of equivalence. - * - * @return a reference to {@code set}, for convenience - */ - // Note: S should logically extend Set but can't due to either - // some javac bug or some weirdness in the spec, not sure which. - public > S copyInto(S set) { - set.addAll(this); - return set; - } - } - - /** - * Returns an unmodifiable view of the union of two sets. The returned - * set contains all elements that are contained in either backing set. - * Iterating over the returned set iterates first over all the elements of - * {@code set1}, then over each element of {@code set2}, in order, that is not - * contained in {@code set1}. - * - *

Results are undefined if {@code set1} and {@code set2} are sets based on - * different equivalence relations (as {@link HashSet}, {@link TreeSet}, and - * the {@link Map#keySet} of an {@code IdentityHashMap} all are). - * - *

Note: The returned view performs better when {@code set1} is the - * smaller of the two sets. If you have reason to believe one of your sets - * will generally be smaller than the other, pass it first. - * - *

Further, note that the current implementation is not suitable for nested - * {@code union} views, i.e. the following should be avoided when in a loop: - * {@code union = Sets.union(union, anotherSet);}, since iterating over the resulting - * set has a cubic complexity to the depth of the nesting. - */ - public static SetView union(final Set set1, final Set set2) { - checkNotNull(set1, "set1"); - checkNotNull(set2, "set2"); - - final Set set2minus1 = difference(set2, set1); - - return new SetView() { - @Override - public int size() { - return set1.size() + set2minus1.size(); - } - - @Override - public boolean isEmpty() { - return set1.isEmpty() && set2.isEmpty(); - } - - @Override - public Iterator iterator() { - return Iterators.unmodifiableIterator( - Iterators.concat(set1.iterator(), set2minus1.iterator())); - } - - @Override - public boolean contains(Object object) { - return set1.contains(object) || set2.contains(object); - } - - @Override - public > S copyInto(S set) { - set.addAll(set1); - set.addAll(set2); - return set; - } - - @Override - public ImmutableSet immutableCopy() { - return new ImmutableSet.Builder().addAll(set1).addAll(set2).build(); - } - }; - } - - /** - * Returns an unmodifiable view of the intersection of two sets. The - * returned set contains all elements that are contained by both backing sets. - * The iteration order of the returned set matches that of {@code set1}. - * - *

Results are undefined if {@code set1} and {@code set2} are sets based - * on different equivalence relations (as {@code HashSet}, {@code TreeSet}, - * and the keySet of an {@code IdentityHashMap} all are). - * - *

Note: The returned view performs slightly better when {@code - * set1} is the smaller of the two sets. If you have reason to believe one of - * your sets will generally be smaller than the other, pass it first. - * Unfortunately, since this method sets the generic type of the returned set - * based on the type of the first set passed, this could in rare cases force - * you to make a cast, for example:

   {@code
-   *
-   *   Set aFewBadObjects = ...
-   *   Set manyBadStrings = ...
-   *
-   *   // impossible for a non-String to be in the intersection
-   *   SuppressWarnings("unchecked")
-   *   Set badStrings = (Set) Sets.intersection(
-   *       aFewBadObjects, manyBadStrings);}
-   *
-   * 

This is unfortunate, but should come up only very rarely. - */ - public static SetView intersection(final Set set1, final Set set2) { - checkNotNull(set1, "set1"); - checkNotNull(set2, "set2"); - - final Predicate inSet2 = Predicates.in(set2); - return new SetView() { - @Override - public Iterator iterator() { - return Iterators.filter(set1.iterator(), inSet2); - } - - @Override - public int size() { - return Iterators.size(iterator()); - } - - @Override - public boolean isEmpty() { - return !iterator().hasNext(); - } - - @Override - public boolean contains(Object object) { - return set1.contains(object) && set2.contains(object); - } - - @Override - public boolean containsAll(Collection collection) { - return set1.containsAll(collection) && set2.containsAll(collection); - } - }; - } - - /** - * Returns an unmodifiable view of the difference of two sets. The - * returned set contains all elements that are contained by {@code set1} and - * not contained by {@code set2}. {@code set2} may also contain elements not - * present in {@code set1}; these are simply ignored. The iteration order of - * the returned set matches that of {@code set1}. - * - *

Results are undefined if {@code set1} and {@code set2} are sets based - * on different equivalence relations (as {@code HashSet}, {@code TreeSet}, - * and the keySet of an {@code IdentityHashMap} all are). - */ - public static SetView difference(final Set set1, final Set set2) { - checkNotNull(set1, "set1"); - checkNotNull(set2, "set2"); - - final Predicate notInSet2 = Predicates.not(Predicates.in(set2)); - return new SetView() { - @Override - public Iterator iterator() { - return Iterators.filter(set1.iterator(), notInSet2); - } - - @Override - public int size() { - return Iterators.size(iterator()); - } - - @Override - public boolean isEmpty() { - return set2.containsAll(set1); - } - - @Override - public boolean contains(Object element) { - return set1.contains(element) && !set2.contains(element); - } - }; - } - - /** - * Returns an unmodifiable view of the symmetric difference of two - * sets. The returned set contains all elements that are contained in either - * {@code set1} or {@code set2} but not in both. The iteration order of the - * returned set is undefined. - * - *

Results are undefined if {@code set1} and {@code set2} are sets based - * on different equivalence relations (as {@code HashSet}, {@code TreeSet}, - * and the keySet of an {@code IdentityHashMap} all are). - * - * @since 3.0 - */ - public static SetView symmetricDifference( - final Set set1, final Set set2) { - checkNotNull(set1, "set1"); - checkNotNull(set2, "set2"); - - return new SetView() { - @Override - public Iterator iterator() { - final Iterator itr1 = set1.iterator(); - final Iterator itr2 = set2.iterator(); - return new AbstractIterator() { - @Override - public E computeNext() { - while (itr1.hasNext()) { - E elem1 = itr1.next(); - if (!set2.contains(elem1)) { - return elem1; - } - } - while (itr2.hasNext()) { - E elem2 = itr2.next(); - if (!set1.contains(elem2)) { - return elem2; - } - } - return endOfData(); - } - }; - } - - @Override - public int size() { - return Iterators.size(iterator()); - } - - @Override - public boolean isEmpty() { - return set1.equals(set2); - } - - @Override - public boolean contains(Object element) { - return set1.contains(element) ^ set2.contains(element); - } - }; - } - - /** - * Returns the elements of {@code unfiltered} that satisfy a predicate. The - * returned set is a live view of {@code unfiltered}; changes to one affect - * the other. - * - *

The resulting set's iterator does not support {@code remove()}, but all - * other set methods are supported. When given an element that doesn't satisfy - * the predicate, the set's {@code add()} and {@code addAll()} methods throw - * an {@link IllegalArgumentException}. When methods such as {@code - * removeAll()} and {@code clear()} are called on the filtered set, only - * elements that satisfy the filter will be removed from the underlying set. - * - *

The returned set isn't threadsafe or serializable, even if - * {@code unfiltered} is. - * - *

Many of the filtered set's methods, such as {@code size()}, iterate - * across every element in the underlying set and determine which elements - * satisfy the filter. When a live view is not needed, it may be faster - * to copy {@code Iterables.filter(unfiltered, predicate)} and use the copy. - * - *

Warning: {@code predicate} must be consistent with equals, - * as documented at {@link Predicate#apply}. Do not provide a predicate such - * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent - * with equals. (See {@link Iterables#filter(Iterable, Class)} for related - * functionality.) - */ - // TODO(kevinb): how to omit that last sentence when building GWT javadoc? - @CheckReturnValue - public static Set filter(Set unfiltered, Predicate predicate) { - if (unfiltered instanceof SortedSet) { - return filter((SortedSet) unfiltered, predicate); - } - if (unfiltered instanceof FilteredSet) { - // Support clear(), removeAll(), and retainAll() when filtering a filtered - // collection. - FilteredSet filtered = (FilteredSet) unfiltered; - Predicate combinedPredicate = Predicates.and(filtered.predicate, predicate); - return new FilteredSet((Set) filtered.unfiltered, combinedPredicate); - } - - return new FilteredSet(checkNotNull(unfiltered), checkNotNull(predicate)); - } - - private static class FilteredSet extends FilteredCollection implements Set { - FilteredSet(Set unfiltered, Predicate predicate) { - super(unfiltered, predicate); - } - - @Override - public boolean equals(@Nullable Object object) { - return equalsImpl(this, object); - } - - @Override - public int hashCode() { - return hashCodeImpl(this); - } - } - - /** - * Returns the elements of a {@code SortedSet}, {@code unfiltered}, that - * satisfy a predicate. The returned set is a live view of {@code unfiltered}; - * changes to one affect the other. - * - *

The resulting set's iterator does not support {@code remove()}, but all - * other set methods are supported. When given an element that doesn't satisfy - * the predicate, the set's {@code add()} and {@code addAll()} methods throw - * an {@link IllegalArgumentException}. When methods such as - * {@code removeAll()} and {@code clear()} are called on the filtered set, - * only elements that satisfy the filter will be removed from the underlying - * set. - * - *

The returned set isn't threadsafe or serializable, even if - * {@code unfiltered} is. - * - *

Many of the filtered set's methods, such as {@code size()}, iterate across - * every element in the underlying set and determine which elements satisfy - * the filter. When a live view is not needed, it may be faster to copy - * {@code Iterables.filter(unfiltered, predicate)} and use the copy. - * - *

Warning: {@code predicate} must be consistent with equals, - * as documented at {@link Predicate#apply}. Do not provide a predicate such as - * {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent with - * equals. (See {@link Iterables#filter(Iterable, Class)} for related - * functionality.) - * - * @since 11.0 - */ - @CheckReturnValue - public static SortedSet filter(SortedSet unfiltered, Predicate predicate) { - return Platform.setsFilterSortedSet(unfiltered, predicate); - } - - static SortedSet filterSortedIgnoreNavigable( - SortedSet unfiltered, Predicate predicate) { - if (unfiltered instanceof FilteredSet) { - // Support clear(), removeAll(), and retainAll() when filtering a filtered - // collection. - FilteredSet filtered = (FilteredSet) unfiltered; - Predicate combinedPredicate = Predicates.and(filtered.predicate, predicate); - return new FilteredSortedSet((SortedSet) filtered.unfiltered, combinedPredicate); - } - - return new FilteredSortedSet(checkNotNull(unfiltered), checkNotNull(predicate)); - } - - private static class FilteredSortedSet extends FilteredSet implements SortedSet { - - FilteredSortedSet(SortedSet unfiltered, Predicate predicate) { - super(unfiltered, predicate); - } - - @Override - public Comparator comparator() { - return ((SortedSet) unfiltered).comparator(); - } - - @Override - public SortedSet subSet(E fromElement, E toElement) { - return new FilteredSortedSet( - ((SortedSet) unfiltered).subSet(fromElement, toElement), predicate); - } - - @Override - public SortedSet headSet(E toElement) { - return new FilteredSortedSet(((SortedSet) unfiltered).headSet(toElement), predicate); - } - - @Override - public SortedSet tailSet(E fromElement) { - return new FilteredSortedSet(((SortedSet) unfiltered).tailSet(fromElement), predicate); - } - - @Override - public E first() { - return iterator().next(); - } - - @Override - public E last() { - SortedSet sortedUnfiltered = (SortedSet) unfiltered; - while (true) { - E element = sortedUnfiltered.last(); - if (predicate.apply(element)) { - return element; - } - sortedUnfiltered = sortedUnfiltered.headSet(element); - } - } - } - - /** - * Returns the elements of a {@code NavigableSet}, {@code unfiltered}, that - * satisfy a predicate. The returned set is a live view of {@code unfiltered}; - * changes to one affect the other. - * - *

The resulting set's iterator does not support {@code remove()}, but all - * other set methods are supported. When given an element that doesn't satisfy - * the predicate, the set's {@code add()} and {@code addAll()} methods throw - * an {@link IllegalArgumentException}. When methods such as - * {@code removeAll()} and {@code clear()} are called on the filtered set, - * only elements that satisfy the filter will be removed from the underlying - * set. - * - *

The returned set isn't threadsafe or serializable, even if - * {@code unfiltered} is. - * - *

Many of the filtered set's methods, such as {@code size()}, iterate across - * every element in the underlying set and determine which elements satisfy - * the filter. When a live view is not needed, it may be faster to copy - * {@code Iterables.filter(unfiltered, predicate)} and use the copy. - * - *

Warning: {@code predicate} must be consistent with equals, - * as documented at {@link Predicate#apply}. Do not provide a predicate such as - * {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent with - * equals. (See {@link Iterables#filter(Iterable, Class)} for related - * functionality.) - * - * @since 14.0 - */ - @GwtIncompatible("NavigableSet") - @SuppressWarnings("unchecked") - @CheckReturnValue - public static NavigableSet filter( - NavigableSet unfiltered, Predicate predicate) { - if (unfiltered instanceof FilteredSet) { - // Support clear(), removeAll(), and retainAll() when filtering a filtered - // collection. - FilteredSet filtered = (FilteredSet) unfiltered; - Predicate combinedPredicate = Predicates.and(filtered.predicate, predicate); - return new FilteredNavigableSet((NavigableSet) filtered.unfiltered, combinedPredicate); - } - - return new FilteredNavigableSet(checkNotNull(unfiltered), checkNotNull(predicate)); - } - - @GwtIncompatible("NavigableSet") - private static class FilteredNavigableSet extends FilteredSortedSet - implements NavigableSet { - FilteredNavigableSet(NavigableSet unfiltered, Predicate predicate) { - super(unfiltered, predicate); - } - - NavigableSet unfiltered() { - return (NavigableSet) unfiltered; - } - - @Override - @Nullable - public E lower(E e) { - return Iterators.getNext(headSet(e, false).descendingIterator(), null); - } - - @Override - @Nullable - public E floor(E e) { - return Iterators.getNext(headSet(e, true).descendingIterator(), null); - } - - @Override - public E ceiling(E e) { - return Iterables.getFirst(tailSet(e, true), null); - } - - @Override - public E higher(E e) { - return Iterables.getFirst(tailSet(e, false), null); - } - - @Override - public E pollFirst() { - return Iterables.removeFirstMatching(unfiltered(), predicate); - } - - @Override - public E pollLast() { - return Iterables.removeFirstMatching(unfiltered().descendingSet(), predicate); - } - - @Override - public NavigableSet descendingSet() { - return Sets.filter(unfiltered().descendingSet(), predicate); - } - - @Override - public Iterator descendingIterator() { - return Iterators.filter(unfiltered().descendingIterator(), predicate); - } - - @Override - public E last() { - return descendingIterator().next(); - } - - @Override - public NavigableSet subSet( - E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { - return filter( - unfiltered().subSet(fromElement, fromInclusive, toElement, toInclusive), predicate); - } - - @Override - public NavigableSet headSet(E toElement, boolean inclusive) { - return filter(unfiltered().headSet(toElement, inclusive), predicate); - } - - @Override - public NavigableSet tailSet(E fromElement, boolean inclusive) { - return filter(unfiltered().tailSet(fromElement, inclusive), predicate); - } - } - - /** - * Returns every possible list that can be formed by choosing one element - * from each of the given sets in order; the "n-ary - * Cartesian - * product" of the sets. For example:

   {@code
-   *
-   *   Sets.cartesianProduct(ImmutableList.of(
-   *       ImmutableSet.of(1, 2),
-   *       ImmutableSet.of("A", "B", "C")))}
- * - *

returns a set containing six lists: - * - *

    - *
  • {@code ImmutableList.of(1, "A")} - *
  • {@code ImmutableList.of(1, "B")} - *
  • {@code ImmutableList.of(1, "C")} - *
  • {@code ImmutableList.of(2, "A")} - *
  • {@code ImmutableList.of(2, "B")} - *
  • {@code ImmutableList.of(2, "C")} - *
- * - *

The result is guaranteed to be in the "traditional", lexicographical - * order for Cartesian products that you would get from nesting for loops: - *

   {@code
-   *
-   *   for (B b0 : sets.get(0)) {
-   *     for (B b1 : sets.get(1)) {
-   *       ...
-   *       ImmutableList tuple = ImmutableList.of(b0, b1, ...);
-   *       // operate on tuple
-   *     }
-   *   }}
- * - *

Note that if any input set is empty, the Cartesian product will also be - * empty. If no sets at all are provided (an empty list), the resulting - * Cartesian product has one element, an empty list (counter-intuitive, but - * mathematically consistent). - * - *

Performance notes: while the cartesian product of sets of size - * {@code m, n, p} is a set of size {@code m x n x p}, its actual memory - * consumption is much smaller. When the cartesian set is constructed, the - * input sets are merely copied. Only as the resulting set is iterated are the - * individual lists created, and these are not retained after iteration. - * - * @param sets the sets to choose elements from, in the order that - * the elements chosen from those sets should appear in the resulting - * lists - * @param any common base class shared by all axes (often just {@link - * Object}) - * @return the Cartesian product, as an immutable set containing immutable - * lists - * @throws NullPointerException if {@code sets}, any one of the {@code sets}, - * or any element of a provided set is null - * @since 2.0 - */ - public static Set> cartesianProduct(List> sets) { - return CartesianSet.create(sets); - } - - /** - * Returns every possible list that can be formed by choosing one element - * from each of the given sets in order; the "n-ary - * Cartesian - * product" of the sets. For example:

   {@code
-   *
-   *   Sets.cartesianProduct(
-   *       ImmutableSet.of(1, 2),
-   *       ImmutableSet.of("A", "B", "C"))}
- * - *

returns a set containing six lists: - * - *

    - *
  • {@code ImmutableList.of(1, "A")} - *
  • {@code ImmutableList.of(1, "B")} - *
  • {@code ImmutableList.of(1, "C")} - *
  • {@code ImmutableList.of(2, "A")} - *
  • {@code ImmutableList.of(2, "B")} - *
  • {@code ImmutableList.of(2, "C")} - *
- * - *

The result is guaranteed to be in the "traditional", lexicographical - * order for Cartesian products that you would get from nesting for loops: - *

   {@code
-   *
-   *   for (B b0 : sets.get(0)) {
-   *     for (B b1 : sets.get(1)) {
-   *       ...
-   *       ImmutableList tuple = ImmutableList.of(b0, b1, ...);
-   *       // operate on tuple
-   *     }
-   *   }}
- * - *

Note that if any input set is empty, the Cartesian product will also be - * empty. If no sets at all are provided (an empty list), the resulting - * Cartesian product has one element, an empty list (counter-intuitive, but - * mathematically consistent). - * - *

Performance notes: while the cartesian product of sets of size - * {@code m, n, p} is a set of size {@code m x n x p}, its actual memory - * consumption is much smaller. When the cartesian set is constructed, the - * input sets are merely copied. Only as the resulting set is iterated are the - * individual lists created, and these are not retained after iteration. - * - * @param sets the sets to choose elements from, in the order that - * the elements chosen from those sets should appear in the resulting - * lists - * @param any common base class shared by all axes (often just {@link - * Object}) - * @return the Cartesian product, as an immutable set containing immutable - * lists - * @throws NullPointerException if {@code sets}, any one of the {@code sets}, - * or any element of a provided set is null - * @since 2.0 - */ - public static Set> cartesianProduct(Set... sets) { - return cartesianProduct(Arrays.asList(sets)); - } - - private static final class CartesianSet extends ForwardingCollection> - implements Set> { - private transient final ImmutableList> axes; - private transient final CartesianList delegate; - - static Set> create(List> sets) { - ImmutableList.Builder> axesBuilder = - new ImmutableList.Builder>(sets.size()); - for (Set set : sets) { - ImmutableSet copy = ImmutableSet.copyOf(set); - if (copy.isEmpty()) { - return ImmutableSet.of(); - } - axesBuilder.add(copy); - } - final ImmutableList> axes = axesBuilder.build(); - ImmutableList> listAxes = - new ImmutableList>() { - @Override - public int size() { - return axes.size(); - } - - @Override - public List get(int index) { - return axes.get(index).asList(); - } - - @Override - boolean isPartialView() { - return true; - } - }; - return new CartesianSet(axes, new CartesianList(listAxes)); - } - - private CartesianSet(ImmutableList> axes, CartesianList delegate) { - this.axes = axes; - this.delegate = delegate; - } - - @Override - protected Collection> delegate() { - return delegate; - } - - @Override - public boolean equals(@Nullable Object object) { - // Warning: this is broken if size() == 0, so it is critical that we - // substitute an empty ImmutableSet to the user in place of this - if (object instanceof CartesianSet) { - CartesianSet that = (CartesianSet) object; - return this.axes.equals(that.axes); - } - return super.equals(object); - } - - @Override - public int hashCode() { - // Warning: this is broken if size() == 0, so it is critical that we - // substitute an empty ImmutableSet to the user in place of this - - // It's a weird formula, but tests prove it works. - int adjust = size() - 1; - for (int i = 0; i < axes.size(); i++) { - adjust *= 31; - adjust = ~~adjust; - // in GWT, we have to deal with integer overflow carefully - } - int hash = 1; - for (Set axis : axes) { - hash = 31 * hash + (size() / axis.size() * axis.hashCode()); - - hash = ~~hash; - } - hash += adjust; - return ~~hash; - } - } - - /** - * Returns the set of all possible subsets of {@code set}. For example, - * {@code powerSet(ImmutableSet.of(1, 2))} returns the set {@code {{}, - * {1}, {2}, {1, 2}}}. - * - *

Elements appear in these subsets in the same iteration order as they - * appeared in the input set. The order in which these subsets appear in the - * outer set is undefined. Note that the power set of the empty set is not the - * empty set, but a one-element set containing the empty set. - * - *

The returned set and its constituent sets use {@code equals} to decide - * whether two elements are identical, even if the input set uses a different - * concept of equivalence. - * - *

Performance notes: while the power set of a set with size {@code - * n} is of size {@code 2^n}, its memory usage is only {@code O(n)}. When the - * power set is constructed, the input set is merely copied. Only as the - * power set is iterated are the individual subsets created, and these subsets - * themselves occupy only a small constant amount of memory. - * - * @param set the set of elements to construct a power set from - * @return the power set, as an immutable set of immutable sets - * @throws IllegalArgumentException if {@code set} has more than 30 unique - * elements (causing the power set size to exceed the {@code int} range) - * @throws NullPointerException if {@code set} is or contains {@code null} - * @see Power set article at - * Wikipedia - * @since 4.0 - */ - @GwtCompatible(serializable = false) - public static Set> powerSet(Set set) { - return new PowerSet(set); - } - - private static final class SubSet extends AbstractSet { - private final ImmutableMap inputSet; - private final int mask; - - SubSet(ImmutableMap inputSet, int mask) { - this.inputSet = inputSet; - this.mask = mask; - } - - @Override - public Iterator iterator() { - return new UnmodifiableIterator() { - final ImmutableList elements = inputSet.keySet().asList(); - int remainingSetBits = mask; - - @Override - public boolean hasNext() { - return remainingSetBits != 0; - } - - @Override - public E next() { - int index = Integer.numberOfTrailingZeros(remainingSetBits); - if (index == 32) { - throw new NoSuchElementException(); - } - remainingSetBits &= ~(1 << index); - return elements.get(index); - } - }; - } - - @Override - public int size() { - return Integer.bitCount(mask); - } - - @Override - public boolean contains(@Nullable Object o) { - Integer index = inputSet.get(o); - return index != null && (mask & (1 << index)) != 0; - } - } - - private static final class PowerSet extends AbstractSet> { - final ImmutableMap inputSet; - - PowerSet(Set input) { - this.inputSet = Maps.indexMap(input); - checkArgument( - inputSet.size() <= 30, "Too many elements to create power set: %s > 30", inputSet.size()); - } - - @Override - public int size() { - return 1 << inputSet.size(); - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public Iterator> iterator() { - return new AbstractIndexedListIterator>(size()) { - @Override - protected Set get(final int setBits) { - return new SubSet(inputSet, setBits); - } - }; - } - - @Override - public boolean contains(@Nullable Object obj) { - if (obj instanceof Set) { - Set set = (Set) obj; - return inputSet.keySet().containsAll(set); - } - return false; - } - - @Override - public boolean equals(@Nullable Object obj) { - if (obj instanceof PowerSet) { - PowerSet that = (PowerSet) obj; - return inputSet.equals(that.inputSet); - } - return super.equals(obj); - } - - @Override - public int hashCode() { - /* - * The sum of the sums of the hash codes in each subset is just the sum of - * each input element's hash code times the number of sets that element - * appears in. Each element appears in exactly half of the 2^n sets, so: - */ - return inputSet.keySet().hashCode() << (inputSet.size() - 1); - } - - @Override - public String toString() { - return "powerSet(" + inputSet + ")"; - } - } - - /** - * An implementation for {@link Set#hashCode()}. - */ - static int hashCodeImpl(Set s) { - int hashCode = 0; - for (Object o : s) { - hashCode += o != null ? o.hashCode() : 0; - - hashCode = ~~hashCode; - // Needed to deal with unusual integer overflow in GWT. - } - return hashCode; - } - - /** - * An implementation for {@link Set#equals(Object)}. - */ - static boolean equalsImpl(Set s, @Nullable Object object) { - if (s == object) { - return true; - } - if (object instanceof Set) { - Set o = (Set) object; - - try { - return s.size() == o.size() && s.containsAll(o); - } catch (NullPointerException ignored) { - return false; - } catch (ClassCastException ignored) { - return false; - } - } - return false; - } - - /** - * Returns an unmodifiable view of the specified navigable set. This method - * allows modules to provide users with "read-only" access to internal - * navigable sets. Query operations on the returned set "read through" to the - * specified set, and attempts to modify the returned set, whether direct or - * via its collection views, result in an - * {@code UnsupportedOperationException}. - * - *

The returned navigable set will be serializable if the specified - * navigable set is serializable. - * - * @param set the navigable set for which an unmodifiable view is to be - * returned - * @return an unmodifiable view of the specified navigable set - * @since 12.0 - */ - @GwtIncompatible("NavigableSet") - public static NavigableSet unmodifiableNavigableSet(NavigableSet set) { - if (set instanceof ImmutableSortedSet || set instanceof UnmodifiableNavigableSet) { - return set; - } - return new UnmodifiableNavigableSet(set); - } - - @GwtIncompatible("NavigableSet") - static final class UnmodifiableNavigableSet extends ForwardingSortedSet - implements NavigableSet, Serializable { - private final NavigableSet delegate; - - UnmodifiableNavigableSet(NavigableSet delegate) { - this.delegate = checkNotNull(delegate); - } - - @Override - protected SortedSet delegate() { - return Collections.unmodifiableSortedSet(delegate); - } - - @Override - public E lower(E e) { - return delegate.lower(e); - } - - @Override - public E floor(E e) { - return delegate.floor(e); - } - - @Override - public E ceiling(E e) { - return delegate.ceiling(e); - } - - @Override - public E higher(E e) { - return delegate.higher(e); - } - - @Override - public E pollFirst() { - throw new UnsupportedOperationException(); - } - - @Override - public E pollLast() { - throw new UnsupportedOperationException(); - } - - private transient UnmodifiableNavigableSet descendingSet; - - @Override - public NavigableSet descendingSet() { - UnmodifiableNavigableSet result = descendingSet; - if (result == null) { - result = descendingSet = new UnmodifiableNavigableSet(delegate.descendingSet()); - result.descendingSet = this; - } - return result; - } - - @Override - public Iterator descendingIterator() { - return Iterators.unmodifiableIterator(delegate.descendingIterator()); - } - - @Override - public NavigableSet subSet( - E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { - return unmodifiableNavigableSet( - delegate.subSet(fromElement, fromInclusive, toElement, toInclusive)); - } - - @Override - public NavigableSet headSet(E toElement, boolean inclusive) { - return unmodifiableNavigableSet(delegate.headSet(toElement, inclusive)); - } - - @Override - public NavigableSet tailSet(E fromElement, boolean inclusive) { - return unmodifiableNavigableSet(delegate.tailSet(fromElement, inclusive)); - } - - private static final long serialVersionUID = 0; - } - - /** - * Returns a synchronized (thread-safe) navigable set backed by the specified - * navigable set. In order to guarantee serial access, it is critical that - * all access to the backing navigable set is accomplished - * through the returned navigable set (or its views). - * - *

It is imperative that the user manually synchronize on the returned - * sorted set when iterating over it or any of its {@code descendingSet}, - * {@code subSet}, {@code headSet}, or {@code tailSet} views.

   {@code
-   *
-   *   NavigableSet set = synchronizedNavigableSet(new TreeSet());
-   *    ...
-   *   synchronized (set) {
-   *     // Must be in the synchronized block
-   *     Iterator it = set.iterator();
-   *     while (it.hasNext()) {
-   *       foo(it.next());
-   *     }
-   *   }}
- * - *

or:

   {@code
-   *
-   *   NavigableSet set = synchronizedNavigableSet(new TreeSet());
-   *   NavigableSet set2 = set.descendingSet().headSet(foo);
-   *    ...
-   *   synchronized (set) { // Note: set, not set2!!!
-   *     // Must be in the synchronized block
-   *     Iterator it = set2.descendingIterator();
-   *     while (it.hasNext())
-   *       foo(it.next());
-   *     }
-   *   }}
- * - *

Failure to follow this advice may result in non-deterministic behavior. - * - *

The returned navigable set will be serializable if the specified - * navigable set is serializable. - * - * @param navigableSet the navigable set to be "wrapped" in a synchronized - * navigable set. - * @return a synchronized view of the specified navigable set. - * @since 13.0 - */ - @GwtIncompatible("NavigableSet") - public static NavigableSet synchronizedNavigableSet(NavigableSet navigableSet) { - return Synchronized.navigableSet(navigableSet); - } - - /** - * Remove each element in an iterable from a set. - */ - static boolean removeAllImpl(Set set, Iterator iterator) { - boolean changed = false; - while (iterator.hasNext()) { - changed |= set.remove(iterator.next()); - } - return changed; - } - - static boolean removeAllImpl(Set set, Collection collection) { - checkNotNull(collection); // for GWT - if (collection instanceof Multiset) { - collection = ((Multiset) collection).elementSet(); - } - /* - * AbstractSet.removeAll(List) has quadratic behavior if the list size - * is just less than the set's size. We augment the test by - * assuming that sets have fast contains() performance, and other - * collections don't. See - * http://code.google.com/p/guava-libraries/issues/detail?id=1013 - */ - if (collection instanceof Set && collection.size() > set.size()) { - return Iterators.removeAll(set.iterator(), collection); - } else { - return removeAllImpl(set, collection.iterator()); - } - } - - @GwtIncompatible("NavigableSet") - static class DescendingSet extends ForwardingNavigableSet { - private final NavigableSet forward; - - DescendingSet(NavigableSet forward) { - this.forward = forward; - } - - @Override - protected NavigableSet delegate() { - return forward; - } - - @Override - public E lower(E e) { - return forward.higher(e); - } - - @Override - public E floor(E e) { - return forward.ceiling(e); - } - - @Override - public E ceiling(E e) { - return forward.floor(e); - } - - @Override - public E higher(E e) { - return forward.lower(e); - } - - @Override - public E pollFirst() { - return forward.pollLast(); - } - - @Override - public E pollLast() { - return forward.pollFirst(); - } - - @Override - public NavigableSet descendingSet() { - return forward; - } - - @Override - public Iterator descendingIterator() { - return forward.iterator(); - } - - @Override - public NavigableSet subSet( - E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { - return forward.subSet(toElement, toInclusive, fromElement, fromInclusive).descendingSet(); - } - - @Override - public NavigableSet headSet(E toElement, boolean inclusive) { - return forward.tailSet(toElement, inclusive).descendingSet(); - } - - @Override - public NavigableSet tailSet(E fromElement, boolean inclusive) { - return forward.headSet(fromElement, inclusive).descendingSet(); - } - - @SuppressWarnings("unchecked") - @Override - public Comparator comparator() { - Comparator forwardComparator = forward.comparator(); - if (forwardComparator == null) { - return (Comparator) Ordering.natural().reverse(); - } else { - return reverse(forwardComparator); - } - } - - // If we inline this, we get a javac error. - private static Ordering reverse(Comparator forward) { - return Ordering.from(forward).reverse(); - } - - @Override - public E first() { - return forward.last(); - } - - @Override - public SortedSet headSet(E toElement) { - return standardHeadSet(toElement); - } - - @Override - public E last() { - return forward.first(); - } - - @Override - public SortedSet subSet(E fromElement, E toElement) { - return standardSubSet(fromElement, toElement); - } - - @Override - public SortedSet tailSet(E fromElement) { - return standardTailSet(fromElement); - } - - @Override - public Iterator iterator() { - return forward.descendingIterator(); - } - - @Override - public Object[] toArray() { - return standardToArray(); - } - - @Override - public T[] toArray(T[] array) { - return standardToArray(array); - } - - @Override - public String toString() { - return standardToString(); - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/SingletonImmutableBiMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/SingletonImmutableBiMap.java deleted file mode 100644 index d330190bf601..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/SingletonImmutableBiMap.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.collect.CollectPreconditions.checkEntryNotNull; - -import com.google.common.annotations.GwtCompatible; - -import javax.annotation.Nullable; - -/** - * Implementation of {@link ImmutableMap} with exactly one entry. - * - * @author Jesse Wilson - * @author Kevin Bourrillion - */ -@GwtCompatible(serializable = true, emulated = true) -@SuppressWarnings("serial") // uses writeReplace(), not default serialization -final class SingletonImmutableBiMap extends ImmutableBiMap { - - final transient K singleKey; - final transient V singleValue; - - SingletonImmutableBiMap(K singleKey, V singleValue) { - checkEntryNotNull(singleKey, singleValue); - this.singleKey = singleKey; - this.singleValue = singleValue; - } - - private SingletonImmutableBiMap(K singleKey, V singleValue, ImmutableBiMap inverse) { - this.singleKey = singleKey; - this.singleValue = singleValue; - this.inverse = inverse; - } - - @Override - public V get(@Nullable Object key) { - return singleKey.equals(key) ? singleValue : null; - } - - @Override - public int size() { - return 1; - } - - @Override - public boolean containsKey(@Nullable Object key) { - return singleKey.equals(key); - } - - @Override - public boolean containsValue(@Nullable Object value) { - return singleValue.equals(value); - } - - @Override - boolean isPartialView() { - return false; - } - - @Override - ImmutableSet> createEntrySet() { - return ImmutableSet.of(Maps.immutableEntry(singleKey, singleValue)); - } - - @Override - ImmutableSet createKeySet() { - return ImmutableSet.of(singleKey); - } - - transient ImmutableBiMap inverse; - - @Override - public ImmutableBiMap inverse() { - // racy single-check idiom - ImmutableBiMap result = inverse; - if (result == null) { - return inverse = new SingletonImmutableBiMap(singleValue, singleKey, this); - } else { - return result; - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/SingletonImmutableList.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/SingletonImmutableList.java deleted file mode 100644 index 267d94698835..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/SingletonImmutableList.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Preconditions; - -/** - * Implementation of {@link ImmutableList} with exactly one element. - * - * @author Hayward Chan - */ -@GwtCompatible(serializable = true, emulated = true) -@SuppressWarnings("serial") // uses writeReplace(), not default serialization -final class SingletonImmutableList extends ImmutableList { - - final transient E element; - - SingletonImmutableList(E element) { - this.element = checkNotNull(element); - } - - @Override - public E get(int index) { - Preconditions.checkElementIndex(index, 1); - return element; - } - - @Override - public UnmodifiableIterator iterator() { - return Iterators.singletonIterator(element); - } - - @Override - public int size() { - return 1; - } - - @Override - public ImmutableList subList(int fromIndex, int toIndex) { - Preconditions.checkPositionIndexes(fromIndex, toIndex, 1); - return (fromIndex == toIndex) ? ImmutableList.of() : this; - } - - @Override - public String toString() { - String elementToString = element.toString(); - return new StringBuilder(elementToString.length() + 2) - .append('[') - .append(elementToString) - .append(']') - .toString(); - } - - @Override - boolean isPartialView() { - return false; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/SingletonImmutableSet.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/SingletonImmutableSet.java deleted file mode 100644 index 9067e60afe09..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/SingletonImmutableSet.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Preconditions; - -/** - * Implementation of {@link ImmutableSet} with exactly one element. - * - * @author Kevin Bourrillion - * @author Nick Kralevich - */ -@GwtCompatible(serializable = true, emulated = true) -@SuppressWarnings("serial") // uses writeReplace(), not default serialization -final class SingletonImmutableSet extends ImmutableSet { - - final transient E element; - // This is transient because it will be recalculated on the first - // call to hashCode(). - // - // A race condition is avoided since threads will either see that the value - // is zero and recalculate it themselves, or two threads will see it at - // the same time, and both recalculate it. If the cachedHashCode is 0, - // it will always be recalculated, unfortunately. - private transient int cachedHashCode; - - SingletonImmutableSet(E element) { - this.element = Preconditions.checkNotNull(element); - } - - SingletonImmutableSet(E element, int hashCode) { - // Guaranteed to be non-null by the presence of the pre-computed hash code. - this.element = element; - cachedHashCode = hashCode; - } - - @Override - public int size() { - return 1; - } - - @Override - public boolean contains(Object target) { - return element.equals(target); - } - - @Override - public UnmodifiableIterator iterator() { - return Iterators.singletonIterator(element); - } - - @Override - boolean isPartialView() { - return false; - } - - @Override - int copyIntoArray(Object[] dst, int offset) { - dst[offset] = element; - return offset + 1; - } - - @Override - public final int hashCode() { - // Racy single-check. - int code = cachedHashCode; - if (code == 0) { - cachedHashCode = code = element.hashCode(); - } - return code; - } - - @Override - boolean isHashCodeFast() { - return cachedHashCode != 0; - } - - @Override - public String toString() { - String elementToString = element.toString(); - return new StringBuilder(elementToString.length() + 2) - .append('[') - .append(elementToString) - .append(']') - .toString(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/SingletonImmutableTable.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/SingletonImmutableTable.java deleted file mode 100644 index 33e89cdbe703..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/SingletonImmutableTable.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Map; - -/** - * An implementation of {@link ImmutableTable} that holds a single cell. - * - * @author Gregory Kick - */ -@GwtCompatible -class SingletonImmutableTable extends ImmutableTable { - final R singleRowKey; - final C singleColumnKey; - final V singleValue; - - SingletonImmutableTable(R rowKey, C columnKey, V value) { - this.singleRowKey = checkNotNull(rowKey); - this.singleColumnKey = checkNotNull(columnKey); - this.singleValue = checkNotNull(value); - } - - SingletonImmutableTable(Cell cell) { - this(cell.getRowKey(), cell.getColumnKey(), cell.getValue()); - } - - @Override - public ImmutableMap column(C columnKey) { - checkNotNull(columnKey); - return containsColumn(columnKey) - ? ImmutableMap.of(singleRowKey, singleValue) - : ImmutableMap.of(); - } - - @Override - public ImmutableMap> columnMap() { - return ImmutableMap.of(singleColumnKey, (Map) ImmutableMap.of(singleRowKey, singleValue)); - } - - @Override - public ImmutableMap> rowMap() { - return ImmutableMap.of(singleRowKey, (Map) ImmutableMap.of(singleColumnKey, singleValue)); - } - - @Override - public int size() { - return 1; - } - - @Override - ImmutableSet> createCellSet() { - return ImmutableSet.of(cellOf(singleRowKey, singleColumnKey, singleValue)); - } - - @Override - ImmutableCollection createValues() { - return ImmutableSet.of(singleValue); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedIterable.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedIterable.java deleted file mode 100644 index e859114abcaf..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedIterable.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Comparator; -import java.util.Iterator; - -/** - * An {@code Iterable} whose elements are sorted relative to a {@code Comparator}, typically - * provided at creation time. - * - * @author Louis Wasserman - */ -@GwtCompatible -interface SortedIterable extends Iterable { - /** - * Returns the {@code Comparator} by which the elements of this iterable are ordered, or {@code - * Ordering.natural()} if the elements are ordered by their natural ordering. - */ - Comparator comparator(); - - /** - * Returns an iterator over elements of type {@code T}. The elements are returned in - * nondecreasing order according to the associated {@link #comparator}. - */ - @Override - Iterator iterator(); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedIterables.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedIterables.java deleted file mode 100644 index 2158e9fca468..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedIterables.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Comparator; -import java.util.SortedSet; - -/** - * Utilities for dealing with sorted collections of all types. - * - * @author Louis Wasserman - */ -@GwtCompatible -final class SortedIterables { - private SortedIterables() {} - - /** - * Returns {@code true} if {@code elements} is a sorted collection using an ordering equivalent - * to {@code comparator}. - */ - public static boolean hasSameComparator(Comparator comparator, Iterable elements) { - checkNotNull(comparator); - checkNotNull(elements); - Comparator comparator2; - if (elements instanceof SortedSet) { - comparator2 = comparator((SortedSet) elements); - } else if (elements instanceof SortedIterable) { - comparator2 = ((SortedIterable) elements).comparator(); - } else { - return false; - } - return comparator.equals(comparator2); - } - - @SuppressWarnings("unchecked") - // if sortedSet.comparator() is null, the set must be naturally ordered - public static Comparator comparator(SortedSet sortedSet) { - Comparator result = sortedSet.comparator(); - if (result == null) { - result = (Comparator) Ordering.natural(); - } - return result; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedLists.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedLists.java deleted file mode 100644 index bc7cad7a0cee..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedLists.java +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (C) 2010 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Function; - -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.RandomAccess; - -import javax.annotation.Nullable; - -/** - * Static methods pertaining to sorted {@link List} instances. - * - * In this documentation, the terms greatest, greater, least, and - * lesser are considered to refer to the comparator on the elements, and the terms - * first and last are considered to refer to the elements' ordering in a - * list. - * - * @author Louis Wasserman - */ -@GwtCompatible -@Beta final class SortedLists { - private SortedLists() {} - - /** - * A specification for which index to return if the list contains at least one element that - * compares as equal to the key. - */ - public enum KeyPresentBehavior { - /** - * Return the index of any list element that compares as equal to the key. No guarantees are - * made as to which index is returned, if more than one element compares as equal to the key. - */ - ANY_PRESENT { - @Override - int resultIndex( - Comparator comparator, E key, List list, int foundIndex) { - return foundIndex; - } - }, - /** - * Return the index of the last list element that compares as equal to the key. - */ - LAST_PRESENT { - @Override - int resultIndex( - Comparator comparator, E key, List list, int foundIndex) { - // Of course, we have to use binary search to find the precise - // breakpoint... - int lower = foundIndex; - int upper = list.size() - 1; - // Everything between lower and upper inclusive compares at >= 0. - while (lower < upper) { - int middle = (lower + upper + 1) >>> 1; - int c = comparator.compare(list.get(middle), key); - if (c > 0) { - upper = middle - 1; - } else { // c == 0 - lower = middle; - } - } - return lower; - } - }, - /** - * Return the index of the first list element that compares as equal to the key. - */ - FIRST_PRESENT { - @Override - int resultIndex( - Comparator comparator, E key, List list, int foundIndex) { - // Of course, we have to use binary search to find the precise - // breakpoint... - int lower = 0; - int upper = foundIndex; - // Of course, we have to use binary search to find the precise breakpoint... - // Everything between lower and upper inclusive compares at <= 0. - while (lower < upper) { - int middle = (lower + upper) >>> 1; - int c = comparator.compare(list.get(middle), key); - if (c < 0) { - lower = middle + 1; - } else { // c == 0 - upper = middle; - } - } - return lower; - } - }, - /** - * Return the index of the first list element that compares as greater than the key, or {@code - * list.size()} if there is no such element. - */ - FIRST_AFTER { - @Override - public int resultIndex( - Comparator comparator, E key, List list, int foundIndex) { - return LAST_PRESENT.resultIndex(comparator, key, list, foundIndex) + 1; - } - }, - /** - * Return the index of the last list element that compares as less than the key, or {@code -1} - * if there is no such element. - */ - LAST_BEFORE { - @Override - public int resultIndex( - Comparator comparator, E key, List list, int foundIndex) { - return FIRST_PRESENT.resultIndex(comparator, key, list, foundIndex) - 1; - } - }; - - abstract int resultIndex( - Comparator comparator, E key, List list, int foundIndex); - } - - /** - * A specification for which index to return if the list contains no elements that compare as - * equal to the key. - */ - public enum KeyAbsentBehavior { - /** - * Return the index of the next lower element in the list, or {@code -1} if there is no such - * element. - */ - NEXT_LOWER { - @Override - int resultIndex(int higherIndex) { - return higherIndex - 1; - } - }, - /** - * Return the index of the next higher element in the list, or {@code list.size()} if there is - * no such element. - */ - NEXT_HIGHER { - @Override - public int resultIndex(int higherIndex) { - return higherIndex; - } - }, - /** - * Return {@code ~insertionIndex}, where {@code insertionIndex} is defined as the point at - * which the key would be inserted into the list: the index of the next higher element in the - * list, or {@code list.size()} if there is no such element. - * - *

Note that the return value will be {@code >= 0} if and only if there is an element of the - * list that compares as equal to the key. - * - *

This is equivalent to the behavior of - * {@link java.util.Collections#binarySearch(List, Object)} when the key isn't present, since - * {@code ~insertionIndex} is equal to {@code -1 - insertionIndex}. - */ - INVERTED_INSERTION_INDEX { - @Override - public int resultIndex(int higherIndex) { - return ~higherIndex; - } - }; - - abstract int resultIndex(int higherIndex); - } - - /** - * Searches the specified naturally ordered list for the specified object using the binary search - * algorithm. - * - *

Equivalent to {@link #binarySearch(List, Function, Object, Comparator, KeyPresentBehavior, - * KeyAbsentBehavior)} using {@link Ordering#natural}. - */ - public static int binarySearch( - List list, - E e, - KeyPresentBehavior presentBehavior, - KeyAbsentBehavior absentBehavior) { - checkNotNull(e); - return binarySearch(list, e, Ordering.natural(), presentBehavior, absentBehavior); - } - - /** - * Binary searches the list for the specified key, using the specified key function. - * - *

Equivalent to {@link #binarySearch(List, Function, Object, Comparator, KeyPresentBehavior, - * KeyAbsentBehavior)} using {@link Ordering#natural}. - */ - public static int binarySearch( - List list, - Function keyFunction, - @Nullable K key, - KeyPresentBehavior presentBehavior, - KeyAbsentBehavior absentBehavior) { - return binarySearch( - list, keyFunction, key, Ordering.natural(), presentBehavior, absentBehavior); - } - - /** - * Binary searches the list for the specified key, using the specified key function. - * - *

Equivalent to - * {@link #binarySearch(List, Object, Comparator, KeyPresentBehavior, KeyAbsentBehavior)} using - * {@link Lists#transform(List, Function) Lists.transform(list, keyFunction)}. - */ - public static int binarySearch( - List list, - Function keyFunction, - @Nullable K key, - Comparator keyComparator, - KeyPresentBehavior presentBehavior, - KeyAbsentBehavior absentBehavior) { - return binarySearch( - Lists.transform(list, keyFunction), key, keyComparator, presentBehavior, absentBehavior); - } - - /** - * Searches the specified list for the specified object using the binary search algorithm. The - * list must be sorted into ascending order according to the specified comparator (as by the - * {@link Collections#sort(List, Comparator) Collections.sort(List, Comparator)} method), prior - * to making this call. If it is not sorted, the results are undefined. - * - *

If there are elements in the list which compare as equal to the key, the choice of - * {@link KeyPresentBehavior} decides which index is returned. If no elements compare as equal to - * the key, the choice of {@link KeyAbsentBehavior} decides which index is returned. - * - *

This method runs in log(n) time on random-access lists, which offer near-constant-time - * access to each list element. - * - * @param list the list to be searched. - * @param key the value to be searched for. - * @param comparator the comparator by which the list is ordered. - * @param presentBehavior the specification for what to do if at least one element of the list - * compares as equal to the key. - * @param absentBehavior the specification for what to do if no elements of the list compare as - * equal to the key. - * @return the index determined by the {@code KeyPresentBehavior}, if the key is in the list; - * otherwise the index determined by the {@code KeyAbsentBehavior}. - */ - public static int binarySearch( - List list, - @Nullable E key, - Comparator comparator, - KeyPresentBehavior presentBehavior, - KeyAbsentBehavior absentBehavior) { - checkNotNull(comparator); - checkNotNull(list); - checkNotNull(presentBehavior); - checkNotNull(absentBehavior); - if (!(list instanceof RandomAccess)) { - list = Lists.newArrayList(list); - } - // TODO(lowasser): benchmark when it's best to do a linear search - - int lower = 0; - int upper = list.size() - 1; - - while (lower <= upper) { - int middle = (lower + upper) >>> 1; - int c = comparator.compare(key, list.get(middle)); - if (c < 0) { - upper = middle - 1; - } else if (c > 0) { - lower = middle + 1; - } else { - return lower + presentBehavior.resultIndex( - comparator, key, list.subList(lower, upper + 1), middle - lower); - } - } - return absentBehavior.resultIndex(lower); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedMapDifference.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedMapDifference.java deleted file mode 100644 index 07f75eedadb2..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedMapDifference.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2010 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.SortedMap; - -/** - * An object representing the differences between two sorted maps. - * - * @author Louis Wasserman - * @since 8.0 - */ -@GwtCompatible -public interface SortedMapDifference extends MapDifference { - - @Override - SortedMap entriesOnlyOnLeft(); - - @Override - SortedMap entriesOnlyOnRight(); - - @Override - SortedMap entriesInCommon(); - - @Override - SortedMap> entriesDiffering(); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedMultiset.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedMultiset.java deleted file mode 100644 index 8c9221288bf7..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedMultiset.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import java.util.Collection; -import java.util.Comparator; -import java.util.Iterator; -import java.util.NavigableSet; -import java.util.Set; - -/** - * A {@link Multiset} which maintains the ordering of its elements, according to - * either their natural order or an explicit {@link Comparator}. This order is - * reflected when iterating over the sorted multiset, either directly, or through - * its {@code elementSet} or {@code entrySet} views. In all cases, - * this implementation uses {@link Comparable#compareTo} or - * {@link Comparator#compare} instead of {@link Object#equals} to determine - * equivalence of instances. - * - *

Warning: The comparison must be consistent with equals as - * explained by the {@link Comparable} class specification. Otherwise, the - * resulting multiset will violate the {@link Collection} contract, which it is - * specified in terms of {@link Object#equals}. - * - *

See the Guava User Guide article on - * {@code Multiset}. - * - * @author Louis Wasserman - * @since 11.0 - */ -@Beta -@GwtCompatible(emulated = true) -public interface SortedMultiset extends SortedMultisetBridge, SortedIterable { - /** - * Returns the comparator that orders this multiset, or - * {@link Ordering#natural()} if the natural ordering of the elements is used. - */ - Comparator comparator(); - - /** - * Returns the entry of the first element in this multiset, or {@code null} if - * this multiset is empty. - */ - Entry firstEntry(); - - /** - * Returns the entry of the last element in this multiset, or {@code null} if - * this multiset is empty. - */ - Entry lastEntry(); - - /** - * Returns and removes the entry associated with the lowest element in this - * multiset, or returns {@code null} if this multiset is empty. - */ - Entry pollFirstEntry(); - - /** - * Returns and removes the entry associated with the greatest element in this - * multiset, or returns {@code null} if this multiset is empty. - */ - Entry pollLastEntry(); - - /** - * Returns a {@link NavigableSet} view of the distinct elements in this multiset. - * - * @since 14.0 (present with return type {@code SortedSet} since 11.0) - */ - @Override - NavigableSet elementSet(); - - /** - * {@inheritDoc} - * - *

The {@code entrySet}'s iterator returns entries in ascending element - * order according to the this multiset's comparator. - */ - @Override - Set> entrySet(); - - /** - * {@inheritDoc} - * - *

The iterator returns the elements in ascending order according to this - * multiset's comparator. - */ - @Override - Iterator iterator(); - - /** - * Returns a descending view of this multiset. Modifications made to either - * map will be reflected in the other. - */ - SortedMultiset descendingMultiset(); - - /** - * Returns a view of this multiset restricted to the elements less than - * {@code upperBound}, optionally including {@code upperBound} itself. The - * returned multiset is a view of this multiset, so changes to one will be - * reflected in the other. The returned multiset supports all operations that - * this multiset supports. - * - *

The returned multiset will throw an {@link IllegalArgumentException} on - * attempts to add elements outside its range. - */ - SortedMultiset headMultiset(E upperBound, BoundType boundType); - - /** - * Returns a view of this multiset restricted to the range between - * {@code lowerBound} and {@code upperBound}. The returned multiset is a view - * of this multiset, so changes to one will be reflected in the other. The - * returned multiset supports all operations that this multiset supports. - * - *

The returned multiset will throw an {@link IllegalArgumentException} on - * attempts to add elements outside its range. - * - *

This method is equivalent to - * {@code tailMultiset(lowerBound, lowerBoundType).headMultiset(upperBound, - * upperBoundType)}. - */ - SortedMultiset subMultiset( - E lowerBound, BoundType lowerBoundType, E upperBound, BoundType upperBoundType); - - /** - * Returns a view of this multiset restricted to the elements greater than - * {@code lowerBound}, optionally including {@code lowerBound} itself. The - * returned multiset is a view of this multiset, so changes to one will be - * reflected in the other. The returned multiset supports all operations that - * this multiset supports. - * - *

The returned multiset will throw an {@link IllegalArgumentException} on - * attempts to add elements outside its range. - */ - SortedMultiset tailMultiset(E lowerBound, BoundType boundType); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedMultisetBridge.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedMultisetBridge.java deleted file mode 100644 index a2d04edb3a25..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedMultisetBridge.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import java.util.SortedSet; - -/** - * Superinterface of {@link SortedMultiset} to introduce a bridge method for - * {@code elementSet()}, to ensure binary compatibility with older Guava versions - * that specified {@code elementSet()} to return {@code SortedSet}. - * - * @author Louis Wasserman - */ -interface SortedMultisetBridge extends Multiset { - @Override - SortedSet elementSet(); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedMultisets.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedMultisets.java deleted file mode 100644 index b0695a210c3f..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedMultisets.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import static com.google.common.collect.BoundType.CLOSED; -import static com.google.common.collect.BoundType.OPEN; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.collect.Multiset.Entry; -import com.google.j2objc.annotations.Weak; - -import java.util.Comparator; -import java.util.Iterator; -import java.util.NavigableSet; -import java.util.NoSuchElementException; -import java.util.SortedSet; - -import javax.annotation.Nullable; - -/** - * Provides static utility methods for creating and working with - * {@link SortedMultiset} instances. - * - * @author Louis Wasserman - */ -@GwtCompatible(emulated = true) -final class SortedMultisets { - private SortedMultisets() {} - - /** - * A skeleton implementation for {@link SortedMultiset#elementSet}. - */ - static class ElementSet extends Multisets.ElementSet implements SortedSet { - @Weak private final SortedMultiset multiset; - - ElementSet(SortedMultiset multiset) { - this.multiset = multiset; - } - - @Override - final SortedMultiset multiset() { - return multiset; - } - - @Override - public Comparator comparator() { - return multiset().comparator(); - } - - @Override - public SortedSet subSet(E fromElement, E toElement) { - return multiset().subMultiset(fromElement, CLOSED, toElement, OPEN).elementSet(); - } - - @Override - public SortedSet headSet(E toElement) { - return multiset().headMultiset(toElement, OPEN).elementSet(); - } - - @Override - public SortedSet tailSet(E fromElement) { - return multiset().tailMultiset(fromElement, CLOSED).elementSet(); - } - - @Override - public E first() { - return getElementOrThrow(multiset().firstEntry()); - } - - @Override - public E last() { - return getElementOrThrow(multiset().lastEntry()); - } - } - - /** - * A skeleton navigable implementation for {@link SortedMultiset#elementSet}. - */ - @GwtIncompatible("Navigable") - static class NavigableElementSet extends ElementSet implements NavigableSet { - NavigableElementSet(SortedMultiset multiset) { - super(multiset); - } - - @Override - public E lower(E e) { - return getElementOrNull(multiset().headMultiset(e, OPEN).lastEntry()); - } - - @Override - public E floor(E e) { - return getElementOrNull(multiset().headMultiset(e, CLOSED).lastEntry()); - } - - @Override - public E ceiling(E e) { - return getElementOrNull(multiset().tailMultiset(e, CLOSED).firstEntry()); - } - - @Override - public E higher(E e) { - return getElementOrNull(multiset().tailMultiset(e, OPEN).firstEntry()); - } - - @Override - public NavigableSet descendingSet() { - return new NavigableElementSet(multiset().descendingMultiset()); - } - - @Override - public Iterator descendingIterator() { - return descendingSet().iterator(); - } - - @Override - public E pollFirst() { - return getElementOrNull(multiset().pollFirstEntry()); - } - - @Override - public E pollLast() { - return getElementOrNull(multiset().pollLastEntry()); - } - - @Override - public NavigableSet subSet( - E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { - return new NavigableElementSet( - multiset().subMultiset( - fromElement, BoundType.forBoolean(fromInclusive), - toElement, BoundType.forBoolean(toInclusive))); - } - - @Override - public NavigableSet headSet(E toElement, boolean inclusive) { - return new NavigableElementSet( - multiset().headMultiset(toElement, BoundType.forBoolean(inclusive))); - } - - @Override - public NavigableSet tailSet(E fromElement, boolean inclusive) { - return new NavigableElementSet( - multiset().tailMultiset(fromElement, BoundType.forBoolean(inclusive))); - } - } - - private static E getElementOrThrow(Entry entry) { - if (entry == null) { - throw new NoSuchElementException(); - } - return entry.getElement(); - } - - private static E getElementOrNull(@Nullable Entry entry) { - return (entry == null) ? null : entry.getElement(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedSetMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedSetMultimap.java deleted file mode 100644 index 436ca5db3da3..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/SortedSetMultimap.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Collection; -import java.util.Comparator; -import java.util.Map; -import java.util.Set; -import java.util.SortedSet; - -import javax.annotation.Nullable; - -/** - * A {@code SetMultimap} whose set of values for a given key are kept sorted; - * that is, they comprise a {@link SortedSet}. It cannot hold duplicate - * key-value pairs; adding a key-value pair that's already in the multimap has - * no effect. This interface does not specify the ordering of the multimap's - * keys. See the {@link Multimap} documentation for information common to all - * multimaps. - * - *

The {@link #get}, {@link #removeAll}, and {@link #replaceValues} methods - * each return a {@link SortedSet} of values, while {@link Multimap#entries()} - * returns a {@link Set} of map entries. Though the method signature doesn't say - * so explicitly, the map returned by {@link #asMap} has {@code SortedSet} - * values. - * - *

See the Guava User Guide article on - * {@code Multimap}. - * - * @author Jared Levy - * @since 2.0 - */ -@GwtCompatible -public interface SortedSetMultimap extends SetMultimap { - // Following Javadoc copied from Multimap. - - /** - * Returns a collection view of all values associated with a key. If no - * mappings in the multimap have the provided key, an empty collection is - * returned. - * - *

Changes to the returned collection will update the underlying multimap, - * and vice versa. - * - *

Because a {@code SortedSetMultimap} has unique sorted values for a given - * key, this method returns a {@link SortedSet}, instead of the - * {@link java.util.Collection} specified in the {@link Multimap} interface. - */ - @Override - SortedSet get(@Nullable K key); - - /** - * Removes all values associated with a given key. - * - *

Because a {@code SortedSetMultimap} has unique sorted values for a given - * key, this method returns a {@link SortedSet}, instead of the - * {@link java.util.Collection} specified in the {@link Multimap} interface. - */ - @Override - SortedSet removeAll(@Nullable Object key); - - /** - * Stores a collection of values with the same key, replacing any existing - * values for that key. - * - *

Because a {@code SortedSetMultimap} has unique sorted values for a given - * key, this method returns a {@link SortedSet}, instead of the - * {@link java.util.Collection} specified in the {@link Multimap} interface. - * - *

Any duplicates in {@code values} will be stored in the multimap once. - */ - @Override - SortedSet replaceValues(K key, Iterable values); - - /** - * Returns a map view that associates each key with the corresponding values - * in the multimap. Changes to the returned map, such as element removal, will - * update the underlying multimap. The map does not support {@code setValue()} - * on its entries, {@code put}, or {@code putAll}. - * - *

When passed a key that is present in the map, {@code - * asMap().get(Object)} has the same behavior as {@link #get}, returning a - * live collection. When passed a key that is not present, however, {@code - * asMap().get(Object)} returns {@code null} instead of an empty collection. - * - *

Note: The returned map's values are guaranteed to be of type - * {@link SortedSet}. To obtain this map with the more specific generic type - * {@code Map>}, call - * {@link Multimaps#asMap(SortedSetMultimap)} instead. - */ - @Override - Map> asMap(); - - /** - * Returns the comparator that orders the multimap values, with {@code null} - * indicating that natural ordering is used. - */ - Comparator valueComparator(); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/SparseImmutableTable.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/SparseImmutableTable.java deleted file mode 100644 index deebd112dca2..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/SparseImmutableTable.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.LinkedHashMap; -import java.util.Map; - -import javax.annotation.concurrent.Immutable; - -/** - * A {@code RegularImmutableTable} optimized for sparse data. - */ -@GwtCompatible -@Immutable -final class SparseImmutableTable extends RegularImmutableTable { - - private final ImmutableMap> rowMap; - private final ImmutableMap> columnMap; - private final int[] iterationOrderRow; - private final int[] iterationOrderColumn; - - SparseImmutableTable( - ImmutableList> cellList, - ImmutableSet rowSpace, - ImmutableSet columnSpace) { - Map rowIndex = Maps.indexMap(rowSpace); - Map> rows = Maps.newLinkedHashMap(); - for (R row : rowSpace) { - rows.put(row, new LinkedHashMap()); - } - Map> columns = Maps.newLinkedHashMap(); - for (C col : columnSpace) { - columns.put(col, new LinkedHashMap()); - } - int[] iterationOrderRow = new int[cellList.size()]; - int[] iterationOrderColumn = new int[cellList.size()]; - for (int i = 0; i < cellList.size(); i++) { - Cell cell = cellList.get(i); - R rowKey = cell.getRowKey(); - C columnKey = cell.getColumnKey(); - V value = cell.getValue(); - - iterationOrderRow[i] = rowIndex.get(rowKey); - Map thisRow = rows.get(rowKey); - iterationOrderColumn[i] = thisRow.size(); - V oldValue = thisRow.put(columnKey, value); - if (oldValue != null) { - throw new IllegalArgumentException( - "Duplicate value for row=" + rowKey + ", column=" + columnKey + ": " - + value + ", " + oldValue); - } - columns.get(columnKey).put(rowKey, value); - } - this.iterationOrderRow = iterationOrderRow; - this.iterationOrderColumn = iterationOrderColumn; - ImmutableMap.Builder> rowBuilder = - new ImmutableMap.Builder>(rows.size()); - for (Map.Entry> row : rows.entrySet()) { - rowBuilder.put(row.getKey(), ImmutableMap.copyOf(row.getValue())); - } - this.rowMap = rowBuilder.build(); - - ImmutableMap.Builder> columnBuilder = - new ImmutableMap.Builder>(columns.size()); - for (Map.Entry> col : columns.entrySet()) { - columnBuilder.put(col.getKey(), ImmutableMap.copyOf(col.getValue())); - } - this.columnMap = columnBuilder.build(); - } - - @Override - public ImmutableMap> columnMap() { - return columnMap; - } - - @Override - public ImmutableMap> rowMap() { - return rowMap; - } - - @Override - public int size() { - return iterationOrderRow.length; - } - - @Override - Cell getCell(int index) { - int rowIndex = iterationOrderRow[index]; - Map.Entry> rowEntry = rowMap.entrySet().asList().get(rowIndex); - ImmutableMap row = (ImmutableMap) rowEntry.getValue(); - int columnIndex = iterationOrderColumn[index]; - Map.Entry colEntry = row.entrySet().asList().get(columnIndex); - return cellOf(rowEntry.getKey(), colEntry.getKey(), colEntry.getValue()); - } - - @Override - V getValue(int index) { - int rowIndex = iterationOrderRow[index]; - ImmutableMap row = (ImmutableMap) rowMap.values().asList().get(rowIndex); - int columnIndex = iterationOrderColumn[index]; - return row.values().asList().get(columnIndex); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/StandardRowSortedTable.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/StandardRowSortedTable.java deleted file mode 100644 index 54bd03c4dc1b..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/StandardRowSortedTable.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Supplier; -import com.google.j2objc.annotations.WeakOuter; - -import java.util.Comparator; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; -import java.util.SortedSet; - -/** - * Implementation of {@code Table} whose iteration ordering across row keys is - * sorted by their natural ordering or by a supplied comparator. Note that - * iterations across the columns keys for a single row key may or may not be - * ordered, depending on the implementation. When rows and columns are both - * sorted, it's easier to use the {@link TreeBasedTable} subclass. - * - *

The {@link #rowKeySet} method returns a {@link SortedSet} and the {@link - * #rowMap} method returns a {@link SortedMap}, instead of the {@link Set} and - * {@link Map} specified by the {@link Table} interface. - * - *

Null keys and values are not supported. - * - *

See the {@link StandardTable} superclass for more information about the - * behavior of this class. - * - * @author Jared Levy - */ -@GwtCompatible -class StandardRowSortedTable extends StandardTable - implements RowSortedTable { - /* - * TODO(jlevy): Consider adding headTable, tailTable, and subTable methods, - * which return a Table view with rows keys in a given range. Create a - * RowSortedTable subinterface with the revised methods? - */ - - StandardRowSortedTable( - SortedMap> backingMap, Supplier> factory) { - super(backingMap, factory); - } - - private SortedMap> sortedBackingMap() { - return (SortedMap>) backingMap; - } - - /** - * {@inheritDoc} - * - *

This method returns a {@link SortedSet}, instead of the {@code Set} - * specified in the {@link Table} interface. - */ - @Override - public SortedSet rowKeySet() { - return (SortedSet) rowMap().keySet(); - } - - /** - * {@inheritDoc} - * - *

This method returns a {@link SortedMap}, instead of the {@code Map} - * specified in the {@link Table} interface. - */ - @Override - public SortedMap> rowMap() { - return (SortedMap>) super.rowMap(); - } - - @Override - SortedMap> createRowMap() { - return new RowSortedMap(); - } - - @WeakOuter - private class RowSortedMap extends RowMap implements SortedMap> { - @Override - public SortedSet keySet() { - return (SortedSet) super.keySet(); - } - - @Override - SortedSet createKeySet() { - return new Maps.SortedKeySet>(this); - } - - @Override - public Comparator comparator() { - return sortedBackingMap().comparator(); - } - - @Override - public R firstKey() { - return sortedBackingMap().firstKey(); - } - - @Override - public R lastKey() { - return sortedBackingMap().lastKey(); - } - - @Override - public SortedMap> headMap(R toKey) { - checkNotNull(toKey); - return new StandardRowSortedTable(sortedBackingMap().headMap(toKey), factory) - .rowMap(); - } - - @Override - public SortedMap> subMap(R fromKey, R toKey) { - checkNotNull(fromKey); - checkNotNull(toKey); - return new StandardRowSortedTable(sortedBackingMap().subMap(fromKey, toKey), factory) - .rowMap(); - } - - @Override - public SortedMap> tailMap(R fromKey) { - checkNotNull(fromKey); - return new StandardRowSortedTable(sortedBackingMap().tailMap(fromKey), factory) - .rowMap(); - } - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/StandardTable.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/StandardTable.java deleted file mode 100644 index 6d7d751fc931..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/StandardTable.java +++ /dev/null @@ -1,969 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Predicates.alwaysTrue; -import static com.google.common.base.Predicates.equalTo; -import static com.google.common.base.Predicates.in; -import static com.google.common.base.Predicates.not; -import static com.google.common.collect.Maps.safeContainsKey; -import static com.google.common.collect.Maps.safeGet; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Function; -import com.google.common.base.Predicate; -import com.google.common.base.Supplier; -import com.google.common.collect.Maps.IteratorBasedAbstractMap; -import com.google.common.collect.Maps.ViewCachingAbstractMap; -import com.google.common.collect.Sets.ImprovedAbstractSet; -import com.google.j2objc.annotations.WeakOuter; - -import java.io.Serializable; -import java.util.Collection; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * {@link Table} implementation backed by a map that associates row keys with - * column key / value secondary maps. This class provides rapid access to - * records by the row key alone or by both keys, but not by just the column key. - * - *

The views returned by {@link #column}, {@link #columnKeySet()}, and {@link - * #columnMap()} have iterators that don't support {@code remove()}. Otherwise, - * all optional operations are supported. Null row keys, columns keys, and - * values are not supported. - * - *

Lookups by row key are often faster than lookups by column key, because - * the data is stored in a {@code Map>}. A method call like {@code - * column(columnKey).get(rowKey)} still runs quickly, since the row key is - * provided. However, {@code column(columnKey).size()} takes longer, since an - * iteration across all row keys occurs. - * - *

Note that this implementation is not synchronized. If multiple threads - * access this table concurrently and one of the threads modifies the table, it - * must be synchronized externally. - * - * @author Jared Levy - */ -@GwtCompatible -class StandardTable extends AbstractTable implements Serializable { - @GwtTransient final Map> backingMap; - @GwtTransient final Supplier> factory; - - StandardTable(Map> backingMap, Supplier> factory) { - this.backingMap = backingMap; - this.factory = factory; - } - - // Accessors - - @Override - public boolean contains(@Nullable Object rowKey, @Nullable Object columnKey) { - return rowKey != null && columnKey != null && super.contains(rowKey, columnKey); - } - - @Override - public boolean containsColumn(@Nullable Object columnKey) { - if (columnKey == null) { - return false; - } - for (Map map : backingMap.values()) { - if (safeContainsKey(map, columnKey)) { - return true; - } - } - return false; - } - - @Override - public boolean containsRow(@Nullable Object rowKey) { - return rowKey != null && safeContainsKey(backingMap, rowKey); - } - - @Override - public boolean containsValue(@Nullable Object value) { - return value != null && super.containsValue(value); - } - - @Override - public V get(@Nullable Object rowKey, @Nullable Object columnKey) { - return (rowKey == null || columnKey == null) ? null : super.get(rowKey, columnKey); - } - - @Override - public boolean isEmpty() { - return backingMap.isEmpty(); - } - - @Override - public int size() { - int size = 0; - for (Map map : backingMap.values()) { - size += map.size(); - } - return size; - } - - // Mutators - - @Override - public void clear() { - backingMap.clear(); - } - - private Map getOrCreate(R rowKey) { - Map map = backingMap.get(rowKey); - if (map == null) { - map = factory.get(); - backingMap.put(rowKey, map); - } - return map; - } - - @Override - public V put(R rowKey, C columnKey, V value) { - checkNotNull(rowKey); - checkNotNull(columnKey); - checkNotNull(value); - return getOrCreate(rowKey).put(columnKey, value); - } - - @Override - public V remove(@Nullable Object rowKey, @Nullable Object columnKey) { - if ((rowKey == null) || (columnKey == null)) { - return null; - } - Map map = safeGet(backingMap, rowKey); - if (map == null) { - return null; - } - V value = map.remove(columnKey); - if (map.isEmpty()) { - backingMap.remove(rowKey); - } - return value; - } - - private Map removeColumn(Object column) { - Map output = new LinkedHashMap(); - Iterator>> iterator = backingMap.entrySet().iterator(); - while (iterator.hasNext()) { - Entry> entry = iterator.next(); - V value = entry.getValue().remove(column); - if (value != null) { - output.put(entry.getKey(), value); - if (entry.getValue().isEmpty()) { - iterator.remove(); - } - } - } - return output; - } - - private boolean containsMapping(Object rowKey, Object columnKey, Object value) { - return value != null && value.equals(get(rowKey, columnKey)); - } - - /** Remove a row key / column key / value mapping, if present. */ - private boolean removeMapping(Object rowKey, Object columnKey, Object value) { - if (containsMapping(rowKey, columnKey, value)) { - remove(rowKey, columnKey); - return true; - } - return false; - } - - // Views - - /** - * Abstract set whose {@code isEmpty()} returns whether the table is empty and - * whose {@code clear()} clears all table mappings. - */ - @WeakOuter - private abstract class TableSet extends ImprovedAbstractSet { - @Override - public boolean isEmpty() { - return backingMap.isEmpty(); - } - - @Override - public void clear() { - backingMap.clear(); - } - } - - /** - * {@inheritDoc} - * - *

The set's iterator traverses the mappings for the first row, the - * mappings for the second row, and so on. - * - *

Each cell is an immutable snapshot of a row key / column key / value - * mapping, taken at the time the cell is returned by a method call to the - * set or its iterator. - */ - @Override - public Set> cellSet() { - return super.cellSet(); - } - - @Override - Iterator> cellIterator() { - return new CellIterator(); - } - - private class CellIterator implements Iterator> { - final Iterator>> rowIterator = backingMap.entrySet().iterator(); - Entry> rowEntry; - Iterator> columnIterator = Iterators.emptyModifiableIterator(); - - @Override - public boolean hasNext() { - return rowIterator.hasNext() || columnIterator.hasNext(); - } - - @Override - public Cell next() { - if (!columnIterator.hasNext()) { - rowEntry = rowIterator.next(); - columnIterator = rowEntry.getValue().entrySet().iterator(); - } - Entry columnEntry = columnIterator.next(); - return Tables.immutableCell(rowEntry.getKey(), columnEntry.getKey(), columnEntry.getValue()); - } - - @Override - public void remove() { - columnIterator.remove(); - if (rowEntry.getValue().isEmpty()) { - rowIterator.remove(); - } - } - } - - @Override - public Map row(R rowKey) { - return new Row(rowKey); - } - - class Row extends IteratorBasedAbstractMap { - final R rowKey; - - Row(R rowKey) { - this.rowKey = checkNotNull(rowKey); - } - - Map backingRowMap; - - Map backingRowMap() { - return (backingRowMap == null || (backingRowMap.isEmpty() && backingMap.containsKey(rowKey))) - ? backingRowMap = computeBackingRowMap() - : backingRowMap; - } - - Map computeBackingRowMap() { - return backingMap.get(rowKey); - } - - // Call this every time we perform a removal. - void maintainEmptyInvariant() { - if (backingRowMap() != null && backingRowMap.isEmpty()) { - backingMap.remove(rowKey); - backingRowMap = null; - } - } - - @Override - public boolean containsKey(Object key) { - Map backingRowMap = backingRowMap(); - return (key != null && backingRowMap != null) && Maps.safeContainsKey(backingRowMap, key); - } - - @Override - public V get(Object key) { - Map backingRowMap = backingRowMap(); - return (key != null && backingRowMap != null) ? Maps.safeGet(backingRowMap, key) : null; - } - - @Override - public V put(C key, V value) { - checkNotNull(key); - checkNotNull(value); - if (backingRowMap != null && !backingRowMap.isEmpty()) { - return backingRowMap.put(key, value); - } - return StandardTable.this.put(rowKey, key, value); - } - - @Override - public V remove(Object key) { - Map backingRowMap = backingRowMap(); - if (backingRowMap == null) { - return null; - } - V result = Maps.safeRemove(backingRowMap, key); - maintainEmptyInvariant(); - return result; - } - - @Override - public void clear() { - Map backingRowMap = backingRowMap(); - if (backingRowMap != null) { - backingRowMap.clear(); - } - maintainEmptyInvariant(); - } - - @Override - public int size() { - Map map = backingRowMap(); - return (map == null) ? 0 : map.size(); - } - - @Override - Iterator> entryIterator() { - final Map map = backingRowMap(); - if (map == null) { - return Iterators.emptyModifiableIterator(); - } - final Iterator> iterator = map.entrySet().iterator(); - return new Iterator>() { - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public Entry next() { - final Entry entry = iterator.next(); - return new ForwardingMapEntry() { - @Override - protected Entry delegate() { - return entry; - } - - @Override - public V setValue(V value) { - return super.setValue(checkNotNull(value)); - } - - @Override - public boolean equals(Object object) { - // TODO(lowasser): identify why this affects GWT tests - return standardEquals(object); - } - }; - } - - @Override - public void remove() { - iterator.remove(); - maintainEmptyInvariant(); - } - }; - } - } - - /** - * {@inheritDoc} - * - *

The returned map's views have iterators that don't support - * {@code remove()}. - */ - @Override - public Map column(C columnKey) { - return new Column(columnKey); - } - - private class Column extends ViewCachingAbstractMap { - final C columnKey; - - Column(C columnKey) { - this.columnKey = checkNotNull(columnKey); - } - - @Override - public V put(R key, V value) { - return StandardTable.this.put(key, columnKey, value); - } - - @Override - public V get(Object key) { - return StandardTable.this.get(key, columnKey); - } - - @Override - public boolean containsKey(Object key) { - return StandardTable.this.contains(key, columnKey); - } - - @Override - public V remove(Object key) { - return StandardTable.this.remove(key, columnKey); - } - - /** - * Removes all {@code Column} mappings whose row key and value satisfy the - * given predicate. - */ - boolean removeFromColumnIf(Predicate> predicate) { - boolean changed = false; - Iterator>> iterator = backingMap.entrySet().iterator(); - while (iterator.hasNext()) { - Entry> entry = iterator.next(); - Map map = entry.getValue(); - V value = map.get(columnKey); - if (value != null && predicate.apply(Maps.immutableEntry(entry.getKey(), value))) { - map.remove(columnKey); - changed = true; - if (map.isEmpty()) { - iterator.remove(); - } - } - } - return changed; - } - - @Override - Set> createEntrySet() { - return new EntrySet(); - } - - @WeakOuter - private class EntrySet extends ImprovedAbstractSet> { - @Override - public Iterator> iterator() { - return new EntrySetIterator(); - } - - @Override - public int size() { - int size = 0; - for (Map map : backingMap.values()) { - if (map.containsKey(columnKey)) { - size++; - } - } - return size; - } - - @Override - public boolean isEmpty() { - return !containsColumn(columnKey); - } - - @Override - public void clear() { - removeFromColumnIf(alwaysTrue()); - } - - @Override - public boolean contains(Object o) { - if (o instanceof Entry) { - Entry entry = (Entry) o; - return containsMapping(entry.getKey(), columnKey, entry.getValue()); - } - return false; - } - - @Override - public boolean remove(Object obj) { - if (obj instanceof Entry) { - Entry entry = (Entry) obj; - return removeMapping(entry.getKey(), columnKey, entry.getValue()); - } - return false; - } - - @Override - public boolean retainAll(Collection c) { - return removeFromColumnIf(not(in(c))); - } - } - - private class EntrySetIterator extends AbstractIterator> { - final Iterator>> iterator = backingMap.entrySet().iterator(); - - @Override - protected Entry computeNext() { - while (iterator.hasNext()) { - final Entry> entry = iterator.next(); - if (entry.getValue().containsKey(columnKey)) { - @WeakOuter - class EntryImpl extends AbstractMapEntry { - @Override - public R getKey() { - return entry.getKey(); - } - - @Override - public V getValue() { - return entry.getValue().get(columnKey); - } - - @Override - public V setValue(V value) { - return entry.getValue().put(columnKey, checkNotNull(value)); - } - } - return new EntryImpl(); - } - } - return endOfData(); - } - } - - @Override - Set createKeySet() { - return new KeySet(); - } - - @WeakOuter - private class KeySet extends Maps.KeySet { - KeySet() { - super(Column.this); - } - - @Override - public boolean contains(Object obj) { - return StandardTable.this.contains(obj, columnKey); - } - - @Override - public boolean remove(Object obj) { - return StandardTable.this.remove(obj, columnKey) != null; - } - - @Override - public boolean retainAll(final Collection c) { - return removeFromColumnIf(Maps.keyPredicateOnEntries(not(in(c)))); - } - } - - @Override - Collection createValues() { - return new Values(); - } - - @WeakOuter - private class Values extends Maps.Values { - Values() { - super(Column.this); - } - - @Override - public boolean remove(Object obj) { - return obj != null && removeFromColumnIf(Maps.valuePredicateOnEntries(equalTo(obj))); - } - - @Override - public boolean removeAll(final Collection c) { - return removeFromColumnIf(Maps.valuePredicateOnEntries(in(c))); - } - - @Override - public boolean retainAll(final Collection c) { - return removeFromColumnIf(Maps.valuePredicateOnEntries(not(in(c)))); - } - } - } - - @Override - public Set rowKeySet() { - return rowMap().keySet(); - } - - private transient Set columnKeySet; - - /** - * {@inheritDoc} - * - *

The returned set has an iterator that does not support {@code remove()}. - * - *

The set's iterator traverses the columns of the first row, the - * columns of the second row, etc., skipping any columns that have - * appeared previously. - */ - @Override - public Set columnKeySet() { - Set result = columnKeySet; - return (result == null) ? columnKeySet = new ColumnKeySet() : result; - } - - @WeakOuter - private class ColumnKeySet extends TableSet { - @Override - public Iterator iterator() { - return createColumnKeyIterator(); - } - - @Override - public int size() { - return Iterators.size(iterator()); - } - - @Override - public boolean remove(Object obj) { - if (obj == null) { - return false; - } - boolean changed = false; - Iterator> iterator = backingMap.values().iterator(); - while (iterator.hasNext()) { - Map map = iterator.next(); - if (map.keySet().remove(obj)) { - changed = true; - if (map.isEmpty()) { - iterator.remove(); - } - } - } - return changed; - } - - @Override - public boolean removeAll(Collection c) { - checkNotNull(c); - boolean changed = false; - Iterator> iterator = backingMap.values().iterator(); - while (iterator.hasNext()) { - Map map = iterator.next(); - // map.keySet().removeAll(c) can throw a NPE when map is a TreeMap with - // natural ordering and c contains a null. - if (Iterators.removeAll(map.keySet().iterator(), c)) { - changed = true; - if (map.isEmpty()) { - iterator.remove(); - } - } - } - return changed; - } - - @Override - public boolean retainAll(Collection c) { - checkNotNull(c); - boolean changed = false; - Iterator> iterator = backingMap.values().iterator(); - while (iterator.hasNext()) { - Map map = iterator.next(); - if (map.keySet().retainAll(c)) { - changed = true; - if (map.isEmpty()) { - iterator.remove(); - } - } - } - return changed; - } - - @Override - public boolean contains(Object obj) { - return containsColumn(obj); - } - } - - /** - * Creates an iterator that returns each column value with duplicates - * omitted. - */ - Iterator createColumnKeyIterator() { - return new ColumnKeyIterator(); - } - - private class ColumnKeyIterator extends AbstractIterator { - // Use the same map type to support TreeMaps with comparators that aren't - // consistent with equals(). - final Map seen = factory.get(); - final Iterator> mapIterator = backingMap.values().iterator(); - Iterator> entryIterator = Iterators.emptyIterator(); - - @Override - protected C computeNext() { - while (true) { - if (entryIterator.hasNext()) { - Entry entry = entryIterator.next(); - if (!seen.containsKey(entry.getKey())) { - seen.put(entry.getKey(), entry.getValue()); - return entry.getKey(); - } - } else if (mapIterator.hasNext()) { - entryIterator = mapIterator.next().entrySet().iterator(); - } else { - return endOfData(); - } - } - } - } - - /** - * {@inheritDoc} - * - *

The collection's iterator traverses the values for the first row, - * the values for the second row, and so on. - */ - @Override - public Collection values() { - return super.values(); - } - - private transient Map> rowMap; - - @Override - public Map> rowMap() { - Map> result = rowMap; - return (result == null) ? rowMap = createRowMap() : result; - } - - Map> createRowMap() { - return new RowMap(); - } - - @WeakOuter - class RowMap extends ViewCachingAbstractMap> { - @Override - public boolean containsKey(Object key) { - return containsRow(key); - } - - // performing cast only when key is in backing map and has the correct type - @SuppressWarnings("unchecked") - @Override - public Map get(Object key) { - return containsRow(key) ? row((R) key) : null; - } - - @Override - public Map remove(Object key) { - return (key == null) ? null : backingMap.remove(key); - } - - @Override - protected Set>> createEntrySet() { - return new EntrySet(); - } - - @WeakOuter - class EntrySet extends TableSet>> { - @Override - public Iterator>> iterator() { - return Maps.asMapEntryIterator( - backingMap.keySet(), - new Function>() { - @Override - public Map apply(R rowKey) { - return row(rowKey); - } - }); - } - - @Override - public int size() { - return backingMap.size(); - } - - @Override - public boolean contains(Object obj) { - if (obj instanceof Entry) { - Entry entry = (Entry) obj; - return entry.getKey() != null - && entry.getValue() instanceof Map - && Collections2.safeContains(backingMap.entrySet(), entry); - } - return false; - } - - @Override - public boolean remove(Object obj) { - if (obj instanceof Entry) { - Entry entry = (Entry) obj; - return entry.getKey() != null - && entry.getValue() instanceof Map - && backingMap.entrySet().remove(entry); - } - return false; - } - } - } - - private transient ColumnMap columnMap; - - @Override - public Map> columnMap() { - ColumnMap result = columnMap; - return (result == null) ? columnMap = new ColumnMap() : result; - } - - @WeakOuter - private class ColumnMap extends ViewCachingAbstractMap> { - // The cast to C occurs only when the key is in the map, implying that it - // has the correct type. - @SuppressWarnings("unchecked") - @Override - public Map get(Object key) { - return containsColumn(key) ? column((C) key) : null; - } - - @Override - public boolean containsKey(Object key) { - return containsColumn(key); - } - - @Override - public Map remove(Object key) { - return containsColumn(key) ? removeColumn(key) : null; - } - - @Override - public Set>> createEntrySet() { - return new ColumnMapEntrySet(); - } - - @Override - public Set keySet() { - return columnKeySet(); - } - - @Override - Collection> createValues() { - return new ColumnMapValues(); - } - - @WeakOuter - class ColumnMapEntrySet extends TableSet>> { - @Override - public Iterator>> iterator() { - return Maps.asMapEntryIterator( - columnKeySet(), - new Function>() { - @Override - public Map apply(C columnKey) { - return column(columnKey); - } - }); - } - - @Override - public int size() { - return columnKeySet().size(); - } - - @Override - public boolean contains(Object obj) { - if (obj instanceof Entry) { - Entry entry = (Entry) obj; - if (containsColumn(entry.getKey())) { - // The cast to C occurs only when the key is in the map, implying - // that it has the correct type. - @SuppressWarnings("unchecked") - C columnKey = (C) entry.getKey(); - return get(columnKey).equals(entry.getValue()); - } - } - return false; - } - - @Override - public boolean remove(Object obj) { - if (contains(obj)) { - Entry entry = (Entry) obj; - removeColumn(entry.getKey()); - return true; - } - return false; - } - - @Override - public boolean removeAll(Collection c) { - /* - * We can't inherit the normal implementation (which calls - * Sets.removeAllImpl(Set, *Collection*) because, under some - * circumstances, it attempts to call columnKeySet().iterator().remove, - * which is unsupported. - */ - checkNotNull(c); - return Sets.removeAllImpl(this, c.iterator()); - } - - @Override - public boolean retainAll(Collection c) { - checkNotNull(c); - boolean changed = false; - for (C columnKey : Lists.newArrayList(columnKeySet().iterator())) { - if (!c.contains(Maps.immutableEntry(columnKey, column(columnKey)))) { - removeColumn(columnKey); - changed = true; - } - } - return changed; - } - } - - @WeakOuter - private class ColumnMapValues extends Maps.Values> { - ColumnMapValues() { - super(ColumnMap.this); - } - - @Override - public boolean remove(Object obj) { - for (Entry> entry : ColumnMap.this.entrySet()) { - if (entry.getValue().equals(obj)) { - removeColumn(entry.getKey()); - return true; - } - } - return false; - } - - @Override - public boolean removeAll(Collection c) { - checkNotNull(c); - boolean changed = false; - for (C columnKey : Lists.newArrayList(columnKeySet().iterator())) { - if (c.contains(column(columnKey))) { - removeColumn(columnKey); - changed = true; - } - } - return changed; - } - - @Override - public boolean retainAll(Collection c) { - checkNotNull(c); - boolean changed = false; - for (C columnKey : Lists.newArrayList(columnKeySet().iterator())) { - if (!c.contains(column(columnKey))) { - removeColumn(columnKey); - changed = true; - } - } - return changed; - } - } - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Synchronized.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Synchronized.java deleted file mode 100644 index 29c43efcbe18..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Synchronized.java +++ /dev/null @@ -1,1836 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.annotations.VisibleForTesting; - -import java.io.IOException; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.util.Collection; -import java.util.Comparator; -import java.util.Deque; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.NavigableMap; -import java.util.NavigableSet; -import java.util.Queue; -import java.util.RandomAccess; -import java.util.Set; -import java.util.SortedMap; -import java.util.SortedSet; - -import javax.annotation.Nullable; - -/** - * Synchronized collection views. The returned synchronized collection views are - * serializable if the backing collection and the mutex are serializable. - * - *

If {@code null} is passed as the {@code mutex} parameter to any of this - * class's top-level methods or inner class constructors, the created object - * uses itself as the synchronization mutex. - * - *

This class should be used by other collection classes only. - * - * @author Mike Bostock - * @author Jared Levy - */ -@GwtCompatible(emulated = true) -final class Synchronized { - private Synchronized() {} - - static class SynchronizedObject implements Serializable { - final Object delegate; - final Object mutex; - - SynchronizedObject(Object delegate, @Nullable Object mutex) { - this.delegate = checkNotNull(delegate); - this.mutex = (mutex == null) ? this : mutex; - } - - Object delegate() { - return delegate; - } - - // No equals and hashCode; see ForwardingObject for details. - - @Override - public String toString() { - synchronized (mutex) { - return delegate.toString(); - } - } - - // Serialization invokes writeObject only when it's private. - // The SynchronizedObject subclasses don't need a writeObject method since - // they don't contain any non-transient member variables, while the - // following writeObject() handles the SynchronizedObject members. - - @GwtIncompatible("java.io.ObjectOutputStream") - private void writeObject(ObjectOutputStream stream) throws IOException { - synchronized (mutex) { - stream.defaultWriteObject(); - } - } - - @GwtIncompatible("not needed in emulated source") - private static final long serialVersionUID = 0; - } - - private static Collection collection(Collection collection, @Nullable Object mutex) { - return new SynchronizedCollection(collection, mutex); - } - - @VisibleForTesting - static class SynchronizedCollection extends SynchronizedObject implements Collection { - private SynchronizedCollection(Collection delegate, @Nullable Object mutex) { - super(delegate, mutex); - } - - @SuppressWarnings("unchecked") - @Override - Collection delegate() { - return (Collection) super.delegate(); - } - - @Override - public boolean add(E e) { - synchronized (mutex) { - return delegate().add(e); - } - } - - @Override - public boolean addAll(Collection c) { - synchronized (mutex) { - return delegate().addAll(c); - } - } - - @Override - public void clear() { - synchronized (mutex) { - delegate().clear(); - } - } - - @Override - public boolean contains(Object o) { - synchronized (mutex) { - return delegate().contains(o); - } - } - - @Override - public boolean containsAll(Collection c) { - synchronized (mutex) { - return delegate().containsAll(c); - } - } - - @Override - public boolean isEmpty() { - synchronized (mutex) { - return delegate().isEmpty(); - } - } - - @Override - public Iterator iterator() { - return delegate().iterator(); // manually synchronized - } - - @Override - public boolean remove(Object o) { - synchronized (mutex) { - return delegate().remove(o); - } - } - - @Override - public boolean removeAll(Collection c) { - synchronized (mutex) { - return delegate().removeAll(c); - } - } - - @Override - public boolean retainAll(Collection c) { - synchronized (mutex) { - return delegate().retainAll(c); - } - } - - @Override - public int size() { - synchronized (mutex) { - return delegate().size(); - } - } - - @Override - public Object[] toArray() { - synchronized (mutex) { - return delegate().toArray(); - } - } - - @Override - public T[] toArray(T[] a) { - synchronized (mutex) { - return delegate().toArray(a); - } - } - - private static final long serialVersionUID = 0; - } - - @VisibleForTesting - static Set set(Set set, @Nullable Object mutex) { - return new SynchronizedSet(set, mutex); - } - - static class SynchronizedSet extends SynchronizedCollection implements Set { - - SynchronizedSet(Set delegate, @Nullable Object mutex) { - super(delegate, mutex); - } - - @Override - Set delegate() { - return (Set) super.delegate(); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - synchronized (mutex) { - return delegate().equals(o); - } - } - - @Override - public int hashCode() { - synchronized (mutex) { - return delegate().hashCode(); - } - } - - private static final long serialVersionUID = 0; - } - - private static SortedSet sortedSet(SortedSet set, @Nullable Object mutex) { - return new SynchronizedSortedSet(set, mutex); - } - - static class SynchronizedSortedSet extends SynchronizedSet implements SortedSet { - SynchronizedSortedSet(SortedSet delegate, @Nullable Object mutex) { - super(delegate, mutex); - } - - @Override - SortedSet delegate() { - return (SortedSet) super.delegate(); - } - - @Override - public Comparator comparator() { - synchronized (mutex) { - return delegate().comparator(); - } - } - - @Override - public SortedSet subSet(E fromElement, E toElement) { - synchronized (mutex) { - return sortedSet(delegate().subSet(fromElement, toElement), mutex); - } - } - - @Override - public SortedSet headSet(E toElement) { - synchronized (mutex) { - return sortedSet(delegate().headSet(toElement), mutex); - } - } - - @Override - public SortedSet tailSet(E fromElement) { - synchronized (mutex) { - return sortedSet(delegate().tailSet(fromElement), mutex); - } - } - - @Override - public E first() { - synchronized (mutex) { - return delegate().first(); - } - } - - @Override - public E last() { - synchronized (mutex) { - return delegate().last(); - } - } - - private static final long serialVersionUID = 0; - } - - private static List list(List list, @Nullable Object mutex) { - return (list instanceof RandomAccess) - ? new SynchronizedRandomAccessList(list, mutex) - : new SynchronizedList(list, mutex); - } - - private static class SynchronizedList extends SynchronizedCollection implements List { - SynchronizedList(List delegate, @Nullable Object mutex) { - super(delegate, mutex); - } - - @Override - List delegate() { - return (List) super.delegate(); - } - - @Override - public void add(int index, E element) { - synchronized (mutex) { - delegate().add(index, element); - } - } - - @Override - public boolean addAll(int index, Collection c) { - synchronized (mutex) { - return delegate().addAll(index, c); - } - } - - @Override - public E get(int index) { - synchronized (mutex) { - return delegate().get(index); - } - } - - @Override - public int indexOf(Object o) { - synchronized (mutex) { - return delegate().indexOf(o); - } - } - - @Override - public int lastIndexOf(Object o) { - synchronized (mutex) { - return delegate().lastIndexOf(o); - } - } - - @Override - public ListIterator listIterator() { - return delegate().listIterator(); // manually synchronized - } - - @Override - public ListIterator listIterator(int index) { - return delegate().listIterator(index); // manually synchronized - } - - @Override - public E remove(int index) { - synchronized (mutex) { - return delegate().remove(index); - } - } - - @Override - public E set(int index, E element) { - synchronized (mutex) { - return delegate().set(index, element); - } - } - - @Override - public List subList(int fromIndex, int toIndex) { - synchronized (mutex) { - return list(delegate().subList(fromIndex, toIndex), mutex); - } - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - synchronized (mutex) { - return delegate().equals(o); - } - } - - @Override - public int hashCode() { - synchronized (mutex) { - return delegate().hashCode(); - } - } - - private static final long serialVersionUID = 0; - } - - private static class SynchronizedRandomAccessList extends SynchronizedList - implements RandomAccess { - SynchronizedRandomAccessList(List list, @Nullable Object mutex) { - super(list, mutex); - } - - private static final long serialVersionUID = 0; - } - - static Multiset multiset(Multiset multiset, @Nullable Object mutex) { - if (multiset instanceof SynchronizedMultiset || multiset instanceof ImmutableMultiset) { - return multiset; - } - return new SynchronizedMultiset(multiset, mutex); - } - - private static class SynchronizedMultiset extends SynchronizedCollection - implements Multiset { - transient Set elementSet; - transient Set> entrySet; - - SynchronizedMultiset(Multiset delegate, @Nullable Object mutex) { - super(delegate, mutex); - } - - @Override - Multiset delegate() { - return (Multiset) super.delegate(); - } - - @Override - public int count(Object o) { - synchronized (mutex) { - return delegate().count(o); - } - } - - @Override - public int add(E e, int n) { - synchronized (mutex) { - return delegate().add(e, n); - } - } - - @Override - public int remove(Object o, int n) { - synchronized (mutex) { - return delegate().remove(o, n); - } - } - - @Override - public int setCount(E element, int count) { - synchronized (mutex) { - return delegate().setCount(element, count); - } - } - - @Override - public boolean setCount(E element, int oldCount, int newCount) { - synchronized (mutex) { - return delegate().setCount(element, oldCount, newCount); - } - } - - @Override - public Set elementSet() { - synchronized (mutex) { - if (elementSet == null) { - elementSet = typePreservingSet(delegate().elementSet(), mutex); - } - return elementSet; - } - } - - @Override - public Set> entrySet() { - synchronized (mutex) { - if (entrySet == null) { - entrySet = typePreservingSet(delegate().entrySet(), mutex); - } - return entrySet; - } - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - synchronized (mutex) { - return delegate().equals(o); - } - } - - @Override - public int hashCode() { - synchronized (mutex) { - return delegate().hashCode(); - } - } - - private static final long serialVersionUID = 0; - } - - static Multimap multimap(Multimap multimap, @Nullable Object mutex) { - if (multimap instanceof SynchronizedMultimap || multimap instanceof ImmutableMultimap) { - return multimap; - } - return new SynchronizedMultimap(multimap, mutex); - } - - private static class SynchronizedMultimap extends SynchronizedObject - implements Multimap { - transient Set keySet; - transient Collection valuesCollection; - transient Collection> entries; - transient Map> asMap; - transient Multiset keys; - - @SuppressWarnings("unchecked") - @Override - Multimap delegate() { - return (Multimap) super.delegate(); - } - - SynchronizedMultimap(Multimap delegate, @Nullable Object mutex) { - super(delegate, mutex); - } - - @Override - public int size() { - synchronized (mutex) { - return delegate().size(); - } - } - - @Override - public boolean isEmpty() { - synchronized (mutex) { - return delegate().isEmpty(); - } - } - - @Override - public boolean containsKey(Object key) { - synchronized (mutex) { - return delegate().containsKey(key); - } - } - - @Override - public boolean containsValue(Object value) { - synchronized (mutex) { - return delegate().containsValue(value); - } - } - - @Override - public boolean containsEntry(Object key, Object value) { - synchronized (mutex) { - return delegate().containsEntry(key, value); - } - } - - @Override - public Collection get(K key) { - synchronized (mutex) { - return typePreservingCollection(delegate().get(key), mutex); - } - } - - @Override - public boolean put(K key, V value) { - synchronized (mutex) { - return delegate().put(key, value); - } - } - - @Override - public boolean putAll(K key, Iterable values) { - synchronized (mutex) { - return delegate().putAll(key, values); - } - } - - @Override - public boolean putAll(Multimap multimap) { - synchronized (mutex) { - return delegate().putAll(multimap); - } - } - - @Override - public Collection replaceValues(K key, Iterable values) { - synchronized (mutex) { - return delegate().replaceValues(key, values); // copy not synchronized - } - } - - @Override - public boolean remove(Object key, Object value) { - synchronized (mutex) { - return delegate().remove(key, value); - } - } - - @Override - public Collection removeAll(Object key) { - synchronized (mutex) { - return delegate().removeAll(key); // copy not synchronized - } - } - - @Override - public void clear() { - synchronized (mutex) { - delegate().clear(); - } - } - - @Override - public Set keySet() { - synchronized (mutex) { - if (keySet == null) { - keySet = typePreservingSet(delegate().keySet(), mutex); - } - return keySet; - } - } - - @Override - public Collection values() { - synchronized (mutex) { - if (valuesCollection == null) { - valuesCollection = collection(delegate().values(), mutex); - } - return valuesCollection; - } - } - - @Override - public Collection> entries() { - synchronized (mutex) { - if (entries == null) { - entries = typePreservingCollection(delegate().entries(), mutex); - } - return entries; - } - } - - @Override - public Map> asMap() { - synchronized (mutex) { - if (asMap == null) { - asMap = new SynchronizedAsMap(delegate().asMap(), mutex); - } - return asMap; - } - } - - @Override - public Multiset keys() { - synchronized (mutex) { - if (keys == null) { - keys = multiset(delegate().keys(), mutex); - } - return keys; - } - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - synchronized (mutex) { - return delegate().equals(o); - } - } - - @Override - public int hashCode() { - synchronized (mutex) { - return delegate().hashCode(); - } - } - - private static final long serialVersionUID = 0; - } - - static ListMultimap listMultimap( - ListMultimap multimap, @Nullable Object mutex) { - if (multimap instanceof SynchronizedListMultimap || multimap instanceof ImmutableListMultimap) { - return multimap; - } - return new SynchronizedListMultimap(multimap, mutex); - } - - private static class SynchronizedListMultimap extends SynchronizedMultimap - implements ListMultimap { - SynchronizedListMultimap(ListMultimap delegate, @Nullable Object mutex) { - super(delegate, mutex); - } - - @Override - ListMultimap delegate() { - return (ListMultimap) super.delegate(); - } - - @Override - public List get(K key) { - synchronized (mutex) { - return list(delegate().get(key), mutex); - } - } - - @Override - public List removeAll(Object key) { - synchronized (mutex) { - return delegate().removeAll(key); // copy not synchronized - } - } - - @Override - public List replaceValues(K key, Iterable values) { - synchronized (mutex) { - return delegate().replaceValues(key, values); // copy not synchronized - } - } - - private static final long serialVersionUID = 0; - } - - static SetMultimap setMultimap(SetMultimap multimap, @Nullable Object mutex) { - if (multimap instanceof SynchronizedSetMultimap || multimap instanceof ImmutableSetMultimap) { - return multimap; - } - return new SynchronizedSetMultimap(multimap, mutex); - } - - private static class SynchronizedSetMultimap extends SynchronizedMultimap - implements SetMultimap { - transient Set> entrySet; - - SynchronizedSetMultimap(SetMultimap delegate, @Nullable Object mutex) { - super(delegate, mutex); - } - - @Override - SetMultimap delegate() { - return (SetMultimap) super.delegate(); - } - - @Override - public Set get(K key) { - synchronized (mutex) { - return set(delegate().get(key), mutex); - } - } - - @Override - public Set removeAll(Object key) { - synchronized (mutex) { - return delegate().removeAll(key); // copy not synchronized - } - } - - @Override - public Set replaceValues(K key, Iterable values) { - synchronized (mutex) { - return delegate().replaceValues(key, values); // copy not synchronized - } - } - - @Override - public Set> entries() { - synchronized (mutex) { - if (entrySet == null) { - entrySet = set(delegate().entries(), mutex); - } - return entrySet; - } - } - - private static final long serialVersionUID = 0; - } - - static SortedSetMultimap sortedSetMultimap( - SortedSetMultimap multimap, @Nullable Object mutex) { - if (multimap instanceof SynchronizedSortedSetMultimap) { - return multimap; - } - return new SynchronizedSortedSetMultimap(multimap, mutex); - } - - private static class SynchronizedSortedSetMultimap extends SynchronizedSetMultimap - implements SortedSetMultimap { - SynchronizedSortedSetMultimap(SortedSetMultimap delegate, @Nullable Object mutex) { - super(delegate, mutex); - } - - @Override - SortedSetMultimap delegate() { - return (SortedSetMultimap) super.delegate(); - } - - @Override - public SortedSet get(K key) { - synchronized (mutex) { - return sortedSet(delegate().get(key), mutex); - } - } - - @Override - public SortedSet removeAll(Object key) { - synchronized (mutex) { - return delegate().removeAll(key); // copy not synchronized - } - } - - @Override - public SortedSet replaceValues(K key, Iterable values) { - synchronized (mutex) { - return delegate().replaceValues(key, values); // copy not synchronized - } - } - - @Override - public Comparator valueComparator() { - synchronized (mutex) { - return delegate().valueComparator(); - } - } - - private static final long serialVersionUID = 0; - } - - private static Collection typePreservingCollection( - Collection collection, @Nullable Object mutex) { - if (collection instanceof SortedSet) { - return sortedSet((SortedSet) collection, mutex); - } - if (collection instanceof Set) { - return set((Set) collection, mutex); - } - if (collection instanceof List) { - return list((List) collection, mutex); - } - return collection(collection, mutex); - } - - private static Set typePreservingSet(Set set, @Nullable Object mutex) { - if (set instanceof SortedSet) { - return sortedSet((SortedSet) set, mutex); - } else { - return set(set, mutex); - } - } - - private static class SynchronizedAsMapEntries - extends SynchronizedSet>> { - SynchronizedAsMapEntries(Set>> delegate, @Nullable Object mutex) { - super(delegate, mutex); - } - - @Override - public Iterator>> iterator() { - // Must be manually synchronized. - return new TransformedIterator>, Map.Entry>>( - super.iterator()) { - @Override - Map.Entry> transform(final Map.Entry> entry) { - return new ForwardingMapEntry>() { - @Override - protected Map.Entry> delegate() { - return entry; - } - - @Override - public Collection getValue() { - return typePreservingCollection(entry.getValue(), mutex); - } - }; - } - }; - } - - // See Collections.CheckedMap.CheckedEntrySet for details on attacks. - - @Override - public Object[] toArray() { - synchronized (mutex) { - return ObjectArrays.toArrayImpl(delegate()); - } - } - - @Override - public T[] toArray(T[] array) { - synchronized (mutex) { - return ObjectArrays.toArrayImpl(delegate(), array); - } - } - - @Override - public boolean contains(Object o) { - synchronized (mutex) { - return Maps.containsEntryImpl(delegate(), o); - } - } - - @Override - public boolean containsAll(Collection c) { - synchronized (mutex) { - return Collections2.containsAllImpl(delegate(), c); - } - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - synchronized (mutex) { - return Sets.equalsImpl(delegate(), o); - } - } - - @Override - public boolean remove(Object o) { - synchronized (mutex) { - return Maps.removeEntryImpl(delegate(), o); - } - } - - @Override - public boolean removeAll(Collection c) { - synchronized (mutex) { - return Iterators.removeAll(delegate().iterator(), c); - } - } - - @Override - public boolean retainAll(Collection c) { - synchronized (mutex) { - return Iterators.retainAll(delegate().iterator(), c); - } - } - - private static final long serialVersionUID = 0; - } - - @VisibleForTesting - static Map map(Map map, @Nullable Object mutex) { - return new SynchronizedMap(map, mutex); - } - - private static class SynchronizedMap extends SynchronizedObject implements Map { - transient Set keySet; - transient Collection values; - transient Set> entrySet; - - SynchronizedMap(Map delegate, @Nullable Object mutex) { - super(delegate, mutex); - } - - @SuppressWarnings("unchecked") - @Override - Map delegate() { - return (Map) super.delegate(); - } - - @Override - public void clear() { - synchronized (mutex) { - delegate().clear(); - } - } - - @Override - public boolean containsKey(Object key) { - synchronized (mutex) { - return delegate().containsKey(key); - } - } - - @Override - public boolean containsValue(Object value) { - synchronized (mutex) { - return delegate().containsValue(value); - } - } - - @Override - public Set> entrySet() { - synchronized (mutex) { - if (entrySet == null) { - entrySet = set(delegate().entrySet(), mutex); - } - return entrySet; - } - } - - @Override - public V get(Object key) { - synchronized (mutex) { - return delegate().get(key); - } - } - - @Override - public boolean isEmpty() { - synchronized (mutex) { - return delegate().isEmpty(); - } - } - - @Override - public Set keySet() { - synchronized (mutex) { - if (keySet == null) { - keySet = set(delegate().keySet(), mutex); - } - return keySet; - } - } - - @Override - public V put(K key, V value) { - synchronized (mutex) { - return delegate().put(key, value); - } - } - - @Override - public void putAll(Map map) { - synchronized (mutex) { - delegate().putAll(map); - } - } - - @Override - public V remove(Object key) { - synchronized (mutex) { - return delegate().remove(key); - } - } - - @Override - public int size() { - synchronized (mutex) { - return delegate().size(); - } - } - - @Override - public Collection values() { - synchronized (mutex) { - if (values == null) { - values = collection(delegate().values(), mutex); - } - return values; - } - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - synchronized (mutex) { - return delegate().equals(o); - } - } - - @Override - public int hashCode() { - synchronized (mutex) { - return delegate().hashCode(); - } - } - - private static final long serialVersionUID = 0; - } - - static SortedMap sortedMap(SortedMap sortedMap, @Nullable Object mutex) { - return new SynchronizedSortedMap(sortedMap, mutex); - } - - static class SynchronizedSortedMap extends SynchronizedMap - implements SortedMap { - - SynchronizedSortedMap(SortedMap delegate, @Nullable Object mutex) { - super(delegate, mutex); - } - - @Override - SortedMap delegate() { - return (SortedMap) super.delegate(); - } - - @Override - public Comparator comparator() { - synchronized (mutex) { - return delegate().comparator(); - } - } - - @Override - public K firstKey() { - synchronized (mutex) { - return delegate().firstKey(); - } - } - - @Override - public SortedMap headMap(K toKey) { - synchronized (mutex) { - return sortedMap(delegate().headMap(toKey), mutex); - } - } - - @Override - public K lastKey() { - synchronized (mutex) { - return delegate().lastKey(); - } - } - - @Override - public SortedMap subMap(K fromKey, K toKey) { - synchronized (mutex) { - return sortedMap(delegate().subMap(fromKey, toKey), mutex); - } - } - - @Override - public SortedMap tailMap(K fromKey) { - synchronized (mutex) { - return sortedMap(delegate().tailMap(fromKey), mutex); - } - } - - private static final long serialVersionUID = 0; - } - - static BiMap biMap(BiMap bimap, @Nullable Object mutex) { - if (bimap instanceof SynchronizedBiMap || bimap instanceof ImmutableBiMap) { - return bimap; - } - return new SynchronizedBiMap(bimap, mutex, null); - } - - @VisibleForTesting - static class SynchronizedBiMap extends SynchronizedMap - implements BiMap, Serializable { - private transient Set valueSet; - private transient BiMap inverse; - - private SynchronizedBiMap( - BiMap delegate, @Nullable Object mutex, @Nullable BiMap inverse) { - super(delegate, mutex); - this.inverse = inverse; - } - - @Override - BiMap delegate() { - return (BiMap) super.delegate(); - } - - @Override - public Set values() { - synchronized (mutex) { - if (valueSet == null) { - valueSet = set(delegate().values(), mutex); - } - return valueSet; - } - } - - @Override - public V forcePut(K key, V value) { - synchronized (mutex) { - return delegate().forcePut(key, value); - } - } - - @Override - public BiMap inverse() { - synchronized (mutex) { - if (inverse == null) { - inverse = new SynchronizedBiMap(delegate().inverse(), mutex, this); - } - return inverse; - } - } - - private static final long serialVersionUID = 0; - } - - private static class SynchronizedAsMap extends SynchronizedMap> { - transient Set>> asMapEntrySet; - transient Collection> asMapValues; - - SynchronizedAsMap(Map> delegate, @Nullable Object mutex) { - super(delegate, mutex); - } - - @Override - public Collection get(Object key) { - synchronized (mutex) { - Collection collection = super.get(key); - return (collection == null) ? null : typePreservingCollection(collection, mutex); - } - } - - @Override - public Set>> entrySet() { - synchronized (mutex) { - if (asMapEntrySet == null) { - asMapEntrySet = new SynchronizedAsMapEntries(delegate().entrySet(), mutex); - } - return asMapEntrySet; - } - } - - @Override - public Collection> values() { - synchronized (mutex) { - if (asMapValues == null) { - asMapValues = new SynchronizedAsMapValues(delegate().values(), mutex); - } - return asMapValues; - } - } - - @Override - public boolean containsValue(Object o) { - // values() and its contains() method are both synchronized. - return values().contains(o); - } - - private static final long serialVersionUID = 0; - } - - private static class SynchronizedAsMapValues extends SynchronizedCollection> { - SynchronizedAsMapValues(Collection> delegate, @Nullable Object mutex) { - super(delegate, mutex); - } - - @Override - public Iterator> iterator() { - // Must be manually synchronized. - return new TransformedIterator, Collection>(super.iterator()) { - @Override - Collection transform(Collection from) { - return typePreservingCollection(from, mutex); - } - }; - } - - private static final long serialVersionUID = 0; - } - - @GwtIncompatible("NavigableSet") - @VisibleForTesting - static class SynchronizedNavigableSet extends SynchronizedSortedSet - implements NavigableSet { - SynchronizedNavigableSet(NavigableSet delegate, @Nullable Object mutex) { - super(delegate, mutex); - } - - @Override - NavigableSet delegate() { - return (NavigableSet) super.delegate(); - } - - @Override - public E ceiling(E e) { - synchronized (mutex) { - return delegate().ceiling(e); - } - } - - @Override - public Iterator descendingIterator() { - return delegate().descendingIterator(); // manually synchronized - } - - transient NavigableSet descendingSet; - - @Override - public NavigableSet descendingSet() { - synchronized (mutex) { - if (descendingSet == null) { - NavigableSet dS = Synchronized.navigableSet(delegate().descendingSet(), mutex); - descendingSet = dS; - return dS; - } - return descendingSet; - } - } - - @Override - public E floor(E e) { - synchronized (mutex) { - return delegate().floor(e); - } - } - - @Override - public NavigableSet headSet(E toElement, boolean inclusive) { - synchronized (mutex) { - return Synchronized.navigableSet(delegate().headSet(toElement, inclusive), mutex); - } - } - - @Override - public E higher(E e) { - synchronized (mutex) { - return delegate().higher(e); - } - } - - @Override - public E lower(E e) { - synchronized (mutex) { - return delegate().lower(e); - } - } - - @Override - public E pollFirst() { - synchronized (mutex) { - return delegate().pollFirst(); - } - } - - @Override - public E pollLast() { - synchronized (mutex) { - return delegate().pollLast(); - } - } - - @Override - public NavigableSet subSet( - E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { - synchronized (mutex) { - return Synchronized.navigableSet( - delegate().subSet(fromElement, fromInclusive, toElement, toInclusive), mutex); - } - } - - @Override - public NavigableSet tailSet(E fromElement, boolean inclusive) { - synchronized (mutex) { - return Synchronized.navigableSet(delegate().tailSet(fromElement, inclusive), mutex); - } - } - - @Override - public SortedSet headSet(E toElement) { - return headSet(toElement, false); - } - - @Override - public SortedSet subSet(E fromElement, E toElement) { - return subSet(fromElement, true, toElement, false); - } - - @Override - public SortedSet tailSet(E fromElement) { - return tailSet(fromElement, true); - } - - private static final long serialVersionUID = 0; - } - - @GwtIncompatible("NavigableSet") - static NavigableSet navigableSet(NavigableSet navigableSet, @Nullable Object mutex) { - return new SynchronizedNavigableSet(navigableSet, mutex); - } - - @GwtIncompatible("NavigableSet") - static NavigableSet navigableSet(NavigableSet navigableSet) { - return navigableSet(navigableSet, null); - } - - @GwtIncompatible("NavigableMap") - static NavigableMap navigableMap(NavigableMap navigableMap) { - return navigableMap(navigableMap, null); - } - - @GwtIncompatible("NavigableMap") - static NavigableMap navigableMap( - NavigableMap navigableMap, @Nullable Object mutex) { - return new SynchronizedNavigableMap(navigableMap, mutex); - } - - @GwtIncompatible("NavigableMap") - @VisibleForTesting - static class SynchronizedNavigableMap extends SynchronizedSortedMap - implements NavigableMap { - - SynchronizedNavigableMap(NavigableMap delegate, @Nullable Object mutex) { - super(delegate, mutex); - } - - @Override - NavigableMap delegate() { - return (NavigableMap) super.delegate(); - } - - @Override - public Entry ceilingEntry(K key) { - synchronized (mutex) { - return nullableSynchronizedEntry(delegate().ceilingEntry(key), mutex); - } - } - - @Override - public K ceilingKey(K key) { - synchronized (mutex) { - return delegate().ceilingKey(key); - } - } - - transient NavigableSet descendingKeySet; - - @Override - public NavigableSet descendingKeySet() { - synchronized (mutex) { - if (descendingKeySet == null) { - return descendingKeySet = Synchronized.navigableSet(delegate().descendingKeySet(), mutex); - } - return descendingKeySet; - } - } - - transient NavigableMap descendingMap; - - @Override - public NavigableMap descendingMap() { - synchronized (mutex) { - if (descendingMap == null) { - return descendingMap = navigableMap(delegate().descendingMap(), mutex); - } - return descendingMap; - } - } - - @Override - public Entry firstEntry() { - synchronized (mutex) { - return nullableSynchronizedEntry(delegate().firstEntry(), mutex); - } - } - - @Override - public Entry floorEntry(K key) { - synchronized (mutex) { - return nullableSynchronizedEntry(delegate().floorEntry(key), mutex); - } - } - - @Override - public K floorKey(K key) { - synchronized (mutex) { - return delegate().floorKey(key); - } - } - - @Override - public NavigableMap headMap(K toKey, boolean inclusive) { - synchronized (mutex) { - return navigableMap(delegate().headMap(toKey, inclusive), mutex); - } - } - - @Override - public Entry higherEntry(K key) { - synchronized (mutex) { - return nullableSynchronizedEntry(delegate().higherEntry(key), mutex); - } - } - - @Override - public K higherKey(K key) { - synchronized (mutex) { - return delegate().higherKey(key); - } - } - - @Override - public Entry lastEntry() { - synchronized (mutex) { - return nullableSynchronizedEntry(delegate().lastEntry(), mutex); - } - } - - @Override - public Entry lowerEntry(K key) { - synchronized (mutex) { - return nullableSynchronizedEntry(delegate().lowerEntry(key), mutex); - } - } - - @Override - public K lowerKey(K key) { - synchronized (mutex) { - return delegate().lowerKey(key); - } - } - - @Override - public Set keySet() { - return navigableKeySet(); - } - - transient NavigableSet navigableKeySet; - - @Override - public NavigableSet navigableKeySet() { - synchronized (mutex) { - if (navigableKeySet == null) { - return navigableKeySet = Synchronized.navigableSet(delegate().navigableKeySet(), mutex); - } - return navigableKeySet; - } - } - - @Override - public Entry pollFirstEntry() { - synchronized (mutex) { - return nullableSynchronizedEntry(delegate().pollFirstEntry(), mutex); - } - } - - @Override - public Entry pollLastEntry() { - synchronized (mutex) { - return nullableSynchronizedEntry(delegate().pollLastEntry(), mutex); - } - } - - @Override - public NavigableMap subMap( - K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { - synchronized (mutex) { - return navigableMap(delegate().subMap(fromKey, fromInclusive, toKey, toInclusive), mutex); - } - } - - @Override - public NavigableMap tailMap(K fromKey, boolean inclusive) { - synchronized (mutex) { - return navigableMap(delegate().tailMap(fromKey, inclusive), mutex); - } - } - - @Override - public SortedMap headMap(K toKey) { - return headMap(toKey, false); - } - - @Override - public SortedMap subMap(K fromKey, K toKey) { - return subMap(fromKey, true, toKey, false); - } - - @Override - public SortedMap tailMap(K fromKey) { - return tailMap(fromKey, true); - } - - private static final long serialVersionUID = 0; - } - - @GwtIncompatible("works but is needed only for NavigableMap") - private static Entry nullableSynchronizedEntry( - @Nullable Entry entry, @Nullable Object mutex) { - if (entry == null) { - return null; - } - return new SynchronizedEntry(entry, mutex); - } - - @GwtIncompatible("works but is needed only for NavigableMap") - private static class SynchronizedEntry extends SynchronizedObject implements Entry { - - SynchronizedEntry(Entry delegate, @Nullable Object mutex) { - super(delegate, mutex); - } - - @SuppressWarnings("unchecked") // guaranteed by the constructor - @Override - Entry delegate() { - return (Entry) super.delegate(); - } - - @Override - public boolean equals(Object obj) { - synchronized (mutex) { - return delegate().equals(obj); - } - } - - @Override - public int hashCode() { - synchronized (mutex) { - return delegate().hashCode(); - } - } - - @Override - public K getKey() { - synchronized (mutex) { - return delegate().getKey(); - } - } - - @Override - public V getValue() { - synchronized (mutex) { - return delegate().getValue(); - } - } - - @Override - public V setValue(V value) { - synchronized (mutex) { - return delegate().setValue(value); - } - } - - private static final long serialVersionUID = 0; - } - - static Queue queue(Queue queue, @Nullable Object mutex) { - return (queue instanceof SynchronizedQueue) ? queue : new SynchronizedQueue(queue, mutex); - } - - private static class SynchronizedQueue extends SynchronizedCollection implements Queue { - - SynchronizedQueue(Queue delegate, @Nullable Object mutex) { - super(delegate, mutex); - } - - @Override - Queue delegate() { - return (Queue) super.delegate(); - } - - @Override - public E element() { - synchronized (mutex) { - return delegate().element(); - } - } - - @Override - public boolean offer(E e) { - synchronized (mutex) { - return delegate().offer(e); - } - } - - @Override - public E peek() { - synchronized (mutex) { - return delegate().peek(); - } - } - - @Override - public E poll() { - synchronized (mutex) { - return delegate().poll(); - } - } - - @Override - public E remove() { - synchronized (mutex) { - return delegate().remove(); - } - } - - private static final long serialVersionUID = 0; - } - - @GwtIncompatible("Deque") - static Deque deque(Deque deque, @Nullable Object mutex) { - return new SynchronizedDeque(deque, mutex); - } - - @GwtIncompatible("Deque") - private static final class SynchronizedDeque extends SynchronizedQueue implements Deque { - - SynchronizedDeque(Deque delegate, @Nullable Object mutex) { - super(delegate, mutex); - } - - @Override - Deque delegate() { - return (Deque) super.delegate(); - } - - @Override - public void addFirst(E e) { - synchronized (mutex) { - delegate().addFirst(e); - } - } - - @Override - public void addLast(E e) { - synchronized (mutex) { - delegate().addLast(e); - } - } - - @Override - public boolean offerFirst(E e) { - synchronized (mutex) { - return delegate().offerFirst(e); - } - } - - @Override - public boolean offerLast(E e) { - synchronized (mutex) { - return delegate().offerLast(e); - } - } - - @Override - public E removeFirst() { - synchronized (mutex) { - return delegate().removeFirst(); - } - } - - @Override - public E removeLast() { - synchronized (mutex) { - return delegate().removeLast(); - } - } - - @Override - public E pollFirst() { - synchronized (mutex) { - return delegate().pollFirst(); - } - } - - @Override - public E pollLast() { - synchronized (mutex) { - return delegate().pollLast(); - } - } - - @Override - public E getFirst() { - synchronized (mutex) { - return delegate().getFirst(); - } - } - - @Override - public E getLast() { - synchronized (mutex) { - return delegate().getLast(); - } - } - - @Override - public E peekFirst() { - synchronized (mutex) { - return delegate().peekFirst(); - } - } - - @Override - public E peekLast() { - synchronized (mutex) { - return delegate().peekLast(); - } - } - - @Override - public boolean removeFirstOccurrence(Object o) { - synchronized (mutex) { - return delegate().removeFirstOccurrence(o); - } - } - - @Override - public boolean removeLastOccurrence(Object o) { - synchronized (mutex) { - return delegate().removeLastOccurrence(o); - } - } - - @Override - public void push(E e) { - synchronized (mutex) { - delegate().push(e); - } - } - - @Override - public E pop() { - synchronized (mutex) { - return delegate().pop(); - } - } - - @Override - public Iterator descendingIterator() { - synchronized (mutex) { - return delegate().descendingIterator(); - } - } - - private static final long serialVersionUID = 0; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Table.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Table.java deleted file mode 100644 index b993fb7c8d63..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Table.java +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Objects; - -import java.util.Collection; -import java.util.Map; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * A collection that associates an ordered pair of keys, called a row key and a - * column key, with a single value. A table may be sparse, with only a small - * fraction of row key / column key pairs possessing a corresponding value. - * - *

The mappings corresponding to a given row key may be viewed as a {@link - * Map} whose keys are the columns. The reverse is also available, associating a - * column with a row key / value map. Note that, in some implementations, data - * access by column key may have fewer supported operations or worse performance - * than data access by row key. - * - *

The methods returning collections or maps always return views of the - * underlying table. Updating the table can change the contents of those - * collections, and updating the collections will change the table. - * - *

All methods that modify the table are optional, and the views returned by - * the table may or may not be modifiable. When modification isn't supported, - * those methods will throw an {@link UnsupportedOperationException}. - * - *

See the Guava User Guide article on - * {@code Table}. - * - * @author Jared Levy - * @param the type of the table row keys - * @param the type of the table column keys - * @param the type of the mapped values - * @since 7.0 - */ -@GwtCompatible -public interface Table { - // TODO(jlevy): Consider adding methods similar to ConcurrentMap methods. - - // Accessors - - /** - * Returns {@code true} if the table contains a mapping with the specified - * row and column keys. - * - * @param rowKey key of row to search for - * @param columnKey key of column to search for - */ - boolean contains(@Nullable Object rowKey, @Nullable Object columnKey); - - /** - * Returns {@code true} if the table contains a mapping with the specified - * row key. - * - * @param rowKey key of row to search for - */ - boolean containsRow(@Nullable Object rowKey); - - /** - * Returns {@code true} if the table contains a mapping with the specified - * column. - * - * @param columnKey key of column to search for - */ - boolean containsColumn(@Nullable Object columnKey); - - /** - * Returns {@code true} if the table contains a mapping with the specified - * value. - * - * @param value value to search for - */ - boolean containsValue(@Nullable Object value); - - /** - * Returns the value corresponding to the given row and column keys, or - * {@code null} if no such mapping exists. - * - * @param rowKey key of row to search for - * @param columnKey key of column to search for - */ - V get(@Nullable Object rowKey, @Nullable Object columnKey); - - /** Returns {@code true} if the table contains no mappings. */ - boolean isEmpty(); - - /** - * Returns the number of row key / column key / value mappings in the table. - */ - int size(); - - /** - * Compares the specified object with this table for equality. Two tables are - * equal when their cell views, as returned by {@link #cellSet}, are equal. - */ - @Override - boolean equals(@Nullable Object obj); - - /** - * Returns the hash code for this table. The hash code of a table is defined - * as the hash code of its cell view, as returned by {@link #cellSet}. - */ - @Override - int hashCode(); - - // Mutators - - /** Removes all mappings from the table. */ - void clear(); - - /** - * Associates the specified value with the specified keys. If the table - * already contained a mapping for those keys, the old value is replaced with - * the specified value. - * - * @param rowKey row key that the value should be associated with - * @param columnKey column key that the value should be associated with - * @param value value to be associated with the specified keys - * @return the value previously associated with the keys, or {@code null} if - * no mapping existed for the keys - */ - @Nullable - V put(R rowKey, C columnKey, V value); - - /** - * Copies all mappings from the specified table to this table. The effect is - * equivalent to calling {@link #put} with each row key / column key / value - * mapping in {@code table}. - * - * @param table the table to add to this table - */ - void putAll(Table table); - - /** - * Removes the mapping, if any, associated with the given keys. - * - * @param rowKey row key of mapping to be removed - * @param columnKey column key of mapping to be removed - * @return the value previously associated with the keys, or {@code null} if - * no such value existed - */ - @Nullable - V remove(@Nullable Object rowKey, @Nullable Object columnKey); - - // Views - - /** - * Returns a view of all mappings that have the given row key. For each row - * key / column key / value mapping in the table with that row key, the - * returned map associates the column key with the value. If no mappings in - * the table have the provided row key, an empty map is returned. - * - *

Changes to the returned map will update the underlying table, and vice - * versa. - * - * @param rowKey key of row to search for in the table - * @return the corresponding map from column keys to values - */ - Map row(R rowKey); - - /** - * Returns a view of all mappings that have the given column key. For each row - * key / column key / value mapping in the table with that column key, the - * returned map associates the row key with the value. If no mappings in the - * table have the provided column key, an empty map is returned. - * - *

Changes to the returned map will update the underlying table, and vice - * versa. - * - * @param columnKey key of column to search for in the table - * @return the corresponding map from row keys to values - */ - Map column(C columnKey); - - /** - * Returns a set of all row key / column key / value triplets. Changes to the - * returned set will update the underlying table, and vice versa. The cell set - * does not support the {@code add} or {@code addAll} methods. - * - * @return set of table cells consisting of row key / column key / value - * triplets - */ - Set> cellSet(); - - /** - * Returns a set of row keys that have one or more values in the table. - * Changes to the set will update the underlying table, and vice versa. - * - * @return set of row keys - */ - Set rowKeySet(); - - /** - * Returns a set of column keys that have one or more values in the table. - * Changes to the set will update the underlying table, and vice versa. - * - * @return set of column keys - */ - Set columnKeySet(); - - /** - * Returns a collection of all values, which may contain duplicates. Changes - * to the returned collection will update the underlying table, and vice - * versa. - * - * @return collection of values - */ - Collection values(); - - /** - * Returns a view that associates each row key with the corresponding map from - * column keys to values. Changes to the returned map will update this table. - * The returned map does not support {@code put()} or {@code putAll()}, or - * {@code setValue()} on its entries. - * - *

In contrast, the maps returned by {@code rowMap().get()} have the same - * behavior as those returned by {@link #row}. Those maps may support {@code - * setValue()}, {@code put()}, and {@code putAll()}. - * - * @return a map view from each row key to a secondary map from column keys to - * values - */ - Map> rowMap(); - - /** - * Returns a view that associates each column key with the corresponding map - * from row keys to values. Changes to the returned map will update this - * table. The returned map does not support {@code put()} or {@code putAll()}, - * or {@code setValue()} on its entries. - * - *

In contrast, the maps returned by {@code columnMap().get()} have the - * same behavior as those returned by {@link #column}. Those maps may support - * {@code setValue()}, {@code put()}, and {@code putAll()}. - * - * @return a map view from each column key to a secondary map from row keys to - * values - */ - Map> columnMap(); - - /** - * Row key / column key / value triplet corresponding to a mapping in a table. - * - * @since 7.0 - */ - interface Cell { - /** - * Returns the row key of this cell. - */ - @Nullable - R getRowKey(); - - /** - * Returns the column key of this cell. - */ - @Nullable - C getColumnKey(); - - /** - * Returns the value of this cell. - */ - @Nullable - V getValue(); - - /** - * Compares the specified object with this cell for equality. Two cells are - * equal when they have equal row keys, column keys, and values. - */ - @Override - boolean equals(@Nullable Object obj); - - /** - * Returns the hash code of this cell. - * - *

The hash code of a table cell is equal to {@link - * Objects#hashCode}{@code (e.getRowKey(), e.getColumnKey(), e.getValue())}. - */ - @Override - int hashCode(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/Tables.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/Tables.java deleted file mode 100644 index 8f438a557c67..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/Tables.java +++ /dev/null @@ -1,622 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Function; -import com.google.common.base.Objects; -import com.google.common.base.Supplier; -import com.google.common.collect.Table.Cell; - -import java.io.Serializable; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; -import java.util.SortedSet; - -import javax.annotation.Nullable; - -/** - * Provides static methods that involve a {@code Table}. - * - *

See the Guava User Guide article on - * {@code Tables}. - * - * @author Jared Levy - * @author Louis Wasserman - * @since 7.0 - */ -@GwtCompatible -public final class Tables { - private Tables() {} - - /** - * Returns an immutable cell with the specified row key, column key, and - * value. - * - *

The returned cell is serializable. - * - * @param rowKey the row key to be associated with the returned cell - * @param columnKey the column key to be associated with the returned cell - * @param value the value to be associated with the returned cell - */ - public static Cell immutableCell( - @Nullable R rowKey, @Nullable C columnKey, @Nullable V value) { - return new ImmutableCell(rowKey, columnKey, value); - } - - static final class ImmutableCell extends AbstractCell implements Serializable { - private final R rowKey; - private final C columnKey; - private final V value; - - ImmutableCell(@Nullable R rowKey, @Nullable C columnKey, @Nullable V value) { - this.rowKey = rowKey; - this.columnKey = columnKey; - this.value = value; - } - - @Override - public R getRowKey() { - return rowKey; - } - - @Override - public C getColumnKey() { - return columnKey; - } - - @Override - public V getValue() { - return value; - } - - private static final long serialVersionUID = 0; - } - - abstract static class AbstractCell implements Cell { - // needed for serialization - AbstractCell() {} - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (obj instanceof Cell) { - Cell other = (Cell) obj; - return Objects.equal(getRowKey(), other.getRowKey()) - && Objects.equal(getColumnKey(), other.getColumnKey()) - && Objects.equal(getValue(), other.getValue()); - } - return false; - } - - @Override - public int hashCode() { - return Objects.hashCode(getRowKey(), getColumnKey(), getValue()); - } - - @Override - public String toString() { - return "(" + getRowKey() + "," + getColumnKey() + ")=" + getValue(); - } - } - - /** - * Creates a transposed view of a given table that flips its row and column - * keys. In other words, calling {@code get(columnKey, rowKey)} on the - * generated table always returns the same value as calling {@code - * get(rowKey, columnKey)} on the original table. Updating the original table - * changes the contents of the transposed table and vice versa. - * - *

The returned table supports update operations as long as the input table - * supports the analogous operation with swapped rows and columns. For - * example, in a {@link HashBasedTable} instance, {@code - * rowKeySet().iterator()} supports {@code remove()} but {@code - * columnKeySet().iterator()} doesn't. With a transposed {@link - * HashBasedTable}, it's the other way around. - */ - public static Table transpose(Table table) { - return (table instanceof TransposeTable) - ? ((TransposeTable) table).original - : new TransposeTable(table); - } - - private static class TransposeTable extends AbstractTable { - final Table original; - - TransposeTable(Table original) { - this.original = checkNotNull(original); - } - - @Override - public void clear() { - original.clear(); - } - - @Override - public Map column(R columnKey) { - return original.row(columnKey); - } - - @Override - public Set columnKeySet() { - return original.rowKeySet(); - } - - @Override - public Map> columnMap() { - return original.rowMap(); - } - - @Override - public boolean contains(@Nullable Object rowKey, @Nullable Object columnKey) { - return original.contains(columnKey, rowKey); - } - - @Override - public boolean containsColumn(@Nullable Object columnKey) { - return original.containsRow(columnKey); - } - - @Override - public boolean containsRow(@Nullable Object rowKey) { - return original.containsColumn(rowKey); - } - - @Override - public boolean containsValue(@Nullable Object value) { - return original.containsValue(value); - } - - @Override - public V get(@Nullable Object rowKey, @Nullable Object columnKey) { - return original.get(columnKey, rowKey); - } - - @Override - public V put(C rowKey, R columnKey, V value) { - return original.put(columnKey, rowKey, value); - } - - @Override - public void putAll(Table table) { - original.putAll(transpose(table)); - } - - @Override - public V remove(@Nullable Object rowKey, @Nullable Object columnKey) { - return original.remove(columnKey, rowKey); - } - - @Override - public Map row(C rowKey) { - return original.column(rowKey); - } - - @Override - public Set rowKeySet() { - return original.columnKeySet(); - } - - @Override - public Map> rowMap() { - return original.columnMap(); - } - - @Override - public int size() { - return original.size(); - } - - @Override - public Collection values() { - return original.values(); - } - - // Will cast TRANSPOSE_CELL to a type that always succeeds - private static final Function, Cell> TRANSPOSE_CELL = - new Function, Cell>() { - @Override - public Cell apply(Cell cell) { - return immutableCell(cell.getColumnKey(), cell.getRowKey(), cell.getValue()); - } - }; - - @SuppressWarnings("unchecked") - @Override - Iterator> cellIterator() { - return Iterators.transform(original.cellSet().iterator(), (Function) TRANSPOSE_CELL); - } - } - - /** - * Creates a table that uses the specified backing map and factory. It can - * generate a table based on arbitrary {@link Map} classes. - * - *

The {@code factory}-generated and {@code backingMap} classes determine - * the table iteration order. However, the table's {@code row()} method - * returns instances of a different class than {@code factory.get()} does. - * - *

Call this method only when the simpler factory methods in classes like - * {@link HashBasedTable} and {@link TreeBasedTable} won't suffice. - * - *

The views returned by the {@code Table} methods {@link Table#column}, - * {@link Table#columnKeySet}, and {@link Table#columnMap} have iterators that - * don't support {@code remove()}. Otherwise, all optional operations are - * supported. Null row keys, columns keys, and values are not supported. - * - *

Lookups by row key are often faster than lookups by column key, because - * the data is stored in a {@code Map>}. A method call like - * {@code column(columnKey).get(rowKey)} still runs quickly, since the row key - * is provided. However, {@code column(columnKey).size()} takes longer, since - * an iteration across all row keys occurs. - * - *

Note that this implementation is not synchronized. If multiple threads - * access this table concurrently and one of the threads modifies the table, - * it must be synchronized externally. - * - *

The table is serializable if {@code backingMap}, {@code factory}, the - * maps generated by {@code factory}, and the table contents are all - * serializable. - * - *

Note: the table assumes complete ownership over of {@code backingMap} - * and the maps returned by {@code factory}. Those objects should not be - * manually updated and they should not use soft, weak, or phantom references. - * - * @param backingMap place to store the mapping from each row key to its - * corresponding column key / value map - * @param factory supplier of new, empty maps that will each hold all column - * key / value mappings for a given row key - * @throws IllegalArgumentException if {@code backingMap} is not empty - * @since 10.0 - */ - @Beta - public static Table newCustomTable( - Map> backingMap, Supplier> factory) { - checkArgument(backingMap.isEmpty()); - checkNotNull(factory); - // TODO(jlevy): Wrap factory to validate that the supplied maps are empty? - return new StandardTable(backingMap, factory); - } - - /** - * Returns a view of a table where each value is transformed by a function. - * All other properties of the table, such as iteration order, are left - * intact. - * - *

Changes in the underlying table are reflected in this view. Conversely, - * this view supports removal operations, and these are reflected in the - * underlying table. - * - *

It's acceptable for the underlying table to contain null keys, and even - * null values provided that the function is capable of accepting null input. - * The transformed table might contain null values, if the function sometimes - * gives a null result. - * - *

The returned table is not thread-safe or serializable, even if the - * underlying table is. - * - *

The function is applied lazily, invoked when needed. This is necessary - * for the returned table to be a view, but it means that the function will be - * applied many times for bulk operations like {@link Table#containsValue} and - * {@code Table.toString()}. For this to perform well, {@code function} should - * be fast. To avoid lazy evaluation when the returned table doesn't need to - * be a view, copy the returned table into a new table of your choosing. - * - * @since 10.0 - */ - @Beta - public static Table transformValues( - Table fromTable, Function function) { - return new TransformedTable(fromTable, function); - } - - private static class TransformedTable extends AbstractTable { - final Table fromTable; - final Function function; - - TransformedTable(Table fromTable, Function function) { - this.fromTable = checkNotNull(fromTable); - this.function = checkNotNull(function); - } - - @Override - public boolean contains(Object rowKey, Object columnKey) { - return fromTable.contains(rowKey, columnKey); - } - - @Override - public V2 get(Object rowKey, Object columnKey) { - // The function is passed a null input only when the table contains a null - // value. - return contains(rowKey, columnKey) ? function.apply(fromTable.get(rowKey, columnKey)) : null; - } - - @Override - public int size() { - return fromTable.size(); - } - - @Override - public void clear() { - fromTable.clear(); - } - - @Override - public V2 put(R rowKey, C columnKey, V2 value) { - throw new UnsupportedOperationException(); - } - - @Override - public void putAll(Table table) { - throw new UnsupportedOperationException(); - } - - @Override - public V2 remove(Object rowKey, Object columnKey) { - return contains(rowKey, columnKey) - ? function.apply(fromTable.remove(rowKey, columnKey)) - : null; - } - - @Override - public Map row(R rowKey) { - return Maps.transformValues(fromTable.row(rowKey), function); - } - - @Override - public Map column(C columnKey) { - return Maps.transformValues(fromTable.column(columnKey), function); - } - - Function, Cell> cellFunction() { - return new Function, Cell>() { - @Override - public Cell apply(Cell cell) { - return immutableCell( - cell.getRowKey(), cell.getColumnKey(), function.apply(cell.getValue())); - } - }; - } - - @Override - Iterator> cellIterator() { - return Iterators.transform(fromTable.cellSet().iterator(), cellFunction()); - } - - @Override - public Set rowKeySet() { - return fromTable.rowKeySet(); - } - - @Override - public Set columnKeySet() { - return fromTable.columnKeySet(); - } - - @Override - Collection createValues() { - return Collections2.transform(fromTable.values(), function); - } - - @Override - public Map> rowMap() { - Function, Map> rowFunction = - new Function, Map>() { - @Override - public Map apply(Map row) { - return Maps.transformValues(row, function); - } - }; - return Maps.transformValues(fromTable.rowMap(), rowFunction); - } - - @Override - public Map> columnMap() { - Function, Map> columnFunction = - new Function, Map>() { - @Override - public Map apply(Map column) { - return Maps.transformValues(column, function); - } - }; - return Maps.transformValues(fromTable.columnMap(), columnFunction); - } - } - - /** - * Returns an unmodifiable view of the specified table. This method allows modules to provide - * users with "read-only" access to internal tables. Query operations on the returned table - * "read through" to the specified table, and attempts to modify the returned table, whether - * direct or via its collection views, result in an {@code UnsupportedOperationException}. - * - *

The returned table will be serializable if the specified table is serializable. - * - *

Consider using an {@link ImmutableTable}, which is guaranteed never to change. - * - * @param table - * the table for which an unmodifiable view is to be returned - * @return an unmodifiable view of the specified table - * @since 11.0 - */ - public static Table unmodifiableTable( - Table table) { - return new UnmodifiableTable(table); - } - - private static class UnmodifiableTable extends ForwardingTable - implements Serializable { - final Table delegate; - - UnmodifiableTable(Table delegate) { - this.delegate = checkNotNull(delegate); - } - - @SuppressWarnings("unchecked") // safe, covariant cast - @Override - protected Table delegate() { - return (Table) delegate; - } - - @Override - public Set> cellSet() { - return Collections.unmodifiableSet(super.cellSet()); - } - - @Override - public void clear() { - throw new UnsupportedOperationException(); - } - - @Override - public Map column(@Nullable C columnKey) { - return Collections.unmodifiableMap(super.column(columnKey)); - } - - @Override - public Set columnKeySet() { - return Collections.unmodifiableSet(super.columnKeySet()); - } - - @Override - public Map> columnMap() { - Function, Map> wrapper = unmodifiableWrapper(); - return Collections.unmodifiableMap(Maps.transformValues(super.columnMap(), wrapper)); - } - - @Override - public V put(@Nullable R rowKey, @Nullable C columnKey, @Nullable V value) { - throw new UnsupportedOperationException(); - } - - @Override - public void putAll(Table table) { - throw new UnsupportedOperationException(); - } - - @Override - public V remove(@Nullable Object rowKey, @Nullable Object columnKey) { - throw new UnsupportedOperationException(); - } - - @Override - public Map row(@Nullable R rowKey) { - return Collections.unmodifiableMap(super.row(rowKey)); - } - - @Override - public Set rowKeySet() { - return Collections.unmodifiableSet(super.rowKeySet()); - } - - @Override - public Map> rowMap() { - Function, Map> wrapper = unmodifiableWrapper(); - return Collections.unmodifiableMap(Maps.transformValues(super.rowMap(), wrapper)); - } - - @Override - public Collection values() { - return Collections.unmodifiableCollection(super.values()); - } - - private static final long serialVersionUID = 0; - } - - /** - * Returns an unmodifiable view of the specified row-sorted table. This method allows modules to - * provide users with "read-only" access to internal tables. Query operations on the returned - * table "read through" to the specified table, and attemps to modify the returned table, whether - * direct or via its collection views, result in an {@code UnsupportedOperationException}. - * - *

The returned table will be serializable if the specified table is serializable. - * - * @param table the row-sorted table for which an unmodifiable view is to be returned - * @return an unmodifiable view of the specified table - * @since 11.0 - */ - @Beta - public static RowSortedTable unmodifiableRowSortedTable( - RowSortedTable table) { - /* - * It's not ? extends R, because it's technically not covariant in R. Specifically, - * table.rowMap().comparator() could return a comparator that only works for the ? extends R. - * Collections.unmodifiableSortedMap makes the same distinction. - */ - return new UnmodifiableRowSortedMap(table); - } - - static final class UnmodifiableRowSortedMap extends UnmodifiableTable - implements RowSortedTable { - - public UnmodifiableRowSortedMap(RowSortedTable delegate) { - super(delegate); - } - - @Override - protected RowSortedTable delegate() { - return (RowSortedTable) super.delegate(); - } - - @Override - public SortedMap> rowMap() { - Function, Map> wrapper = unmodifiableWrapper(); - return Collections.unmodifiableSortedMap(Maps.transformValues(delegate().rowMap(), wrapper)); - } - - @Override - public SortedSet rowKeySet() { - return Collections.unmodifiableSortedSet(delegate().rowKeySet()); - } - - private static final long serialVersionUID = 0; - } - - @SuppressWarnings("unchecked") - private static Function, Map> unmodifiableWrapper() { - return (Function) UNMODIFIABLE_WRAPPER; - } - - private static final Function, ? extends Map> UNMODIFIABLE_WRAPPER = - new Function, Map>() { - @Override - public Map apply(Map input) { - return Collections.unmodifiableMap(input); - } - }; - - static boolean equalsImpl(Table table, @Nullable Object obj) { - if (obj == table) { - return true; - } else if (obj instanceof Table) { - Table that = (Table) obj; - return table.cellSet().equals(that.cellSet()); - } else { - return false; - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/TransformedIterator.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/TransformedIterator.java deleted file mode 100644 index c082d7dcc7c7..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/TransformedIterator.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Iterator; - -/** - * An iterator that transforms a backing iterator; for internal use. This avoids - * the object overhead of constructing a {@link Function} for internal methods. - * - * @author Louis Wasserman - */ -@GwtCompatible -abstract class TransformedIterator implements Iterator { - final Iterator backingIterator; - - TransformedIterator(Iterator backingIterator) { - this.backingIterator = checkNotNull(backingIterator); - } - - abstract T transform(F from); - - @Override - public final boolean hasNext() { - return backingIterator.hasNext(); - } - - @Override - public final T next() { - return transform(backingIterator.next()); - } - - @Override - public final void remove() { - backingIterator.remove(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/TransformedListIterator.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/TransformedListIterator.java deleted file mode 100644 index c74303089fa7..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/TransformedListIterator.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Function; - -import java.util.ListIterator; - -/** - * An iterator that transforms a backing list iterator; for internal use. This - * avoids the object overhead of constructing a {@link Function} for internal - * methods. - * - * @author Louis Wasserman - */ -@GwtCompatible -abstract class TransformedListIterator extends TransformedIterator - implements ListIterator { - TransformedListIterator(ListIterator backingIterator) { - super(backingIterator); - } - - private ListIterator backingIterator() { - return Iterators.cast(backingIterator); - } - - @Override - public final boolean hasPrevious() { - return backingIterator().hasPrevious(); - } - - @Override - public final T previous() { - return transform(backingIterator().previous()); - } - - @Override - public final int nextIndex() { - return backingIterator().nextIndex(); - } - - @Override - public final int previousIndex() { - return backingIterator().previousIndex(); - } - - @Override - public void set(T element) { - throw new UnsupportedOperationException(); - } - - @Override - public void add(T element) { - throw new UnsupportedOperationException(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/TreeBasedTable.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/TreeBasedTable.java deleted file mode 100644 index 10023d3a5ae3..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/TreeBasedTable.java +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Function; -import com.google.common.base.Supplier; - -import java.io.Serializable; -import java.util.Comparator; -import java.util.Iterator; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Set; -import java.util.SortedMap; -import java.util.SortedSet; -import java.util.TreeMap; - -import javax.annotation.Nullable; - -/** - * Implementation of {@code Table} whose row keys and column keys are ordered - * by their natural ordering or by supplied comparators. When constructing a - * {@code TreeBasedTable}, you may provide comparators for the row keys and - * the column keys, or you may use natural ordering for both. - * - *

The {@link #rowKeySet} method returns a {@link SortedSet} and the {@link - * #rowMap} method returns a {@link SortedMap}, instead of the {@link Set} and - * {@link Map} specified by the {@link Table} interface. - * - *

The views returned by {@link #column}, {@link #columnKeySet()}, and {@link - * #columnMap()} have iterators that don't support {@code remove()}. Otherwise, - * all optional operations are supported. Null row keys, columns keys, and - * values are not supported. - * - *

Lookups by row key are often faster than lookups by column key, because - * the data is stored in a {@code Map>}. A method call like {@code - * column(columnKey).get(rowKey)} still runs quickly, since the row key is - * provided. However, {@code column(columnKey).size()} takes longer, since an - * iteration across all row keys occurs. - * - *

Because a {@code TreeBasedTable} has unique sorted values for a given - * row, both {@code row(rowKey)} and {@code rowMap().get(rowKey)} are {@link - * SortedMap} instances, instead of the {@link Map} specified in the {@link - * Table} interface. - * - *

Note that this implementation is not synchronized. If multiple threads - * access this table concurrently and one of the threads modifies the table, it - * must be synchronized externally. - * - *

See the Guava User Guide article on - * {@code Table}. - * - * @author Jared Levy - * @author Louis Wasserman - * @since 7.0 - */ -@GwtCompatible(serializable = true) -@Beta -public class TreeBasedTable extends StandardRowSortedTable { - private final Comparator columnComparator; - - private static class Factory implements Supplier>, Serializable { - final Comparator comparator; - - Factory(Comparator comparator) { - this.comparator = comparator; - } - - @Override - public TreeMap get() { - return new TreeMap(comparator); - } - - private static final long serialVersionUID = 0; - } - - /** - * Creates an empty {@code TreeBasedTable} that uses the natural orderings - * of both row and column keys. - * - *

The method signature specifies {@code R extends Comparable} with a raw - * {@link Comparable}, instead of {@code R extends Comparable}, - * and the same for {@code C}. That's necessary to support classes defined - * without generics. - */ - public static TreeBasedTable create() { - return new TreeBasedTable(Ordering.natural(), Ordering.natural()); - } - - /** - * Creates an empty {@code TreeBasedTable} that is ordered by the specified - * comparators. - * - * @param rowComparator the comparator that orders the row keys - * @param columnComparator the comparator that orders the column keys - */ - public static TreeBasedTable create( - Comparator rowComparator, Comparator columnComparator) { - checkNotNull(rowComparator); - checkNotNull(columnComparator); - return new TreeBasedTable(rowComparator, columnComparator); - } - - /** - * Creates a {@code TreeBasedTable} with the same mappings and sort order - * as the specified {@code TreeBasedTable}. - */ - public static TreeBasedTable create(TreeBasedTable table) { - TreeBasedTable result = - new TreeBasedTable(table.rowComparator(), table.columnComparator()); - result.putAll(table); - return result; - } - - TreeBasedTable(Comparator rowComparator, Comparator columnComparator) { - super(new TreeMap>(rowComparator), new Factory(columnComparator)); - this.columnComparator = columnComparator; - } - - // TODO(jlevy): Move to StandardRowSortedTable? - - /** - * Returns the comparator that orders the rows. With natural ordering, - * {@link Ordering#natural()} is returned. - */ - public Comparator rowComparator() { - return rowKeySet().comparator(); - } - - /** - * Returns the comparator that orders the columns. With natural ordering, - * {@link Ordering#natural()} is returned. - */ - public Comparator columnComparator() { - return columnComparator; - } - - // TODO(lowasser): make column return a SortedMap - - /** - * {@inheritDoc} - * - *

Because a {@code TreeBasedTable} has unique sorted values for a given - * row, this method returns a {@link SortedMap}, instead of the {@link Map} - * specified in the {@link Table} interface. - * @since 10.0 - * (mostly source-compatible since 7.0) - */ - @Override - public SortedMap row(R rowKey) { - return new TreeRow(rowKey); - } - - private class TreeRow extends Row implements SortedMap { - @Nullable final C lowerBound; - @Nullable final C upperBound; - - TreeRow(R rowKey) { - this(rowKey, null, null); - } - - TreeRow(R rowKey, @Nullable C lowerBound, @Nullable C upperBound) { - super(rowKey); - this.lowerBound = lowerBound; - this.upperBound = upperBound; - checkArgument( - lowerBound == null || upperBound == null || compare(lowerBound, upperBound) <= 0); - } - - @Override - public SortedSet keySet() { - return new Maps.SortedKeySet(this); - } - - @Override - public Comparator comparator() { - return columnComparator(); - } - - int compare(Object a, Object b) { - // pretend we can compare anything - @SuppressWarnings({"rawtypes", "unchecked"}) - Comparator cmp = (Comparator) comparator(); - return cmp.compare(a, b); - } - - boolean rangeContains(@Nullable Object o) { - return o != null - && (lowerBound == null || compare(lowerBound, o) <= 0) - && (upperBound == null || compare(upperBound, o) > 0); - } - - @Override - public SortedMap subMap(C fromKey, C toKey) { - checkArgument(rangeContains(checkNotNull(fromKey)) && rangeContains(checkNotNull(toKey))); - return new TreeRow(rowKey, fromKey, toKey); - } - - @Override - public SortedMap headMap(C toKey) { - checkArgument(rangeContains(checkNotNull(toKey))); - return new TreeRow(rowKey, lowerBound, toKey); - } - - @Override - public SortedMap tailMap(C fromKey) { - checkArgument(rangeContains(checkNotNull(fromKey))); - return new TreeRow(rowKey, fromKey, upperBound); - } - - @Override - public C firstKey() { - SortedMap backing = backingRowMap(); - if (backing == null) { - throw new NoSuchElementException(); - } - return backingRowMap().firstKey(); - } - - @Override - public C lastKey() { - SortedMap backing = backingRowMap(); - if (backing == null) { - throw new NoSuchElementException(); - } - return backingRowMap().lastKey(); - } - - transient SortedMap wholeRow; - - /* - * If the row was previously empty, we check if there's a new row here every - * time we're queried. - */ - SortedMap wholeRow() { - if (wholeRow == null || (wholeRow.isEmpty() && backingMap.containsKey(rowKey))) { - wholeRow = (SortedMap) backingMap.get(rowKey); - } - return wholeRow; - } - - @Override - SortedMap backingRowMap() { - return (SortedMap) super.backingRowMap(); - } - - @Override - SortedMap computeBackingRowMap() { - SortedMap map = wholeRow(); - if (map != null) { - if (lowerBound != null) { - map = map.tailMap(lowerBound); - } - if (upperBound != null) { - map = map.headMap(upperBound); - } - return map; - } - return null; - } - - @Override - void maintainEmptyInvariant() { - if (wholeRow() != null && wholeRow.isEmpty()) { - backingMap.remove(rowKey); - wholeRow = null; - backingRowMap = null; - } - } - - @Override - public boolean containsKey(Object key) { - return rangeContains(key) && super.containsKey(key); - } - - @Override - public V put(C key, V value) { - checkArgument(rangeContains(checkNotNull(key))); - return super.put(key, value); - } - } - - // rowKeySet() and rowMap() are defined here so they appear in the Javadoc. - - @Override - public SortedSet rowKeySet() { - return super.rowKeySet(); - } - - @Override - public SortedMap> rowMap() { - return super.rowMap(); - } - - /** - * Overridden column iterator to return columns values in globally sorted - * order. - */ - @Override - Iterator createColumnKeyIterator() { - final Comparator comparator = columnComparator(); - - final Iterator merged = - Iterators.mergeSorted( - Iterables.transform( - backingMap.values(), - new Function, Iterator>() { - @Override - public Iterator apply(Map input) { - return input.keySet().iterator(); - } - }), - comparator); - - return new AbstractIterator() { - C lastValue; - - @Override - protected C computeNext() { - while (merged.hasNext()) { - C next = merged.next(); - boolean duplicate = lastValue != null && comparator.compare(next, lastValue) == 0; - - // Keep looping till we find a non-duplicate value. - if (!duplicate) { - lastValue = next; - return lastValue; - } - } - - lastValue = null; // clear reference to unused data - return endOfData(); - } - }; - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/TreeMultimap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/TreeMultimap.java deleted file mode 100644 index e3586e0bcd28..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/TreeMultimap.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.Collection; -import java.util.Comparator; -import java.util.NavigableMap; -import java.util.NavigableSet; -import java.util.SortedSet; -import java.util.TreeMap; -import java.util.TreeSet; - -import javax.annotation.Nullable; - -/** - * Implementation of {@code Multimap} whose keys and values are ordered by - * their natural ordering or by supplied comparators. In all cases, this - * implementation uses {@link Comparable#compareTo} or {@link - * Comparator#compare} instead of {@link Object#equals} to determine - * equivalence of instances. - * - *

Warning: The comparators or comparables used must be consistent - * with equals as explained by the {@link Comparable} class specification. - * Otherwise, the resulting multiset will violate the general contract of {@link - * SetMultimap}, which it is specified in terms of {@link Object#equals}. - * - *

The collections returned by {@code keySet} and {@code asMap} iterate - * through the keys according to the key comparator ordering or the natural - * ordering of the keys. Similarly, {@code get}, {@code removeAll}, and {@code - * replaceValues} return collections that iterate through the values according - * to the value comparator ordering or the natural ordering of the values. The - * collections generated by {@code entries}, {@code keys}, and {@code values} - * iterate across the keys according to the above key ordering, and for each - * key they iterate across the values according to the value ordering. - * - *

The multimap does not store duplicate key-value pairs. Adding a new - * key-value pair equal to an existing key-value pair has no effect. - * - *

Null keys and values are permitted (provided, of course, that the - * respective comparators support them). All optional multimap methods are - * supported, and all returned views are modifiable. - * - *

This class is not threadsafe when any concurrent operations update the - * multimap. Concurrent read operations will work correctly. To allow concurrent - * update operations, wrap your multimap with a call to {@link - * Multimaps#synchronizedSortedSetMultimap}. - * - *

See the Guava User Guide article on - * {@code Multimap}. - * - * @author Jared Levy - * @author Louis Wasserman - * @since 2.0 - */ -@GwtCompatible(serializable = true, emulated = true) -public class TreeMultimap extends AbstractSortedKeySortedSetMultimap { - private transient Comparator keyComparator; - private transient Comparator valueComparator; - - /** - * Creates an empty {@code TreeMultimap} ordered by the natural ordering of - * its keys and values. - */ - public static TreeMultimap create() { - return new TreeMultimap(Ordering.natural(), Ordering.natural()); - } - - /** - * Creates an empty {@code TreeMultimap} instance using explicit comparators. - * Neither comparator may be null; use {@link Ordering#natural()} to specify - * natural order. - * - * @param keyComparator the comparator that determines the key ordering - * @param valueComparator the comparator that determines the value ordering - */ - public static TreeMultimap create( - Comparator keyComparator, Comparator valueComparator) { - return new TreeMultimap(checkNotNull(keyComparator), checkNotNull(valueComparator)); - } - - /** - * Constructs a {@code TreeMultimap}, ordered by the natural ordering of its - * keys and values, with the same mappings as the specified multimap. - * - * @param multimap the multimap whose contents are copied to this multimap - */ - public static TreeMultimap create( - Multimap multimap) { - return new TreeMultimap(Ordering.natural(), Ordering.natural(), multimap); - } - - TreeMultimap(Comparator keyComparator, Comparator valueComparator) { - super(new TreeMap>(keyComparator)); - this.keyComparator = keyComparator; - this.valueComparator = valueComparator; - } - - private TreeMultimap( - Comparator keyComparator, - Comparator valueComparator, - Multimap multimap) { - this(keyComparator, valueComparator); - putAll(multimap); - } - - /** - * {@inheritDoc} - * - *

Creates an empty {@code TreeSet} for a collection of values for one key. - * - * @return a new {@code TreeSet} containing a collection of values for one - * key - */ - @Override - SortedSet createCollection() { - return new TreeSet(valueComparator); - } - - @Override - Collection createCollection(@Nullable K key) { - if (key == null) { - keyComparator().compare(key, key); - } - return super.createCollection(key); - } - - /** - * Returns the comparator that orders the multimap keys. - */ - public Comparator keyComparator() { - return keyComparator; - } - - @Override - public Comparator valueComparator() { - return valueComparator; - } - - /* - * The following @GwtIncompatible methods override the methods in - * AbstractSortedKeySortedSetMultimap, so GWT will fall back to the ASKSSM implementations, - * which return SortedSets and SortedMaps. - */ - - @Override - @GwtIncompatible("NavigableMap") - NavigableMap> backingMap() { - return (NavigableMap>) super.backingMap(); - } - - /** - * @since 14.0 (present with return type {@code SortedSet} since 2.0) - */ - @Override - @GwtIncompatible("NavigableSet") - public NavigableSet get(@Nullable K key) { - return (NavigableSet) super.get(key); - } - - @Override - @GwtIncompatible("NavigableSet") - Collection unmodifiableCollectionSubclass(Collection collection) { - return Sets.unmodifiableNavigableSet((NavigableSet) collection); - } - - @Override - @GwtIncompatible("NavigableSet") - Collection wrapCollection(K key, Collection collection) { - return new WrappedNavigableSet(key, (NavigableSet) collection, null); - } - - /** - * {@inheritDoc} - * - *

Because a {@code TreeMultimap} has unique sorted keys, this method - * returns a {@link NavigableSet}, instead of the {@link java.util.Set} specified - * in the {@link Multimap} interface. - * - * @since 14.0 (present with return type {@code SortedSet} since 2.0) - */ - @Override - @GwtIncompatible("NavigableSet") - public NavigableSet keySet() { - return (NavigableSet) super.keySet(); - } - - @Override - @GwtIncompatible("NavigableSet") - NavigableSet createKeySet() { - return new NavigableKeySet(backingMap()); - } - - /** - * {@inheritDoc} - * - *

Because a {@code TreeMultimap} has unique sorted keys, this method - * returns a {@link NavigableMap}, instead of the {@link java.util.Map} specified - * in the {@link Multimap} interface. - * - * @since 14.0 (present with return type {@code SortedMap} since 2.0) - */ - @Override - @GwtIncompatible("NavigableMap") - public NavigableMap> asMap() { - return (NavigableMap>) super.asMap(); - } - - @Override - @GwtIncompatible("NavigableMap") - NavigableMap> createAsMap() { - return new NavigableAsMap(backingMap()); - } - - /** - * @serialData key comparator, value comparator, number of distinct keys, and - * then for each distinct key: the key, number of values for that key, and - * key values - */ - @GwtIncompatible("java.io.ObjectOutputStream") - private void writeObject(ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); - stream.writeObject(keyComparator()); - stream.writeObject(valueComparator()); - Serialization.writeMultimap(this, stream); - } - - @GwtIncompatible("java.io.ObjectInputStream") - @SuppressWarnings("unchecked") // reading data stored by writeObject - private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - keyComparator = checkNotNull((Comparator) stream.readObject()); - valueComparator = checkNotNull((Comparator) stream.readObject()); - setMap(new TreeMap>(keyComparator)); - Serialization.populateMultimap(this, stream); - } - - @GwtIncompatible("not needed in emulated source") - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/TreeMultiset.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/TreeMultiset.java deleted file mode 100644 index 5d0fbb8d81cb..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/TreeMultiset.java +++ /dev/null @@ -1,991 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkState; -import static com.google.common.collect.CollectPreconditions.checkNonnegative; -import static com.google.common.collect.CollectPreconditions.checkRemove; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.base.MoreObjects; -import com.google.common.primitives.Ints; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.util.Comparator; -import java.util.ConcurrentModificationException; -import java.util.Iterator; -import java.util.NoSuchElementException; - -import javax.annotation.Nullable; - -/** - * A multiset which maintains the ordering of its elements, according to either their natural order - * or an explicit {@link Comparator}. In all cases, this implementation uses - * {@link Comparable#compareTo} or {@link Comparator#compare} instead of {@link Object#equals} to - * determine equivalence of instances. - * - *

Warning: The comparison must be consistent with equals as explained by the - * {@link Comparable} class specification. Otherwise, the resulting multiset will violate the - * {@link java.util.Collection} contract, which is specified in terms of {@link Object#equals}. - * - *

See the Guava User Guide article on - * {@code Multiset}. - * - * @author Louis Wasserman - * @author Jared Levy - * @since 2.0 - */ -@GwtCompatible(emulated = true) -public final class TreeMultiset extends AbstractSortedMultiset implements Serializable { - - /** - * Creates a new, empty multiset, sorted according to the elements' natural order. All elements - * inserted into the multiset must implement the {@code Comparable} interface. Furthermore, all - * such elements must be mutually comparable: {@code e1.compareTo(e2)} must not throw a - * {@code ClassCastException} for any elements {@code e1} and {@code e2} in the multiset. If the - * user attempts to add an element to the multiset that violates this constraint (for example, - * the user attempts to add a string element to a set whose elements are integers), the - * {@code add(Object)} call will throw a {@code ClassCastException}. - * - *

The type specification is {@code }, instead of the more specific - * {@code >}, to support classes defined without generics. - */ - public static TreeMultiset create() { - return new TreeMultiset(Ordering.natural()); - } - - /** - * Creates a new, empty multiset, sorted according to the specified comparator. All elements - * inserted into the multiset must be mutually comparable by the specified comparator: - * {@code comparator.compare(e1, - * e2)} must not throw a {@code ClassCastException} for any elements {@code e1} and {@code e2} in - * the multiset. If the user attempts to add an element to the multiset that violates this - * constraint, the {@code add(Object)} call will throw a {@code ClassCastException}. - * - * @param comparator - * the comparator that will be used to sort this multiset. A null value indicates that - * the elements' natural ordering should be used. - */ - @SuppressWarnings("unchecked") - public static TreeMultiset create(@Nullable Comparator comparator) { - return (comparator == null) - ? new TreeMultiset((Comparator) Ordering.natural()) - : new TreeMultiset(comparator); - } - - /** - * Creates an empty multiset containing the given initial elements, sorted according to the - * elements' natural order. - * - *

This implementation is highly efficient when {@code elements} is itself a {@link Multiset}. - * - *

The type specification is {@code }, instead of the more specific - * {@code >}, to support classes defined without generics. - */ - public static TreeMultiset create(Iterable elements) { - TreeMultiset multiset = create(); - Iterables.addAll(multiset, elements); - return multiset; - } - - private final transient Reference> rootReference; - private final transient GeneralRange range; - private final transient AvlNode header; - - TreeMultiset(Reference> rootReference, GeneralRange range, AvlNode endLink) { - super(range.comparator()); - this.rootReference = rootReference; - this.range = range; - this.header = endLink; - } - - TreeMultiset(Comparator comparator) { - super(comparator); - this.range = GeneralRange.all(comparator); - this.header = new AvlNode(null, 1); - successor(header, header); - this.rootReference = new Reference>(); - } - - /** - * A function which can be summed across a subtree. - */ - private enum Aggregate { - SIZE { - @Override - int nodeAggregate(AvlNode node) { - return node.elemCount; - } - - @Override - long treeAggregate(@Nullable AvlNode root) { - return (root == null) ? 0 : root.totalCount; - } - }, - DISTINCT { - @Override - int nodeAggregate(AvlNode node) { - return 1; - } - - @Override - long treeAggregate(@Nullable AvlNode root) { - return (root == null) ? 0 : root.distinctElements; - } - }; - - abstract int nodeAggregate(AvlNode node); - - abstract long treeAggregate(@Nullable AvlNode root); - } - - private long aggregateForEntries(Aggregate aggr) { - AvlNode root = rootReference.get(); - long total = aggr.treeAggregate(root); - if (range.hasLowerBound()) { - total -= aggregateBelowRange(aggr, root); - } - if (range.hasUpperBound()) { - total -= aggregateAboveRange(aggr, root); - } - return total; - } - - private long aggregateBelowRange(Aggregate aggr, @Nullable AvlNode node) { - if (node == null) { - return 0; - } - int cmp = comparator().compare(range.getLowerEndpoint(), node.elem); - if (cmp < 0) { - return aggregateBelowRange(aggr, node.left); - } else if (cmp == 0) { - switch (range.getLowerBoundType()) { - case OPEN: - return aggr.nodeAggregate(node) + aggr.treeAggregate(node.left); - case CLOSED: - return aggr.treeAggregate(node.left); - default: - throw new AssertionError(); - } - } else { - return aggr.treeAggregate(node.left) - + aggr.nodeAggregate(node) - + aggregateBelowRange(aggr, node.right); - } - } - - private long aggregateAboveRange(Aggregate aggr, @Nullable AvlNode node) { - if (node == null) { - return 0; - } - int cmp = comparator().compare(range.getUpperEndpoint(), node.elem); - if (cmp > 0) { - return aggregateAboveRange(aggr, node.right); - } else if (cmp == 0) { - switch (range.getUpperBoundType()) { - case OPEN: - return aggr.nodeAggregate(node) + aggr.treeAggregate(node.right); - case CLOSED: - return aggr.treeAggregate(node.right); - default: - throw new AssertionError(); - } - } else { - return aggr.treeAggregate(node.right) - + aggr.nodeAggregate(node) - + aggregateAboveRange(aggr, node.left); - } - } - - @Override - public int size() { - return Ints.saturatedCast(aggregateForEntries(Aggregate.SIZE)); - } - - @Override - int distinctElements() { - return Ints.saturatedCast(aggregateForEntries(Aggregate.DISTINCT)); - } - - @Override - public int count(@Nullable Object element) { - try { - @SuppressWarnings("unchecked") - E e = (E) element; - AvlNode root = rootReference.get(); - if (!range.contains(e) || root == null) { - return 0; - } - return root.count(comparator(), e); - } catch (ClassCastException e) { - return 0; - } catch (NullPointerException e) { - return 0; - } - } - - @Override - public int add(@Nullable E element, int occurrences) { - checkNonnegative(occurrences, "occurrences"); - if (occurrences == 0) { - return count(element); - } - checkArgument(range.contains(element)); - AvlNode root = rootReference.get(); - if (root == null) { - comparator().compare(element, element); - AvlNode newRoot = new AvlNode(element, occurrences); - successor(header, newRoot, header); - rootReference.checkAndSet(root, newRoot); - return 0; - } - int[] result = new int[1]; // used as a mutable int reference to hold result - AvlNode newRoot = root.add(comparator(), element, occurrences, result); - rootReference.checkAndSet(root, newRoot); - return result[0]; - } - - @Override - public int remove(@Nullable Object element, int occurrences) { - checkNonnegative(occurrences, "occurrences"); - if (occurrences == 0) { - return count(element); - } - AvlNode root = rootReference.get(); - int[] result = new int[1]; // used as a mutable int reference to hold result - AvlNode newRoot; - try { - @SuppressWarnings("unchecked") - E e = (E) element; - if (!range.contains(e) || root == null) { - return 0; - } - newRoot = root.remove(comparator(), e, occurrences, result); - } catch (ClassCastException e) { - return 0; - } catch (NullPointerException e) { - return 0; - } - rootReference.checkAndSet(root, newRoot); - return result[0]; - } - - @Override - public int setCount(@Nullable E element, int count) { - checkNonnegative(count, "count"); - if (!range.contains(element)) { - checkArgument(count == 0); - return 0; - } - - AvlNode root = rootReference.get(); - if (root == null) { - if (count > 0) { - add(element, count); - } - return 0; - } - int[] result = new int[1]; // used as a mutable int reference to hold result - AvlNode newRoot = root.setCount(comparator(), element, count, result); - rootReference.checkAndSet(root, newRoot); - return result[0]; - } - - @Override - public boolean setCount(@Nullable E element, int oldCount, int newCount) { - checkNonnegative(newCount, "newCount"); - checkNonnegative(oldCount, "oldCount"); - checkArgument(range.contains(element)); - - AvlNode root = rootReference.get(); - if (root == null) { - if (oldCount == 0) { - if (newCount > 0) { - add(element, newCount); - } - return true; - } else { - return false; - } - } - int[] result = new int[1]; // used as a mutable int reference to hold result - AvlNode newRoot = root.setCount(comparator(), element, oldCount, newCount, result); - rootReference.checkAndSet(root, newRoot); - return result[0] == oldCount; - } - - private Entry wrapEntry(final AvlNode baseEntry) { - return new Multisets.AbstractEntry() { - @Override - public E getElement() { - return baseEntry.getElement(); - } - - @Override - public int getCount() { - int result = baseEntry.getCount(); - if (result == 0) { - return count(getElement()); - } else { - return result; - } - } - }; - } - - /** - * Returns the first node in the tree that is in range. - */ - @Nullable - private AvlNode firstNode() { - AvlNode root = rootReference.get(); - if (root == null) { - return null; - } - AvlNode node; - if (range.hasLowerBound()) { - E endpoint = range.getLowerEndpoint(); - node = rootReference.get().ceiling(comparator(), endpoint); - if (node == null) { - return null; - } - if (range.getLowerBoundType() == BoundType.OPEN - && comparator().compare(endpoint, node.getElement()) == 0) { - node = node.succ; - } - } else { - node = header.succ; - } - return (node == header || !range.contains(node.getElement())) ? null : node; - } - - @Nullable - private AvlNode lastNode() { - AvlNode root = rootReference.get(); - if (root == null) { - return null; - } - AvlNode node; - if (range.hasUpperBound()) { - E endpoint = range.getUpperEndpoint(); - node = rootReference.get().floor(comparator(), endpoint); - if (node == null) { - return null; - } - if (range.getUpperBoundType() == BoundType.OPEN - && comparator().compare(endpoint, node.getElement()) == 0) { - node = node.pred; - } - } else { - node = header.pred; - } - return (node == header || !range.contains(node.getElement())) ? null : node; - } - - @Override - Iterator> entryIterator() { - return new Iterator>() { - AvlNode current = firstNode(); - Entry prevEntry; - - @Override - public boolean hasNext() { - if (current == null) { - return false; - } else if (range.tooHigh(current.getElement())) { - current = null; - return false; - } else { - return true; - } - } - - @Override - public Entry next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - Entry result = wrapEntry(current); - prevEntry = result; - if (current.succ == header) { - current = null; - } else { - current = current.succ; - } - return result; - } - - @Override - public void remove() { - checkRemove(prevEntry != null); - setCount(prevEntry.getElement(), 0); - prevEntry = null; - } - }; - } - - @Override - Iterator> descendingEntryIterator() { - return new Iterator>() { - AvlNode current = lastNode(); - Entry prevEntry = null; - - @Override - public boolean hasNext() { - if (current == null) { - return false; - } else if (range.tooLow(current.getElement())) { - current = null; - return false; - } else { - return true; - } - } - - @Override - public Entry next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - Entry result = wrapEntry(current); - prevEntry = result; - if (current.pred == header) { - current = null; - } else { - current = current.pred; - } - return result; - } - - @Override - public void remove() { - checkRemove(prevEntry != null); - setCount(prevEntry.getElement(), 0); - prevEntry = null; - } - }; - } - - @Override - public SortedMultiset headMultiset(@Nullable E upperBound, BoundType boundType) { - return new TreeMultiset( - rootReference, - range.intersect(GeneralRange.upTo(comparator(), upperBound, boundType)), - header); - } - - @Override - public SortedMultiset tailMultiset(@Nullable E lowerBound, BoundType boundType) { - return new TreeMultiset( - rootReference, - range.intersect(GeneralRange.downTo(comparator(), lowerBound, boundType)), - header); - } - - static int distinctElements(@Nullable AvlNode node) { - return (node == null) ? 0 : node.distinctElements; - } - - private static final class Reference { - @Nullable private T value; - - @Nullable - public T get() { - return value; - } - - public void checkAndSet(@Nullable T expected, T newValue) { - if (value != expected) { - throw new ConcurrentModificationException(); - } - value = newValue; - } - } - - private static final class AvlNode extends Multisets.AbstractEntry { - @Nullable private final E elem; - - // elemCount is 0 iff this node has been deleted. - private int elemCount; - - private int distinctElements; - private long totalCount; - private int height; - private AvlNode left; - private AvlNode right; - private AvlNode pred; - private AvlNode succ; - - AvlNode(@Nullable E elem, int elemCount) { - checkArgument(elemCount > 0); - this.elem = elem; - this.elemCount = elemCount; - this.totalCount = elemCount; - this.distinctElements = 1; - this.height = 1; - this.left = null; - this.right = null; - } - - public int count(Comparator comparator, E e) { - int cmp = comparator.compare(e, elem); - if (cmp < 0) { - return (left == null) ? 0 : left.count(comparator, e); - } else if (cmp > 0) { - return (right == null) ? 0 : right.count(comparator, e); - } else { - return elemCount; - } - } - - private AvlNode addRightChild(E e, int count) { - right = new AvlNode(e, count); - successor(this, right, succ); - height = Math.max(2, height); - distinctElements++; - totalCount += count; - return this; - } - - private AvlNode addLeftChild(E e, int count) { - left = new AvlNode(e, count); - successor(pred, left, this); - height = Math.max(2, height); - distinctElements++; - totalCount += count; - return this; - } - - AvlNode add(Comparator comparator, @Nullable E e, int count, int[] result) { - /* - * It speeds things up considerably to unconditionally add count to totalCount here, - * but that destroys failure atomicity in the case of count overflow. =( - */ - int cmp = comparator.compare(e, elem); - if (cmp < 0) { - AvlNode initLeft = left; - if (initLeft == null) { - result[0] = 0; - return addLeftChild(e, count); - } - int initHeight = initLeft.height; - - left = initLeft.add(comparator, e, count, result); - if (result[0] == 0) { - distinctElements++; - } - this.totalCount += count; - return (left.height == initHeight) ? this : rebalance(); - } else if (cmp > 0) { - AvlNode initRight = right; - if (initRight == null) { - result[0] = 0; - return addRightChild(e, count); - } - int initHeight = initRight.height; - - right = initRight.add(comparator, e, count, result); - if (result[0] == 0) { - distinctElements++; - } - this.totalCount += count; - return (right.height == initHeight) ? this : rebalance(); - } - - // adding count to me! No rebalance possible. - result[0] = elemCount; - long resultCount = (long) elemCount + count; - checkArgument(resultCount <= Integer.MAX_VALUE); - this.elemCount += count; - this.totalCount += count; - return this; - } - - AvlNode remove(Comparator comparator, @Nullable E e, int count, int[] result) { - int cmp = comparator.compare(e, elem); - if (cmp < 0) { - AvlNode initLeft = left; - if (initLeft == null) { - result[0] = 0; - return this; - } - - left = initLeft.remove(comparator, e, count, result); - - if (result[0] > 0) { - if (count >= result[0]) { - this.distinctElements--; - this.totalCount -= result[0]; - } else { - this.totalCount -= count; - } - } - return (result[0] == 0) ? this : rebalance(); - } else if (cmp > 0) { - AvlNode initRight = right; - if (initRight == null) { - result[0] = 0; - return this; - } - - right = initRight.remove(comparator, e, count, result); - - if (result[0] > 0) { - if (count >= result[0]) { - this.distinctElements--; - this.totalCount -= result[0]; - } else { - this.totalCount -= count; - } - } - return rebalance(); - } - - // removing count from me! - result[0] = elemCount; - if (count >= elemCount) { - return deleteMe(); - } else { - this.elemCount -= count; - this.totalCount -= count; - return this; - } - } - - AvlNode setCount(Comparator comparator, @Nullable E e, int count, int[] result) { - int cmp = comparator.compare(e, elem); - if (cmp < 0) { - AvlNode initLeft = left; - if (initLeft == null) { - result[0] = 0; - return (count > 0) ? addLeftChild(e, count) : this; - } - - left = initLeft.setCount(comparator, e, count, result); - - if (count == 0 && result[0] != 0) { - this.distinctElements--; - } else if (count > 0 && result[0] == 0) { - this.distinctElements++; - } - - this.totalCount += count - result[0]; - return rebalance(); - } else if (cmp > 0) { - AvlNode initRight = right; - if (initRight == null) { - result[0] = 0; - return (count > 0) ? addRightChild(e, count) : this; - } - - right = initRight.setCount(comparator, e, count, result); - - if (count == 0 && result[0] != 0) { - this.distinctElements--; - } else if (count > 0 && result[0] == 0) { - this.distinctElements++; - } - - this.totalCount += count - result[0]; - return rebalance(); - } - - // setting my count - result[0] = elemCount; - if (count == 0) { - return deleteMe(); - } - this.totalCount += count - elemCount; - this.elemCount = count; - return this; - } - - AvlNode setCount( - Comparator comparator, - @Nullable E e, - int expectedCount, - int newCount, - int[] result) { - int cmp = comparator.compare(e, elem); - if (cmp < 0) { - AvlNode initLeft = left; - if (initLeft == null) { - result[0] = 0; - if (expectedCount == 0 && newCount > 0) { - return addLeftChild(e, newCount); - } - return this; - } - - left = initLeft.setCount(comparator, e, expectedCount, newCount, result); - - if (result[0] == expectedCount) { - if (newCount == 0 && result[0] != 0) { - this.distinctElements--; - } else if (newCount > 0 && result[0] == 0) { - this.distinctElements++; - } - this.totalCount += newCount - result[0]; - } - return rebalance(); - } else if (cmp > 0) { - AvlNode initRight = right; - if (initRight == null) { - result[0] = 0; - if (expectedCount == 0 && newCount > 0) { - return addRightChild(e, newCount); - } - return this; - } - - right = initRight.setCount(comparator, e, expectedCount, newCount, result); - - if (result[0] == expectedCount) { - if (newCount == 0 && result[0] != 0) { - this.distinctElements--; - } else if (newCount > 0 && result[0] == 0) { - this.distinctElements++; - } - this.totalCount += newCount - result[0]; - } - return rebalance(); - } - - // setting my count - result[0] = elemCount; - if (expectedCount == elemCount) { - if (newCount == 0) { - return deleteMe(); - } - this.totalCount += newCount - elemCount; - this.elemCount = newCount; - } - return this; - } - - private AvlNode deleteMe() { - int oldElemCount = this.elemCount; - this.elemCount = 0; - successor(pred, succ); - if (left == null) { - return right; - } else if (right == null) { - return left; - } else if (left.height >= right.height) { - AvlNode newTop = pred; - // newTop is the maximum node in my left subtree - newTop.left = left.removeMax(newTop); - newTop.right = right; - newTop.distinctElements = distinctElements - 1; - newTop.totalCount = totalCount - oldElemCount; - return newTop.rebalance(); - } else { - AvlNode newTop = succ; - newTop.right = right.removeMin(newTop); - newTop.left = left; - newTop.distinctElements = distinctElements - 1; - newTop.totalCount = totalCount - oldElemCount; - return newTop.rebalance(); - } - } - - // Removes the minimum node from this subtree to be reused elsewhere - private AvlNode removeMin(AvlNode node) { - if (left == null) { - return right; - } else { - left = left.removeMin(node); - distinctElements--; - totalCount -= node.elemCount; - return rebalance(); - } - } - - // Removes the maximum node from this subtree to be reused elsewhere - private AvlNode removeMax(AvlNode node) { - if (right == null) { - return left; - } else { - right = right.removeMax(node); - distinctElements--; - totalCount -= node.elemCount; - return rebalance(); - } - } - - private void recomputeMultiset() { - this.distinctElements = - 1 + TreeMultiset.distinctElements(left) + TreeMultiset.distinctElements(right); - this.totalCount = elemCount + totalCount(left) + totalCount(right); - } - - private void recomputeHeight() { - this.height = 1 + Math.max(height(left), height(right)); - } - - private void recompute() { - recomputeMultiset(); - recomputeHeight(); - } - - private AvlNode rebalance() { - switch (balanceFactor()) { - case -2: - if (right.balanceFactor() > 0) { - right = right.rotateRight(); - } - return rotateLeft(); - case 2: - if (left.balanceFactor() < 0) { - left = left.rotateLeft(); - } - return rotateRight(); - default: - recomputeHeight(); - return this; - } - } - - private int balanceFactor() { - return height(left) - height(right); - } - - private AvlNode rotateLeft() { - checkState(right != null); - AvlNode newTop = right; - this.right = newTop.left; - newTop.left = this; - newTop.totalCount = this.totalCount; - newTop.distinctElements = this.distinctElements; - this.recompute(); - newTop.recomputeHeight(); - return newTop; - } - - private AvlNode rotateRight() { - checkState(left != null); - AvlNode newTop = left; - this.left = newTop.right; - newTop.right = this; - newTop.totalCount = this.totalCount; - newTop.distinctElements = this.distinctElements; - this.recompute(); - newTop.recomputeHeight(); - return newTop; - } - - private static long totalCount(@Nullable AvlNode node) { - return (node == null) ? 0 : node.totalCount; - } - - private static int height(@Nullable AvlNode node) { - return (node == null) ? 0 : node.height; - } - - @Nullable - private AvlNode ceiling(Comparator comparator, E e) { - int cmp = comparator.compare(e, elem); - if (cmp < 0) { - return (left == null) ? this : MoreObjects.firstNonNull(left.ceiling(comparator, e), this); - } else if (cmp == 0) { - return this; - } else { - return (right == null) ? null : right.ceiling(comparator, e); - } - } - - @Nullable - private AvlNode floor(Comparator comparator, E e) { - int cmp = comparator.compare(e, elem); - if (cmp > 0) { - return (right == null) ? this : MoreObjects.firstNonNull(right.floor(comparator, e), this); - } else if (cmp == 0) { - return this; - } else { - return (left == null) ? null : left.floor(comparator, e); - } - } - - @Override - public E getElement() { - return elem; - } - - @Override - public int getCount() { - return elemCount; - } - - @Override - public String toString() { - return Multisets.immutableEntry(getElement(), getCount()).toString(); - } - } - - private static void successor(AvlNode a, AvlNode b) { - a.succ = b; - b.pred = a; - } - - private static void successor(AvlNode a, AvlNode b, AvlNode c) { - successor(a, b); - successor(b, c); - } - - /* - * TODO(jlevy): Decide whether entrySet() should return entries with an equals() method that - * calls the comparator to compare the two keys. If that change is made, - * AbstractMultiset.equals() can simply check whether two multisets have equal entry sets. - */ - - /** - * @serialData the comparator, the number of distinct elements, the first element, its count, the - * second element, its count, and so on - */ - @GwtIncompatible("java.io.ObjectOutputStream") - private void writeObject(ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); - stream.writeObject(elementSet().comparator()); - Serialization.writeMultiset(this, stream); - } - - @GwtIncompatible("java.io.ObjectInputStream") - private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - @SuppressWarnings("unchecked") - // reading data stored by writeObject - Comparator comparator = (Comparator) stream.readObject(); - Serialization.getFieldSetter(AbstractSortedMultiset.class, "comparator").set(this, comparator); - Serialization.getFieldSetter(TreeMultiset.class, "range") - .set(this, GeneralRange.all(comparator)); - Serialization.getFieldSetter(TreeMultiset.class, "rootReference") - .set(this, new Reference>()); - AvlNode header = new AvlNode(null, 1); - Serialization.getFieldSetter(TreeMultiset.class, "header").set(this, header); - successor(header, header); - Serialization.populateMultiset(this, stream); - } - - @GwtIncompatible("not needed in emulated source") - private static final long serialVersionUID = 1; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/TreeRangeMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/TreeRangeMap.java deleted file mode 100644 index 349570785632..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/TreeRangeMap.java +++ /dev/null @@ -1,661 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Predicates.compose; -import static com.google.common.base.Predicates.in; -import static com.google.common.base.Predicates.not; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.base.MoreObjects; -import com.google.common.base.Predicate; -import com.google.common.collect.Maps.IteratorBasedAbstractMap; - -import java.util.AbstractMap; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.NavigableMap; -import java.util.NoSuchElementException; -import java.util.Set; - -import javax.annotation.Nullable; - -/** - * An implementation of {@code RangeMap} based on a {@code TreeMap}, supporting - * all optional operations. - * - *

Like all {@code RangeMap} implementations, this supports neither null - * keys nor null values. - * - * @author Louis Wasserman - * @since 14.0 - */ -@Beta -@GwtIncompatible("NavigableMap") -public final class TreeRangeMap implements RangeMap { - - private final NavigableMap, RangeMapEntry> entriesByLowerBound; - - public static TreeRangeMap create() { - return new TreeRangeMap(); - } - - private TreeRangeMap() { - this.entriesByLowerBound = Maps.newTreeMap(); - } - - private static final class RangeMapEntry - extends AbstractMapEntry, V> { - private final Range range; - private final V value; - - RangeMapEntry(Cut lowerBound, Cut upperBound, V value) { - this(Range.create(lowerBound, upperBound), value); - } - - RangeMapEntry(Range range, V value) { - this.range = range; - this.value = value; - } - - @Override - public Range getKey() { - return range; - } - - @Override - public V getValue() { - return value; - } - - public boolean contains(K value) { - return range.contains(value); - } - - Cut getLowerBound() { - return range.lowerBound; - } - - Cut getUpperBound() { - return range.upperBound; - } - } - - @Override - @Nullable - public V get(K key) { - Entry, V> entry = getEntry(key); - return (entry == null) ? null : entry.getValue(); - } - - @Override - @Nullable - public Entry, V> getEntry(K key) { - Map.Entry, RangeMapEntry> mapEntry = - entriesByLowerBound.floorEntry(Cut.belowValue(key)); - if (mapEntry != null && mapEntry.getValue().contains(key)) { - return mapEntry.getValue(); - } else { - return null; - } - } - - @Override - public void put(Range range, V value) { - if (!range.isEmpty()) { - checkNotNull(value); - remove(range); - entriesByLowerBound.put(range.lowerBound, new RangeMapEntry(range, value)); - } - } - - @Override - public void putAll(RangeMap rangeMap) { - for (Map.Entry, V> entry : rangeMap.asMapOfRanges().entrySet()) { - put(entry.getKey(), entry.getValue()); - } - } - - @Override - public void clear() { - entriesByLowerBound.clear(); - } - - @Override - public Range span() { - Entry, RangeMapEntry> firstEntry = entriesByLowerBound.firstEntry(); - Entry, RangeMapEntry> lastEntry = entriesByLowerBound.lastEntry(); - if (firstEntry == null) { - throw new NoSuchElementException(); - } - return Range.create( - firstEntry.getValue().getKey().lowerBound, lastEntry.getValue().getKey().upperBound); - } - - private void putRangeMapEntry(Cut lowerBound, Cut upperBound, V value) { - entriesByLowerBound.put(lowerBound, new RangeMapEntry(lowerBound, upperBound, value)); - } - - @Override - public void remove(Range rangeToRemove) { - if (rangeToRemove.isEmpty()) { - return; - } - - /* - * The comments for this method will use [ ] to indicate the bounds of rangeToRemove and ( ) to - * indicate the bounds of ranges in the range map. - */ - Map.Entry, RangeMapEntry> mapEntryBelowToTruncate = - entriesByLowerBound.lowerEntry(rangeToRemove.lowerBound); - if (mapEntryBelowToTruncate != null) { - // we know ( [ - RangeMapEntry rangeMapEntry = mapEntryBelowToTruncate.getValue(); - if (rangeMapEntry.getUpperBound().compareTo(rangeToRemove.lowerBound) > 0) { - // we know ( [ ) - if (rangeMapEntry.getUpperBound().compareTo(rangeToRemove.upperBound) > 0) { - // we know ( [ ] ), so insert the range ] ) back into the map -- - // it's being split apart - putRangeMapEntry( - rangeToRemove.upperBound, - rangeMapEntry.getUpperBound(), - mapEntryBelowToTruncate.getValue().getValue()); - } - // overwrite mapEntryToTruncateBelow with a truncated range - putRangeMapEntry( - rangeMapEntry.getLowerBound(), - rangeToRemove.lowerBound, - mapEntryBelowToTruncate.getValue().getValue()); - } - } - - Map.Entry, RangeMapEntry> mapEntryAboveToTruncate = - entriesByLowerBound.lowerEntry(rangeToRemove.upperBound); - if (mapEntryAboveToTruncate != null) { - // we know ( ] - RangeMapEntry rangeMapEntry = mapEntryAboveToTruncate.getValue(); - if (rangeMapEntry.getUpperBound().compareTo(rangeToRemove.upperBound) > 0) { - // we know ( ] ), and since we dealt with truncating below already, - // we know [ ( ] ) - putRangeMapEntry( - rangeToRemove.upperBound, - rangeMapEntry.getUpperBound(), - mapEntryAboveToTruncate.getValue().getValue()); - entriesByLowerBound.remove(rangeToRemove.lowerBound); - } - } - entriesByLowerBound.subMap(rangeToRemove.lowerBound, rangeToRemove.upperBound).clear(); - } - - @Override - public Map, V> asMapOfRanges() { - return new AsMapOfRanges(entriesByLowerBound.values()); - } - - @Override - public Map, V> asDescendingMapOfRanges() { - return new AsMapOfRanges(entriesByLowerBound.descendingMap().values()); - } - - private final class AsMapOfRanges extends IteratorBasedAbstractMap, V> { - - final Iterable, V>> entryIterable; - - @SuppressWarnings("unchecked") // it's safe to upcast iterables - AsMapOfRanges(Iterable> entryIterable) { - this.entryIterable = (Iterable) entryIterable; - } - - @Override - public boolean containsKey(@Nullable Object key) { - return get(key) != null; - } - - @Override - public V get(@Nullable Object key) { - if (key instanceof Range) { - Range range = (Range) key; - RangeMapEntry rangeMapEntry = entriesByLowerBound.get(range.lowerBound); - if (rangeMapEntry != null && rangeMapEntry.getKey().equals(range)) { - return rangeMapEntry.getValue(); - } - } - return null; - } - - @Override - public int size() { - return entriesByLowerBound.size(); - } - - @Override - Iterator, V>> entryIterator() { - return entryIterable.iterator(); - } - } - - @Override - public RangeMap subRangeMap(Range subRange) { - if (subRange.equals(Range.all())) { - return this; - } else { - return new SubRangeMap(subRange); - } - } - - @SuppressWarnings("unchecked") - private RangeMap emptySubRangeMap() { - return EMPTY_SUB_RANGE_MAP; - } - - private static final RangeMap EMPTY_SUB_RANGE_MAP = - new RangeMap() { - @Override - @Nullable - public Object get(Comparable key) { - return null; - } - - @Override - @Nullable - public Entry getEntry(Comparable key) { - return null; - } - - @Override - public Range span() { - throw new NoSuchElementException(); - } - - @Override - public void put(Range range, Object value) { - checkNotNull(range); - throw new IllegalArgumentException( - "Cannot insert range " + range + " into an empty subRangeMap"); - } - - @Override - public void putAll(RangeMap rangeMap) { - if (!rangeMap.asMapOfRanges().isEmpty()) { - throw new IllegalArgumentException( - "Cannot putAll(nonEmptyRangeMap) into an empty " + "subRangeMap"); - } - } - - @Override - public void clear() {} - - @Override - public void remove(Range range) { - checkNotNull(range); - } - - @Override - public Map asMapOfRanges() { - return Collections.emptyMap(); - } - - @Override - public Map asDescendingMapOfRanges() { - return Collections.emptyMap(); - } - - @Override - public RangeMap subRangeMap(Range range) { - checkNotNull(range); - return this; - } - }; - - private class SubRangeMap implements RangeMap { - - private final Range subRange; - - SubRangeMap(Range subRange) { - this.subRange = subRange; - } - - @Override - @Nullable - public V get(K key) { - return subRange.contains(key) ? TreeRangeMap.this.get(key) : null; - } - - @Override - @Nullable - public Entry, V> getEntry(K key) { - if (subRange.contains(key)) { - Entry, V> entry = TreeRangeMap.this.getEntry(key); - if (entry != null) { - return Maps.immutableEntry(entry.getKey().intersection(subRange), entry.getValue()); - } - } - return null; - } - - @Override - public Range span() { - Cut lowerBound; - Entry, RangeMapEntry> lowerEntry = - entriesByLowerBound.floorEntry(subRange.lowerBound); - if (lowerEntry != null - && lowerEntry.getValue().getUpperBound().compareTo(subRange.lowerBound) > 0) { - lowerBound = subRange.lowerBound; - } else { - lowerBound = entriesByLowerBound.ceilingKey(subRange.lowerBound); - if (lowerBound == null || lowerBound.compareTo(subRange.upperBound) >= 0) { - throw new NoSuchElementException(); - } - } - - Cut upperBound; - Entry, RangeMapEntry> upperEntry = - entriesByLowerBound.lowerEntry(subRange.upperBound); - if (upperEntry == null) { - throw new NoSuchElementException(); - } else if (upperEntry.getValue().getUpperBound().compareTo(subRange.upperBound) >= 0) { - upperBound = subRange.upperBound; - } else { - upperBound = upperEntry.getValue().getUpperBound(); - } - return Range.create(lowerBound, upperBound); - } - - @Override - public void put(Range range, V value) { - checkArgument( - subRange.encloses(range), "Cannot put range %s into a subRangeMap(%s)", range, subRange); - TreeRangeMap.this.put(range, value); - } - - @Override - public void putAll(RangeMap rangeMap) { - if (rangeMap.asMapOfRanges().isEmpty()) { - return; - } - Range span = rangeMap.span(); - checkArgument( - subRange.encloses(span), - "Cannot putAll rangeMap with span %s into a subRangeMap(%s)", - span, - subRange); - TreeRangeMap.this.putAll(rangeMap); - } - - @Override - public void clear() { - TreeRangeMap.this.remove(subRange); - } - - @Override - public void remove(Range range) { - if (range.isConnected(subRange)) { - TreeRangeMap.this.remove(range.intersection(subRange)); - } - } - - @Override - public RangeMap subRangeMap(Range range) { - if (!range.isConnected(subRange)) { - return emptySubRangeMap(); - } else { - return TreeRangeMap.this.subRangeMap(range.intersection(subRange)); - } - } - - @Override - public Map, V> asMapOfRanges() { - return new SubRangeMapAsMap(); - } - - @Override - public Map, V> asDescendingMapOfRanges() { - return new SubRangeMapAsMap() { - - @Override - Iterator, V>> entryIterator() { - if (subRange.isEmpty()) { - return Iterators.emptyIterator(); - } - final Iterator> backingItr = - entriesByLowerBound - .headMap(subRange.upperBound, false) - .descendingMap() - .values() - .iterator(); - return new AbstractIterator, V>>() { - - @Override - protected Entry, V> computeNext() { - while (backingItr.hasNext()) { - RangeMapEntry entry = backingItr.next(); - if (entry.getUpperBound().compareTo(subRange.lowerBound) <= 0) { - return endOfData(); - } - return Maps.immutableEntry(entry.getKey().intersection(subRange), entry.getValue()); - } - return endOfData(); - } - }; - } - }; - } - - @Override - public boolean equals(@Nullable Object o) { - if (o instanceof RangeMap) { - RangeMap rangeMap = (RangeMap) o; - return asMapOfRanges().equals(rangeMap.asMapOfRanges()); - } - return false; - } - - @Override - public int hashCode() { - return asMapOfRanges().hashCode(); - } - - @Override - public String toString() { - return asMapOfRanges().toString(); - } - - class SubRangeMapAsMap extends AbstractMap, V> { - - @Override - public boolean containsKey(Object key) { - return get(key) != null; - } - - @Override - public V get(Object key) { - try { - if (key instanceof Range) { - @SuppressWarnings("unchecked") // we catch ClassCastExceptions - Range r = (Range) key; - if (!subRange.encloses(r) || r.isEmpty()) { - return null; - } - RangeMapEntry candidate = null; - if (r.lowerBound.compareTo(subRange.lowerBound) == 0) { - // r could be truncated on the left - Entry, RangeMapEntry> entry = - entriesByLowerBound.floorEntry(r.lowerBound); - if (entry != null) { - candidate = entry.getValue(); - } - } else { - candidate = entriesByLowerBound.get(r.lowerBound); - } - - if (candidate != null - && candidate.getKey().isConnected(subRange) - && candidate.getKey().intersection(subRange).equals(r)) { - return candidate.getValue(); - } - } - } catch (ClassCastException e) { - return null; - } - return null; - } - - @Override - public V remove(Object key) { - V value = get(key); - if (value != null) { - @SuppressWarnings("unchecked") // it's definitely in the map, so safe - Range range = (Range) key; - TreeRangeMap.this.remove(range); - return value; - } - return null; - } - - @Override - public void clear() { - SubRangeMap.this.clear(); - } - - private boolean removeEntryIf(Predicate, V>> predicate) { - List> toRemove = Lists.newArrayList(); - for (Entry, V> entry : entrySet()) { - if (predicate.apply(entry)) { - toRemove.add(entry.getKey()); - } - } - for (Range range : toRemove) { - TreeRangeMap.this.remove(range); - } - return !toRemove.isEmpty(); - } - - @Override - public Set> keySet() { - return new Maps.KeySet, V>(SubRangeMapAsMap.this) { - @Override - public boolean remove(@Nullable Object o) { - return SubRangeMapAsMap.this.remove(o) != null; - } - - @Override - public boolean retainAll(Collection c) { - return removeEntryIf(compose(not(in(c)), Maps.>keyFunction())); - } - }; - } - - @Override - public Set, V>> entrySet() { - return new Maps.EntrySet, V>() { - @Override - Map, V> map() { - return SubRangeMapAsMap.this; - } - - @Override - public Iterator, V>> iterator() { - return entryIterator(); - } - - @Override - public boolean retainAll(Collection c) { - return removeEntryIf(not(in(c))); - } - - @Override - public int size() { - return Iterators.size(iterator()); - } - - @Override - public boolean isEmpty() { - return !iterator().hasNext(); - } - }; - } - - Iterator, V>> entryIterator() { - if (subRange.isEmpty()) { - return Iterators.emptyIterator(); - } - Cut cutToStart = - MoreObjects.firstNonNull( - entriesByLowerBound.floorKey(subRange.lowerBound), subRange.lowerBound); - final Iterator> backingItr = - entriesByLowerBound.tailMap(cutToStart, true).values().iterator(); - return new AbstractIterator, V>>() { - - @Override - protected Entry, V> computeNext() { - while (backingItr.hasNext()) { - RangeMapEntry entry = backingItr.next(); - if (entry.getLowerBound().compareTo(subRange.upperBound) >= 0) { - return endOfData(); - } else if (entry.getUpperBound().compareTo(subRange.lowerBound) > 0) { - // this might not be true e.g. at the start of the iteration - return Maps.immutableEntry(entry.getKey().intersection(subRange), entry.getValue()); - } - } - return endOfData(); - } - }; - } - - @Override - public Collection values() { - return new Maps.Values, V>(this) { - @Override - public boolean removeAll(Collection c) { - return removeEntryIf(compose(in(c), Maps.valueFunction())); - } - - @Override - public boolean retainAll(Collection c) { - return removeEntryIf(compose(not(in(c)), Maps.valueFunction())); - } - }; - } - } - } - - @Override - public boolean equals(@Nullable Object o) { - if (o instanceof RangeMap) { - RangeMap rangeMap = (RangeMap) o; - return asMapOfRanges().equals(rangeMap.asMapOfRanges()); - } - return false; - } - - @Override - public int hashCode() { - return asMapOfRanges().hashCode(); - } - - @Override - public String toString() { - return entriesByLowerBound.values().toString(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/TreeRangeSet.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/TreeRangeSet.java deleted file mode 100644 index 9bb5c2f9c55a..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/TreeRangeSet.java +++ /dev/null @@ -1,901 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.MoreObjects; - -import java.util.Collection; -import java.util.Comparator; -import java.util.Iterator; -import java.util.Map.Entry; -import java.util.NavigableMap; -import java.util.NoSuchElementException; -import java.util.Set; -import java.util.TreeMap; - -import javax.annotation.Nullable; - -/** - * An implementation of {@link RangeSet} backed by a {@link TreeMap}. - * - * @author Louis Wasserman - * @since 14.0 - */ -@Beta -@GwtIncompatible("uses NavigableMap") -public class TreeRangeSet> extends AbstractRangeSet { - - @VisibleForTesting final NavigableMap, Range> rangesByLowerBound; - - /** - * Creates an empty {@code TreeRangeSet} instance. - */ - public static > TreeRangeSet create() { - return new TreeRangeSet(new TreeMap, Range>()); - } - - /** - * Returns a {@code TreeRangeSet} initialized with the ranges in the specified range set. - */ - public static > TreeRangeSet create(RangeSet rangeSet) { - TreeRangeSet result = create(); - result.addAll(rangeSet); - return result; - } - - private TreeRangeSet(NavigableMap, Range> rangesByLowerCut) { - this.rangesByLowerBound = rangesByLowerCut; - } - - private transient Set> asRanges; - private transient Set> asDescendingSetOfRanges; - - @Override - public Set> asRanges() { - Set> result = asRanges; - return (result == null) ? asRanges = new AsRanges(rangesByLowerBound.values()) : result; - } - - @Override - public Set> asDescendingSetOfRanges() { - Set> result = asDescendingSetOfRanges; - return (result == null) - ? asDescendingSetOfRanges = new AsRanges(rangesByLowerBound.descendingMap().values()) - : result; - } - - final class AsRanges extends ForwardingCollection> implements Set> { - - final Collection> delegate; - - AsRanges(Collection> delegate) { - this.delegate = delegate; - } - - @Override - protected Collection> delegate() { - return delegate; - } - - @Override - public int hashCode() { - return Sets.hashCodeImpl(this); - } - - @Override - public boolean equals(@Nullable Object o) { - return Sets.equalsImpl(this, o); - } - } - - @Override - @Nullable - public Range rangeContaining(C value) { - checkNotNull(value); - Entry, Range> floorEntry = rangesByLowerBound.floorEntry(Cut.belowValue(value)); - if (floorEntry != null && floorEntry.getValue().contains(value)) { - return floorEntry.getValue(); - } else { - // TODO(kevinb): revisit this design choice - return null; - } - } - - @Override - public boolean encloses(Range range) { - checkNotNull(range); - Entry, Range> floorEntry = rangesByLowerBound.floorEntry(range.lowerBound); - return floorEntry != null && floorEntry.getValue().encloses(range); - } - - @Nullable - private Range rangeEnclosing(Range range) { - checkNotNull(range); - Entry, Range> floorEntry = rangesByLowerBound.floorEntry(range.lowerBound); - return (floorEntry != null && floorEntry.getValue().encloses(range)) - ? floorEntry.getValue() - : null; - } - - @Override - public Range span() { - Entry, Range> firstEntry = rangesByLowerBound.firstEntry(); - Entry, Range> lastEntry = rangesByLowerBound.lastEntry(); - if (firstEntry == null) { - throw new NoSuchElementException(); - } - return Range.create(firstEntry.getValue().lowerBound, lastEntry.getValue().upperBound); - } - - @Override - public void add(Range rangeToAdd) { - checkNotNull(rangeToAdd); - - if (rangeToAdd.isEmpty()) { - return; - } - - // We will use { } to illustrate ranges currently in the range set, and < > - // to illustrate rangeToAdd. - Cut lbToAdd = rangeToAdd.lowerBound; - Cut ubToAdd = rangeToAdd.upperBound; - - Entry, Range> entryBelowLB = rangesByLowerBound.lowerEntry(lbToAdd); - if (entryBelowLB != null) { - // { < - Range rangeBelowLB = entryBelowLB.getValue(); - if (rangeBelowLB.upperBound.compareTo(lbToAdd) >= 0) { - // { < }, and we will need to coalesce - if (rangeBelowLB.upperBound.compareTo(ubToAdd) >= 0) { - // { < > } - ubToAdd = rangeBelowLB.upperBound; - /* - * TODO(cpovirk): can we just "return;" here? Or, can we remove this if() entirely? If - * not, add tests to demonstrate the problem with each approach - */ - } - lbToAdd = rangeBelowLB.lowerBound; - } - } - - Entry, Range> entryBelowUB = rangesByLowerBound.floorEntry(ubToAdd); - if (entryBelowUB != null) { - // { > - Range rangeBelowUB = entryBelowUB.getValue(); - if (rangeBelowUB.upperBound.compareTo(ubToAdd) >= 0) { - // { > }, and we need to coalesce - ubToAdd = rangeBelowUB.upperBound; - } - } - - // Remove ranges which are strictly enclosed. - rangesByLowerBound.subMap(lbToAdd, ubToAdd).clear(); - - replaceRangeWithSameLowerBound(Range.create(lbToAdd, ubToAdd)); - } - - @Override - public void remove(Range rangeToRemove) { - checkNotNull(rangeToRemove); - - if (rangeToRemove.isEmpty()) { - return; - } - - // We will use { } to illustrate ranges currently in the range set, and < > - // to illustrate rangeToRemove. - - Entry, Range> entryBelowLB = rangesByLowerBound.lowerEntry(rangeToRemove.lowerBound); - if (entryBelowLB != null) { - // { < - Range rangeBelowLB = entryBelowLB.getValue(); - if (rangeBelowLB.upperBound.compareTo(rangeToRemove.lowerBound) >= 0) { - // { < }, and we will need to subdivide - if (rangeToRemove.hasUpperBound() - && rangeBelowLB.upperBound.compareTo(rangeToRemove.upperBound) >= 0) { - // { < > } - replaceRangeWithSameLowerBound( - Range.create(rangeToRemove.upperBound, rangeBelowLB.upperBound)); - } - replaceRangeWithSameLowerBound( - Range.create(rangeBelowLB.lowerBound, rangeToRemove.lowerBound)); - } - } - - Entry, Range> entryBelowUB = rangesByLowerBound.floorEntry(rangeToRemove.upperBound); - if (entryBelowUB != null) { - // { > - Range rangeBelowUB = entryBelowUB.getValue(); - if (rangeToRemove.hasUpperBound() - && rangeBelowUB.upperBound.compareTo(rangeToRemove.upperBound) >= 0) { - // { > } - replaceRangeWithSameLowerBound( - Range.create(rangeToRemove.upperBound, rangeBelowUB.upperBound)); - } - } - - rangesByLowerBound.subMap(rangeToRemove.lowerBound, rangeToRemove.upperBound).clear(); - } - - private void replaceRangeWithSameLowerBound(Range range) { - if (range.isEmpty()) { - rangesByLowerBound.remove(range.lowerBound); - } else { - rangesByLowerBound.put(range.lowerBound, range); - } - } - - private transient RangeSet complement; - - @Override - public RangeSet complement() { - RangeSet result = complement; - return (result == null) ? complement = new Complement() : result; - } - - @VisibleForTesting - static final class RangesByUpperBound> - extends AbstractNavigableMap, Range> { - private final NavigableMap, Range> rangesByLowerBound; - - /** - * upperBoundWindow represents the headMap/subMap/tailMap view of the entire "ranges by upper - * bound" map; it's a constraint on the *keys*, and does not affect the values. - */ - private final Range> upperBoundWindow; - - RangesByUpperBound(NavigableMap, Range> rangesByLowerBound) { - this.rangesByLowerBound = rangesByLowerBound; - this.upperBoundWindow = Range.all(); - } - - private RangesByUpperBound( - NavigableMap, Range> rangesByLowerBound, Range> upperBoundWindow) { - this.rangesByLowerBound = rangesByLowerBound; - this.upperBoundWindow = upperBoundWindow; - } - - private NavigableMap, Range> subMap(Range> window) { - if (window.isConnected(upperBoundWindow)) { - return new RangesByUpperBound(rangesByLowerBound, window.intersection(upperBoundWindow)); - } else { - return ImmutableSortedMap.of(); - } - } - - @Override - public NavigableMap, Range> subMap( - Cut fromKey, boolean fromInclusive, Cut toKey, boolean toInclusive) { - return subMap( - Range.range( - fromKey, BoundType.forBoolean(fromInclusive), - toKey, BoundType.forBoolean(toInclusive))); - } - - @Override - public NavigableMap, Range> headMap(Cut toKey, boolean inclusive) { - return subMap(Range.upTo(toKey, BoundType.forBoolean(inclusive))); - } - - @Override - public NavigableMap, Range> tailMap(Cut fromKey, boolean inclusive) { - return subMap(Range.downTo(fromKey, BoundType.forBoolean(inclusive))); - } - - @Override - public Comparator> comparator() { - return Ordering.>natural(); - } - - @Override - public boolean containsKey(@Nullable Object key) { - return get(key) != null; - } - - @Override - public Range get(@Nullable Object key) { - if (key instanceof Cut) { - try { - @SuppressWarnings("unchecked") // we catch CCEs - Cut cut = (Cut) key; - if (!upperBoundWindow.contains(cut)) { - return null; - } - Entry, Range> candidate = rangesByLowerBound.lowerEntry(cut); - if (candidate != null && candidate.getValue().upperBound.equals(cut)) { - return candidate.getValue(); - } - } catch (ClassCastException e) { - return null; - } - } - return null; - } - - @Override - Iterator, Range>> entryIterator() { - /* - * We want to start the iteration at the first range where the upper bound is in - * upperBoundWindow. - */ - final Iterator> backingItr; - if (!upperBoundWindow.hasLowerBound()) { - backingItr = rangesByLowerBound.values().iterator(); - } else { - Entry, Range> lowerEntry = - rangesByLowerBound.lowerEntry(upperBoundWindow.lowerEndpoint()); - if (lowerEntry == null) { - backingItr = rangesByLowerBound.values().iterator(); - } else if (upperBoundWindow.lowerBound.isLessThan(lowerEntry.getValue().upperBound)) { - backingItr = rangesByLowerBound.tailMap(lowerEntry.getKey(), true).values().iterator(); - } else { - backingItr = rangesByLowerBound - .tailMap(upperBoundWindow.lowerEndpoint(), true) - .values() - .iterator(); - } - } - return new AbstractIterator, Range>>() { - @Override - protected Entry, Range> computeNext() { - if (!backingItr.hasNext()) { - return endOfData(); - } - Range range = backingItr.next(); - if (upperBoundWindow.upperBound.isLessThan(range.upperBound)) { - return endOfData(); - } else { - return Maps.immutableEntry(range.upperBound, range); - } - } - }; - } - - @Override - Iterator, Range>> descendingEntryIterator() { - Collection> candidates; - if (upperBoundWindow.hasUpperBound()) { - candidates = - rangesByLowerBound - .headMap(upperBoundWindow.upperEndpoint(), false) - .descendingMap() - .values(); - } else { - candidates = rangesByLowerBound.descendingMap().values(); - } - final PeekingIterator> backingItr = Iterators.peekingIterator(candidates.iterator()); - if (backingItr.hasNext() - && upperBoundWindow.upperBound.isLessThan(backingItr.peek().upperBound)) { - backingItr.next(); - } - return new AbstractIterator, Range>>() { - @Override - protected Entry, Range> computeNext() { - if (!backingItr.hasNext()) { - return endOfData(); - } - Range range = backingItr.next(); - return upperBoundWindow.lowerBound.isLessThan(range.upperBound) - ? Maps.immutableEntry(range.upperBound, range) - : endOfData(); - } - }; - } - - @Override - public int size() { - if (upperBoundWindow.equals(Range.all())) { - return rangesByLowerBound.size(); - } - return Iterators.size(entryIterator()); - } - - @Override - public boolean isEmpty() { - return upperBoundWindow.equals(Range.all()) - ? rangesByLowerBound.isEmpty() - : !entryIterator().hasNext(); - } - } - - private static final class ComplementRangesByLowerBound> - extends AbstractNavigableMap, Range> { - private final NavigableMap, Range> positiveRangesByLowerBound; - private final NavigableMap, Range> positiveRangesByUpperBound; - - /** - * complementLowerBoundWindow represents the headMap/subMap/tailMap view of the entire - * "complement ranges by lower bound" map; it's a constraint on the *keys*, and does not affect - * the values. - */ - private final Range> complementLowerBoundWindow; - - ComplementRangesByLowerBound(NavigableMap, Range> positiveRangesByLowerBound) { - this(positiveRangesByLowerBound, Range.>all()); - } - - private ComplementRangesByLowerBound( - NavigableMap, Range> positiveRangesByLowerBound, Range> window) { - this.positiveRangesByLowerBound = positiveRangesByLowerBound; - this.positiveRangesByUpperBound = new RangesByUpperBound(positiveRangesByLowerBound); - this.complementLowerBoundWindow = window; - } - - private NavigableMap, Range> subMap(Range> subWindow) { - if (!complementLowerBoundWindow.isConnected(subWindow)) { - return ImmutableSortedMap.of(); - } else { - subWindow = subWindow.intersection(complementLowerBoundWindow); - return new ComplementRangesByLowerBound(positiveRangesByLowerBound, subWindow); - } - } - - @Override - public NavigableMap, Range> subMap( - Cut fromKey, boolean fromInclusive, Cut toKey, boolean toInclusive) { - return subMap( - Range.range( - fromKey, BoundType.forBoolean(fromInclusive), - toKey, BoundType.forBoolean(toInclusive))); - } - - @Override - public NavigableMap, Range> headMap(Cut toKey, boolean inclusive) { - return subMap(Range.upTo(toKey, BoundType.forBoolean(inclusive))); - } - - @Override - public NavigableMap, Range> tailMap(Cut fromKey, boolean inclusive) { - return subMap(Range.downTo(fromKey, BoundType.forBoolean(inclusive))); - } - - @Override - public Comparator> comparator() { - return Ordering.>natural(); - } - - @Override - Iterator, Range>> entryIterator() { - /* - * firstComplementRangeLowerBound is the first complement range lower bound inside - * complementLowerBoundWindow. Complement range lower bounds are either positive range upper - * bounds, or Cut.belowAll(). - * - * positiveItr starts at the first positive range with lower bound greater than - * firstComplementRangeLowerBound. (Positive range lower bounds correspond to complement range - * upper bounds.) - */ - Collection> positiveRanges; - if (complementLowerBoundWindow.hasLowerBound()) { - positiveRanges = - positiveRangesByUpperBound - .tailMap( - complementLowerBoundWindow.lowerEndpoint(), - complementLowerBoundWindow.lowerBoundType() == BoundType.CLOSED) - .values(); - } else { - positiveRanges = positiveRangesByUpperBound.values(); - } - final PeekingIterator> positiveItr = - Iterators.peekingIterator(positiveRanges.iterator()); - final Cut firstComplementRangeLowerBound; - if (complementLowerBoundWindow.contains(Cut.belowAll()) - && (!positiveItr.hasNext() || positiveItr.peek().lowerBound != Cut.belowAll())) { - firstComplementRangeLowerBound = Cut.belowAll(); - } else if (positiveItr.hasNext()) { - firstComplementRangeLowerBound = positiveItr.next().upperBound; - } else { - return Iterators.emptyIterator(); - } - return new AbstractIterator, Range>>() { - Cut nextComplementRangeLowerBound = firstComplementRangeLowerBound; - - @Override - protected Entry, Range> computeNext() { - if (complementLowerBoundWindow.upperBound.isLessThan(nextComplementRangeLowerBound) - || nextComplementRangeLowerBound == Cut.aboveAll()) { - return endOfData(); - } - Range negativeRange; - if (positiveItr.hasNext()) { - Range positiveRange = positiveItr.next(); - negativeRange = Range.create(nextComplementRangeLowerBound, positiveRange.lowerBound); - nextComplementRangeLowerBound = positiveRange.upperBound; - } else { - negativeRange = Range.create(nextComplementRangeLowerBound, Cut.aboveAll()); - nextComplementRangeLowerBound = Cut.aboveAll(); - } - return Maps.immutableEntry(negativeRange.lowerBound, negativeRange); - } - }; - } - - @Override - Iterator, Range>> descendingEntryIterator() { - /* - * firstComplementRangeUpperBound is the upper bound of the last complement range with lower - * bound inside complementLowerBoundWindow. - * - * positiveItr starts at the first positive range with upper bound less than - * firstComplementRangeUpperBound. (Positive range upper bounds correspond to complement range - * lower bounds.) - */ - Cut startingPoint = - complementLowerBoundWindow.hasUpperBound() - ? complementLowerBoundWindow.upperEndpoint() - : Cut.aboveAll(); - boolean inclusive = - complementLowerBoundWindow.hasUpperBound() - && complementLowerBoundWindow.upperBoundType() == BoundType.CLOSED; - final PeekingIterator> positiveItr = - Iterators.peekingIterator( - positiveRangesByUpperBound - .headMap(startingPoint, inclusive) - .descendingMap() - .values() - .iterator()); - Cut cut; - if (positiveItr.hasNext()) { - cut = (positiveItr.peek().upperBound == Cut.aboveAll()) - ? positiveItr.next().lowerBound - : positiveRangesByLowerBound.higherKey(positiveItr.peek().upperBound); - } else if (!complementLowerBoundWindow.contains(Cut.belowAll()) - || positiveRangesByLowerBound.containsKey(Cut.belowAll())) { - return Iterators.emptyIterator(); - } else { - cut = positiveRangesByLowerBound.higherKey(Cut.belowAll()); - } - final Cut firstComplementRangeUpperBound = - MoreObjects.firstNonNull(cut, Cut.aboveAll()); - return new AbstractIterator, Range>>() { - Cut nextComplementRangeUpperBound = firstComplementRangeUpperBound; - - @Override - protected Entry, Range> computeNext() { - if (nextComplementRangeUpperBound == Cut.belowAll()) { - return endOfData(); - } else if (positiveItr.hasNext()) { - Range positiveRange = positiveItr.next(); - Range negativeRange = - Range.create(positiveRange.upperBound, nextComplementRangeUpperBound); - nextComplementRangeUpperBound = positiveRange.lowerBound; - if (complementLowerBoundWindow.lowerBound.isLessThan(negativeRange.lowerBound)) { - return Maps.immutableEntry(negativeRange.lowerBound, negativeRange); - } - } else if (complementLowerBoundWindow.lowerBound.isLessThan(Cut.belowAll())) { - Range negativeRange = Range.create(Cut.belowAll(), nextComplementRangeUpperBound); - nextComplementRangeUpperBound = Cut.belowAll(); - return Maps.immutableEntry(Cut.belowAll(), negativeRange); - } - return endOfData(); - } - }; - } - - @Override - public int size() { - return Iterators.size(entryIterator()); - } - - @Override - @Nullable - public Range get(Object key) { - if (key instanceof Cut) { - try { - @SuppressWarnings("unchecked") - Cut cut = (Cut) key; - // tailMap respects the current window - Entry, Range> firstEntry = tailMap(cut, true).firstEntry(); - if (firstEntry != null && firstEntry.getKey().equals(cut)) { - return firstEntry.getValue(); - } - } catch (ClassCastException e) { - return null; - } - } - return null; - } - - @Override - public boolean containsKey(Object key) { - return get(key) != null; - } - } - - private final class Complement extends TreeRangeSet { - Complement() { - super(new ComplementRangesByLowerBound(TreeRangeSet.this.rangesByLowerBound)); - } - - @Override - public void add(Range rangeToAdd) { - TreeRangeSet.this.remove(rangeToAdd); - } - - @Override - public void remove(Range rangeToRemove) { - TreeRangeSet.this.add(rangeToRemove); - } - - @Override - public boolean contains(C value) { - return !TreeRangeSet.this.contains(value); - } - - @Override - public RangeSet complement() { - return TreeRangeSet.this; - } - } - - private static final class SubRangeSetRangesByLowerBound> - extends AbstractNavigableMap, Range> { - /** - * lowerBoundWindow is the headMap/subMap/tailMap view; it only restricts the keys, and does not - * affect the values. - */ - private final Range> lowerBoundWindow; - - /** - * restriction is the subRangeSet view; ranges are truncated to their intersection with - * restriction. - */ - private final Range restriction; - - private final NavigableMap, Range> rangesByLowerBound; - private final NavigableMap, Range> rangesByUpperBound; - - private SubRangeSetRangesByLowerBound( - Range> lowerBoundWindow, - Range restriction, - NavigableMap, Range> rangesByLowerBound) { - this.lowerBoundWindow = checkNotNull(lowerBoundWindow); - this.restriction = checkNotNull(restriction); - this.rangesByLowerBound = checkNotNull(rangesByLowerBound); - this.rangesByUpperBound = new RangesByUpperBound(rangesByLowerBound); - } - - private NavigableMap, Range> subMap(Range> window) { - if (!window.isConnected(lowerBoundWindow)) { - return ImmutableSortedMap.of(); - } else { - return new SubRangeSetRangesByLowerBound( - lowerBoundWindow.intersection(window), restriction, rangesByLowerBound); - } - } - - @Override - public NavigableMap, Range> subMap( - Cut fromKey, boolean fromInclusive, Cut toKey, boolean toInclusive) { - return subMap( - Range.range( - fromKey, - BoundType.forBoolean(fromInclusive), - toKey, - BoundType.forBoolean(toInclusive))); - } - - @Override - public NavigableMap, Range> headMap(Cut toKey, boolean inclusive) { - return subMap(Range.upTo(toKey, BoundType.forBoolean(inclusive))); - } - - @Override - public NavigableMap, Range> tailMap(Cut fromKey, boolean inclusive) { - return subMap(Range.downTo(fromKey, BoundType.forBoolean(inclusive))); - } - - @Override - public Comparator> comparator() { - return Ordering.>natural(); - } - - @Override - public boolean containsKey(@Nullable Object key) { - return get(key) != null; - } - - @Override - @Nullable - public Range get(@Nullable Object key) { - if (key instanceof Cut) { - try { - @SuppressWarnings("unchecked") // we catch CCE's - Cut cut = (Cut) key; - if (!lowerBoundWindow.contains(cut) - || cut.compareTo(restriction.lowerBound) < 0 - || cut.compareTo(restriction.upperBound) >= 0) { - return null; - } else if (cut.equals(restriction.lowerBound)) { - // it might be present, truncated on the left - Range candidate = Maps.valueOrNull(rangesByLowerBound.floorEntry(cut)); - if (candidate != null && candidate.upperBound.compareTo(restriction.lowerBound) > 0) { - return candidate.intersection(restriction); - } - } else { - Range result = rangesByLowerBound.get(cut); - if (result != null) { - return result.intersection(restriction); - } - } - } catch (ClassCastException e) { - return null; - } - } - return null; - } - - @Override - Iterator, Range>> entryIterator() { - if (restriction.isEmpty()) { - return Iterators.emptyIterator(); - } - final Iterator> completeRangeItr; - if (lowerBoundWindow.upperBound.isLessThan(restriction.lowerBound)) { - return Iterators.emptyIterator(); - } else if (lowerBoundWindow.lowerBound.isLessThan(restriction.lowerBound)) { - // starts at the first range with upper bound strictly greater than restriction.lowerBound - completeRangeItr = - rangesByUpperBound.tailMap(restriction.lowerBound, false).values().iterator(); - } else { - // starts at the first range with lower bound above lowerBoundWindow.lowerBound - completeRangeItr = - rangesByLowerBound - .tailMap( - lowerBoundWindow.lowerBound.endpoint(), - lowerBoundWindow.lowerBoundType() == BoundType.CLOSED) - .values() - .iterator(); - } - final Cut> upperBoundOnLowerBounds = - Ordering.natural() - .min(lowerBoundWindow.upperBound, Cut.belowValue(restriction.upperBound)); - return new AbstractIterator, Range>>() { - @Override - protected Entry, Range> computeNext() { - if (!completeRangeItr.hasNext()) { - return endOfData(); - } - Range nextRange = completeRangeItr.next(); - if (upperBoundOnLowerBounds.isLessThan(nextRange.lowerBound)) { - return endOfData(); - } else { - nextRange = nextRange.intersection(restriction); - return Maps.immutableEntry(nextRange.lowerBound, nextRange); - } - } - }; - } - - @Override - Iterator, Range>> descendingEntryIterator() { - if (restriction.isEmpty()) { - return Iterators.emptyIterator(); - } - Cut> upperBoundOnLowerBounds = - Ordering.natural() - .min(lowerBoundWindow.upperBound, Cut.belowValue(restriction.upperBound)); - final Iterator> completeRangeItr = - rangesByLowerBound - .headMap( - upperBoundOnLowerBounds.endpoint(), - upperBoundOnLowerBounds.typeAsUpperBound() == BoundType.CLOSED) - .descendingMap() - .values() - .iterator(); - return new AbstractIterator, Range>>() { - @Override - protected Entry, Range> computeNext() { - if (!completeRangeItr.hasNext()) { - return endOfData(); - } - Range nextRange = completeRangeItr.next(); - if (restriction.lowerBound.compareTo(nextRange.upperBound) >= 0) { - return endOfData(); - } - nextRange = nextRange.intersection(restriction); - if (lowerBoundWindow.contains(nextRange.lowerBound)) { - return Maps.immutableEntry(nextRange.lowerBound, nextRange); - } else { - return endOfData(); - } - } - }; - } - - @Override - public int size() { - return Iterators.size(entryIterator()); - } - } - - @Override - public RangeSet subRangeSet(Range view) { - return view.equals(Range.all()) ? this : new SubRangeSet(view); - } - - private final class SubRangeSet extends TreeRangeSet { - private final Range restriction; - - SubRangeSet(Range restriction) { - super(new SubRangeSetRangesByLowerBound( - Range.>all(), restriction, TreeRangeSet.this.rangesByLowerBound)); - this.restriction = restriction; - } - - @Override - public boolean encloses(Range range) { - if (!restriction.isEmpty() && restriction.encloses(range)) { - Range enclosing = TreeRangeSet.this.rangeEnclosing(range); - return enclosing != null && !enclosing.intersection(restriction).isEmpty(); - } - return false; - } - - @Override - @Nullable - public Range rangeContaining(C value) { - if (!restriction.contains(value)) { - return null; - } - Range result = TreeRangeSet.this.rangeContaining(value); - return (result == null) ? null : result.intersection(restriction); - } - - @Override - public void add(Range rangeToAdd) { - checkArgument( - restriction.encloses(rangeToAdd), - "Cannot add range %s to subRangeSet(%s)", - rangeToAdd, - restriction); - super.add(rangeToAdd); - } - - @Override - public void remove(Range rangeToRemove) { - if (rangeToRemove.isConnected(restriction)) { - TreeRangeSet.this.remove(rangeToRemove.intersection(restriction)); - } - } - - @Override - public boolean contains(C value) { - return restriction.contains(value) && TreeRangeSet.this.contains(value); - } - - @Override - public void clear() { - TreeRangeSet.this.remove(restriction); - } - - @Override - public RangeSet subRangeSet(Range view) { - if (view.encloses(restriction)) { - return this; - } else if (view.isConnected(restriction)) { - return new SubRangeSet(restriction.intersection(view)); - } else { - return ImmutableRangeSet.of(); - } - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/TreeTraverser.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/TreeTraverser.java deleted file mode 100644 index 2f3183cdb1f2..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/TreeTraverser.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import java.util.ArrayDeque; -import java.util.Deque; -import java.util.Iterator; -import java.util.Queue; - -/** - * Views elements of a type {@code T} as nodes in a tree, and provides methods to traverse the trees - * induced by this traverser. - * - *

For example, the tree - * - *

          {@code
- *          h
- *        / | \
- *       /  e  \
- *      d       g
- *     /|\      |
- *    / | \     f
- *   a  b  c       }
- * - *

can be iterated over in preorder (hdabcegf), postorder (abcdefgh), or breadth-first order - * (hdegabcf). - * - *

Null nodes are strictly forbidden. - * - * @author Louis Wasserman - * @since 15.0 - */ -@Beta -@GwtCompatible(emulated = true) -public abstract class TreeTraverser { - // TODO(lowasser): make this GWT-compatible when we've checked in ArrayDeque emulation - - /** - * Returns the children of the specified node. Must not contain null. - */ - public abstract Iterable children(T root); - - /** - * Returns an unmodifiable iterable over the nodes in a tree structure, using pre-order - * traversal. That is, each node's subtrees are traversed after the node itself is returned. - * - *

No guarantees are made about the behavior of the traversal when nodes change while - * iteration is in progress or when the iterators generated by {@link #children} are advanced. - */ - public final FluentIterable preOrderTraversal(final T root) { - checkNotNull(root); - return new FluentIterable() { - @Override - public UnmodifiableIterator iterator() { - return preOrderIterator(root); - } - }; - } - - // overridden in BinaryTreeTraverser - UnmodifiableIterator preOrderIterator(T root) { - return new PreOrderIterator(root); - } - - private final class PreOrderIterator extends UnmodifiableIterator { - private final Deque> stack; - - PreOrderIterator(T root) { - this.stack = new ArrayDeque>(); - stack.addLast(Iterators.singletonIterator(checkNotNull(root))); - } - - @Override - public boolean hasNext() { - return !stack.isEmpty(); - } - - @Override - public T next() { - Iterator itr = stack.getLast(); // throws NSEE if empty - T result = checkNotNull(itr.next()); - if (!itr.hasNext()) { - stack.removeLast(); - } - Iterator childItr = children(result).iterator(); - if (childItr.hasNext()) { - stack.addLast(childItr); - } - return result; - } - } - - /** - * Returns an unmodifiable iterable over the nodes in a tree structure, using post-order - * traversal. That is, each node's subtrees are traversed before the node itself is returned. - * - *

No guarantees are made about the behavior of the traversal when nodes change while - * iteration is in progress or when the iterators generated by {@link #children} are advanced. - */ - public final FluentIterable postOrderTraversal(final T root) { - checkNotNull(root); - return new FluentIterable() { - @Override - public UnmodifiableIterator iterator() { - return postOrderIterator(root); - } - }; - } - - // overridden in BinaryTreeTraverser - UnmodifiableIterator postOrderIterator(T root) { - return new PostOrderIterator(root); - } - - private static final class PostOrderNode { - final T root; - final Iterator childIterator; - - PostOrderNode(T root, Iterator childIterator) { - this.root = checkNotNull(root); - this.childIterator = checkNotNull(childIterator); - } - } - - private final class PostOrderIterator extends AbstractIterator { - private final ArrayDeque> stack; - - PostOrderIterator(T root) { - this.stack = new ArrayDeque>(); - stack.addLast(expand(root)); - } - - @Override - protected T computeNext() { - while (!stack.isEmpty()) { - PostOrderNode top = stack.getLast(); - if (top.childIterator.hasNext()) { - T child = top.childIterator.next(); - stack.addLast(expand(child)); - } else { - stack.removeLast(); - return top.root; - } - } - return endOfData(); - } - - private PostOrderNode expand(T t) { - return new PostOrderNode(t, children(t).iterator()); - } - } - - /** - * Returns an unmodifiable iterable over the nodes in a tree structure, using breadth-first - * traversal. That is, all the nodes of depth 0 are returned, then depth 1, then 2, and so on. - * - *

No guarantees are made about the behavior of the traversal when nodes change while - * iteration is in progress or when the iterators generated by {@link #children} are advanced. - */ - public final FluentIterable breadthFirstTraversal(final T root) { - checkNotNull(root); - return new FluentIterable() { - @Override - public UnmodifiableIterator iterator() { - return new BreadthFirstIterator(root); - } - }; - } - - private final class BreadthFirstIterator extends UnmodifiableIterator - implements PeekingIterator { - private final Queue queue; - - BreadthFirstIterator(T root) { - this.queue = new ArrayDeque(); - queue.add(root); - } - - @Override - public boolean hasNext() { - return !queue.isEmpty(); - } - - @Override - public T peek() { - return queue.element(); - } - - @Override - public T next() { - T result = queue.remove(); - Iterables.addAll(queue, children(result)); - return result; - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/UnmodifiableIterator.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/UnmodifiableIterator.java deleted file mode 100644 index 73e8c905d053..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/UnmodifiableIterator.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Iterator; - -/** - * An iterator that does not support {@link #remove}. - * - *

{@code UnmodifiableIterator} is used primarily in conjunction with implementations of - * {@link ImmutableCollection}, such as {@link ImmutableList}. You can, however, convert an existing - * iterator to an {@code UnmodifiableIterator} using {@link Iterators#unmodifiableIterator}. - * - * @author Jared Levy - * @since 2.0 - */ -@GwtCompatible -public abstract class UnmodifiableIterator implements Iterator { - /** Constructor for use by subclasses. */ - protected UnmodifiableIterator() {} - - /** - * Guaranteed to throw an exception and leave the underlying data unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final void remove() { - throw new UnsupportedOperationException(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/UnmodifiableListIterator.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/UnmodifiableListIterator.java deleted file mode 100644 index 37e1bbf3bd37..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/UnmodifiableListIterator.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2010 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.util.ListIterator; - -/** - * A list iterator that does not support {@link #remove}, {@link #add}, or - * {@link #set}. - * - * @since 7.0 - * @author Louis Wasserman - */ -@GwtCompatible -public abstract class UnmodifiableListIterator extends UnmodifiableIterator - implements ListIterator { - /** Constructor for use by subclasses. */ - protected UnmodifiableListIterator() {} - - /** - * Guaranteed to throw an exception and leave the underlying data unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final void add(E e) { - throw new UnsupportedOperationException(); - } - - /** - * Guaranteed to throw an exception and leave the underlying data unmodified. - * - * @throws UnsupportedOperationException always - * @deprecated Unsupported operation. - */ - @Deprecated - @Override - public final void set(E e) { - throw new UnsupportedOperationException(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/UnmodifiableSortedMultiset.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/UnmodifiableSortedMultiset.java deleted file mode 100644 index 446da96dc3a8..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/UnmodifiableSortedMultiset.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.collect.Multisets.UnmodifiableMultiset; - -import java.util.Comparator; -import java.util.NavigableSet; - -/** - * Implementation of {@link Multisets#unmodifiableSortedMultiset(SortedMultiset)}, - * split out into its own file so it can be GWT emulated (to deal with the differing - * elementSet() types in GWT and non-GWT). - * - * @author Louis Wasserman - */ -@GwtCompatible(emulated = true) -final class UnmodifiableSortedMultiset extends UnmodifiableMultiset - implements SortedMultiset { - UnmodifiableSortedMultiset(SortedMultiset delegate) { - super(delegate); - } - - @Override - protected SortedMultiset delegate() { - return (SortedMultiset) super.delegate(); - } - - @Override - public Comparator comparator() { - return delegate().comparator(); - } - - @Override - NavigableSet createElementSet() { - return Sets.unmodifiableNavigableSet(delegate().elementSet()); - } - - @Override - public NavigableSet elementSet() { - return (NavigableSet) super.elementSet(); - } - - private transient UnmodifiableSortedMultiset descendingMultiset; - - @Override - public SortedMultiset descendingMultiset() { - UnmodifiableSortedMultiset result = descendingMultiset; - if (result == null) { - result = new UnmodifiableSortedMultiset(delegate().descendingMultiset()); - result.descendingMultiset = this; - return descendingMultiset = result; - } - return result; - } - - @Override - public Entry firstEntry() { - return delegate().firstEntry(); - } - - @Override - public Entry lastEntry() { - return delegate().lastEntry(); - } - - @Override - public Entry pollFirstEntry() { - throw new UnsupportedOperationException(); - } - - @Override - public Entry pollLastEntry() { - throw new UnsupportedOperationException(); - } - - @Override - public SortedMultiset headMultiset(E upperBound, BoundType boundType) { - return Multisets.unmodifiableSortedMultiset(delegate().headMultiset(upperBound, boundType)); - } - - @Override - public SortedMultiset subMultiset( - E lowerBound, BoundType lowerBoundType, E upperBound, BoundType upperBoundType) { - return Multisets.unmodifiableSortedMultiset( - delegate().subMultiset(lowerBound, lowerBoundType, upperBound, upperBoundType)); - } - - @Override - public SortedMultiset tailMultiset(E lowerBound, BoundType boundType) { - return Multisets.unmodifiableSortedMultiset(delegate().tailMultiset(lowerBound, boundType)); - } - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/UsingToStringOrdering.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/UsingToStringOrdering.java deleted file mode 100644 index d4ce5bb6966d..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/UsingToStringOrdering.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; - -import java.io.Serializable; - -/** - * An ordering that uses the natural order of the string representation of the - * values. - */ -@GwtCompatible(serializable = true) -final class UsingToStringOrdering extends Ordering implements Serializable { - static final UsingToStringOrdering INSTANCE = new UsingToStringOrdering(); - - @Override - public int compare(Object left, Object right) { - return left.toString().compareTo(right.toString()); - } - - // preserve singleton-ness, so equals() and hashCode() work correctly - private Object readResolve() { - return INSTANCE; - } - - @Override - public String toString() { - return "Ordering.usingToString()"; - } - - private UsingToStringOrdering() {} - - private static final long serialVersionUID = 0; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/WellBehavedMap.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/WellBehavedMap.java deleted file mode 100644 index 16993d04fa46..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/WellBehavedMap.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import com.google.common.annotations.GwtCompatible; -import com.google.j2objc.annotations.WeakOuter; - -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -/** - * Workaround for - * - * EnumMap bug. If you want to pass an {@code EnumMap}, with the - * intention of using its {@code entrySet()} method, you should - * wrap the {@code EnumMap} in this class instead. - * - *

This class is not thread-safe even if the underlying map is. - * - * @author Dimitris Andreou - */ -@GwtCompatible -final class WellBehavedMap extends ForwardingMap { - private final Map delegate; - private Set> entrySet; - - private WellBehavedMap(Map delegate) { - this.delegate = delegate; - } - - /** - * Wraps the given map into a {@code WellBehavedEntriesMap}, which - * intercepts its {@code entrySet()} method by taking the - * {@code Set keySet()} and transforming it to - * {@code Set>}. All other invocations are delegated as-is. - */ - static WellBehavedMap wrap(Map delegate) { - return new WellBehavedMap(delegate); - } - - @Override - protected Map delegate() { - return delegate; - } - - @Override - public Set> entrySet() { - Set> es = entrySet; - if (es != null) { - return es; - } - return entrySet = new EntrySet(); - } - - @WeakOuter - private final class EntrySet extends Maps.EntrySet { - @Override - Map map() { - return WellBehavedMap.this; - } - - @Override - public Iterator> iterator() { - return new TransformedIterator>(keySet().iterator()) { - @Override - Entry transform(final K key) { - return new AbstractMapEntry() { - @Override - public K getKey() { - return key; - } - - @Override - public V getValue() { - return get(key); - } - - @Override - public V setValue(V value) { - return put(key, value); - } - }; - } - }; - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/collect/package-info.java b/thirdparty/google-guava/src/main/java/com/google/common/collect/package-info.java deleted file mode 100644 index 640d592c7a12..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/collect/package-info.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * This package contains generic collection interfaces and implementations, and - * other utilities for working with collections. It is a part of the open-source - * Guava libraries. - * - *

Collection Types

- * - *
- *
{@link com.google.common.collect.BiMap} - *
An extension of {@link java.util.Map} that guarantees the uniqueness of - * its values as well as that of its keys. This is sometimes called an - * "invertible map," since the restriction on values enables it to support - * an {@linkplain com.google.common.collect.BiMap#inverse inverse view} -- - * which is another instance of {@code BiMap}. - * - *
{@link com.google.common.collect.Multiset} - *
An extension of {@link java.util.Collection} that may contain duplicate - * values like a {@link java.util.List}, yet has order-independent equality - * like a {@link java.util.Set}. One typical use for a multiset is to - * represent a histogram. - * - *
{@link com.google.common.collect.Multimap} - *
A new type, which is similar to {@link java.util.Map}, but may contain - * multiple entries with the same key. Some behaviors of - * {@link com.google.common.collect.Multimap} are left unspecified and are - * provided only by the subtypes mentioned below. - * - *
{@link com.google.common.collect.ListMultimap} - *
An extension of {@link com.google.common.collect.Multimap} which permits - * duplicate entries, supports random access of values for a particular key, - * and has partially order-dependent equality as defined by - * {@link com.google.common.collect.ListMultimap#equals(Object)}. {@code - * ListMultimap} takes its name from the fact that the {@linkplain - * com.google.common.collect.ListMultimap#get collection of values} - * associated with a given key fulfills the {@link java.util.List} contract. - * - *
{@link com.google.common.collect.SetMultimap} - *
An extension of {@link com.google.common.collect.Multimap} which has - * order-independent equality and does not allow duplicate entries; that is, - * while a key may appear twice in a {@code SetMultimap}, each must map to a - * different value. {@code SetMultimap} takes its name from the fact that - * the {@linkplain com.google.common.collect.SetMultimap#get collection of - * values} associated with a given key fulfills the {@link java.util.Set} - * contract. - * - *
{@link com.google.common.collect.SortedSetMultimap} - *
An extension of {@link com.google.common.collect.SetMultimap} for which - * the {@linkplain com.google.common.collect.SortedSetMultimap#get - * collection values} associated with a given key is a - * {@link java.util.SortedSet}. - * - *
{@link com.google.common.collect.Table} - *
A new type, which is similar to {@link java.util.Map}, but which indexes - * its values by an ordered pair of keys, a row key and column key. - * - *
{@link com.google.common.collect.ClassToInstanceMap} - *
An extension of {@link java.util.Map} that associates a raw type with an - * instance of that type. - *
- * - *

Collection Implementations

- * - *

of {@link java.util.List}

- *
    - *
  • {@link com.google.common.collect.ImmutableList} - *
- * - *

of {@link java.util.Set}

- *
    - *
  • {@link com.google.common.collect.ImmutableSet} - *
  • {@link com.google.common.collect.ImmutableSortedSet} - *
  • {@link com.google.common.collect.ContiguousSet} (see {@code Range}) - *
- * - *

of {@link java.util.Map}

- *
    - *
  • {@link com.google.common.collect.ImmutableMap} - *
  • {@link com.google.common.collect.ImmutableSortedMap} - *
  • {@link com.google.common.collect.MapMaker} - *
- * - *

of {@link com.google.common.collect.BiMap}

- *
    - *
  • {@link com.google.common.collect.ImmutableBiMap} - *
  • {@link com.google.common.collect.HashBiMap} - *
  • {@link com.google.common.collect.EnumBiMap} - *
  • {@link com.google.common.collect.EnumHashBiMap} - *
- * - *

of {@link com.google.common.collect.Multiset}

- *
    - *
  • {@link com.google.common.collect.ImmutableMultiset} - *
  • {@link com.google.common.collect.HashMultiset} - *
  • {@link com.google.common.collect.LinkedHashMultiset} - *
  • {@link com.google.common.collect.TreeMultiset} - *
  • {@link com.google.common.collect.EnumMultiset} - *
  • {@link com.google.common.collect.ConcurrentHashMultiset} - *
- * - *

of {@link com.google.common.collect.Multimap}

- *
    - *
  • {@link com.google.common.collect.ImmutableMultimap} - *
  • {@link com.google.common.collect.ImmutableListMultimap} - *
  • {@link com.google.common.collect.ImmutableSetMultimap} - *
  • {@link com.google.common.collect.ArrayListMultimap} - *
  • {@link com.google.common.collect.HashMultimap} - *
  • {@link com.google.common.collect.TreeMultimap} - *
  • {@link com.google.common.collect.LinkedHashMultimap} - *
  • {@link com.google.common.collect.LinkedListMultimap} - *
- * - *

of {@link com.google.common.collect.Table}

- *
    - *
  • {@link com.google.common.collect.ImmutableTable} - *
  • {@link com.google.common.collect.ArrayTable} - *
  • {@link com.google.common.collect.HashBasedTable} - *
  • {@link com.google.common.collect.TreeBasedTable} - *
- * - *

of {@link com.google.common.collect.ClassToInstanceMap}

- *
    - *
  • {@link com.google.common.collect.ImmutableClassToInstanceMap} - *
  • {@link com.google.common.collect.MutableClassToInstanceMap} - *
- * - *

Classes of static utility methods

- * - *
    - *
  • {@link com.google.common.collect.Collections2} - *
  • {@link com.google.common.collect.Iterators} - *
  • {@link com.google.common.collect.Iterables} - *
  • {@link com.google.common.collect.Lists} - *
  • {@link com.google.common.collect.Maps} - *
  • {@link com.google.common.collect.Queues} - *
  • {@link com.google.common.collect.Sets} - *
  • {@link com.google.common.collect.Multisets} - *
  • {@link com.google.common.collect.Multimaps} - *
  • {@link com.google.common.collect.Tables} - *
  • {@link com.google.common.collect.ObjectArrays} - *
- * - *

Comparison

- * - *
    - *
  • {@link com.google.common.collect.Ordering} - *
  • {@link com.google.common.collect.ComparisonChain} - *
- * - *

Abstract implementations

- * - *
    - *
  • {@link com.google.common.collect.AbstractIterator} - *
  • {@link com.google.common.collect.AbstractSequentialIterator} - *
  • {@link com.google.common.collect.ImmutableCollection} - *
  • {@link com.google.common.collect.UnmodifiableIterator} - *
  • {@link com.google.common.collect.UnmodifiableListIterator} - *
- * - *

Ranges

- * - *
    - *
  • {@link com.google.common.collect.Range} - *
  • {@link com.google.common.collect.RangeMap} - *
  • {@link com.google.common.collect.DiscreteDomain} - *
  • {@link com.google.common.collect.ContiguousSet} - *
- * - *

Other

- * - *
    - *
  • {@link com.google.common.collect.Interner}, - * {@link com.google.common.collect.Interners} - *
  • {@link com.google.common.collect.Constraint}, - * {@link com.google.common.collect.Constraints} - *
  • {@link com.google.common.collect.MapConstraint}, - * {@link com.google.common.collect.MapConstraints} - *
  • {@link com.google.common.collect.MapDifference}, - * {@link com.google.common.collect.SortedMapDifference} - *
  • {@link com.google.common.collect.MinMaxPriorityQueue} - *
  • {@link com.google.common.collect.PeekingIterator} - *
- * - *

Forwarding collections

- * - *
    - *
  • {@link com.google.common.collect.ForwardingCollection} - *
  • {@link com.google.common.collect.ForwardingConcurrentMap} - *
  • {@link com.google.common.collect.ForwardingIterator} - *
  • {@link com.google.common.collect.ForwardingList} - *
  • {@link com.google.common.collect.ForwardingListIterator} - *
  • {@link com.google.common.collect.ForwardingListMultimap} - *
  • {@link com.google.common.collect.ForwardingMap} - *
  • {@link com.google.common.collect.ForwardingMapEntry} - *
  • {@link com.google.common.collect.ForwardingMultimap} - *
  • {@link com.google.common.collect.ForwardingMultiset} - *
  • {@link com.google.common.collect.ForwardingNavigableMap} - *
  • {@link com.google.common.collect.ForwardingNavigableSet} - *
  • {@link com.google.common.collect.ForwardingObject} - *
  • {@link com.google.common.collect.ForwardingQueue} - *
  • {@link com.google.common.collect.ForwardingSet} - *
  • {@link com.google.common.collect.ForwardingSetMultimap} - *
  • {@link com.google.common.collect.ForwardingSortedMap} - *
  • {@link com.google.common.collect.ForwardingSortedMultiset} - *
  • {@link com.google.common.collect.ForwardingSortedSet} - *
  • {@link com.google.common.collect.ForwardingSortedSetMultimap} - *
  • {@link com.google.common.collect.ForwardingTable} - *
- */ -@javax.annotation.ParametersAreNonnullByDefault -package com.google.common.collect; diff --git a/thirdparty/google-guava/src/main/java/com/google/common/escape/ArrayBasedCharEscaper.java b/thirdparty/google-guava/src/main/java/com/google/common/escape/ArrayBasedCharEscaper.java deleted file mode 100644 index 8b5a16153c8c..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/escape/ArrayBasedCharEscaper.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.escape; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import java.util.Map; - -/** - * A {@link CharEscaper} that uses an array to quickly look up replacement - * characters for a given {@code char} value. An additional safe range is - * provided that determines whether {@code char} values without specific - * replacements are to be considered safe and left unescaped or should be - * escaped in a general way. - * - *

A good example of usage of this class is for Java source code escaping - * where the replacement array contains information about special ASCII - * characters such as {@code \\t} and {@code \\n} while {@link #escapeUnsafe} - * is overridden to handle general escaping of the form {@code \\uxxxx}. - * - *

The size of the data structure used by {@link ArrayBasedCharEscaper} is - * proportional to the highest valued character that requires escaping. - * For example a replacement map containing the single character - * '{@code \}{@code u1000}' will require approximately 16K of memory. If you - * need to create multiple escaper instances that have the same character - * replacement mapping consider using {@link ArrayBasedEscaperMap}. - * - * @author Sven Mawson - * @author David Beaumont - * @since 15.0 - */ -@Beta -@GwtCompatible -public abstract class ArrayBasedCharEscaper extends CharEscaper { - // The replacement array (see ArrayBasedEscaperMap). - private final char[][] replacements; - // The number of elements in the replacement array. - private final int replacementsLength; - // The first character in the safe range. - private final char safeMin; - // The last character in the safe range. - private final char safeMax; - - /** - * Creates a new ArrayBasedCharEscaper instance with the given replacement map - * and specified safe range. If {@code safeMax < safeMin} then no characters - * are considered safe. - * - *

If a character has no mapped replacement then it is checked against the - * safe range. If it lies outside that, then {@link #escapeUnsafe} is - * called, otherwise no escaping is performed. - * - * @param replacementMap a map of characters to their escaped representations - * @param safeMin the lowest character value in the safe range - * @param safeMax the highest character value in the safe range - */ - protected ArrayBasedCharEscaper(Map replacementMap, - char safeMin, char safeMax) { - - this(ArrayBasedEscaperMap.create(replacementMap), safeMin, safeMax); - } - - /** - * Creates a new ArrayBasedCharEscaper instance with the given replacement map - * and specified safe range. If {@code safeMax < safeMin} then no characters - * are considered safe. This initializer is useful when explicit instances of - * ArrayBasedEscaperMap are used to allow the sharing of large replacement - * mappings. - * - *

If a character has no mapped replacement then it is checked against the - * safe range. If it lies outside that, then {@link #escapeUnsafe} is - * called, otherwise no escaping is performed. - * - * @param escaperMap the mapping of characters to be escaped - * @param safeMin the lowest character value in the safe range - * @param safeMax the highest character value in the safe range - */ - protected ArrayBasedCharEscaper(ArrayBasedEscaperMap escaperMap, - char safeMin, char safeMax) { - - checkNotNull(escaperMap); // GWT specific check (do not optimize) - this.replacements = escaperMap.getReplacementArray(); - this.replacementsLength = replacements.length; - if (safeMax < safeMin) { - // If the safe range is empty, set the range limits to opposite extremes - // to ensure the first test of either value will (almost certainly) fail. - safeMax = Character.MIN_VALUE; - safeMin = Character.MAX_VALUE; - } - this.safeMin = safeMin; - this.safeMax = safeMax; - } - - /* - * This is overridden to improve performance. Rough benchmarking shows that - * this almost doubles the speed when processing strings that do not require - * any escaping. - */ - @Override - public final String escape(String s) { - checkNotNull(s); // GWT specific check (do not optimize). - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - if ((c < replacementsLength && replacements[c] != null) || - c > safeMax || c < safeMin) { - return escapeSlow(s, i); - } - } - return s; - } - - /** - * Escapes a single character using the replacement array and safe range - * values. If the given character does not have an explicit replacement and - * lies outside the safe range then {@link #escapeUnsafe} is called. - */ - @Override protected final char[] escape(char c) { - if (c < replacementsLength) { - char[] chars = replacements[c]; - if (chars != null) { - return chars; - } - } - if (c >= safeMin && c <= safeMax) { - return null; - } - return escapeUnsafe(c); - } - - /** - * Escapes a {@code char} value that has no direct explicit value in the - * replacement array and lies outside the stated safe range. Subclasses should - * override this method to provide generalized escaping for characters. - * - *

Note that arrays returned by this method must not be modified once they - * have been returned. However it is acceptable to return the same array - * multiple times (even for different input characters). - * - * @param c the character to escape - * @return the replacement characters, or {@code null} if no escaping was - * required - */ - // TODO(user,cpovirk): Rename this something better once refactoring done - protected abstract char[] escapeUnsafe(char c); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/escape/ArrayBasedEscaperMap.java b/thirdparty/google-guava/src/main/java/com/google/common/escape/ArrayBasedEscaperMap.java deleted file mode 100644 index aeac606a1f35..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/escape/ArrayBasedEscaperMap.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.escape; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.VisibleForTesting; - -import java.util.Collections; -import java.util.Map; - -/** - * An implementation-specific parameter class suitable for initializing - * {@link ArrayBasedCharEscaper} or {@link ArrayBasedUnicodeEscaper} instances. - * This class should be used when more than one escaper is created using the - * same character replacement mapping to allow the underlying (implementation - * specific) data structures to be shared. - * - *

The size of the data structure used by ArrayBasedCharEscaper and - * ArrayBasedUnicodeEscaper is proportional to the highest valued character that - * has a replacement. For example a replacement map containing the single - * character '{@literal \}u1000' will require approximately 16K of memory. - * As such sharing this data structure between escaper instances is the primary - * goal of this class. - * - * @author David Beaumont - * @since 15.0 - */ -@Beta -@GwtCompatible -public final class ArrayBasedEscaperMap { - /** - * Returns a new ArrayBasedEscaperMap for creating ArrayBasedCharEscaper or - * ArrayBasedUnicodeEscaper instances. - * - * @param replacements a map of characters to their escaped representations - */ - public static ArrayBasedEscaperMap create( - Map replacements) { - return new ArrayBasedEscaperMap(createReplacementArray(replacements)); - } - - // The underlying replacement array we can share between multiple escaper - // instances. - private final char[][] replacementArray; - - private ArrayBasedEscaperMap(char[][] replacementArray) { - this.replacementArray = replacementArray; - } - - // Returns the non-null array of replacements for fast lookup. - char[][] getReplacementArray() { - return replacementArray; - } - - // Creates a replacement array from the given map. The returned array is a - // linear lookup table of replacement character sequences indexed by the - // original character value. - @VisibleForTesting - static char[][] createReplacementArray(Map map) { - checkNotNull(map); // GWT specific check (do not optimize) - if (map.isEmpty()) { - return EMPTY_REPLACEMENT_ARRAY; - } - char max = Collections.max(map.keySet()); - char[][] replacements = new char[max + 1][]; - for (char c : map.keySet()) { - replacements[c] = map.get(c).toCharArray(); - } - return replacements; - } - - // Immutable empty array for when there are no replacements. - private static final char[][] EMPTY_REPLACEMENT_ARRAY = new char[0][0]; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/escape/ArrayBasedUnicodeEscaper.java b/thirdparty/google-guava/src/main/java/com/google/common/escape/ArrayBasedUnicodeEscaper.java deleted file mode 100644 index 0fd841328238..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/escape/ArrayBasedUnicodeEscaper.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.escape; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import java.util.Map; - -import javax.annotation.Nullable; - -/** - * A {@link UnicodeEscaper} that uses an array to quickly look up replacement - * characters for a given code point. An additional safe range is provided that - * determines whether code points without specific replacements are to be - * considered safe and left unescaped or should be escaped in a general way. - * - *

A good example of usage of this class is for HTML escaping where the - * replacement array contains information about the named HTML entities - * such as {@code &} and {@code "} while {@link #escapeUnsafe} is - * overridden to handle general escaping of the form {@code &#NNNNN;}. - * - *

The size of the data structure used by {@link ArrayBasedUnicodeEscaper} is - * proportional to the highest valued code point that requires escaping. - * For example a replacement map containing the single character - * '{@code \}{@code u1000}' will require approximately 16K of memory. If you - * need to create multiple escaper instances that have the same character - * replacement mapping consider using {@link ArrayBasedEscaperMap}. - * - * @author David Beaumont - * @since 15.0 - */ -@Beta -@GwtCompatible -public abstract class ArrayBasedUnicodeEscaper extends UnicodeEscaper { - // The replacement array (see ArrayBasedEscaperMap). - private final char[][] replacements; - // The number of elements in the replacement array. - private final int replacementsLength; - // The first code point in the safe range. - private final int safeMin; - // The last code point in the safe range. - private final int safeMax; - - // Cropped values used in the fast path range checks. - private final char safeMinChar; - private final char safeMaxChar; - - /** - * Creates a new ArrayBasedUnicodeEscaper instance with the given replacement - * map and specified safe range. If {@code safeMax < safeMin} then no code - * points are considered safe. - * - *

If a code point has no mapped replacement then it is checked against the - * safe range. If it lies outside that, then {@link #escapeUnsafe} is - * called, otherwise no escaping is performed. - * - * @param replacementMap a map of characters to their escaped representations - * @param safeMin the lowest character value in the safe range - * @param safeMax the highest character value in the safe range - * @param unsafeReplacement the default replacement for unsafe characters or - * null if no default replacement is required - */ - protected ArrayBasedUnicodeEscaper(Map replacementMap, - int safeMin, int safeMax, @Nullable String unsafeReplacement) { - - this(ArrayBasedEscaperMap.create(replacementMap), safeMin, safeMax, - unsafeReplacement); - } - - /** - * Creates a new ArrayBasedUnicodeEscaper instance with the given replacement - * map and specified safe range. If {@code safeMax < safeMin} then no code - * points are considered safe. This initializer is useful when explicit - * instances of ArrayBasedEscaperMap are used to allow the sharing of large - * replacement mappings. - * - *

If a code point has no mapped replacement then it is checked against the - * safe range. If it lies outside that, then {@link #escapeUnsafe} is - * called, otherwise no escaping is performed. - * - * @param escaperMap the map of replacements - * @param safeMin the lowest character value in the safe range - * @param safeMax the highest character value in the safe range - * @param unsafeReplacement the default replacement for unsafe characters or - * null if no default replacement is required - */ - protected ArrayBasedUnicodeEscaper(ArrayBasedEscaperMap escaperMap, - int safeMin, int safeMax, @Nullable String unsafeReplacement) { - - checkNotNull(escaperMap); // GWT specific check (do not optimize) - this.replacements = escaperMap.getReplacementArray(); - this.replacementsLength = replacements.length; - if (safeMax < safeMin) { - // If the safe range is empty, set the range limits to opposite extremes - // to ensure the first test of either value will fail. - safeMax = -1; - safeMin = Integer.MAX_VALUE; - } - this.safeMin = safeMin; - this.safeMax = safeMax; - - // This is a bit of a hack but lets us do quicker per-character checks in - // the fast path code. The safe min/max values are very unlikely to extend - // into the range of surrogate characters, but if they do we must not test - // any values in that range. To see why, consider the case where: - // safeMin <= {hi,lo} <= safeMax - // where {hi,lo} are characters forming a surrogate pair such that: - // codePointOf(hi, lo) > safeMax - // which would result in the surrogate pair being (wrongly) considered safe. - // If we clip the safe range used during the per-character tests so it is - // below the values of characters in surrogate pairs, this cannot occur. - // This approach does mean that we break out of the fast path code in cases - // where we don't strictly need to, but this situation will almost never - // occur in practice. - if (safeMin >= Character.MIN_HIGH_SURROGATE) { - // The safe range is empty or the all safe code points lie in or above the - // surrogate range. Either way the character range is empty. - this.safeMinChar = Character.MAX_VALUE; - this.safeMaxChar = 0; - } else { - // The safe range is non empty and contains values below the surrogate - // range but may extend above it. We may need to clip the maximum value. - this.safeMinChar = (char) safeMin; - this.safeMaxChar = (char) Math.min(safeMax, - Character.MIN_HIGH_SURROGATE - 1); - } - } - - /* - * This is overridden to improve performance. Rough benchmarking shows that - * this almost doubles the speed when processing strings that do not require - * any escaping. - */ - @Override - public final String escape(String s) { - checkNotNull(s); // GWT specific check (do not optimize) - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - if ((c < replacementsLength && replacements[c] != null) || - c > safeMaxChar || c < safeMinChar) { - return escapeSlow(s, i); - } - } - return s; - } - - /* Overridden for performance. */ - @Override - protected final int nextEscapeIndex(CharSequence csq, int index, int end) { - while (index < end) { - char c = csq.charAt(index); - if ((c < replacementsLength && replacements[c] != null) || - c > safeMaxChar || c < safeMinChar) { - break; - } - index++; - } - return index; - } - - /** - * Escapes a single Unicode code point using the replacement array and safe - * range values. If the given character does not have an explicit replacement - * and lies outside the safe range then {@link #escapeUnsafe} is called. - */ - @Override - protected final char[] escape(int cp) { - if (cp < replacementsLength) { - char[] chars = replacements[cp]; - if (chars != null) { - return chars; - } - } - if (cp >= safeMin && cp <= safeMax) { - return null; - } - return escapeUnsafe(cp); - } - - /** - * Escapes a code point that has no direct explicit value in the replacement - * array and lies outside the stated safe range. Subclasses should override - * this method to provide generalized escaping for code points if required. - * - *

Note that arrays returned by this method must not be modified once they - * have been returned. However it is acceptable to return the same array - * multiple times (even for different input characters). - * - * @param cp the Unicode code point to escape - * @return the replacement characters, or {@code null} if no escaping was - * required - */ - protected abstract char[] escapeUnsafe(int cp); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/escape/CharEscaper.java b/thirdparty/google-guava/src/main/java/com/google/common/escape/CharEscaper.java deleted file mode 100644 index 264854062c94..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/escape/CharEscaper.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (C) 2006 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.escape; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -/** - * An object that converts literal text into a format safe for inclusion in a particular context - * (such as an XML document). Typically (but not always), the inverse process of "unescaping" the - * text is performed automatically by the relevant parser. - * - *

For example, an XML escaper would convert the literal string {@code "Foo"} into {@code - * "Foo<Bar>"} to prevent {@code ""} from being confused with an XML tag. When the - * resulting XML document is parsed, the parser API will return this text as the original literal - * string {@code "Foo"}. - * - *

A {@code CharEscaper} instance is required to be stateless, and safe when used concurrently by - * multiple threads. - * - *

Popular escapers are defined as constants in classes like {@link - * com.google.common.html.HtmlEscapers} and {@link com.google.common.xml.XmlEscapers}. - * To create your own escapers extend this class and implement the {@link - * #escape(char)} method. - * - * @author Sven Mawson - * @since 15.0 - */ -@Beta -@GwtCompatible -public abstract class CharEscaper extends Escaper { - /** Constructor for use by subclasses. */ - protected CharEscaper() {} - - /** - * Returns the escaped form of a given literal string. - * - * @param string the literal string to be escaped - * @return the escaped form of {@code string} - * @throws NullPointerException if {@code string} is null - */ - @Override public String escape(String string) { - checkNotNull(string); // GWT specific check (do not optimize) - // Inlineable fast-path loop which hands off to escapeSlow() only if needed - int length = string.length(); - for (int index = 0; index < length; index++) { - if (escape(string.charAt(index)) != null) { - return escapeSlow(string, index); - } - } - return string; - } - - /** - * Returns the escaped form of a given literal string, starting at the given index. This method is - * called by the {@link #escape(String)} method when it discovers that escaping is required. It is - * protected to allow subclasses to override the fastpath escaping function to inline their - * escaping test. See {@link CharEscaperBuilder} for an example usage. - * - * @param s the literal string to be escaped - * @param index the index to start escaping from - * @return the escaped form of {@code string} - * @throws NullPointerException if {@code string} is null - */ - protected final String escapeSlow(String s, int index) { - int slen = s.length(); - - // Get a destination buffer and setup some loop variables. - char[] dest = Platform.charBufferFromThreadLocal(); - int destSize = dest.length; - int destIndex = 0; - int lastEscape = 0; - - // Loop through the rest of the string, replacing when needed into the - // destination buffer, which gets grown as needed as well. - for (; index < slen; index++) { - - // Get a replacement for the current character. - char[] r = escape(s.charAt(index)); - - // If no replacement is needed, just continue. - if (r == null) continue; - - int rlen = r.length; - int charsSkipped = index - lastEscape; - - // This is the size needed to add the replacement, not the full size - // needed by the string. We only regrow when we absolutely must, and - // when we do grow, grow enough to avoid excessive growing. Grow. - int sizeNeeded = destIndex + charsSkipped + rlen; - if (destSize < sizeNeeded) { - destSize = sizeNeeded + DEST_PAD_MULTIPLIER * (slen - index); - dest = growBuffer(dest, destIndex, destSize); - } - - // If we have skipped any characters, we need to copy them now. - if (charsSkipped > 0) { - s.getChars(lastEscape, index, dest, destIndex); - destIndex += charsSkipped; - } - - // Copy the replacement string into the dest buffer as needed. - if (rlen > 0) { - System.arraycopy(r, 0, dest, destIndex, rlen); - destIndex += rlen; - } - lastEscape = index + 1; - } - - // Copy leftover characters if there are any. - int charsLeft = slen - lastEscape; - if (charsLeft > 0) { - int sizeNeeded = destIndex + charsLeft; - if (destSize < sizeNeeded) { - - // Regrow and copy, expensive! No padding as this is the final copy. - dest = growBuffer(dest, destIndex, sizeNeeded); - } - s.getChars(lastEscape, slen, dest, destIndex); - destIndex = sizeNeeded; - } - return new String(dest, 0, destIndex); - } - - /** - * Returns the escaped form of the given character, or {@code null} if this character does not - * need to be escaped. If an empty array is returned, this effectively strips the input character - * from the resulting text. - * - *

If the character does not need to be escaped, this method should return {@code null}, rather - * than a one-character array containing the character itself. This enables the escaping algorithm - * to perform more efficiently. - * - *

An escaper is expected to be able to deal with any {@code char} value, so this method should - * not throw any exceptions. - * - * @param c the character to escape if necessary - * @return the replacement characters, or {@code null} if no escaping was needed - */ - protected abstract char[] escape(char c); - - /** - * Helper method to grow the character buffer as needed, this only happens once in a while so it's - * ok if it's in a method call. If the index passed in is 0 then no copying will be done. - */ - private static char[] growBuffer(char[] dest, int index, int size) { - char[] copy = new char[size]; - if (index > 0) { - System.arraycopy(dest, 0, copy, 0, index); - } - return copy; - } - - /** - * The multiplier for padding to use when growing the escape buffer. - */ - private static final int DEST_PAD_MULTIPLIER = 2; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/escape/CharEscaperBuilder.java b/thirdparty/google-guava/src/main/java/com/google/common/escape/CharEscaperBuilder.java deleted file mode 100644 index 3ee7448361a3..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/escape/CharEscaperBuilder.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2006 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.escape; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import java.util.HashMap; -import java.util.Map; - -/** - * Simple helper class to build a "sparse" array of objects based on the indexes that were added to - * it. The array will be from 0 to the maximum index given. All non-set indexes will contain null - * (so it's not really a sparse array, just a pseudo sparse array). The builder can also return a - * CharEscaper based on the generated array. - * - * @author Sven Mawson - * @since 15.0 - */ -@Beta -@GwtCompatible -public final class CharEscaperBuilder { - /** - * Simple decorator that turns an array of replacement char[]s into a CharEscaper, this results in - * a very fast escape method. - */ - private static class CharArrayDecorator extends CharEscaper { - private final char[][] replacements; - private final int replaceLength; - - CharArrayDecorator(char[][] replacements) { - this.replacements = replacements; - this.replaceLength = replacements.length; - } - - /* - * Overriding escape method to be slightly faster for this decorator. We test the replacements - * array directly, saving a method call. - */ - @Override public String escape(String s) { - int slen = s.length(); - for (int index = 0; index < slen; index++) { - char c = s.charAt(index); - if (c < replacements.length && replacements[c] != null) { - return escapeSlow(s, index); - } - } - return s; - } - - @Override protected char[] escape(char c) { - return c < replaceLength ? replacements[c] : null; - } - } - - // Replacement mappings. - private final Map map; - - // The highest index we've seen so far. - private int max = -1; - - /** - * Construct a new sparse array builder. - */ - public CharEscaperBuilder() { - this.map = new HashMap(); - } - - /** - * Add a new mapping from an index to an object to the escaping. - */ - public CharEscaperBuilder addEscape(char c, String r) { - map.put(c, checkNotNull(r)); - if (c > max) { - max = c; - } - return this; - } - - /** - * Add multiple mappings at once for a particular index. - */ - public CharEscaperBuilder addEscapes(char[] cs, String r) { - checkNotNull(r); - for (char c : cs) { - addEscape(c, r); - } - return this; - } - - /** - * Convert this builder into an array of char[]s where the maximum index is the value of the - * highest character that has been seen. The array will be sparse in the sense that any unseen - * index will default to null. - * - * @return a "sparse" array that holds the replacement mappings. - */ - public char[][] toArray() { - char[][] result = new char[max + 1][]; - for (Map.Entry entry : map.entrySet()) { - result[entry.getKey()] = entry.getValue().toCharArray(); - } - return result; - } - - /** - * Convert this builder into a char escaper which is just a decorator around the underlying array - * of replacement char[]s. - * - * @return an escaper that escapes based on the underlying array. - */ - public Escaper toEscaper() { - return new CharArrayDecorator(toArray()); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/escape/Escaper.java b/thirdparty/google-guava/src/main/java/com/google/common/escape/Escaper.java deleted file mode 100644 index f0ddfc12933a..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/escape/Escaper.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.escape; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; -import com.google.common.base.Function; - -/** - * An object that converts literal text into a format safe for inclusion in a particular context - * (such as an XML document). Typically (but not always), the inverse process of "unescaping" the - * text is performed automatically by the relevant parser. - * - *

For example, an XML escaper would convert the literal string {@code "Foo"} into {@code - * "Foo<Bar>"} to prevent {@code ""} from being confused with an XML tag. When the - * resulting XML document is parsed, the parser API will return this text as the original literal - * string {@code "Foo"}. - * - *

An {@code Escaper} instance is required to be stateless, and safe when used concurrently by - * multiple threads. - * - *

Because, in general, escaping operates on the code points of a string and not on its - * individual {@code char} values, it is not safe to assume that {@code escape(s)} is equivalent to - * {@code escape(s.substring(0, n)) + escape(s.substing(n))} for arbitrary {@code n}. This is - * because of the possibility of splitting a surrogate pair. The only case in which it is safe to - * escape strings and concatenate the results is if you can rule out this possibility, either by - * splitting an existing long string into short strings adaptively around {@linkplain - * Character#isHighSurrogate surrogate} {@linkplain Character#isLowSurrogate pairs}, or by starting - * with short strings already known to be free of unpaired surrogates. - * - *

The two primary implementations of this interface are {@link CharEscaper} and {@link - * UnicodeEscaper}. They are heavily optimized for performance and greatly simplify the task of - * implementing new escapers. It is strongly recommended that when implementing a new escaper you - * extend one of these classes. If you find that you are unable to achieve the desired behavior - * using either of these classes, please contact the Java libraries team for advice. - * - *

Popular escapers are defined as constants in classes like {@link - * com.google.common.html.HtmlEscapers} and {@link com.google.common.xml.XmlEscapers}. - * To create your own escapers, use {@link CharEscaperBuilder}, or extend {@code CharEscaper} - * or {@code UnicodeEscaper}. - * - * @author David Beaumont - * @since 15.0 - */ -@Beta -@GwtCompatible -public abstract class Escaper { - // TODO(user): evaluate custom implementations, considering package private constructor. - /** Constructor for use by subclasses. */ - protected Escaper() {} - - /** - * Returns the escaped form of a given literal string. - * - *

Note that this method may treat input characters differently depending on the specific - * escaper implementation. - * - *

    - *
  • {@link UnicodeEscaper} handles UTF-16 - * correctly, including surrogate character pairs. If the input is badly formed the escaper - * should throw {@link IllegalArgumentException}. - *
  • {@link CharEscaper} handles Java characters independently and does not verify the input for - * well formed characters. A {@code CharEscaper} should not be used in situations where input - * is not guaranteed to be restricted to the Basic Multilingual Plane (BMP). - *
- * - * @param string the literal string to be escaped - * @return the escaped form of {@code string} - * @throws NullPointerException if {@code string} is null - * @throws IllegalArgumentException if {@code string} contains badly formed UTF-16 or cannot be - * escaped for any other reason - */ - public abstract String escape(String string); - - private final Function asFunction = - new Function() { - @Override - public String apply(String from) { - return escape(from); - } - }; - - /** - * Returns a {@link Function} that invokes {@link #escape(String)} on this escaper. - */ - public final Function asFunction() { - return asFunction; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/escape/Escapers.java b/thirdparty/google-guava/src/main/java/com/google/common/escape/Escapers.java deleted file mode 100644 index 60af070f11cd..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/escape/Escapers.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.escape; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -import java.util.HashMap; -import java.util.Map; - -import javax.annotation.Nullable; - -/** - * Static utility methods pertaining to {@link Escaper} instances. - * - * @author Sven Mawson - * @author David Beaumont - * @since 15.0 - */ -@Beta -@GwtCompatible -public final class Escapers { - private Escapers() {} - - /** - * Returns an {@link Escaper} that does no escaping, passing all character - * data through unchanged. - */ - public static Escaper nullEscaper() { - return NULL_ESCAPER; - } - - // An Escaper that efficiently performs no escaping. - // Extending CharEscaper (instead of Escaper) makes Escapers.compose() easier. - private static final Escaper NULL_ESCAPER = new CharEscaper() { - @Override public String escape(String string) { - return checkNotNull(string); - } - - @Override protected char[] escape(char c) { - // TODO: Fix tests not to call this directly and make it throw an error. - return null; - } - }; - - /** - * Returns a builder for creating simple, fast escapers. A builder instance - * can be reused and each escaper that is created will be a snapshot of the - * current builder state. Builders are not thread safe. - * - *

The initial state of the builder is such that: - *

    - *
  • There are no replacement mappings
  • - *
  • {@code safeMin == Character.MIN_VALUE}
  • - *
  • {@code safeMax == Character.MAX_VALUE}
  • - *
  • {@code unsafeReplacement == null}
  • - *
- *

For performance reasons escapers created by this builder are not - * Unicode aware and will not validate the well-formedness of their input. - */ - public static Builder builder() { - return new Builder(); - } - - /** - * A builder for simple, fast escapers. - * - *

Typically an escaper needs to deal with the escaping of high valued - * characters or code points. In these cases it is necessary to extend either - * {@link ArrayBasedCharEscaper} or {@link ArrayBasedUnicodeEscaper} to - * provide the desired behavior. However this builder is suitable for creating - * escapers that replace a relative small set of characters. - * - * @author David Beaumont - * @since 15.0 - */ - @Beta - public static final class Builder { - private final Map replacementMap = - new HashMap(); - private char safeMin = Character.MIN_VALUE; - private char safeMax = Character.MAX_VALUE; - private String unsafeReplacement = null; - - // The constructor is exposed via the builder() method above. - private Builder() {} - - /** - * Sets the safe range of characters for the escaper. Characters in this - * range that have no explicit replacement are considered 'safe' and remain - * unescaped in the output. If {@code safeMax < safeMin} then the safe range - * is empty. - * - * @param safeMin the lowest 'safe' character - * @param safeMax the highest 'safe' character - * @return the builder instance - */ - public Builder setSafeRange(char safeMin, char safeMax) { - this.safeMin = safeMin; - this.safeMax = safeMax; - return this; - } - - /** - * Sets the replacement string for any characters outside the 'safe' range - * that have no explicit replacement. If {@code unsafeReplacement} is - * {@code null} then no replacement will occur, if it is {@code ""} then - * the unsafe characters are removed from the output. - * - * @param unsafeReplacement the string to replace unsafe chracters - * @return the builder instance - */ - public Builder setUnsafeReplacement(@Nullable String unsafeReplacement) { - this.unsafeReplacement = unsafeReplacement; - return this; - } - - /** - * Adds a replacement string for the given input character. The specified - * character will be replaced by the given string whenever it occurs in the - * input, irrespective of whether it lies inside or outside the 'safe' - * range. - * - * @param c the character to be replaced - * @param replacement the string to replace the given character - * @return the builder instance - * @throws NullPointerException if {@code replacement} is null - */ - public Builder addEscape(char c, String replacement) { - checkNotNull(replacement); - // This can replace an existing character (the builder is re-usable). - replacementMap.put(c, replacement); - return this; - } - - /** - * Returns a new escaper based on the current state of the builder. - */ - public Escaper build() { - return new ArrayBasedCharEscaper(replacementMap, safeMin, safeMax) { - private final char[] replacementChars = - unsafeReplacement != null ? unsafeReplacement.toCharArray() : null; - @Override protected char[] escapeUnsafe(char c) { - return replacementChars; - } - }; - } - } - - /** - * Returns a {@link UnicodeEscaper} equivalent to the given escaper instance. - * If the escaper is already a UnicodeEscaper then it is simply returned, - * otherwise it is wrapped in a UnicodeEscaper. - * - *

When a {@link CharEscaper} escaper is wrapped by this method it acquires - * extra behavior with respect to the well-formedness of Unicode character - * sequences and will throw {@link IllegalArgumentException} when given bad - * input. - * - * @param escaper the instance to be wrapped - * @return a UnicodeEscaper with the same behavior as the given instance - * @throws NullPointerException if escaper is null - * @throws IllegalArgumentException if escaper is not a UnicodeEscaper or a - * CharEscaper - */ - static UnicodeEscaper asUnicodeEscaper(Escaper escaper) { - checkNotNull(escaper); - if (escaper instanceof UnicodeEscaper) { - return (UnicodeEscaper) escaper; - } else if (escaper instanceof CharEscaper) { - return wrap((CharEscaper) escaper); - } - // In practice this shouldn't happen because it would be very odd not to - // extend either CharEscaper or UnicodeEscaper for non trivial cases. - throw new IllegalArgumentException("Cannot create a UnicodeEscaper from: " + - escaper.getClass().getName()); - } - - /** - * Returns a string that would replace the given character in the specified - * escaper, or {@code null} if no replacement should be made. This method is - * intended for use in tests through the {@code EscaperAsserts} class; - * production users of {@link CharEscaper} should limit themselves to its - * public interface. - * - * @param c the character to escape if necessary - * @return the replacement string, or {@code null} if no escaping was needed - */ - public static String computeReplacement(CharEscaper escaper, char c) { - return stringOrNull(escaper.escape(c)); - } - - /** - * Returns a string that would replace the given character in the specified - * escaper, or {@code null} if no replacement should be made. This method is - * intended for use in tests through the {@code EscaperAsserts} class; - * production users of {@link UnicodeEscaper} should limit themselves to its - * public interface. - * - * @param cp the Unicode code point to escape if necessary - * @return the replacement string, or {@code null} if no escaping was needed - */ - public static String computeReplacement(UnicodeEscaper escaper, int cp) { - return stringOrNull(escaper.escape(cp)); - } - - private static String stringOrNull(char[] in) { - return (in == null) ? null : new String(in); - } - - /** Private helper to wrap a CharEscaper as a UnicodeEscaper. */ - private static UnicodeEscaper wrap(final CharEscaper escaper) { - return new UnicodeEscaper() { - @Override protected char[] escape(int cp) { - // If a code point maps to a single character, just escape that. - if (cp < Character.MIN_SUPPLEMENTARY_CODE_POINT) { - return escaper.escape((char) cp); - } - // Convert the code point to a surrogate pair and escape them both. - // Note: This code path is horribly slow and typically allocates 4 new - // char[] each time it is invoked. However this avoids any - // synchronization issues and makes the escaper thread safe. - char[] surrogateChars = new char[2]; - Character.toChars(cp, surrogateChars, 0); - char[] hiChars = escaper.escape(surrogateChars[0]); - char[] loChars = escaper.escape(surrogateChars[1]); - - // If either hiChars or lowChars are non-null, the CharEscaper is trying - // to escape the characters of a surrogate pair separately. This is - // uncommon and applies only to escapers that assume UCS-2 rather than - // UTF-16. See: http://en.wikipedia.org/wiki/UTF-16/UCS-2 - if (hiChars == null && loChars == null) { - // We expect this to be the common code path for most escapers. - return null; - } - // Combine the characters and/or escaped sequences into a single array. - int hiCount = hiChars != null ? hiChars.length : 1; - int loCount = loChars != null ? loChars.length : 1; - char[] output = new char[hiCount + loCount]; - if (hiChars != null) { - // TODO: Is this faster than System.arraycopy() for small arrays? - for (int n = 0; n < hiChars.length; ++n) { - output[n] = hiChars[n]; - } - } else { - output[0] = surrogateChars[0]; - } - if (loChars != null) { - for (int n = 0; n < loChars.length; ++n) { - output[hiCount + n] = loChars[n]; - } - } else { - output[hiCount] = surrogateChars[1]; - } - return output; - } - }; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/escape/Platform.java b/thirdparty/google-guava/src/main/java/com/google/common/escape/Platform.java deleted file mode 100644 index 984b7eba0bca..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/escape/Platform.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.escape; - -import com.google.common.annotations.GwtCompatible; - -/** - * Methods factored out so that they can be emulated differently in GWT. - * - * @author Jesse Wilson - */ -@GwtCompatible(emulated = true) -final class Platform { - private Platform() {} - - /** Returns a thread-local 1024-char array. */ - static char[] charBufferFromThreadLocal() { - return DEST_TL.get(); - } - - /** - * A thread-local destination buffer to keep us from creating new buffers. - * The starting size is 1024 characters. If we grow past this we don't - * put it back in the threadlocal, we just keep going and grow as needed. - */ - private static final ThreadLocal DEST_TL = new ThreadLocal() { - @Override - protected char[] initialValue() { - return new char[1024]; - } - }; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/escape/UnicodeEscaper.java b/thirdparty/google-guava/src/main/java/com/google/common/escape/UnicodeEscaper.java deleted file mode 100644 index 92e98b995a9c..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/escape/UnicodeEscaper.java +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.escape; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.GwtCompatible; - -/** - * An {@link Escaper} that converts literal text into a format safe for - * inclusion in a particular context (such as an XML document). Typically (but - * not always), the inverse process of "unescaping" the text is performed - * automatically by the relevant parser. - * - *

For example, an XML escaper would convert the literal string {@code - * "Foo"} into {@code "Foo<Bar>"} to prevent {@code ""} from - * being confused with an XML tag. When the resulting XML document is parsed, - * the parser API will return this text as the original literal string {@code - * "Foo"}. - * - *

Note: This class is similar to {@link CharEscaper} but with one - * very important difference. A CharEscaper can only process Java - * UTF16 characters in - * isolation and may not cope when it encounters surrogate pairs. This class - * facilitates the correct escaping of all Unicode characters. - * - *

As there are important reasons, including potential security issues, to - * handle Unicode correctly if you are considering implementing a new escaper - * you should favor using UnicodeEscaper wherever possible. - * - *

A {@code UnicodeEscaper} instance is required to be stateless, and safe - * when used concurrently by multiple threads. - * - *

Popular escapers are defined as constants in classes like {@link - * com.google.common.html.HtmlEscapers} and {@link com.google.common.xml.XmlEscapers}. - * To create your own escapers extend this class and implement the {@link #escape(int)} - * method. - * - * @author David Beaumont - * @since 15.0 - */ -@Beta -@GwtCompatible -public abstract class UnicodeEscaper extends Escaper { - /** The amount of padding (chars) to use when growing the escape buffer. */ - private static final int DEST_PAD = 32; - - /** Constructor for use by subclasses. */ - protected UnicodeEscaper() {} - - /** - * Returns the escaped form of the given Unicode code point, or {@code null} - * if this code point does not need to be escaped. When called as part of an - * escaping operation, the given code point is guaranteed to be in the range - * {@code 0 <= cp <= Character#MAX_CODE_POINT}. - * - *

If an empty array is returned, this effectively strips the input - * character from the resulting text. - * - *

If the character does not need to be escaped, this method should return - * {@code null}, rather than an array containing the character representation - * of the code point. This enables the escaping algorithm to perform more - * efficiently. - * - *

If the implementation of this method cannot correctly handle a - * particular code point then it should either throw an appropriate runtime - * exception or return a suitable replacement character. It must never - * silently discard invalid input as this may constitute a security risk. - * - * @param cp the Unicode code point to escape if necessary - * @return the replacement characters, or {@code null} if no escaping was - * needed - */ - protected abstract char[] escape(int cp); - - /** - * Scans a sub-sequence of characters from a given {@link CharSequence}, - * returning the index of the next character that requires escaping. - * - *

Note: When implementing an escaper, it is a good idea to override - * this method for efficiency. The base class implementation determines - * successive Unicode code points and invokes {@link #escape(int)} for each of - * them. If the semantics of your escaper are such that code points in the - * supplementary range are either all escaped or all unescaped, this method - * can be implemented more efficiently using {@link CharSequence#charAt(int)}. - * - *

Note however that if your escaper does not escape characters in the - * supplementary range, you should either continue to validate the correctness - * of any surrogate characters encountered or provide a clear warning to users - * that your escaper does not validate its input. - * - *

See {@link com.google.common.net.PercentEscaper} for an example. - * - * @param csq a sequence of characters - * @param start the index of the first character to be scanned - * @param end the index immediately after the last character to be scanned - * @throws IllegalArgumentException if the scanned sub-sequence of {@code csq} - * contains invalid surrogate pairs - */ - protected int nextEscapeIndex(CharSequence csq, int start, int end) { - int index = start; - while (index < end) { - int cp = codePointAt(csq, index, end); - if (cp < 0 || escape(cp) != null) { - break; - } - index += Character.isSupplementaryCodePoint(cp) ? 2 : 1; - } - return index; - } - - /** - * Returns the escaped form of a given literal string. - * - *

If you are escaping input in arbitrary successive chunks, then it is not - * generally safe to use this method. If an input string ends with an - * unmatched high surrogate character, then this method will throw - * {@link IllegalArgumentException}. You should ensure your input is valid UTF-16 before calling this - * method. - * - *

Note: When implementing an escaper it is a good idea to override - * this method for efficiency by inlining the implementation of - * {@link #nextEscapeIndex(CharSequence, int, int)} directly. Doing this for - * {@link com.google.common.net.PercentEscaper} more than doubled the - * performance for unescaped strings (as measured by {@link - * CharEscapersBenchmark}). - * - * @param string the literal string to be escaped - * @return the escaped form of {@code string} - * @throws NullPointerException if {@code string} is null - * @throws IllegalArgumentException if invalid surrogate characters are - * encountered - */ - @Override - public String escape(String string) { - checkNotNull(string); - int end = string.length(); - int index = nextEscapeIndex(string, 0, end); - return index == end ? string : escapeSlow(string, index); - } - - /** - * Returns the escaped form of a given literal string, starting at the given - * index. This method is called by the {@link #escape(String)} method when it - * discovers that escaping is required. It is protected to allow subclasses - * to override the fastpath escaping function to inline their escaping test. - * See {@link CharEscaperBuilder} for an example usage. - * - *

This method is not reentrant and may only be invoked by the top level - * {@link #escape(String)} method. - * - * @param s the literal string to be escaped - * @param index the index to start escaping from - * @return the escaped form of {@code string} - * @throws NullPointerException if {@code string} is null - * @throws IllegalArgumentException if invalid surrogate characters are - * encountered - */ - protected final String escapeSlow(String s, int index) { - int end = s.length(); - - // Get a destination buffer and setup some loop variables. - char[] dest = Platform.charBufferFromThreadLocal(); - int destIndex = 0; - int unescapedChunkStart = 0; - - while (index < end) { - int cp = codePointAt(s, index, end); - if (cp < 0) { - throw new IllegalArgumentException( - "Trailing high surrogate at end of input"); - } - // It is possible for this to return null because nextEscapeIndex() may - // (for performance reasons) yield some false positives but it must never - // give false negatives. - char[] escaped = escape(cp); - int nextIndex = index + (Character.isSupplementaryCodePoint(cp) ? 2 : 1); - if (escaped != null) { - int charsSkipped = index - unescapedChunkStart; - - // This is the size needed to add the replacement, not the full - // size needed by the string. We only regrow when we absolutely must. - int sizeNeeded = destIndex + charsSkipped + escaped.length; - if (dest.length < sizeNeeded) { - int destLength = sizeNeeded + (end - index) + DEST_PAD; - dest = growBuffer(dest, destIndex, destLength); - } - // If we have skipped any characters, we need to copy them now. - if (charsSkipped > 0) { - s.getChars(unescapedChunkStart, index, dest, destIndex); - destIndex += charsSkipped; - } - if (escaped.length > 0) { - System.arraycopy(escaped, 0, dest, destIndex, escaped.length); - destIndex += escaped.length; - } - // If we dealt with an escaped character, reset the unescaped range. - unescapedChunkStart = nextIndex; - } - index = nextEscapeIndex(s, nextIndex, end); - } - - // Process trailing unescaped characters - no need to account for escaped - // length or padding the allocation. - int charsSkipped = end - unescapedChunkStart; - if (charsSkipped > 0) { - int endIndex = destIndex + charsSkipped; - if (dest.length < endIndex) { - dest = growBuffer(dest, destIndex, endIndex); - } - s.getChars(unescapedChunkStart, end, dest, destIndex); - destIndex = endIndex; - } - return new String(dest, 0, destIndex); - } - - /** - * Returns the Unicode code point of the character at the given index. - * - *

Unlike {@link Character#codePointAt(CharSequence, int)} or - * {@link String#codePointAt(int)} this method will never fail silently when - * encountering an invalid surrogate pair. - * - *

The behaviour of this method is as follows: - *

    - *
  1. If {@code index >= end}, {@link IndexOutOfBoundsException} is thrown. - *
  2. If the character at the specified index is not a surrogate, it is - * returned. - *
  3. If the first character was a high surrogate value, then an attempt is - * made to read the next character. - *
      - *
    1. If the end of the sequence was reached, the negated value of - * the trailing high surrogate is returned. - *
    2. If the next character was a valid low surrogate, the code point - * value of the high/low surrogate pair is returned. - *
    3. If the next character was not a low surrogate value, then - * {@link IllegalArgumentException} is thrown. - *
    - *
  4. If the first character was a low surrogate value, - * {@link IllegalArgumentException} is thrown. - *
- * - * @param seq the sequence of characters from which to decode the code point - * @param index the index of the first character to decode - * @param end the index beyond the last valid character to decode - * @return the Unicode code point for the given index or the negated value of - * the trailing high surrogate character at the end of the sequence - */ - protected static int codePointAt(CharSequence seq, int index, int end) { - checkNotNull(seq); - if (index < end) { - char c1 = seq.charAt(index++); - if (c1 < Character.MIN_HIGH_SURROGATE || - c1 > Character.MAX_LOW_SURROGATE) { - // Fast path (first test is probably all we need to do) - return c1; - } else if (c1 <= Character.MAX_HIGH_SURROGATE) { - // If the high surrogate was the last character, return its inverse - if (index == end) { - return -c1; - } - // Otherwise look for the low surrogate following it - char c2 = seq.charAt(index); - if (Character.isLowSurrogate(c2)) { - return Character.toCodePoint(c1, c2); - } - throw new IllegalArgumentException( - "Expected low surrogate but got char '" + c2 + - "' with value " + (int) c2 + " at index " + index + - " in '" + seq + "'"); - } else { - throw new IllegalArgumentException( - "Unexpected low surrogate character '" + c1 + - "' with value " + (int) c1 + " at index " + (index - 1) + - " in '" + seq + "'"); - } - } - throw new IndexOutOfBoundsException("Index exceeds specified range"); - } - - /** - * Helper method to grow the character buffer as needed, this only happens - * once in a while so it's ok if it's in a method call. If the index passed - * in is 0 then no copying will be done. - */ - private static char[] growBuffer(char[] dest, int index, int size) { - char[] copy = new char[size]; - if (index > 0) { - System.arraycopy(dest, 0, copy, 0, index); - } - return copy; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/escape/package-info.java b/thirdparty/google-guava/src/main/java/com/google/common/escape/package-info.java deleted file mode 100644 index 3bd1805d4610..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/escape/package-info.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Interfaces, utilities, and simple implementations of escapers and encoders. The primary type is - * {@link com.google.common.escape.Escaper}. - * - *

Additional escapers implementations are found in the applicable packages: {@link - * com.google.common.html.HtmlEscapers} in {@code com.google.common.html}, {@link - * com.google.common.xml.XmlEscapers} in {@code com.google.common.xml}, and {@link - * com.google.common.net.UrlEscapers} in {@code com.google.common.net}. - * - *

This package is a part of the open-source - * Guava libraries. - */ -@ParametersAreNonnullByDefault -package com.google.common.escape; - -import javax.annotation.ParametersAreNonnullByDefault; - diff --git a/thirdparty/google-guava/src/main/java/com/google/common/eventbus/AllowConcurrentEvents.java b/thirdparty/google-guava/src/main/java/com/google/common/eventbus/AllowConcurrentEvents.java deleted file mode 100644 index 77ccdb567485..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/eventbus/AllowConcurrentEvents.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.eventbus; - -import com.google.common.annotations.Beta; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Marks an event subscriber method as being thread-safe. This annotation - * indicates that EventBus may invoke the event subscriber simultaneously from - * multiple threads. - * - *

This does not mark the method, and so should be used in combination with - * {@link Subscribe}. - * - * @author Cliff Biffle - * @since 10.0 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -@Beta -public @interface AllowConcurrentEvents { -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/eventbus/AsyncEventBus.java b/thirdparty/google-guava/src/main/java/com/google/common/eventbus/AsyncEventBus.java deleted file mode 100644 index a150a8a0e628..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/eventbus/AsyncEventBus.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.eventbus; - -import com.google.common.annotations.Beta; - -import java.util.concurrent.Executor; - -/** - * An {@link EventBus} that takes the Executor of your choice and uses it to - * dispatch events, allowing dispatch to occur asynchronously. - * - * @author Cliff Biffle - * @since 10.0 - */ -@Beta -public class AsyncEventBus extends EventBus { - - /** - * Creates a new AsyncEventBus that will use {@code executor} to dispatch - * events. Assigns {@code identifier} as the bus's name for logging purposes. - * - * @param identifier short name for the bus, for logging purposes. - * @param executor Executor to use to dispatch events. It is the caller's - * responsibility to shut down the executor after the last event has - * been posted to this event bus. - */ - public AsyncEventBus(String identifier, Executor executor) { - super(identifier, executor, Dispatcher.legacyAsync(), LoggingHandler.INSTANCE); - } - - /** - * Creates a new AsyncEventBus that will use {@code executor} to dispatch - * events. - * - * @param executor Executor to use to dispatch events. It is the caller's - * responsibility to shut down the executor after the last event has - * been posted to this event bus. - * @param subscriberExceptionHandler Handler used to handle exceptions thrown from subscribers. - * See {@link SubscriberExceptionHandler} for more information. - * @since 16.0 - */ - public AsyncEventBus(Executor executor, SubscriberExceptionHandler subscriberExceptionHandler) { - super("default", executor, Dispatcher.legacyAsync(), subscriberExceptionHandler); - } - - /** - * Creates a new AsyncEventBus that will use {@code executor} to dispatch - * events. - * - * @param executor Executor to use to dispatch events. It is the caller's - * responsibility to shut down the executor after the last event has - * been posted to this event bus. - */ - public AsyncEventBus(Executor executor) { - super("default", executor, Dispatcher.legacyAsync(), LoggingHandler.INSTANCE); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/eventbus/DeadEvent.java b/thirdparty/google-guava/src/main/java/com/google/common/eventbus/DeadEvent.java deleted file mode 100644 index 90929f7d558d..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/eventbus/DeadEvent.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.eventbus; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.base.MoreObjects; - -/** - * Wraps an event that was posted, but which had no subscribers and thus could - * not be delivered. - * - *

Registering a DeadEvent subscriber is useful for debugging or logging, as - * it can detect misconfigurations in a system's event distribution. - * - * @author Cliff Biffle - * @since 10.0 - */ -@Beta -public class DeadEvent { - - private final Object source; - private final Object event; - - /** - * Creates a new DeadEvent. - * - * @param source object broadcasting the DeadEvent (generally the - * {@link EventBus}). - * @param event the event that could not be delivered. - */ - public DeadEvent(Object source, Object event) { - this.source = checkNotNull(source); - this.event = checkNotNull(event); - } - - /** - * Returns the object that originated this event (not the object that - * originated the wrapped event). This is generally an {@link EventBus}. - * - * @return the source of this event. - */ - public Object getSource() { - return source; - } - - /** - * Returns the wrapped, 'dead' event, which the system was unable to deliver - * to any registered subscriber. - * - * @return the 'dead' event that could not be delivered. - */ - public Object getEvent() { - return event; - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("source", source) - .add("event", event) - .toString(); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/eventbus/Dispatcher.java b/thirdparty/google-guava/src/main/java/com/google/common/eventbus/Dispatcher.java deleted file mode 100644 index c406c7eb8b16..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/eventbus/Dispatcher.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (C) 2014 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.eventbus; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.collect.Queues; - -import java.util.Iterator; -import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; - -/** - * Handler for dispatching events to subscribers, providing different event ordering guarantees that - * make sense for different situations. - * - *

Note: The dispatcher is orthogonal to the subscriber's {@code Executor}. The dispatcher - * controls the order in which events are dispatched, while the executor controls how (i.e. on which - * thread) the subscriber is actually called when an event is dispatched to it. - * - * @author Colin Decker - */ -abstract class Dispatcher { - - /** - * Returns a dispatcher that queues events that are posted reentrantly on a thread that is already - * dispatching an event, guaranteeing that all events posted on a single thread are dispatched to - * all subscribers in the order they are posted. - * - *

When all subscribers are dispatched to using a direct executor (which dispatches on - * the same thread that posts the event), this yields a breadth-first dispatch order on each - * thread. That is, all subscribers to a single event A will be called before any subscribers to - * any events B and C that are posted to the event bus by the subscribers to A. - */ - static Dispatcher perThreadDispatchQueue() { - return new PerThreadQueuedDispatcher(); - } - - /** - * Returns a dispatcher that queues events that are posted in a single global queue. This - * behavior matches the original behavior of AsyncEventBus exactly, but is otherwise not - * especially useful. For async dispatch, an {@linkplain #immediate() immediate} dispatcher - * should generally be preferable. - */ - static Dispatcher legacyAsync() { - return new LegacyAsyncDispatcher(); - } - - /** - * Returns a dispatcher that dispatches events to subscribers immediately as they're posted - * without using an intermediate queue to change the dispatch order. This is effectively a - * depth-first dispatch order, vs. breadth-first when using a queue. - */ - static Dispatcher immediate() { - return ImmediateDispatcher.INSTANCE; - } - - /** - * Dispatches the given {@code event} to the given {@code subscribers}. - */ - abstract void dispatch(Object event, Iterator subscribers); - - /** - * Implementation of a {@link #perThreadDispatchQueue()} dispatcher. - */ - private static final class PerThreadQueuedDispatcher extends Dispatcher { - - // This dispatcher matches the original dispatch behavior of EventBus. - - /** - * Per-thread queue of events to dispatch. - */ - private final ThreadLocal> queue = - new ThreadLocal>() { - @Override - protected Queue initialValue() { - return Queues.newArrayDeque(); - } - }; - - /** - * Per-thread dispatch state, used to avoid reentrant event dispatching. - */ - private final ThreadLocal dispatching = - new ThreadLocal() { - @Override - protected Boolean initialValue() { - return false; - } - }; - - @Override - void dispatch(Object event, Iterator subscribers) { - checkNotNull(event); - checkNotNull(subscribers); - Queue queueForThread = queue.get(); - queueForThread.offer(new Event(event, subscribers)); - - if (!dispatching.get()) { - dispatching.set(true); - try { - Event nextEvent; - while ((nextEvent = queueForThread.poll()) != null) { - while (nextEvent.subscribers.hasNext()) { - nextEvent.subscribers.next().dispatchEvent(nextEvent.event); - } - } - } finally { - dispatching.remove(); - queue.remove(); - } - } - } - - private static final class Event { - private final Object event; - private final Iterator subscribers; - - private Event(Object event, Iterator subscribers) { - this.event = event; - this.subscribers = subscribers; - } - } - } - - /** - * Implementation of a {@link #legacyAsync()} dispatcher. - */ - private static final class LegacyAsyncDispatcher extends Dispatcher { - - // This dispatcher matches the original dispatch behavior of AsyncEventBus. - // - // We can't really make any guarantees about the overall dispatch order for this dispatcher in - // a multithreaded environment for a couple reasons: - // - // 1. Subscribers to events posted on different threads can be interleaved with each other - // freely. (A event on one thread, B event on another could yield any of - // [a1, a2, a3, b1, b2], [a1, b2, a2, a3, b2], [a1, b2, b3, a2, a3], etc.) - // 2. It's possible for subscribers to actually be dispatched to in a different order than they - // were added to the queue. It's easily possible for one thread to take the head of the - // queue, immediately followed by another thread taking the next element in the queue. That - // second thread can then dispatch to the subscriber it took before the first thread does. - // - // All this makes me really wonder if there's any value in queueing here at all. A dispatcher - // that simply loops through the subscribers and dispatches the event to each would actually - // probably provide a stronger order guarantee, though that order would obviously be different - // in some cases. - - /** - * Global event queue. - */ - private final ConcurrentLinkedQueue queue = - Queues.newConcurrentLinkedQueue(); - - @Override - void dispatch(Object event, Iterator subscribers) { - checkNotNull(event); - while (subscribers.hasNext()) { - queue.add(new EventWithSubscriber(event, subscribers.next())); - } - - EventWithSubscriber e; - while ((e = queue.poll()) != null) { - e.subscriber.dispatchEvent(e.event); - } - } - - private static final class EventWithSubscriber { - private final Object event; - private final Subscriber subscriber; - - private EventWithSubscriber(Object event, Subscriber subscriber) { - this.event = event; - this.subscriber = subscriber; - } - } - } - - /** - * Implementation of {@link #immediate()}. - */ - private static final class ImmediateDispatcher extends Dispatcher { - private static final ImmediateDispatcher INSTANCE = new ImmediateDispatcher(); - - @Override - void dispatch(Object event, Iterator subscribers) { - checkNotNull(event); - while (subscribers.hasNext()) { - subscribers.next().dispatchEvent(event); - } - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/eventbus/EventBus.java b/thirdparty/google-guava/src/main/java/com/google/common/eventbus/EventBus.java deleted file mode 100644 index 51cfcd63163b..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/eventbus/EventBus.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.eventbus; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.base.MoreObjects; -import com.google.common.util.concurrent.MoreExecutors; - -import java.lang.reflect.Method; -import java.util.Iterator; -import java.util.Locale; -import java.util.concurrent.Executor; -import com.google.common.logging.Level; -import com.google.common.logging.Logger; - -/** - * Dispatches events to listeners, and provides ways for listeners to register - * themselves. - * - *

The EventBus allows publish-subscribe-style communication between - * components without requiring the components to explicitly register with one - * another (and thus be aware of each other). It is designed exclusively to - * replace traditional Java in-process event distribution using explicit - * registration. It is not a general-purpose publish-subscribe system, - * nor is it intended for interprocess communication. - * - *

Receiving Events

- *

To receive events, an object should: - *

    - *
  1. Expose a public method, known as the event subscriber, which accepts - * a single argument of the type of event desired;
  2. - *
  3. Mark it with a {@link Subscribe} annotation;
  4. - *
  5. Pass itself to an EventBus instance's {@link #register(Object)} method. - *
  6. - *
- * - *

Posting Events

- *

To post an event, simply provide the event object to the - * {@link #post(Object)} method. The EventBus instance will determine the type - * of event and route it to all registered listeners. - * - *

Events are routed based on their type — an event will be delivered - * to any subscriber for any type to which the event is assignable. This - * includes implemented interfaces, all superclasses, and all interfaces - * implemented by superclasses. - * - *

When {@code post} is called, all registered subscribers for an event are run - * in sequence, so subscribers should be reasonably quick. If an event may trigger - * an extended process (such as a database load), spawn a thread or queue it for - * later. (For a convenient way to do this, use an {@link AsyncEventBus}.) - * - *

Subscriber Methods

- *

Event subscriber methods must accept only one argument: the event. - * - *

Subscribers should not, in general, throw. If they do, the EventBus will - * catch and log the exception. This is rarely the right solution for error - * handling and should not be relied upon; it is intended solely to help find - * problems during development. - * - *

The EventBus guarantees that it will not call a subscriber method from - * multiple threads simultaneously, unless the method explicitly allows it by - * bearing the {@link AllowConcurrentEvents} annotation. If this annotation is - * not present, subscriber methods need not worry about being reentrant, unless - * also called from outside the EventBus. - * - *

Dead Events

- *

If an event is posted, but no registered subscribers can accept it, it is - * considered "dead." To give the system a second chance to handle dead events, - * they are wrapped in an instance of {@link DeadEvent} and reposted. - * - *

If a subscriber for a supertype of all events (such as Object) is registered, - * no event will ever be considered dead, and no DeadEvents will be generated. - * Accordingly, while DeadEvent extends {@link Object}, a subscriber registered to - * receive any Object will never receive a DeadEvent. - * - *

This class is safe for concurrent use. - * - *

See the Guava User Guide article on - * {@code EventBus}. - * - * @author Cliff Biffle - * @since 10.0 - */ -@Beta -public class EventBus { - - private static final Logger logger = Logger.getLogger(EventBus.class.getName()); - - private final String identifier; - private final Executor executor; - private final SubscriberExceptionHandler exceptionHandler; - - private final SubscriberRegistry subscribers = new SubscriberRegistry(this); - private final Dispatcher dispatcher; - - /** - * Creates a new EventBus named "default". - */ - public EventBus() { - this("default"); - } - - /** - * Creates a new EventBus with the given {@code identifier}. - * - * @param identifier a brief name for this bus, for logging purposes. Should - * be a valid Java identifier. - */ - public EventBus(String identifier) { - this(identifier, MoreExecutors.directExecutor(), - Dispatcher.perThreadDispatchQueue(), LoggingHandler.INSTANCE); - } - - /** - * Creates a new EventBus with the given {@link SubscriberExceptionHandler}. - * - * @param exceptionHandler Handler for subscriber exceptions. - * @since 16.0 - */ - public EventBus(SubscriberExceptionHandler exceptionHandler) { - this("default", - MoreExecutors.directExecutor(), Dispatcher.perThreadDispatchQueue(), exceptionHandler); - } - - EventBus(String identifier, Executor executor, Dispatcher dispatcher, - SubscriberExceptionHandler exceptionHandler) { - this.identifier = checkNotNull(identifier); - this.executor = checkNotNull(executor); - this.dispatcher = checkNotNull(dispatcher); - this.exceptionHandler = checkNotNull(exceptionHandler); - } - - /** - * Returns the identifier for this event bus. - * - * @since 19.0 - */ - public final String identifier() { - return identifier; - } - - /** - * Returns the default executor this event bus uses for dispatching events to subscribers. - */ - final Executor executor() { - return executor; - } - - /** - * Handles the given exception thrown by a subscriber with the given context. - */ - void handleSubscriberException(Throwable e, SubscriberExceptionContext context) { - checkNotNull(e); - checkNotNull(context); - try { - exceptionHandler.handleException(e, context); - } catch (Throwable e2) { - // if the handler threw an exception... well, just log it - logger.log(Level.SEVERE, - String.format(Locale.ROOT, "Exception %s thrown while handling exception: %s", e2, e), - e2); - } - } - - /** - * Registers all subscriber methods on {@code object} to receive events. - * - * @param object object whose subscriber methods should be registered. - */ - public void register(Object object) { - subscribers.register(object); - } - - /** - * Unregisters all subscriber methods on a registered {@code object}. - * - * @param object object whose subscriber methods should be unregistered. - * @throws IllegalArgumentException if the object was not previously registered. - */ - public void unregister(Object object) { - subscribers.unregister(object); - } - - /** - * Posts an event to all registered subscribers. This method will return - * successfully after the event has been posted to all subscribers, and - * regardless of any exceptions thrown by subscribers. - * - *

If no subscribers have been subscribed for {@code event}'s class, and - * {@code event} is not already a {@link DeadEvent}, it will be wrapped in a - * DeadEvent and reposted. - * - * @param event event to post. - */ - public void post(Object event) { - Iterator eventSubscribers = subscribers.getSubscribers(event); - if (eventSubscribers.hasNext()) { - dispatcher.dispatch(event, eventSubscribers); - } else if (!(event instanceof DeadEvent)) { - // the event had no subscribers and was not itself a DeadEvent - post(new DeadEvent(this, event)); - } - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .addValue(identifier) - .toString(); - } - - /** - * Simple logging handler for subscriber exceptions. - */ - static final class LoggingHandler implements SubscriberExceptionHandler { - static final LoggingHandler INSTANCE = new LoggingHandler(); - - @Override - public void handleException(Throwable exception, SubscriberExceptionContext context) { - Logger logger = logger(context); - if (logger.isLoggable(Level.SEVERE)) { - logger.log(Level.SEVERE, message(context), exception); - } - } - - private static Logger logger(SubscriberExceptionContext context) { - return Logger.getLogger(EventBus.class.getName() + "." + context.getEventBus().identifier()); - } - - private static String message(SubscriberExceptionContext context) { - Method method = context.getSubscriberMethod(); - return "Exception thrown by subscriber method " - + method.getName() + '(' + method.getParameterTypes()[0].getName() + ')' - + " on subscriber " + context.getSubscriber() - + " when dispatching event: " + context.getEvent(); - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/eventbus/Subscribe.java b/thirdparty/google-guava/src/main/java/com/google/common/eventbus/Subscribe.java deleted file mode 100644 index b4fa4ec74562..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/eventbus/Subscribe.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.eventbus; - -import com.google.common.annotations.Beta; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Marks a method as an event subscriber. - * - *

The type of event will be indicated by the method's first (and only) - * parameter. If this annotation is applied to methods with zero parameters, - * or more than one parameter, the object containing the method will not be able - * to register for event delivery from the {@link EventBus}. - * - *

Unless also annotated with @{@link AllowConcurrentEvents}, event subscriber - * methods will be invoked serially by each event bus that they are registered - * with. - * - * @author Cliff Biffle - * @since 10.0 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -@Beta -public @interface Subscribe { -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/eventbus/Subscriber.java b/thirdparty/google-guava/src/main/java/com/google/common/eventbus/Subscriber.java deleted file mode 100644 index 9e38f08de900..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/eventbus/Subscriber.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2014 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.eventbus; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.VisibleForTesting; -import com.google.j2objc.annotations.Weak; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.concurrent.Executor; - -import javax.annotation.Nullable; - -/** - * A subscriber method on a specific object, plus the executor that should be used for - * dispatching events to it. - * - *

Two subscribers are equivalent when they refer to the same method on the same object (not - * class). This property is used to ensure that no subscriber method is registered more than once. - * - * @author Colin Decker - */ -class Subscriber { - - /** - * Creates a {@code Subscriber} for {@code method} on {@code listener}. - */ - static Subscriber create(EventBus bus, Object listener, Method method) { - return isDeclaredThreadSafe(method) - ? new Subscriber(bus, listener, method) - : new SynchronizedSubscriber(bus, listener, method); - } - - /** The event bus this subscriber belongs to. */ - @Weak private EventBus bus; - - /** Object sporting the subscriber method. */ - @VisibleForTesting - final Object target; - - /** Subscriber method. */ - private final Method method; - - /** Executor to use for dispatching events to this subscriber. */ - private final Executor executor; - - private Subscriber(EventBus bus, Object target, Method method) { - this.bus = bus; - this.target = checkNotNull(target); - this.method = method; - method.setAccessible(true); - - this.executor = bus.executor(); - } - - /** - * Dispatches {@code event} to this subscriber using the proper executor. - */ - final void dispatchEvent(final Object event) { - executor.execute(new Runnable() { - @Override - public void run() { - try { - invokeSubscriberMethod(event); - } catch (InvocationTargetException e) { - bus.handleSubscriberException(e.getCause(), context(event)); - } - } - }); - } - - /** - * Invokes the subscriber method. This method can be overridden to make the invocation - * synchronized. - */ - @VisibleForTesting - void invokeSubscriberMethod(Object event) throws InvocationTargetException { - try { - method.invoke(target, checkNotNull(event)); - } catch (IllegalArgumentException e) { - throw new Error("Method rejected target/argument: " + event, e); - } catch (IllegalAccessException e) { - throw new Error("Method became inaccessible: " + event, e); - } catch (InvocationTargetException e) { - if (e.getCause() instanceof Error) { - throw (Error) e.getCause(); - } - throw e; - } - } - - /** - * Gets the context for the given event. - */ - private SubscriberExceptionContext context(Object event) { - return new SubscriberExceptionContext(bus, event, target, method); - } - - @Override - public final int hashCode() { - return (31 + method.hashCode()) * 31 + System.identityHashCode(target); - } - - @Override - public final boolean equals(@Nullable Object obj) { - if (obj instanceof Subscriber) { - Subscriber that = (Subscriber) obj; - // Use == so that different equal instances will still receive events. - // We only guard against the case that the same object is registered - // multiple times - return target == that.target && method.equals(that.method); - } - return false; - } - - /** - * Checks whether {@code method} is thread-safe, as indicated by the presence of the - * {@link AllowConcurrentEvents} annotation. - */ - private static boolean isDeclaredThreadSafe(Method method) { - return method.getAnnotation(AllowConcurrentEvents.class) != null; - } - - /** - * Subscriber that synchronizes invocations of a method to ensure that only one thread may enter - * the method at a time. - */ - @VisibleForTesting - static final class SynchronizedSubscriber extends Subscriber { - - private SynchronizedSubscriber(EventBus bus, Object target, Method method) { - super(bus, target, method); - } - - @Override - void invokeSubscriberMethod(Object event) throws InvocationTargetException { - synchronized (this) { - super.invokeSubscriberMethod(event); - } - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/eventbus/SubscriberExceptionContext.java b/thirdparty/google-guava/src/main/java/com/google/common/eventbus/SubscriberExceptionContext.java deleted file mode 100644 index 070c98a5bfc7..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/eventbus/SubscriberExceptionContext.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2013 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.common.eventbus; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.lang.reflect.Method; - -/** - * Context for an exception thrown by a subscriber. - * - * @since 16.0 - */ -public class SubscriberExceptionContext { - private final EventBus eventBus; - private final Object event; - private final Object subscriber; - private final Method subscriberMethod; - - /** - * @param eventBus The {@link EventBus} that handled the event and the - * subscriber. Useful for broadcasting a a new event based on the error. - * @param event The event object that caused the subscriber to throw. - * @param subscriber The source subscriber context. - * @param subscriberMethod the subscribed method. - */ - SubscriberExceptionContext(EventBus eventBus, Object event, Object subscriber, - Method subscriberMethod) { - this.eventBus = checkNotNull(eventBus); - this.event = checkNotNull(event); - this.subscriber = checkNotNull(subscriber); - this.subscriberMethod = checkNotNull(subscriberMethod); - } - - /** - * @return The {@link EventBus} that handled the event and the subscriber. - * Useful for broadcasting a a new event based on the error. - */ - public EventBus getEventBus() { - return eventBus; - } - - /** - * @return The event object that caused the subscriber to throw. - */ - public Object getEvent() { - return event; - } - - /** - * @return The object context that the subscriber was called on. - */ - public Object getSubscriber() { - return subscriber; - } - - /** - * @return The subscribed method that threw the exception. - */ - public Method getSubscriberMethod() { - return subscriberMethod; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/eventbus/SubscriberExceptionHandler.java b/thirdparty/google-guava/src/main/java/com/google/common/eventbus/SubscriberExceptionHandler.java deleted file mode 100644 index f8e4d0b67540..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/eventbus/SubscriberExceptionHandler.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2013 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.google.common.eventbus; - -/** - * Handler for exceptions thrown by event subscribers. - * - * @since 16.0 - */ -public interface SubscriberExceptionHandler { - /** - * Handles exceptions thrown by subscribers. - */ - void handleException(Throwable exception, SubscriberExceptionContext context); -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/eventbus/SubscriberRegistry.java b/thirdparty/google-guava/src/main/java/com/google/common/eventbus/SubscriberRegistry.java deleted file mode 100644 index f0c220d34dee..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/eventbus/SubscriberRegistry.java +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (C) 2014 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.eventbus; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.MoreObjects; -import com.google.common.base.Objects; -import com.google.common.base.Throwables; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterators; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Multimap; -import com.google.common.reflect.TypeToken; -import com.google.common.util.concurrent.UncheckedExecutionException; -import com.google.j2objc.annotations.Weak; - -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.CopyOnWriteArraySet; - -import javax.annotation.Nullable; - -/** - * Registry of subscribers to a single event bus. - * - * @author Colin Decker - */ -final class SubscriberRegistry { - - /** - * All registered subscribers, indexed by event type. - * - *

The {@link CopyOnWriteArraySet} values make it easy and relatively lightweight to get an - * immutable snapshot of all current subscribers to an event without any locking. - */ - private final ConcurrentMap, CopyOnWriteArraySet> subscribers = - Maps.newConcurrentMap(); - - /** - * The event bus this registry belongs to. - */ - @Weak private final EventBus bus; - - SubscriberRegistry(EventBus bus) { - this.bus = checkNotNull(bus); - } - - /** - * Registers all subscriber methods on the given listener object. - */ - void register(Object listener) { - Multimap, Subscriber> listenerMethods = findAllSubscribers(listener); - - for (Map.Entry, Collection> entry : listenerMethods.asMap().entrySet()) { - Class eventType = entry.getKey(); - Collection eventMethodsInListener = entry.getValue(); - - CopyOnWriteArraySet eventSubscribers = subscribers.get(eventType); - - if (eventSubscribers == null) { - CopyOnWriteArraySet newSet = new CopyOnWriteArraySet(); - eventSubscribers = MoreObjects.firstNonNull( - subscribers.putIfAbsent(eventType, newSet), newSet); - } - - eventSubscribers.addAll(eventMethodsInListener); - } - } - - /** - * Unregisters all subscribers on the given listener object. - */ - void unregister(Object listener) { - Multimap, Subscriber> listenerMethods = findAllSubscribers(listener); - - for (Map.Entry, Collection> entry : listenerMethods.asMap().entrySet()) { - Class eventType = entry.getKey(); - Collection listenerMethodsForType = entry.getValue(); - - CopyOnWriteArraySet currentSubscribers = subscribers.get(eventType); - if (currentSubscribers == null || !currentSubscribers.removeAll(listenerMethodsForType)) { - // if removeAll returns true, all we really know is that at least one subscriber was - // removed... however, barring something very strange we can assume that if at least one - // subscriber was removed, all subscribers on listener for that event type were... after - // all, the definition of subscribers on a particular class is totally static - throw new IllegalArgumentException( - "missing event subscriber for an annotated method. Is " + listener + " registered?"); - } - - // don't try to remove the set if it's empty; that can't be done safely without a lock - // anyway, if the set is empty it'll just be wrapping an array of length 0 - } - } - - @VisibleForTesting - Set getSubscribersForTesting(Class eventType) { - return MoreObjects.firstNonNull(subscribers.get(eventType), ImmutableSet.of()); - } - - /** - * Gets an iterator representing an immutable snapshot of all subscribers to the given event at - * the time this method is called. - */ - Iterator getSubscribers(Object event) { - ImmutableSet> eventTypes = flattenHierarchy(event.getClass()); - - List> subscriberIterators = - Lists.newArrayListWithCapacity(eventTypes.size()); - - for (Class eventType : eventTypes) { - CopyOnWriteArraySet eventSubscribers = subscribers.get(eventType); - if (eventSubscribers != null) { - // eager no-copy snapshot - subscriberIterators.add(eventSubscribers.iterator()); - } - } - - return Iterators.concat(subscriberIterators.iterator()); - } - - /** - * A thread-safe cache that contains the mapping from each class to all methods in that class and - * all super-classes, that are annotated with {@code @Subscribe}. The cache is shared across all - * instances of this class; this greatly improves performance if multiple EventBus instances are - * created and objects of the same class are registered on all of them. - */ - private static final LoadingCache, ImmutableList> subscriberMethodsCache = - CacheBuilder.newBuilder() - .weakKeys() - .build(new CacheLoader, ImmutableList>() { - @Override - public ImmutableList load(Class concreteClass) throws Exception { - return getAnnotatedMethodsNotCached(concreteClass); - } - }); - - /** - * Returns all subscribers for the given listener grouped by the type of event they subscribe to. - */ - private Multimap, Subscriber> findAllSubscribers(Object listener) { - Multimap, Subscriber> methodsInListener = HashMultimap.create(); - Class clazz = listener.getClass(); - for (Method method : getAnnotatedMethods(clazz)) { - Class[] parameterTypes = method.getParameterTypes(); - Class eventType = parameterTypes[0]; - methodsInListener.put(eventType, Subscriber.create(bus, listener, method)); - } - return methodsInListener; - } - - private static ImmutableList getAnnotatedMethods(Class clazz) { - return subscriberMethodsCache.getUnchecked(clazz); - } - - private static ImmutableList getAnnotatedMethodsNotCached(Class clazz) { - Set> supertypes = TypeToken.of(clazz).getTypes().rawTypes(); - Map identifiers = Maps.newHashMap(); - for (Class supertype : supertypes) { - for (Method method : supertype.getDeclaredMethods()) { - if (method.isAnnotationPresent(Subscribe.class) && !method.isSynthetic()) { - // TODO(cgdecker): Should check for a generic parameter type and error out - Class[] parameterTypes = method.getParameterTypes(); - checkArgument(parameterTypes.length == 1, - "Method %s has @Subscribe annotation but has %s parameters." - + "Subscriber methods must have exactly 1 parameter.", - method, parameterTypes.length); - - MethodIdentifier ident = new MethodIdentifier(method); - if (!identifiers.containsKey(ident)) { - identifiers.put(ident, method); - } - } - } - } - return ImmutableList.copyOf(identifiers.values()); - } - - /** - * Global cache of classes to their flattened hierarchy of supertypes. - */ - private static final LoadingCache, ImmutableSet>> flattenHierarchyCache = - CacheBuilder.newBuilder() - .weakKeys() - .build(new CacheLoader, ImmutableSet>>() { - @SuppressWarnings("RedundantTypeArguments") // > is actually needed to compile - @Override - public ImmutableSet> load(Class concreteClass) { - return ImmutableSet.>copyOf( - TypeToken.of(concreteClass).getTypes().rawTypes()); - } - }); - - /** - * Flattens a class's type hierarchy into a set of {@code Class} objects including all - * superclasses (transitively) and all interfaces implemented by these superclasses. - */ - @VisibleForTesting - static ImmutableSet> flattenHierarchy(Class concreteClass) { - try { - return flattenHierarchyCache.getUnchecked(concreteClass); - } catch (UncheckedExecutionException e) { - throw Throwables.propagate(e.getCause()); - } - } - - private static final class MethodIdentifier { - - private final String name; - private final List> parameterTypes; - - MethodIdentifier(Method method) { - this.name = method.getName(); - this.parameterTypes = Arrays.asList(method.getParameterTypes()); - } - - @Override - public int hashCode() { - return Objects.hashCode(name, parameterTypes); - } - - @Override - public boolean equals(@Nullable Object o) { - if (o instanceof MethodIdentifier) { - MethodIdentifier ident = (MethodIdentifier) o; - return name.equals(ident.name) && parameterTypes.equals(ident.parameterTypes); - } - return false; - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/eventbus/package-info.java b/thirdparty/google-guava/src/main/java/com/google/common/eventbus/package-info.java deleted file mode 100644 index f7b333c60ab3..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/eventbus/package-info.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * The EventBus allows publish-subscribe-style communication between components - * without requiring the components to explicitly register with one another - * (and thus be aware of each other). It is designed exclusively to replace - * traditional Java in-process event distribution using explicit registration. - * It is not a general-purpose publish-subscribe system, nor is it - * intended for interprocess communication. - * - *

See the Guava User Guide article on - * {@code EventBus}. - * - *

One-Minute Guide

- * - *

Converting an existing EventListener-based system to use the EventBus is - * easy. - * - *

For Listeners

- *

To listen for a specific flavor of event (say, a CustomerChangeEvent)... - *

    - *
  • ...in traditional Java events: implement an interface - * defined with the event — such as CustomerChangeEventListener.
  • - *
  • ...with EventBus: create a method that accepts - * CustomerChangeEvent as its sole argument, and mark it with the - * {@link com.google.common.eventbus.Subscribe} annotation.
  • - *
- * - *

To register your listener methods with the event producers... - *

    - *
  • ...in traditional Java events: pass your object to each - * producer's {@code registerCustomerChangeEventListener} method. These - * methods are rarely defined in common interfaces, so in addition to - * knowing every possible producer, you must also know its type.
  • - *
  • ...with EventBus: pass your object to the - * {@link com.google.common.eventbus.EventBus#register(Object)} method on an - * EventBus. You'll need to - * make sure that your object shares an EventBus instance with the event - * producers.
  • - *
- * - *

To listen for a common event supertype (such as EventObject or Object)... - *

    - *
  • ...in traditional Java events: not easy.
  • - *
  • ...with EventBus: events are automatically dispatched to - * listeners of any supertype, allowing listeners for interface types - * or "wildcard listeners" for Object.
  • - *
- * - *

To listen for and detect events that were dispatched without listeners... - *

    - *
  • ...in traditional Java events: add code to each - * event-dispatching method (perhaps using AOP).
  • - *
  • ...with EventBus: subscribe to {@link - * com.google.common.eventbus.DeadEvent}. The - * EventBus will notify you of any events that were posted but not - * delivered. (Handy for debugging.)
  • - *
- * - *

For Producers

- *

To keep track of listeners to your events... - *

    - *
  • ...in traditional Java events: write code to manage - * a list of listeners to your object, including synchronization, or use a - * utility class like EventListenerList.
  • - *
  • ...with EventBus: EventBus does this for you.
  • - *
- * - *

To dispatch an event to listeners... - *

    - *
  • ...in traditional Java events: write a method to - * dispatch events to each event listener, including error isolation and - * (if desired) asynchronicity.
  • - *
  • ...with EventBus: pass the event object to an EventBus's - * {@link com.google.common.eventbus.EventBus#post(Object)} method.
  • - *
- * - *

Glossary

- * - *

The EventBus system and code use the following terms to discuss event - * distribution: - *

- *
Event
Any object that may be posted to a bus.
- *
Subscribing
The act of registering a listener with an - * EventBus, so that its subscriber methods will receive events.
- *
Listener
An object that wishes to receive events, by exposing - * subscriber methods. - *
Subscriber method
A public method that the EventBus should use to - * deliver posted events. Subscriber methods are marked by the - * {@link com.google.common.eventbus.Subscribe} annotation.
- *
Posting an event
Making the event available to any - * listeners through the EventBus. - *
- * - *

FAQ

- *

Why must I create my own Event Bus, rather than using a singleton?

- * - *

The Event Bus doesn't specify how you use it; there's nothing stopping your - * application from having separate EventBus instances for each component, or - * using separate instances to separate events by context or topic. This also - * makes it trivial to set up and tear down EventBus objects in your tests. - * - *

Of course, if you'd like to have a process-wide EventBus singleton, - * there's nothing stopping you from doing it that way. Simply have your - * container (such as Guice) create the EventBus as a singleton at global scope - * (or stash it in a static field, if you're into that sort of thing). - * - *

In short, the EventBus is not a singleton because we'd rather not make - * that decision for you. Use it how you like. - * - *

Why use an annotation to mark subscriber methods, rather than requiring the - * listener to implement an interface?

- *

We feel that the Event Bus's {@code @Subscribe} annotation conveys your - * intentions just as explicitly as implementing an interface (or perhaps more - * so), while leaving you free to place event subscriber methods wherever you wish - * and give them intention-revealing names. - * - *

Traditional Java Events use a listener interface which typically sports - * only a handful of methods -- typically one. This has a number of - * disadvantages: - *

    - *
  • Any one class can only implement a single response to a given event. - *
  • Listener interface methods may conflict. - *
  • The method must be named after the event (e.g. {@code - * handleChangeEvent}), rather than its purpose (e.g. {@code - * recordChangeInJournal}). - *
  • Each event usually has its own interface, without a common parent - * interface for a family of events (e.g. all UI events). - *
- * - *

The difficulties in implementing this cleanly has given rise to a pattern, - * particularly common in Swing apps, of using tiny anonymous classes to - * implement event listener interfaces. - * - *

Compare these two cases:

- *   class ChangeRecorder {
- *     void setCustomer(Customer cust) {
- *       cust.addChangeListener(new ChangeListener() {
- *         void customerChanged(ChangeEvent e) {
- *           recordChange(e.getChange());
- *         }
- *       };
- *     }
- *   }
- *
- *   // Class is typically registered by the container.
- *   class EventBusChangeRecorder {
- *     @Subscribe void recordCustomerChange(ChangeEvent e) {
- *       recordChange(e.getChange());
- *     }
- *   }
- * - *

The intent is actually clearer in the second case: there's less noise code, - * and the event subscriber has a clear and meaningful name. - * - *

What about a generic {@code Subscriber} interface?

- *

Some have proposed a generic {@code Subscriber} interface for EventBus - * listeners. This runs into issues with Java's use of type erasure, not to - * mention problems in usability. - * - *

Let's say the interface looked something like the following:

   {@code
- *   interface Subscriber {
- *     void handleEvent(T event);
- *   }}
- * - *

Due to erasure, no single class can implement a generic interface more than - * once with different type parameters. This is a giant step backwards from - * traditional Java Events, where even if {@code actionPerformed} and {@code - * keyPressed} aren't very meaningful names, at least you can implement both - * methods! - * - *

Doesn't EventBus destroy static typing and eliminate automated - * refactoring support?

- *

Some have freaked out about EventBus's {@code register(Object)} and {@code - * post(Object)} methods' use of the {@code Object} type. - * - *

{@code Object} is used here for a good reason: the Event Bus library - * places no restrictions on the types of either your event listeners (as in - * {@code register(Object)}) or the events themselves (in {@code post(Object)}). - * - *

Event subscriber methods, on the other hand, must explicitly declare their - * argument type -- the type of event desired (or one of its supertypes). Thus, - * searching for references to an event class will instantly find all subscriber - * methods for that event, and renaming the type will affect all subscriber methods - * within view of your IDE (and any code that creates the event). - * - *

It's true that you can rename your {@code @Subscribed} event subscriber - * methods at will; Event Bus will not stop this or do anything to propagate the - * rename because, to Event Bus, the names of your subscriber methods are - * irrelevant. Test code that calls the methods directly, of course, will be - * affected by your renaming -- but that's what your refactoring tools are for. - * - *

What happens if I {@code register} a listener without any subscriber - * methods?

- *

Nothing at all. - * - *

The Event Bus was designed to integrate with containers and module - * systems, with Guice as the prototypical example. In these cases, it's - * convenient to have the container/factory/environment pass every - * created object to an EventBus's {@code register(Object)} method. - * - *

This way, any object created by the container/factory/environment can - * hook into the system's event model simply by exposing subscriber methods. - * - *

What Event Bus problems can be detected at compile time?

- *

Any problem that can be unambiguously detected by Java's type system. For - * example, defining a subscriber method for a nonexistent event type. - * - *

What Event Bus problems can be detected immediately at registration?

- *

Immediately upon invoking {@code register(Object)} , the listener being - * registered is checked for the well-formedness of its subscriber methods. - * Specifically, any methods marked with {@code @Subscribe} must take only a - * single argument. - * - *

Any violations of this rule will cause an {@code IllegalArgumentException} - * to be thrown. - * - *

(This check could be moved to compile-time using APT, a solution we're - * researching.) - * - *

What Event Bus problems may only be detected later, at runtime?

- *

If a component posts events with no registered listeners, it may - * indicate an error (typically an indication that you missed a - * {@code @Subscribe} annotation, or that the listening component is not loaded). - * - *

(Note that this is not necessarily indicative of a problem. There - * are many cases where an application will deliberately ignore a posted event, - * particularly if the event is coming from code you don't control.) - * - *

To handle such events, register a subscriber method for the {@code DeadEvent} - * class. Whenever EventBus receives an event with no registered subscribers, it - * will turn it into a {@code DeadEvent} and pass it your way -- allowing you to - * log it or otherwise recover. - * - *

How do I test event listeners and their subscriber methods?

- *

Because subscriber methods on your listener classes are normal methods, you can - * simply call them from your test code to simulate the EventBus. - */ -package com.google.common.eventbus; diff --git a/thirdparty/google-guava/src/main/java/com/google/common/hash/AbstractByteHasher.java b/thirdparty/google-guava/src/main/java/com/google/common/hash/AbstractByteHasher.java deleted file mode 100644 index dbddf9cef8ed..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/hash/AbstractByteHasher.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.hash; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkPositionIndexes; - -import com.google.common.primitives.Chars; -import com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; -import com.google.common.primitives.Shorts; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -/** - * Abstract {@link Hasher} that handles converting primitives to bytes using a scratch {@code - * ByteBuffer} and streams all bytes to a sink to compute the hash. - * - * @author Colin Decker - */ -abstract class AbstractByteHasher extends AbstractHasher { - private final ByteBuffer scratch = ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN); - - /** - * Updates this hasher with the given byte. - */ - protected abstract void update(byte b); - - /** - * Updates this hasher with the given bytes. - */ - protected void update(byte[] b) { - update(b, 0, b.length); - } - - /** - * Updates this hasher with {@code len} bytes starting at {@code off} in the given buffer. - */ - protected void update(byte[] b, int off, int len) { - for (int i = off; i < off + len; i++) { - update(b[i]); - } - } - - @Override - public Hasher putByte(byte b) { - update(b); - return this; - } - - @Override - public Hasher putBytes(byte[] bytes) { - checkNotNull(bytes); - update(bytes); - return this; - } - - @Override - public Hasher putBytes(byte[] bytes, int off, int len) { - checkPositionIndexes(off, off + len, bytes.length); - update(bytes, off, len); - return this; - } - - /** - * Updates the sink with the given number of bytes from the buffer. - */ - private Hasher update(int bytes) { - try { - update(scratch.array(), 0, bytes); - } finally { - scratch.clear(); - } - return this; - } - - @Override - public Hasher putShort(short s) { - scratch.putShort(s); - return update(Shorts.BYTES); - } - - @Override - public Hasher putInt(int i) { - scratch.putInt(i); - return update(Ints.BYTES); - } - - @Override - public Hasher putLong(long l) { - scratch.putLong(l); - return update(Longs.BYTES); - } - - @Override - public Hasher putChar(char c) { - scratch.putChar(c); - return update(Chars.BYTES); - } - - @Override - public Hasher putObject(T instance, Funnel funnel) { - funnel.funnel(instance, this); - return this; - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/hash/AbstractCompositeHashFunction.java b/thirdparty/google-guava/src/main/java/com/google/common/hash/AbstractCompositeHashFunction.java deleted file mode 100644 index 21229085a118..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/hash/AbstractCompositeHashFunction.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.hash; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.nio.charset.Charset; - -/** - * An abstract composition of multiple hash functions. {@linkplain #newHasher()} delegates to the - * {@code Hasher} objects of the delegate hash functions, and in the end, they are used by - * {@linkplain #makeHash(Hasher[])} that constructs the final {@code HashCode}. - * - * @author Dimitris Andreou - */ -abstract class AbstractCompositeHashFunction extends AbstractStreamingHashFunction { - final HashFunction[] functions; - - AbstractCompositeHashFunction(HashFunction... functions) { - for (HashFunction function : functions) { - checkNotNull(function); - } - this.functions = functions; - } - - /** - * Constructs a {@code HashCode} from the {@code Hasher} objects of the functions. Each of them - * has consumed the entire input and they are ready to output a {@code HashCode}. The order of - * the hashers are the same order as the functions given to the constructor. - */ - // this could be cleaner if it passed HashCode[], but that would create yet another array... - /* protected */ abstract HashCode makeHash(Hasher[] hashers); - - @Override - public Hasher newHasher() { - final Hasher[] hashers = new Hasher[functions.length]; - for (int i = 0; i < hashers.length; i++) { - hashers[i] = functions[i].newHasher(); - } - return new Hasher() { - @Override - public Hasher putByte(byte b) { - for (Hasher hasher : hashers) { - hasher.putByte(b); - } - return this; - } - - @Override - public Hasher putBytes(byte[] bytes) { - for (Hasher hasher : hashers) { - hasher.putBytes(bytes); - } - return this; - } - - @Override - public Hasher putBytes(byte[] bytes, int off, int len) { - for (Hasher hasher : hashers) { - hasher.putBytes(bytes, off, len); - } - return this; - } - - @Override - public Hasher putShort(short s) { - for (Hasher hasher : hashers) { - hasher.putShort(s); - } - return this; - } - - @Override - public Hasher putInt(int i) { - for (Hasher hasher : hashers) { - hasher.putInt(i); - } - return this; - } - - @Override - public Hasher putLong(long l) { - for (Hasher hasher : hashers) { - hasher.putLong(l); - } - return this; - } - - @Override - public Hasher putFloat(float f) { - for (Hasher hasher : hashers) { - hasher.putFloat(f); - } - return this; - } - - @Override - public Hasher putDouble(double d) { - for (Hasher hasher : hashers) { - hasher.putDouble(d); - } - return this; - } - - @Override - public Hasher putBoolean(boolean b) { - for (Hasher hasher : hashers) { - hasher.putBoolean(b); - } - return this; - } - - @Override - public Hasher putChar(char c) { - for (Hasher hasher : hashers) { - hasher.putChar(c); - } - return this; - } - - @Override - public Hasher putUnencodedChars(CharSequence chars) { - for (Hasher hasher : hashers) { - hasher.putUnencodedChars(chars); - } - return this; - } - - @Override - public Hasher putString(CharSequence chars, Charset charset) { - for (Hasher hasher : hashers) { - hasher.putString(chars, charset); - } - return this; - } - - @Override - public Hasher putObject(T instance, Funnel funnel) { - for (Hasher hasher : hashers) { - hasher.putObject(instance, funnel); - } - return this; - } - - @Override - public HashCode hash() { - return makeHash(hashers); - } - }; - } - - private static final long serialVersionUID = 0L; -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/hash/AbstractHasher.java b/thirdparty/google-guava/src/main/java/com/google/common/hash/AbstractHasher.java deleted file mode 100644 index df572e582da9..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/hash/AbstractHasher.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.hash; - -import java.nio.charset.Charset; - -/** - * An abstract hasher, implementing {@link #putBoolean(boolean)}, {@link #putDouble(double)}, - * {@link #putFloat(float)}, {@link #putUnencodedChars(CharSequence)}, and - * {@link #putString(CharSequence, Charset)} as prescribed by {@link Hasher}. - * - * @author Dimitris Andreou - */ -abstract class AbstractHasher implements Hasher { - @Override - public final Hasher putBoolean(boolean b) { - return putByte(b ? (byte) 1 : (byte) 0); - } - - @Override - public final Hasher putDouble(double d) { - return putLong(Double.doubleToRawLongBits(d)); - } - - @Override - public final Hasher putFloat(float f) { - return putInt(Float.floatToRawIntBits(f)); - } - - @Override - public Hasher putUnencodedChars(CharSequence charSequence) { - for (int i = 0, len = charSequence.length(); i < len; i++) { - putChar(charSequence.charAt(i)); - } - return this; - } - - @Override - public Hasher putString(CharSequence charSequence, Charset charset) { - return putBytes(charSequence.toString().getBytes(charset)); - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/hash/AbstractNonStreamingHashFunction.java b/thirdparty/google-guava/src/main/java/com/google/common/hash/AbstractNonStreamingHashFunction.java deleted file mode 100644 index f1838eef9d00..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/hash/AbstractNonStreamingHashFunction.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.hash; - -import com.google.common.base.Preconditions; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.charset.Charset; - -/** - * Skeleton implementation of {@link HashFunction}, appropriate for non-streaming algorithms. - * All the hash computation done using {@linkplain #newHasher()} are delegated to the {@linkplain - * #hashBytes(byte[], int, int)} method. - * - * @author Dimitris Andreou - */ -abstract class AbstractNonStreamingHashFunction implements HashFunction { - @Override - public Hasher newHasher() { - return new BufferingHasher(32); - } - - @Override - public Hasher newHasher(int expectedInputSize) { - Preconditions.checkArgument(expectedInputSize >= 0); - return new BufferingHasher(expectedInputSize); - } - - @Override - public HashCode hashObject(T instance, Funnel funnel) { - return newHasher().putObject(instance, funnel).hash(); - } - - @Override - public HashCode hashUnencodedChars(CharSequence input) { - int len = input.length(); - Hasher hasher = newHasher(len * 2); - for (int i = 0; i < len; i++) { - hasher.putChar(input.charAt(i)); - } - return hasher.hash(); - } - - @Override - public HashCode hashString(CharSequence input, Charset charset) { - return hashBytes(input.toString().getBytes(charset)); - } - - @Override - public HashCode hashInt(int input) { - return newHasher(4).putInt(input).hash(); - } - - @Override - public HashCode hashLong(long input) { - return newHasher(8).putLong(input).hash(); - } - - @Override - public HashCode hashBytes(byte[] input) { - return hashBytes(input, 0, input.length); - } - - /** - * In-memory stream-based implementation of Hasher. - */ - private final class BufferingHasher extends AbstractHasher { - final ExposedByteArrayOutputStream stream; - static final int BOTTOM_BYTE = 0xFF; - - BufferingHasher(int expectedInputSize) { - this.stream = new ExposedByteArrayOutputStream(expectedInputSize); - } - - @Override - public Hasher putByte(byte b) { - stream.write(b); - return this; - } - - @Override - public Hasher putBytes(byte[] bytes) { - try { - stream.write(bytes); - } catch (IOException e) { - throw new RuntimeException(e); - } - return this; - } - - @Override - public Hasher putBytes(byte[] bytes, int off, int len) { - stream.write(bytes, off, len); - return this; - } - - @Override - public Hasher putShort(short s) { - stream.write(s & BOTTOM_BYTE); - stream.write((s >>> 8) & BOTTOM_BYTE); - return this; - } - - @Override - public Hasher putInt(int i) { - stream.write(i & BOTTOM_BYTE); - stream.write((i >>> 8) & BOTTOM_BYTE); - stream.write((i >>> 16) & BOTTOM_BYTE); - stream.write((i >>> 24) & BOTTOM_BYTE); - return this; - } - - @Override - public Hasher putLong(long l) { - for (int i = 0; i < 64; i += 8) { - stream.write((byte) ((l >>> i) & BOTTOM_BYTE)); - } - return this; - } - - @Override - public Hasher putChar(char c) { - stream.write(c & BOTTOM_BYTE); - stream.write((c >>> 8) & BOTTOM_BYTE); - return this; - } - - @Override - public Hasher putObject(T instance, Funnel funnel) { - funnel.funnel(instance, this); - return this; - } - - @Override - public HashCode hash() { - return hashBytes(stream.byteArray(), 0, stream.length()); - } - } - - // Just to access the byte[] without introducing an unnecessary copy - private static final class ExposedByteArrayOutputStream extends ByteArrayOutputStream { - ExposedByteArrayOutputStream(int expectedInputSize) { - super(expectedInputSize); - } - - byte[] byteArray() { - return buf; - } - - int length() { - return count; - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/hash/AbstractStreamingHashFunction.java b/thirdparty/google-guava/src/main/java/com/google/common/hash/AbstractStreamingHashFunction.java deleted file mode 100644 index 8d8bf9b0da7e..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/hash/AbstractStreamingHashFunction.java +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.hash; - -import static com.google.common.base.Preconditions.checkArgument; - -import com.google.common.base.Preconditions; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.charset.Charset; - -/** - * Skeleton implementation of {@link HashFunction}. Provides default implementations which - * invokes the appropriate method on {@link #newHasher()}, then return the result of - * {@link Hasher#hash}. - * - *

Invocations of {@link #newHasher(int)} also delegate to {@linkplain #newHasher()}, ignoring - * the expected input size parameter. - * - * @author Kevin Bourrillion - */ -abstract class AbstractStreamingHashFunction implements HashFunction { - @Override - public HashCode hashObject(T instance, Funnel funnel) { - return newHasher().putObject(instance, funnel).hash(); - } - - @Override - public HashCode hashUnencodedChars(CharSequence input) { - return newHasher().putUnencodedChars(input).hash(); - } - - @Override - public HashCode hashString(CharSequence input, Charset charset) { - return newHasher().putString(input, charset).hash(); - } - - @Override - public HashCode hashInt(int input) { - return newHasher().putInt(input).hash(); - } - - @Override - public HashCode hashLong(long input) { - return newHasher().putLong(input).hash(); - } - - @Override - public HashCode hashBytes(byte[] input) { - return newHasher().putBytes(input).hash(); - } - - @Override - public HashCode hashBytes(byte[] input, int off, int len) { - return newHasher().putBytes(input, off, len).hash(); - } - - @Override - public Hasher newHasher(int expectedInputSize) { - Preconditions.checkArgument(expectedInputSize >= 0); - return newHasher(); - } - - /** - * A convenience base class for implementors of {@code Hasher}; handles accumulating data - * until an entire "chunk" (of implementation-dependent length) is ready to be hashed. - * - * @author Kevin Bourrillion - * @author Dimitris Andreou - */ - // TODO(kevinb): this class still needs some design-and-document-for-inheritance love - protected static abstract class AbstractStreamingHasher extends AbstractHasher { - /** Buffer via which we pass data to the hash algorithm (the implementor) */ - private final ByteBuffer buffer; - - /** Number of bytes to be filled before process() invocation(s). */ - private final int bufferSize; - - /** Number of bytes processed per process() invocation. */ - private final int chunkSize; - - /** - * Constructor for use by subclasses. This hasher instance will process chunks of the specified - * size. - * - * @param chunkSize the number of bytes available per {@link #process(ByteBuffer)} invocation; - * must be at least 4 - */ - protected AbstractStreamingHasher(int chunkSize) { - this(chunkSize, chunkSize); - } - - /** - * Constructor for use by subclasses. This hasher instance will process chunks of the specified - * size, using an internal buffer of {@code bufferSize} size, which must be a multiple of - * {@code chunkSize}. - * - * @param chunkSize the number of bytes available per {@link #process(ByteBuffer)} invocation; - * must be at least 4 - * @param bufferSize the size of the internal buffer. Must be a multiple of chunkSize - */ - protected AbstractStreamingHasher(int chunkSize, int bufferSize) { - // TODO(kevinb): check more preconditions (as bufferSize >= chunkSize) if this is ever public - checkArgument(bufferSize % chunkSize == 0); - - // TODO(user): benchmark performance difference with longer buffer - // always space for a single primitive - this.buffer = ByteBuffer.allocate(bufferSize + 7).order(ByteOrder.LITTLE_ENDIAN); - this.bufferSize = bufferSize; - this.chunkSize = chunkSize; - } - - /** - * Processes the available bytes of the buffer (at most {@code chunk} bytes). - */ - protected abstract void process(ByteBuffer bb); - - /** - * This is invoked for the last bytes of the input, which are not enough to - * fill a whole chunk. The passed {@code ByteBuffer} is guaranteed to be - * non-empty. - * - *

This implementation simply pads with zeros and delegates to - * {@link #process(ByteBuffer)}. - */ - protected void processRemaining(ByteBuffer bb) { - bb.position(bb.limit()); // move at the end - bb.limit(chunkSize + 7); // get ready to pad with longs - while (bb.position() < chunkSize) { - bb.putLong(0); - } - bb.limit(chunkSize); - bb.flip(); - process(bb); - } - - @Override - public final Hasher putBytes(byte[] bytes) { - return putBytes(bytes, 0, bytes.length); - } - - @Override - public final Hasher putBytes(byte[] bytes, int off, int len) { - return putBytes(ByteBuffer.wrap(bytes, off, len).order(ByteOrder.LITTLE_ENDIAN)); - } - - private Hasher putBytes(ByteBuffer readBuffer) { - // If we have room for all of it, this is easy - if (readBuffer.remaining() <= buffer.remaining()) { - buffer.put(readBuffer); - munchIfFull(); - return this; - } - - // First add just enough to fill buffer size, and munch that - int bytesToCopy = bufferSize - buffer.position(); - for (int i = 0; i < bytesToCopy; i++) { - buffer.put(readBuffer.get()); - } - munch(); // buffer becomes empty here, since chunkSize divides bufferSize - - // Now process directly from the rest of the input buffer - while (readBuffer.remaining() >= chunkSize) { - process(readBuffer); - } - - // Finally stick the remainder back in our usual buffer - buffer.put(readBuffer); - return this; - } - - @Override - public final Hasher putUnencodedChars(CharSequence charSequence) { - for (int i = 0; i < charSequence.length(); i++) { - putChar(charSequence.charAt(i)); - } - return this; - } - - /* - * Note: hashString(CharSequence, Charset) is intentionally not overridden. - * - * While intuitively, using CharsetEncoder to encode the CharSequence directly to the buffer - * (or even to an intermediate buffer) should be considerably more efficient than potentially - * copying the CharSequence to a String and then calling getBytes(Charset) on that String, in - * reality there are optimizations that make the getBytes(Charset) approach considerably faster, - * at least for commonly used charsets like UTF-8. - */ - - @Override - public final Hasher putByte(byte b) { - buffer.put(b); - munchIfFull(); - return this; - } - - @Override - public final Hasher putShort(short s) { - buffer.putShort(s); - munchIfFull(); - return this; - } - - @Override - public final Hasher putChar(char c) { - buffer.putChar(c); - munchIfFull(); - return this; - } - - @Override - public final Hasher putInt(int i) { - buffer.putInt(i); - munchIfFull(); - return this; - } - - @Override - public final Hasher putLong(long l) { - buffer.putLong(l); - munchIfFull(); - return this; - } - - @Override - public final Hasher putObject(T instance, Funnel funnel) { - funnel.funnel(instance, this); - return this; - } - - @Override - public final HashCode hash() { - munch(); - buffer.flip(); - if (buffer.remaining() > 0) { - processRemaining(buffer); - } - return makeHash(); - } - - abstract HashCode makeHash(); - - // Process pent-up data in chunks - private void munchIfFull() { - if (buffer.remaining() < 8) { - // buffer is full; not enough room for a primitive. We have at least one full chunk. - munch(); - } - } - - private void munch() { - buffer.flip(); - while (buffer.remaining() >= chunkSize) { - // we could limit the buffer to ensure process() does not read more than - // chunkSize number of bytes, but we trust the implementations - process(buffer); - } - buffer.compact(); // preserve any remaining data that do not make a full chunk - } - } -} diff --git a/thirdparty/google-guava/src/main/java/com/google/common/hash/BloomFilter.java b/thirdparty/google-guava/src/main/java/com/google/common/hash/BloomFilter.java deleted file mode 100644 index 4c70575ea099..000000000000 --- a/thirdparty/google-guava/src/main/java/com/google/common/hash/BloomFilter.java +++ /dev/null @@ -1,548 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.common.hash; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Objects; -import com.google.common.base.Predicate; -import com.google.common.hash.BloomFilterStrategies.BitArray; -import com.google.common.primitives.SignedBytes; -import com.google.common.primitives.UnsignedBytes; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Serializable; - -import javax.annotation.CheckReturnValue; -import javax.annotation.Nullable; - -/** - * A Bloom filter for instances of {@code T}. A Bloom filter offers an approximate containment test - * with one-sided error: if it claims that an element is contained in it, this might be in error, - * but if it claims that an element is not contained in it, then this is definitely true. - * - *

If you are unfamiliar with Bloom filters, this nice - * tutorial may help you understand - * how they work. - * - *

The false positive probability ({@code FPP}) of a bloom filter is defined as the probability - * that {@linkplain #mightContain(Object)} will erroneously return {@code true} for an object that - * has not actually been put in the {@code BloomFilter}. - * - *

Bloom filters are serializable. They also support a more compact serial representation via - * the {@link #writeTo} and {@link #readFrom} methods. Both serialized forms will continue to be - * supported by future versions of this library. However, serial forms generated by newer versions - * of the code may not be readable by older versions of the code (e.g., a serialized bloom filter - * generated today may not be readable by a binary that was compiled 6 months ago). - * - * @param the type of instances that the {@code BloomFilter} accepts - * @author Dimitris Andreou - * @author Kevin Bourrillion - * @since 11.0 - */ -@Beta -public final class BloomFilter implements Predicate, Serializable { - /** - * A strategy to translate T instances, to {@code numHashFunctions} bit indexes. - * - *

Implementations should be collections of pure functions (i.e. stateless). - */ - interface Strategy extends java.io.Serializable { - - /** - * Sets {@code numHashFunctions} bits of the given bit array, by hashing a user element. - * - *

Returns whether any bits changed as a result of this operation. - */ - boolean put(T object, Funnel funnel, int numHashFunctions, BitArray bits); - - /** - * Queries {@code numHashFunctions} bits of the given bit array, by hashing a user element; - * returns {@code true} if and only if all selected bits are set. - */ - boolean mightContain( - T object, Funnel funnel, int numHashFunctions, BitArray bits); - - /** - * Identifier used to encode this strategy, when marshalled as part of a BloomFilter. - * Only values in the [-128, 127] range are valid for the compact serial form. - * Non-negative values are reserved for enums defined in BloomFilterStrategies; - * negative values are reserved for any custom, stateful strategy we may define - * (e.g. any kind of strategy that would depend on user input). - */ - int ordinal(); - } - - /** The bit set of the BloomFilter (not necessarily power of 2!)*/ - private final BitArray bits; - - /** Number of hashes per element */ - private final int numHashFunctions; - - /** The funnel to translate Ts to bytes */ - private final Funnel funnel; - - /** - * The strategy we employ to map an element T to {@code numHashFunctions} bit indexes. - */ - private final Strategy strategy; - - /** - * Creates a BloomFilter. - */ - private BloomFilter( - BitArray bits, int numHashFunctions, Funnel funnel, Strategy strategy) { - checkArgument(numHashFunctions > 0, "numHashFunctions (%s) must be > 0", numHashFunctions); - checkArgument( - numHashFunctions <= 255, "numHashFunctions (%s) must be <= 255", numHashFunctions); - this.bits = checkNotNull(bits); - this.numHashFunctions = numHashFunctions; - this.funnel = checkNotNull(funnel); - this.strategy = checkNotNull(strategy); - } - - /** - * Creates a new {@code BloomFilter} that's a copy of this instance. The new instance is equal to - * this instance but shares no mutable state. - * - * @since 12.0 - */ - @CheckReturnValue - public BloomFilter copy() { - return new BloomFilter(bits.copy(), numHashFunctions, funnel, strategy); - } - - /** - * Returns {@code true} if the element might have been put in this Bloom filter, - * {@code false} if this is definitely not the case. - */ - @CheckReturnValue - public boolean mightContain(T object) { - return strategy.mightContain(object, funnel, numHashFunctions, bits); - } - - /** - * @deprecated Provided only to satisfy the {@link Predicate} interface; use {@link #mightContain} - * instead. - */ - @Deprecated - @Override - @CheckReturnValue - public boolean apply(T input) { - return mightContain(input); - } - - /** - * Puts an element into this {@code BloomFilter}. Ensures that subsequent invocations of - * {@link #mightContain(Object)} with the same element will always return {@code true}. - * - * @return true if the bloom filter's bits changed as a result of this operation. If the bits - * changed, this is definitely the first time {@code object} has been added to the - * filter. If the bits haven't changed, this might be the first time {@code object} - * has been added to the filter. Note that {@code put(t)} always returns the - * opposite result to what {@code mightContain(t)} would have returned at the time - * it is called." - * @since 12.0 (present in 11.0 with {@code void} return type}) - */ - public boolean put(T object) { - return strategy.put(object, funnel, numHashFunctions, bits); - } - - /** - * Returns the probability that {@linkplain #mightContain(Object)} will erroneously return - * {@code true} for an object that has not actually been put in the {@code BloomFilter}. - * - *

Ideally, this number should be close to the {@code fpp} parameter - * passed in {@linkplain #create(Funnel, int, double)}, or smaller. If it is - * significantly higher, it is usually the case that too many elements (more than - * expected) have been put in the {@code BloomFilter}, degenerating it. - * - * @since 14.0 (since 11.0 as expectedFalsePositiveProbability()) - */ - @CheckReturnValue - public double expectedFpp() { - // You down with FPP? (Yeah you know me!) Who's down with FPP? (Every last homie!) - return Math.pow((double) bits.bitCount() / bitSize(), numHashFunctions); - } - - /** - * Returns the number of bits in the underlying bit array. - */ - @VisibleForTesting - long bitSize() { - return bits.bitSize(); - } - - /** - * Determines whether a given bloom filter is compatible with this bloom filter. For two - * bloom filters to be compatible, they must: - * - *

See the Guava User Guide article on - * {@code Splitter}. - * - * @author Julien Silland - * @author Jesse Wilson - * @author Kevin Bourrillion - * @author Louis Wasserman - * @since 1.0 - */ -@GwtCompatible(emulated = true) -public final class Splitter { - private final CharMatcher trimmer; - private final boolean omitEmptyStrings; - private final Strategy strategy; - private final int limit; - - private Splitter(Strategy strategy) { - this(strategy, false, CharMatcher.NONE, Integer.MAX_VALUE); - } - - private Splitter(Strategy strategy, boolean omitEmptyStrings, CharMatcher trimmer, int limit) { - this.strategy = strategy; - this.omitEmptyStrings = omitEmptyStrings; - this.trimmer = trimmer; - this.limit = limit; - } - - /** - * Returns a splitter that uses the given single-character separator. For - * example, {@code Splitter.on(',').split("foo,,bar")} returns an iterable - * containing {@code ["foo", "", "bar"]}. - * - * @param separator the character to recognize as a separator - * @return a splitter, with default settings, that recognizes that separator - */ - @CheckReturnValue - public static Splitter on(char separator) { - return on(CharMatcher.is(separator)); - } - - /** - * Returns a splitter that considers any single character matched by the - * given {@code CharMatcher} to be a separator. For example, {@code - * Splitter.on(CharMatcher.anyOf(";,")).split("foo,;bar,quux")} returns an - * iterable containing {@code ["foo", "", "bar", "quux"]}. - * - * @param separatorMatcher a {@link CharMatcher} that determines whether a - * character is a separator - * @return a splitter, with default settings, that uses this matcher - */ - @CheckReturnValue - public static Splitter on(final CharMatcher separatorMatcher) { - checkNotNull(separatorMatcher); - - return new Splitter( - new Strategy() { - @Override - public SplittingIterator iterator(Splitter splitter, final CharSequence toSplit) { - return new SplittingIterator(splitter, toSplit) { - @Override - int separatorStart(int start) { - return separatorMatcher.indexIn(toSplit, start); - } - - @Override - int separatorEnd(int separatorPosition) { - return separatorPosition + 1; - } - }; - } - }); - } - - /** - * Returns a splitter that uses the given fixed string as a separator. For - * example, {@code Splitter.on(", ").split("foo, bar,baz")} returns an - * iterable containing {@code ["foo", "bar,baz"]}. - * - * @param separator the literal, nonempty string to recognize as a separator - * @return a splitter, with default settings, that recognizes that separator - */ - @CheckReturnValue - public static Splitter on(final String separator) { - checkArgument(separator.length() != 0, "The separator may not be the empty string."); - if (separator.length() == 1) { - return Splitter.on(separator.charAt(0)); - } - return new Splitter( - new Strategy() { - @Override - public SplittingIterator iterator(Splitter splitter, CharSequence toSplit) { - return new SplittingIterator(splitter, toSplit) { - @Override - public int separatorStart(int start) { - int separatorLength = separator.length(); - - positions: - for (int p = start, last = toSplit.length() - separatorLength; p <= last; p++) { - for (int i = 0; i < separatorLength; i++) { - if (toSplit.charAt(i + p) != separator.charAt(i)) { - continue positions; - } - } - return p; - } - return -1; - } - - @Override - public int separatorEnd(int separatorPosition) { - return separatorPosition + separator.length(); - } - }; - } - }); - } - - /** - * Returns a splitter that considers any subsequence matching {@code - * pattern} to be a separator. For example, {@code - * Splitter.on(Pattern.compile("\r?\n")).split(entireFile)} splits a string - * into lines whether it uses DOS-style or UNIX-style line terminators. - * - * @param separatorPattern the pattern that determines whether a subsequence - * is a separator. This pattern may not match the empty string. - * @return a splitter, with default settings, that uses this pattern - * @throws IllegalArgumentException if {@code separatorPattern} matches the - * empty string - */ - @CheckReturnValue - @GwtIncompatible("java.util.regex") - public static Splitter on(final Pattern separatorPattern) { - checkNotNull(separatorPattern); - checkArgument( - !separatorPattern.matcher("").matches(), - "The pattern may not match the empty string: %s", - separatorPattern); - - return new Splitter( - new Strategy() { - @Override - public SplittingIterator iterator(final Splitter splitter, CharSequence toSplit) { - final Matcher matcher = separatorPattern.matcher(toSplit); - return new SplittingIterator(splitter, toSplit) { - @Override - public int separatorStart(int start) { - return matcher.find(start) ? matcher.start() : -1; - } - - @Override - public int separatorEnd(int separatorPosition) { - return matcher.end(); - } - }; - } - }); - } - - /** - * Returns a splitter that considers any subsequence matching a given - * pattern (regular expression) to be a separator. For example, {@code - * Splitter.onPattern("\r?\n").split(entireFile)} splits a string into lines - * whether it uses DOS-style or UNIX-style line terminators. This is - * equivalent to {@code Splitter.on(Pattern.compile(pattern))}. - * - * @param separatorPattern the pattern that determines whether a subsequence - * is a separator. This pattern may not match the empty string. - * @return a splitter, with default settings, that uses this pattern - * @throws java.util.regex.PatternSyntaxException if {@code separatorPattern} - * is a malformed expression - * @throws IllegalArgumentException if {@code separatorPattern} matches the - * empty string - */ - @CheckReturnValue - @GwtIncompatible("java.util.regex") - public static Splitter onPattern(String separatorPattern) { - return on(Pattern.compile(separatorPattern)); - } - - /** - * Returns a splitter that divides strings into pieces of the given length. - * For example, {@code Splitter.fixedLength(2).split("abcde")} returns an - * iterable containing {@code ["ab", "cd", "e"]}. The last piece can be - * smaller than {@code length} but will never be empty. - * - *