
org.glassfish.pfl.dynamic.copyobject.impl.FastCache Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pfl-dynamic Show documentation
Show all versions of pfl-dynamic Show documentation
Functionality that may include class generation
/*
* Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0, which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.glassfish.pfl.dynamic.copyobject.impl;
import java.util.Set ;
import java.util.Map ;
import java.util.AbstractMap ;
/** A cache intended to help speed up access to a Map.
* The idea is that some maps have a few values that are retrieved
* more frequently than others. So, we create a fixed size array
* that holds keys and values, and do a very fast hash on the key's
* identityHashCode. The cache is backed by a map, which can be
* an IdentityHashMap, or any other map (such as a WeakHashMap)
* where the keys satisfy k1.equals(k2) implies k1 == k2.
* Note that all put operations MUST go through this class,
* because calling put on the underlying map can result in
* the cache returning incorrect results for get.
*/
public class FastCache extends AbstractMap {
public static final int TABLE_SIZE = 256 ; // must be a power of 2
private Map map ;
private Object[] keys = new Object[256] ;
private Object[] values = new Object[256] ;
private long cacheCount = 0 ;
private long totalCount = 0 ;
public long getCacheCount() {
return cacheCount ;
}
public long getTotalCount() {
return totalCount ;
}
public FastCache( Map map ) {
this.map = map ;
}
@Override
public Set> entrySet() {
return map.entrySet() ;
}
private int hash( Object key ) {
// int hv = key.hashCode() ;
int hv = System.identityHashCode( key ) ;
return hv & (TABLE_SIZE-1) ;
}
@Override
@SuppressWarnings("unchecked")
public V get( Object key ) {
totalCount++ ;
int slot = hash( key ) ;
@SuppressWarnings("unchecked")
K ckey = (K)keys[slot] ;
if (ckey == key ) {
cacheCount++ ;
return (V)values[slot] ;
} else {
V result = map.get( key ) ;
keys[slot] = key ;
values[slot] = result ;
return result ;
}
}
/** Put the key and value in the cache and the underlying
* map. This writes through to the map, rather than
* first storing a value in the cache which is only
* written as required, because that makes it easier
* to preserve the correct behavior of the map.
*/
@Override
public V put( K key, V value ) {
int slot = hash( key ) ;
keys[slot] = key ;
values[slot] = value ;
return map.put( key, value ) ;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy