com.google.firebase.database.collection.ImmutableSortedMap Maven / Gradle / Ivy
/*
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.firebase.database.collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public abstract class ImmutableSortedMap implements Iterable> {
public abstract boolean containsKey(K key);
public abstract V get(K key);
public abstract ImmutableSortedMap remove(K key);
public abstract ImmutableSortedMap insert(K key, V value);
public abstract K getMinKey();
public abstract K getMaxKey();
public abstract int size();
public abstract boolean isEmpty();
public abstract void inOrderTraversal(LLRBNode.NodeVisitor visitor);
public abstract Iterator> iterator();
public abstract Iterator> iteratorFrom(K key);
public abstract Iterator> reverseIteratorFrom(K key);
public abstract Iterator> reverseIterator();
public abstract K getPredecessorKey(K key);
public abstract K getSuccessorKey(K key);
public abstract Comparator getComparator();
@Override
@SuppressWarnings("unchecked")
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof ImmutableSortedMap)) {
return false;
}
ImmutableSortedMap that = (ImmutableSortedMap) o;
if (!this.getComparator().equals(that.getComparator())) {
return false;
}
if (this.size() != that.size()) {
return false;
}
Iterator> thisIterator = this.iterator();
Iterator> thatIterator = that.iterator();
while (thisIterator.hasNext()) {
if (!thisIterator.next().equals(thatIterator.next())) {
return false;
}
}
return true;
}
@Override
public int hashCode() {
int result = this.getComparator().hashCode();
for (Map.Entry entry : this) {
result = 31 * result + entry.hashCode();
}
return result;
}
public String toString() {
StringBuilder b = new StringBuilder();
b.append(this.getClass().getSimpleName());
b.append("{");
boolean first = true;
for (Map.Entry entry : this) {
if (first) {
first = false;
} else {
b.append(", ");
}
b.append("(");
b.append(entry.getKey());
b.append("=>");
b.append(entry.getValue());
b.append(")");
}
b.append("};");
return b.toString();
}
public static class Builder {
/**
* The size threshold where we use a tree backed sorted map instead of an array backed sorted
* map. This is a more or less arbitrary chosen value, that was chosen to be large enough to fit
* most of object kind of Database data, but small enough to not notice degradation in
* performance for inserting and lookups. Feel free to empirically determine this constant, but
* don't expect much gain in real world performance.
*/
static final int ARRAY_TO_RB_TREE_SIZE_THRESHOLD = 25;
private static final KeyTranslator IDENTITY_TRANSLATOR =
new KeyTranslator() {
@Override
public Object translate(Object key) {
return key;
}
};
public static ImmutableSortedMap emptyMap(Comparator comparator) {
return new ArraySortedMap<>(comparator);
}
@SuppressWarnings("unchecked")
public static KeyTranslator identityTranslator() {
return IDENTITY_TRANSLATOR;
}
public static ImmutableSortedMap fromMap(
Map values, Comparator comparator) {
if (values.size() < ARRAY_TO_RB_TREE_SIZE_THRESHOLD) {
return ArraySortedMap.fromMap(values, comparator);
} else {
return RBTreeSortedMap.fromMap(values, comparator);
}
}
public static ImmutableSortedMap buildFrom(
List keys,
Map values,
ImmutableSortedMap.Builder.KeyTranslator translator,
Comparator comparator) {
if (keys.size() < ARRAY_TO_RB_TREE_SIZE_THRESHOLD) {
return ArraySortedMap.buildFrom(keys, values, translator, comparator);
} else {
return RBTreeSortedMap.buildFrom(keys, values, translator, comparator);
}
}
public interface KeyTranslator {
D translate(C key);
}
}
}