introduce a native int/long open immutable map, and use it in in routing table
This commit is contained in:
parent
1dc8c079da
commit
809e870b8d
|
@ -19,6 +19,9 @@
|
||||||
|
|
||||||
package org.elasticsearch.cluster.routing;
|
package org.elasticsearch.cluster.routing;
|
||||||
|
|
||||||
|
import com.carrotsearch.hppc.cursors.IntCursor;
|
||||||
|
import com.carrotsearch.hppc.cursors.IntObjectCursor;
|
||||||
|
import com.carrotsearch.hppc.cursors.LongObjectCursor;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
@ -26,6 +29,8 @@ import com.google.common.collect.UnmodifiableIterator;
|
||||||
import org.elasticsearch.ElasticSearchIllegalStateException;
|
import org.elasticsearch.ElasticSearchIllegalStateException;
|
||||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||||
import org.elasticsearch.cluster.metadata.MetaData;
|
import org.elasticsearch.cluster.metadata.MetaData;
|
||||||
|
import org.elasticsearch.common.collect.ImmutableOpenIntMap;
|
||||||
|
import org.elasticsearch.common.collect.ImmutableOpenLongMap;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.index.shard.ShardId;
|
import org.elasticsearch.index.shard.ShardId;
|
||||||
|
@ -57,20 +62,20 @@ public class IndexRoutingTable implements Iterable<IndexShardRoutingTable> {
|
||||||
|
|
||||||
// note, we assume that when the index routing is created, ShardRoutings are created for all possible number of
|
// note, we assume that when the index routing is created, ShardRoutings are created for all possible number of
|
||||||
// shards with state set to UNASSIGNED
|
// shards with state set to UNASSIGNED
|
||||||
private final ImmutableMap<Integer, IndexShardRoutingTable> shards;
|
private final ImmutableOpenIntMap<IndexShardRoutingTable> shards;
|
||||||
|
|
||||||
private final ImmutableList<ShardRouting> allShards;
|
private final ImmutableList<ShardRouting> allShards;
|
||||||
private final ImmutableList<ShardRouting> allActiveShards;
|
private final ImmutableList<ShardRouting> allActiveShards;
|
||||||
|
|
||||||
private final AtomicInteger counter = new AtomicInteger();
|
private final AtomicInteger counter = new AtomicInteger();
|
||||||
|
|
||||||
IndexRoutingTable(String index, Map<Integer, IndexShardRoutingTable> shards) {
|
IndexRoutingTable(String index, ImmutableOpenIntMap<IndexShardRoutingTable> shards) {
|
||||||
this.index = index;
|
this.index = index;
|
||||||
this.shards = ImmutableMap.copyOf(shards);
|
this.shards = shards;
|
||||||
ImmutableList.Builder<ShardRouting> allShards = ImmutableList.builder();
|
ImmutableList.Builder<ShardRouting> allShards = ImmutableList.builder();
|
||||||
ImmutableList.Builder<ShardRouting> allActiveShards = ImmutableList.builder();
|
ImmutableList.Builder<ShardRouting> allActiveShards = ImmutableList.builder();
|
||||||
for (IndexShardRoutingTable indexShardRoutingTable : shards.values()) {
|
for (IntObjectCursor<IndexShardRoutingTable> cursor : shards) {
|
||||||
for (ShardRouting shardRouting : indexShardRoutingTable) {
|
for (ShardRouting shardRouting : cursor.value) {
|
||||||
allShards.add(shardRouting);
|
allShards.add(shardRouting);
|
||||||
if (shardRouting.active()) {
|
if (shardRouting.active()) {
|
||||||
allActiveShards.add(shardRouting);
|
allActiveShards.add(shardRouting);
|
||||||
|
@ -107,8 +112,8 @@ public class IndexRoutingTable implements Iterable<IndexShardRoutingTable> {
|
||||||
*/
|
*/
|
||||||
public IndexRoutingTable normalizeVersions() {
|
public IndexRoutingTable normalizeVersions() {
|
||||||
IndexRoutingTable.Builder builder = new Builder(this.index);
|
IndexRoutingTable.Builder builder = new Builder(this.index);
|
||||||
for (IndexShardRoutingTable shardTable : shards.values()) {
|
for (IntObjectCursor<IndexShardRoutingTable> cursor : shards) {
|
||||||
builder.addIndexShard(shardTable.normalizeVersions());
|
builder.addIndexShard(cursor.value.normalizeVersions());
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
@ -147,7 +152,7 @@ public class IndexRoutingTable implements Iterable<IndexShardRoutingTable> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UnmodifiableIterator<IndexShardRoutingTable> iterator() {
|
public UnmodifiableIterator<IndexShardRoutingTable> iterator() {
|
||||||
return shards.values().iterator();
|
return shards.valuesIt();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -182,11 +187,11 @@ public class IndexRoutingTable implements Iterable<IndexShardRoutingTable> {
|
||||||
return nodes.size();
|
return nodes.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImmutableMap<Integer, IndexShardRoutingTable> shards() {
|
public ImmutableOpenIntMap<IndexShardRoutingTable> shards() {
|
||||||
return shards;
|
return shards;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImmutableMap<Integer, IndexShardRoutingTable> getShards() {
|
public ImmutableOpenIntMap<IndexShardRoutingTable> getShards() {
|
||||||
return shards();
|
return shards();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,7 +312,7 @@ public class IndexRoutingTable implements Iterable<IndexShardRoutingTable> {
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
|
||||||
private final String index;
|
private final String index;
|
||||||
private final Map<Integer, IndexShardRoutingTable> shards = new HashMap<Integer, IndexShardRoutingTable>();
|
private final ImmutableOpenIntMap.Builder<IndexShardRoutingTable> shards = ImmutableOpenIntMap.builder();
|
||||||
|
|
||||||
public Builder(String index) {
|
public Builder(String index) {
|
||||||
this.index = index;
|
this.index = index;
|
||||||
|
@ -410,7 +415,8 @@ public class IndexRoutingTable implements Iterable<IndexShardRoutingTable> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder addReplica() {
|
public Builder addReplica() {
|
||||||
for (int shardId : shards.keySet()) {
|
for (IntCursor cursor : shards.keys()) {
|
||||||
|
int shardId = cursor.value;
|
||||||
// version 0, will get updated when reroute will happen
|
// version 0, will get updated when reroute will happen
|
||||||
ImmutableShardRouting shard = new ImmutableShardRouting(index, shardId, null, false, ShardRoutingState.UNASSIGNED, 0);
|
ImmutableShardRouting shard = new ImmutableShardRouting(index, shardId, null, false, ShardRoutingState.UNASSIGNED, 0);
|
||||||
shards.put(shardId,
|
shards.put(shardId,
|
||||||
|
@ -421,7 +427,8 @@ public class IndexRoutingTable implements Iterable<IndexShardRoutingTable> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder removeReplica() {
|
public Builder removeReplica() {
|
||||||
for (int shardId : shards.keySet()) {
|
for (IntCursor cursor : shards.keys()) {
|
||||||
|
int shardId = cursor.value;
|
||||||
IndexShardRoutingTable indexShard = shards.get(shardId);
|
IndexShardRoutingTable indexShard = shards.get(shardId);
|
||||||
if (indexShard.replicaShards().isEmpty()) {
|
if (indexShard.replicaShards().isEmpty()) {
|
||||||
// nothing to do here!
|
// nothing to do here!
|
||||||
|
@ -486,7 +493,7 @@ public class IndexRoutingTable implements Iterable<IndexShardRoutingTable> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public IndexRoutingTable build() throws RoutingValidationException {
|
public IndexRoutingTable build() throws RoutingValidationException {
|
||||||
IndexRoutingTable indexRoutingTable = new IndexRoutingTable(index, ImmutableMap.copyOf(shards));
|
IndexRoutingTable indexRoutingTable = new IndexRoutingTable(index, shards.build());
|
||||||
indexRoutingTable.validate();
|
indexRoutingTable.validate();
|
||||||
return indexRoutingTable;
|
return indexRoutingTable;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,329 @@
|
||||||
|
/*
|
||||||
|
* Licensed to ElasticSearch and Shay Banon under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. ElasticSearch licenses this
|
||||||
|
* file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.common.collect;
|
||||||
|
|
||||||
|
import com.carrotsearch.hppc.*;
|
||||||
|
import com.carrotsearch.hppc.cursors.IntCursor;
|
||||||
|
import com.carrotsearch.hppc.cursors.IntObjectCursor;
|
||||||
|
import com.carrotsearch.hppc.cursors.ObjectCursor;
|
||||||
|
import com.carrotsearch.hppc.predicates.IntPredicate;
|
||||||
|
import com.carrotsearch.hppc.procedures.IntObjectProcedure;
|
||||||
|
import com.google.common.collect.UnmodifiableIterator;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An immutable map implementation based on open hash map.
|
||||||
|
* <p/>
|
||||||
|
* Can be constructed using a {@link #builder()}, or using {@link #builder(org.elasticsearch.common.collect.ImmutableOpenIntMap)} (which is an optimized
|
||||||
|
* option to copy over existing content and modify it).
|
||||||
|
*/
|
||||||
|
public final class ImmutableOpenIntMap<VType> implements Iterable<IntObjectCursor<VType>> {
|
||||||
|
|
||||||
|
private final IntObjectOpenHashMap<VType> map;
|
||||||
|
|
||||||
|
private ImmutableOpenIntMap(IntObjectOpenHashMap<VType> map) {
|
||||||
|
this.map = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the value associated with the given key or the default value
|
||||||
|
* for the key type, if the key is not associated with any value.
|
||||||
|
* <p/>
|
||||||
|
* <b>Important note:</b> For primitive type values, the value returned for a non-existing
|
||||||
|
* key may not be the default value of the primitive type (it may be any value previously
|
||||||
|
* assigned to that slot).
|
||||||
|
*/
|
||||||
|
public VType get(int key) {
|
||||||
|
return map.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> if this container has an association to a value for
|
||||||
|
* the given key.
|
||||||
|
*/
|
||||||
|
public boolean containsKey(int key) {
|
||||||
|
return map.containsKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the current size (number of assigned keys) in the container.
|
||||||
|
*/
|
||||||
|
public int size() {
|
||||||
|
return map.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Return <code>true</code> if this hash map contains no assigned keys.
|
||||||
|
*/
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return map.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a cursor over the entries (key-value pairs) in this map. The iterator is
|
||||||
|
* implemented as a cursor and it returns <b>the same cursor instance</b> on every
|
||||||
|
* call to {@link java.util.Iterator#next()}. To read the current key and value use the cursor's
|
||||||
|
* public fields. An example is shown below.
|
||||||
|
* <pre>
|
||||||
|
* for (IntShortCursor c : intShortMap)
|
||||||
|
* {
|
||||||
|
* System.out.println("index=" + c.index
|
||||||
|
* + " key=" + c.key
|
||||||
|
* + " value=" + c.value);
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
* <p/>
|
||||||
|
* <p>The <code>index</code> field inside the cursor gives the internal index inside
|
||||||
|
* the container's implementation. The interpretation of this index depends on
|
||||||
|
* to the container.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Iterator<IntObjectCursor<VType>> iterator() {
|
||||||
|
return map.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a specialized view of the keys of this associated container.
|
||||||
|
* The view additionally implements {@link com.carrotsearch.hppc.ObjectLookupContainer}.
|
||||||
|
*/
|
||||||
|
public IntLookupContainer keys() {
|
||||||
|
return map.keys();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a direct iterator over the keys.
|
||||||
|
*/
|
||||||
|
public UnmodifiableIterator<Integer> keysIt() {
|
||||||
|
final Iterator<IntCursor> iterator = map.keys().iterator();
|
||||||
|
return new UnmodifiableIterator<Integer>() {
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return iterator.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer next() {
|
||||||
|
return iterator.next().value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns a container with all values stored in this map.
|
||||||
|
*/
|
||||||
|
public ObjectContainer<VType> values() {
|
||||||
|
return map.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a direct iterator over the keys.
|
||||||
|
*/
|
||||||
|
public UnmodifiableIterator<VType> valuesIt() {
|
||||||
|
final Iterator<ObjectCursor<VType>> iterator = map.values().iterator();
|
||||||
|
return new UnmodifiableIterator<VType>() {
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return iterator.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VType next() {
|
||||||
|
return iterator.next().value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return map.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
ImmutableOpenIntMap that = (ImmutableOpenIntMap) o;
|
||||||
|
|
||||||
|
if (!map.equals(that.map)) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return map.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static final ImmutableOpenIntMap EMPTY = new ImmutableOpenIntMap(new IntObjectOpenHashMap());
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <VType> ImmutableOpenIntMap<VType> of() {
|
||||||
|
return EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <VType> Builder<VType> builder() {
|
||||||
|
return new Builder<VType>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <VType> Builder<VType> builder(int size) {
|
||||||
|
return new Builder<VType>(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <VType> Builder<VType> builder(ImmutableOpenIntMap<VType> map) {
|
||||||
|
return new Builder<VType>(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder<VType> implements IntObjectMap<VType> {
|
||||||
|
|
||||||
|
private IntObjectOpenHashMap<VType> map;
|
||||||
|
|
||||||
|
public Builder() {
|
||||||
|
//noinspection unchecked
|
||||||
|
this(EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder(int size) {
|
||||||
|
this.map = new IntObjectOpenHashMap<VType>(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder(ImmutableOpenIntMap<VType> map) {
|
||||||
|
this.map = map.map.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a new instance of the
|
||||||
|
*/
|
||||||
|
public ImmutableOpenIntMap<VType> build() {
|
||||||
|
IntObjectOpenHashMap<VType> map = this.map;
|
||||||
|
this.map = null; // nullify the map, so any operation post build will fail! (hackish, but safest)
|
||||||
|
return new ImmutableOpenIntMap<VType>(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts all the entries in the map to the builder.
|
||||||
|
*/
|
||||||
|
public Builder<VType> putAll(Map<Integer, VType> map) {
|
||||||
|
for (Map.Entry<Integer, VType> entry : map.entrySet()) {
|
||||||
|
this.map.put(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A put operation that can be used in the fluent pattern.
|
||||||
|
*/
|
||||||
|
public Builder<VType> fPut(int key, VType value) {
|
||||||
|
map.put(key, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VType put(int key, VType value) {
|
||||||
|
return map.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VType get(int key) {
|
||||||
|
return map.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VType getOrDefault(int kType, VType vType) {
|
||||||
|
return map.getOrDefault(kType, vType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove that can be used in the fluent pattern.
|
||||||
|
*/
|
||||||
|
public Builder<VType> fRemove(int key) {
|
||||||
|
map.remove(key);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VType remove(int key) {
|
||||||
|
return map.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<IntObjectCursor<VType>> iterator() {
|
||||||
|
return map.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsKey(int key) {
|
||||||
|
return map.containsKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return map.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return map.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
map.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int putAll(IntObjectAssociativeContainer<? extends VType> container) {
|
||||||
|
return map.putAll(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int putAll(Iterable<? extends IntObjectCursor<? extends VType>> iterable) {
|
||||||
|
return map.putAll(iterable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int removeAll(IntContainer container) {
|
||||||
|
return map.removeAll(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int removeAll(IntPredicate predicate) {
|
||||||
|
return map.removeAll(predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends IntObjectProcedure<? super VType>> T forEach(T procedure) {
|
||||||
|
return map.forEach(procedure);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IntCollection keys() {
|
||||||
|
return map.keys();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectContainer<VType> values() {
|
||||||
|
return map.values();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,329 @@
|
||||||
|
/*
|
||||||
|
* Licensed to ElasticSearch and Shay Banon under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. ElasticSearch licenses this
|
||||||
|
* file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.common.collect;
|
||||||
|
|
||||||
|
import com.carrotsearch.hppc.*;
|
||||||
|
import com.carrotsearch.hppc.cursors.LongCursor;
|
||||||
|
import com.carrotsearch.hppc.cursors.LongObjectCursor;
|
||||||
|
import com.carrotsearch.hppc.cursors.ObjectCursor;
|
||||||
|
import com.carrotsearch.hppc.predicates.LongPredicate;
|
||||||
|
import com.carrotsearch.hppc.procedures.LongObjectProcedure;
|
||||||
|
import com.google.common.collect.UnmodifiableIterator;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An immutable map implementation based on open hash map.
|
||||||
|
* <p/>
|
||||||
|
* Can be constructed using a {@link #builder()}, or using {@link #builder(org.elasticsearch.common.collect.ImmutableOpenLongMap)} (which is an optimized
|
||||||
|
* option to copy over existing content and modify it).
|
||||||
|
*/
|
||||||
|
public final class ImmutableOpenLongMap<VType> implements Iterable<LongObjectCursor<VType>> {
|
||||||
|
|
||||||
|
private final LongObjectOpenHashMap<VType> map;
|
||||||
|
|
||||||
|
private ImmutableOpenLongMap(LongObjectOpenHashMap<VType> map) {
|
||||||
|
this.map = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the value associated with the given key or the default value
|
||||||
|
* for the key type, if the key is not associated with any value.
|
||||||
|
* <p/>
|
||||||
|
* <b>Important note:</b> For primitive type values, the value returned for a non-existing
|
||||||
|
* key may not be the default value of the primitive type (it may be any value previously
|
||||||
|
* assigned to that slot).
|
||||||
|
*/
|
||||||
|
public VType get(long key) {
|
||||||
|
return map.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> if this container has an association to a value for
|
||||||
|
* the given key.
|
||||||
|
*/
|
||||||
|
public boolean containsKey(long key) {
|
||||||
|
return map.containsKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the current size (number of assigned keys) in the container.
|
||||||
|
*/
|
||||||
|
public int size() {
|
||||||
|
return map.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Return <code>true</code> if this hash map contains no assigned keys.
|
||||||
|
*/
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return map.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a cursor over the entries (key-value pairs) in this map. The iterator is
|
||||||
|
* implemented as a cursor and it returns <b>the same cursor instance</b> on every
|
||||||
|
* call to {@link java.util.Iterator#next()}. To read the current key and value use the cursor's
|
||||||
|
* public fields. An example is shown below.
|
||||||
|
* <pre>
|
||||||
|
* for (IntShortCursor c : intShortMap)
|
||||||
|
* {
|
||||||
|
* System.out.println("index=" + c.index
|
||||||
|
* + " key=" + c.key
|
||||||
|
* + " value=" + c.value);
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
* <p/>
|
||||||
|
* <p>The <code>index</code> field inside the cursor gives the internal index inside
|
||||||
|
* the container's implementation. The interpretation of this index depends on
|
||||||
|
* to the container.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Iterator<LongObjectCursor<VType>> iterator() {
|
||||||
|
return map.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a specialized view of the keys of this associated container.
|
||||||
|
* The view additionally implements {@link com.carrotsearch.hppc.ObjectLookupContainer}.
|
||||||
|
*/
|
||||||
|
public LongLookupContainer keys() {
|
||||||
|
return map.keys();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a direct iterator over the keys.
|
||||||
|
*/
|
||||||
|
public UnmodifiableIterator<Long> keysIt() {
|
||||||
|
final Iterator<LongCursor> iterator = map.keys().iterator();
|
||||||
|
return new UnmodifiableIterator<Long>() {
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return iterator.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long next() {
|
||||||
|
return iterator.next().value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns a container with all values stored in this map.
|
||||||
|
*/
|
||||||
|
public ObjectContainer<VType> values() {
|
||||||
|
return map.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a direct iterator over the keys.
|
||||||
|
*/
|
||||||
|
public UnmodifiableIterator<VType> valuesIt() {
|
||||||
|
final Iterator<ObjectCursor<VType>> iterator = map.values().iterator();
|
||||||
|
return new UnmodifiableIterator<VType>() {
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return iterator.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VType next() {
|
||||||
|
return iterator.next().value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return map.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
ImmutableOpenLongMap that = (ImmutableOpenLongMap) o;
|
||||||
|
|
||||||
|
if (!map.equals(that.map)) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return map.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static final ImmutableOpenLongMap EMPTY = new ImmutableOpenLongMap(new LongObjectOpenHashMap());
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <VType> ImmutableOpenLongMap<VType> of() {
|
||||||
|
return EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <VType> Builder<VType> builder() {
|
||||||
|
return new Builder<VType>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <VType> Builder<VType> builder(int size) {
|
||||||
|
return new Builder<VType>(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <VType> Builder<VType> builder(ImmutableOpenLongMap<VType> map) {
|
||||||
|
return new Builder<VType>(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder<VType> implements LongObjectMap<VType> {
|
||||||
|
|
||||||
|
private LongObjectOpenHashMap<VType> map;
|
||||||
|
|
||||||
|
public Builder() {
|
||||||
|
//noinspection unchecked
|
||||||
|
this(EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder(int size) {
|
||||||
|
this.map = new LongObjectOpenHashMap<VType>(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder(ImmutableOpenLongMap<VType> map) {
|
||||||
|
this.map = map.map.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a new instance of the
|
||||||
|
*/
|
||||||
|
public ImmutableOpenLongMap<VType> build() {
|
||||||
|
LongObjectOpenHashMap<VType> map = this.map;
|
||||||
|
this.map = null; // nullify the map, so any operation post build will fail! (hackish, but safest)
|
||||||
|
return new ImmutableOpenLongMap<VType>(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts all the entries in the map to the builder.
|
||||||
|
*/
|
||||||
|
public Builder<VType> putAll(Map<Long, VType> map) {
|
||||||
|
for (Map.Entry<Long, VType> entry : map.entrySet()) {
|
||||||
|
this.map.put(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A put operation that can be used in the fluent pattern.
|
||||||
|
*/
|
||||||
|
public Builder<VType> fPut(long key, VType value) {
|
||||||
|
map.put(key, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VType put(long key, VType value) {
|
||||||
|
return map.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VType get(long key) {
|
||||||
|
return map.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VType getOrDefault(long kType, VType vType) {
|
||||||
|
return map.getOrDefault(kType, vType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove that can be used in the fluent pattern.
|
||||||
|
*/
|
||||||
|
public Builder<VType> fRemove(long key) {
|
||||||
|
map.remove(key);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VType remove(long key) {
|
||||||
|
return map.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<LongObjectCursor<VType>> iterator() {
|
||||||
|
return map.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsKey(long key) {
|
||||||
|
return map.containsKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return map.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return map.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
map.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int putAll(LongObjectAssociativeContainer<? extends VType> container) {
|
||||||
|
return map.putAll(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int putAll(Iterable<? extends LongObjectCursor<? extends VType>> iterable) {
|
||||||
|
return map.putAll(iterable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int removeAll(LongContainer container) {
|
||||||
|
return map.removeAll(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int removeAll(LongPredicate predicate) {
|
||||||
|
return map.removeAll(predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends LongObjectProcedure<? super VType>> T forEach(T procedure) {
|
||||||
|
return map.forEach(procedure);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LongCollection keys() {
|
||||||
|
return map.keys();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectContainer<VType> values() {
|
||||||
|
return map.values();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue