/*
* 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;
import gnu.trove.map.hash.*;
import gnu.trove.set.hash.THashSet;
import org.elasticsearch.common.trove.ExtTDoubleObjectHashMap;
import org.elasticsearch.common.trove.ExtTHashMap;
import org.elasticsearch.common.trove.ExtTLongObjectHashMap;
import org.elasticsearch.common.util.concurrent.ConcurrentCollections;
import java.lang.ref.SoftReference;
import java.util.Arrays;
import java.util.Queue;
public class CacheRecycler {
public static void clear() {
hashMap.clear();
hashSet.clear();
doubleObjectHashMap.clear();
longObjectHashMap.clear();
longLongHashMap.clear();
intIntHashMap.clear();
floatIntHashMap.clear();
doubleIntHashMap.clear();
shortIntHashMap.clear();
longIntHashMap.clear();
objectIntHashMap.clear();
objectArray.clear();
intArray.clear();
}
static class SoftWrapper<T> {
private SoftReference<T> ref;
public SoftWrapper() {
}
public void set(T ref) {
this.ref = new SoftReference<T>(ref);
}
public T get() {
return ref == null ? null : ref.get();
}
public void clear() {
ref = null;
}
}
// ----- ExtTHashMap -----
private static SoftWrapper<Queue<ExtTHashMap>> hashMap = new SoftWrapper<Queue<ExtTHashMap>>();
public static <K, V> ExtTHashMap<K, V> popHashMap() {
Queue<ExtTHashMap> ref = hashMap.get();
if (ref == null) {
return new ExtTHashMap<K, V>();
}
ExtTHashMap map = ref.poll();
if (map == null) {
return new ExtTHashMap<K, V>();
}
return map;
}
public static void pushHashMap(ExtTHashMap map) {
Queue<ExtTHashMap> ref = hashMap.get();
if (ref == null) {
ref = ConcurrentCollections.newQueue();
hashMap.set(ref);
}
map.clear();
ref.add(map);
}
// ----- THashSet -----
private static SoftWrapper<Queue<THashSet>> hashSet = new SoftWrapper<Queue<THashSet>>();
public static <T> THashSet<T> popHashSet() {
Queue<THashSet> ref = hashSet.get();
if (ref == null) {
return new THashSet<T>();
}
THashSet set = ref.poll();
if (set == null) {
return new THashSet<T>();
}
return set;
}
public static void pushHashSet(THashSet map) {
Queue<THashSet> ref = hashSet.get();
if (ref == null) {
ref = ConcurrentCollections.newQueue();
hashSet.set(ref);
}
map.clear();
ref.add(map);
}
// ------ ExtTDoubleObjectHashMap -----
private static SoftWrapper<Queue<ExtTDoubleObjectHashMap>> doubleObjectHashMap = new SoftWrapper<Queue<ExtTDoubleObjectHashMap>>();
public static <T> ExtTDoubleObjectHashMap<T> popDoubleObjectMap() {
Queue<ExtTDoubleObjectHashMap> ref = doubleObjectHashMap.get();
if (ref == null) {
return new ExtTDoubleObjectHashMap();
}
ExtTDoubleObjectHashMap map = ref.poll();
if (map == null) {
return new ExtTDoubleObjectHashMap();
}
return map;
}
public static void pushDoubleObjectMap(ExtTDoubleObjectHashMap map) {
Queue<ExtTDoubleObjectHashMap> ref = doubleObjectHashMap.get();
if (ref == null) {
ref = ConcurrentCollections.newQueue();
doubleObjectHashMap.set(ref);
}
map.clear();
ref.add(map);
}
// ----- ExtTLongObjectHashMap ----
private static SoftWrapper<Queue<ExtTLongObjectHashMap>> longObjectHashMap = new SoftWrapper<Queue<ExtTLongObjectHashMap>>();
public static <T> ExtTLongObjectHashMap<T> popLongObjectMap() {
Queue<ExtTLongObjectHashMap> ref = longObjectHashMap.get();
if (ref == null) {
return new ExtTLongObjectHashMap();
}
ExtTLongObjectHashMap map = ref.poll();
if (map == null) {
return new ExtTLongObjectHashMap();
}
return map;
}
public static void pushLongObjectMap(ExtTLongObjectHashMap map) {
Queue<ExtTLongObjectHashMap> ref = longObjectHashMap.get();
if (ref == null) {
ref = ConcurrentCollections.newQueue();
longObjectHashMap.set(ref);
}
map.clear();
ref.add(map);
}
// ----- TLongLongHashMap ----
private static SoftWrapper<Queue<TLongLongHashMap>> longLongHashMap = new SoftWrapper<Queue<TLongLongHashMap>>();
public static TLongLongHashMap popLongLongMap() {
Queue<TLongLongHashMap> ref = longLongHashMap.get();
if (ref == null) {
return new TLongLongHashMap();
}
TLongLongHashMap map = ref.poll();
if (map == null) {
return new TLongLongHashMap();
}
return map;
}
public static void pushLongLongMap(TLongLongHashMap map) {
Queue<TLongLongHashMap> ref = longLongHashMap.get();
if (ref == null) {
ref = ConcurrentCollections.newQueue();
longLongHashMap.set(ref);
}
map.clear();
ref.add(map);
}
// ----- TIntIntHashMap ----
private static SoftWrapper<Queue<TIntIntHashMap>> intIntHashMap = new SoftWrapper<Queue<TIntIntHashMap>>();
public static TIntIntHashMap popIntIntMap() {
Queue<TIntIntHashMap> ref = intIntHashMap.get();
if (ref == null) {
return new TIntIntHashMap();
}
TIntIntHashMap map = ref.poll();
if (map == null) {
return new TIntIntHashMap();
}
return map;
}
public static void pushIntIntMap(TIntIntHashMap map) {
Queue<TIntIntHashMap> ref = intIntHashMap.get();
if (ref == null) {
ref = ConcurrentCollections.newQueue();
intIntHashMap.set(ref);
}
map.clear();
ref.add(map);
}
// ----- TFloatIntHashMap ---
private static SoftWrapper<Queue<TFloatIntHashMap>> floatIntHashMap = new SoftWrapper<Queue<TFloatIntHashMap>>();
public static TFloatIntHashMap popFloatIntMap() {
Queue<TFloatIntHashMap> ref = floatIntHashMap.get();
if (ref == null) {
return new TFloatIntHashMap();
}
TFloatIntHashMap map = ref.poll();
if (map == null) {
return new TFloatIntHashMap();
}
return map;
}
public static void pushFloatIntMap(TFloatIntHashMap map) {
Queue<TFloatIntHashMap> ref = floatIntHashMap.get();
if (ref == null) {
ref = ConcurrentCollections.newQueue();
floatIntHashMap.set(ref);
}
map.clear();
ref.add(map);
}
// ----- TDoubleIntHashMap ---
private static SoftWrapper<Queue<TDoubleIntHashMap>> doubleIntHashMap = new SoftWrapper<Queue<TDoubleIntHashMap>>();
public static TDoubleIntHashMap popDoubleIntMap() {
Queue<TDoubleIntHashMap> ref = doubleIntHashMap.get();
if (ref == null) {
return new TDoubleIntHashMap();
}
TDoubleIntHashMap map = ref.poll();
if (map == null) {
return new TDoubleIntHashMap();
}
return map;
}
public static void pushDoubleIntMap(TDoubleIntHashMap map) {
Queue<TDoubleIntHashMap> ref = doubleIntHashMap.get();
if (ref == null) {
ref = ConcurrentCollections.newQueue();
doubleIntHashMap.set(ref);
}
map.clear();
ref.add(map);
}
// ----- TByteIntHashMap ---
private static SoftWrapper<Queue<TByteIntHashMap>> byteIntHashMap = new SoftWrapper<Queue<TByteIntHashMap>>();
public static TByteIntHashMap popByteIntMap() {
Queue<TByteIntHashMap> ref = byteIntHashMap.get();
if (ref == null) {
return new TByteIntHashMap();
}
TByteIntHashMap map = ref.poll();
if (map == null) {
return new TByteIntHashMap();
}
return map;
}
public static void pushByteIntMap(TByteIntHashMap map) {
Queue<TByteIntHashMap> ref = byteIntHashMap.get();
if (ref == null) {
ref = ConcurrentCollections.newQueue();
byteIntHashMap.set(ref);
}
map.clear();
ref.add(map);
}
// ----- TShortIntHashMap ---
private static SoftWrapper<Queue<TShortIntHashMap>> shortIntHashMap = new SoftWrapper<Queue<TShortIntHashMap>>();
public static TShortIntHashMap popShortIntMap() {
Queue<TShortIntHashMap> ref = shortIntHashMap.get();
if (ref == null) {
return new TShortIntHashMap();
}
TShortIntHashMap map = ref.poll();
if (map == null) {
return new TShortIntHashMap();
}
return map;
}
public static void pushShortIntMap(TShortIntHashMap map) {
Queue<TShortIntHashMap> ref = shortIntHashMap.get();
if (ref == null) {
ref = ConcurrentCollections.newQueue();
shortIntHashMap.set(ref);
}
map.clear();
ref.add(map);
}
// ----- TLongIntHashMap ----
private static SoftWrapper<Queue<TLongIntHashMap>> longIntHashMap = new SoftWrapper<Queue<TLongIntHashMap>>();
public static TLongIntHashMap popLongIntMap() {
Queue<TLongIntHashMap> ref = longIntHashMap.get();
if (ref == null) {
return new TLongIntHashMap();
}
TLongIntHashMap map = ref.poll();
if (map == null) {
return new TLongIntHashMap();
}
return map;
}
public static void pushLongIntMap(TLongIntHashMap map) {
Queue<TLongIntHashMap> ref = longIntHashMap.get();
if (ref == null) {
ref = ConcurrentCollections.newQueue();
longIntHashMap.set(ref);
}
map.clear();
ref.add(map);
}
// ------ TObjectIntHashMap -----
private static SoftWrapper<Queue<TObjectIntHashMap>> objectIntHashMap = new SoftWrapper<Queue<TObjectIntHashMap>>();
@SuppressWarnings({"unchecked"})
public static <T> TObjectIntHashMap<T> popObjectIntMap() {
Queue<TObjectIntHashMap> ref = objectIntHashMap.get();
if (ref == null) {
return new TObjectIntHashMap();
}
TObjectIntHashMap map = ref.poll();
if (map == null) {
return new TObjectIntHashMap();
}
return map;
}
public static <T> void pushObjectIntMap(TObjectIntHashMap<T> map) {
Queue<TObjectIntHashMap> ref = objectIntHashMap.get();
if (ref == null) {
ref = ConcurrentCollections.newQueue();
objectIntHashMap.set(ref);
}
map.clear();
ref.add(map);
}
// ----- int[] -----
private static SoftWrapper<Queue<Object[]>> objectArray = new SoftWrapper<Queue<Object[]>>();
public static Object[] popObjectArray(int size) {
size = size < 100 ? 100 : size;
Queue<Object[]> ref = objectArray.get();
if (ref == null) {
return new Object[size];
}
Object[] objects = ref.poll();
if (objects == null) {
return new Object[size];
}
if (objects.length < size) {
return new Object[size];
}
return objects;
}
public static void pushObjectArray(Object[] objects) {
Queue<Object[]> ref = objectArray.get();
if (ref == null) {
ref = ConcurrentCollections.newQueue();
objectArray.set(ref);
}
Arrays.fill(objects, null);
ref.add(objects);
}
private static SoftWrapper<Queue<int[]>> intArray = new SoftWrapper<Queue<int[]>>();
public static int[] popIntArray(int size) {
return popIntArray(size, 0);
}
public static int[] popIntArray(int size, int sentinal) {
size = size < 100 ? 100 : size;
Queue<int[]> ref = intArray.get();
if (ref == null) {
int[] ints = new int[size];
if (sentinal != 0) {
Arrays.fill(ints, sentinal);
}
return ints;
}
int[] ints = ref.poll();
if (ints == null) {
ints = new int[size];
if (sentinal != 0) {
Arrays.fill(ints, sentinal);
}
return ints;
}
if (ints.length < size) {
ints = new int[size];
if (sentinal != 0) {
Arrays.fill(ints, sentinal);
}
return ints;
}
return ints;
}
public static void pushIntArray(int[] ints) {
pushIntArray(ints, 0);
}
public static void pushIntArray(int[] ints, int sentinal) {
Queue<int[]> ref = intArray.get();
if (ref == null) {
ref = ConcurrentCollections.newQueue();
intArray.set(ref);
}
Arrays.fill(ints, sentinal);
ref.add(ints);
}
}