Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.yangtools.util;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Verify;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.ImmutableSet;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
final class OffsetMapCache {
/*
* Cache for offsets where order matters. The key is a List, which defines the iteration order. Since we want
* to retain this order, it is okay to use a simple LoadingCache.
*/
private static final LoadingCache, ImmutableMap, Integer>> ORDERED_CACHE =
CacheBuilder.newBuilder().weakValues().build(new CacheLoader, ImmutableMap, Integer>>() {
@Override
public ImmutableMap, Integer> load(final List> key) {
return createMap(key);
}
});
/*
* Cache for offsets where order does not mapper. The key is a Set of elements. We use manual two-stage loading
* because of the nature of the objects we store as values, which is ImmutableMaps. An ImmutableMap, when queried
* for keys (as is done in ImmutableOffsetMap.keySet()), will instantiate an ImmutableSet to hold these keys. It
* would be wasteful to use one Set for lookup only to have the map have an exact copy.
*
* We perform the first look up using a Set (which may come from the user, for example via
* ImmutableOffsetMap.unorderedCopyOf()), hence potentially saving a copy operation. If we fail to find an entry,
* we construct the map and put it conditionally with Map.keySet() as the key. This will detect concurrent loading
* and also lead to the cache and the map sharing the same Set.
*/
private static final Cache, ImmutableMap, Integer>> UNORDERED_CACHE =
CacheBuilder.newBuilder().weakValues().build();
private OffsetMapCache() {
// Hidden on purpose
}
@VisibleForTesting
static void invalidateCache() {
ORDERED_CACHE.invalidateAll();
UNORDERED_CACHE.invalidateAll();
}
@SuppressWarnings("unchecked")
static ImmutableMap orderedOffsets(final Collection args) {
if (args.size() == 1) {
return unorderedOffsets(args);
}
return (ImmutableMap) ORDERED_CACHE.getUnchecked(ImmutableList.copyOf(args));
}
static ImmutableMap unorderedOffsets(final Collection args) {
return unorderedOffsets(args instanceof Set ? (Set)args : ImmutableSet.copyOf(args));
}
@SuppressWarnings("unchecked")
private static ImmutableMap unorderedOffsets(final Set args) {
final ImmutableMap existing = (ImmutableMap) UNORDERED_CACHE.getIfPresent(args);
if (existing != null) {
return existing;
}
final ImmutableMap newMap = createMap(args);
final ImmutableMap, Integer> raced = UNORDERED_CACHE.asMap().putIfAbsent(newMap.keySet(), newMap);
return raced == null ? newMap : (ImmutableMap)raced;
}
static V[] adjustedArray(final Map offsets, final List keys, final V[] array) {
Verify.verify(offsets.size() == keys.size(), "Offsets %s do not match keys %s", offsets, keys);
// This relies on the fact that offsets has an ascending iterator
final Iterator oi = offsets.keySet().iterator();
final Iterator ki = keys.iterator();
while (oi.hasNext()) {
final K o = oi.next();
final K k = ki.next();
if (!k.equals(o)) {
return adjustArray(offsets, keys, array);
}
}
return array;
}
private static ImmutableMap createMap(final Collection keys) {
final Builder b = ImmutableMap.builder();
int counter = 0;
for (T arg : keys) {
b.put(arg, counter++);
}
return b.build();
}
private static V[] adjustArray(final Map offsets, final List keys, final V[] array) {
@SuppressWarnings("unchecked")
final V[] ret = (V[]) Array.newInstance(array.getClass().getComponentType(), array.length);
int offset = 0;
for (final K k : keys) {
final Integer o = Verify.verifyNotNull(offsets.get(k), "Key %s not present in offsets %s", k, offsets);
ret[o] = array[offset++];
}
return ret;
}
}