org.hd.d.pg2k.svrCore
Class Name.AdHocPrefixCache<TerminusKey extends java.lang.Number>

java.lang.Object
  extended by org.hd.d.pg2k.svrCore.Name.AdHocPrefixCache<TerminusKey>
Type Parameters:
TerminusKey - type of key for prefix of Name instances must be immutable and support consistent hashCode() and equals()
Enclosing class:
Name

private static final class Name.AdHocPrefixCache<TerminusKey extends java.lang.Number>
extends java.lang.Object

Contains lookup cache by prefix for all Name instances. This is used to try to find a prefix for a newly-constructed Name where no prefix has been supplied at all.

This looks up in a short list of recent/useful Name values with the same fixed-length prefix for something of the same concrete type and the longest available prefix match, returning the candidate 'prev' item (or null if none) which then can be used in the usual way.

The Name instances are held via WeakReference wrappers which should ensure that the cache does not keep them from being garbage collected.

This would usually be invoked by the factory method or constructor where no 'prev' has been supplied.

This cache should grow as needed to get a decent hit rate, and shrink to release memory when the hit rate is high or the memory subsystem is stressed.

Thread-safe but does not support concurrency (fully synchronized).

A lock can be held on instances of this object to make compound operations atomic.


Field Summary
private static int MAX_LIST_LEN
          Maximum list length under normal circumstances; strictly positive.
private static int MAX_SECONDARY_LIST_LEN
          Maximum secondary list length under normal circumstances; strictly positive.
private  MemoryTools.CacheMiniMap<TerminusKey,java.util.LinkedList<java.lang.ref.WeakReference<Name>>> prefixStore
          The lookup from prefix key to list of candidate same-prefix instances; never null.
private static int STRESSED_LIST_LEN
          Maximum list length under memory stress; strictly positive, less than MAX_LIST_LEN.
private  MemoryTools.CacheMiniMap<TerminusKey,java.util.LinkedList<java.lang.ref.WeakReference<Name>>> suffixStore
          The lookup from suffix key to list of candidate same-suffix instances; never null.
 
Constructor Summary
private Name.AdHocPrefixCache()
           
 
Method Summary
private static int computeCacheMaxSize()
          Compute maximum (prefix) cache size, partly based on heap size; strictly positive.
(package private)  Name findPrev(java.lang.CharSequence putativeName)
          Returns a suitable prev (with a shared prefix/suffix) for the supplied non-null Name of any Name subclass, else null if none found.
(package private)  int getMaxListLen(boolean isPrefix)
          Maximum same-prefix list length; strictly positive.
(package private)
<N extends Name>
N
offerNewInstance(N name)
          Offer a newly constructed Name instance to the cache; returns the value passed in.
private  void trimDeadRefs(java.util.List<java.lang.ref.WeakReference<Name>> l)
          Trim dead references from the supplied non-null list.
private  void trimListLength(java.util.LinkedList<java.lang.ref.WeakReference<Name>> l, boolean isPrefix)
          Trim the supplied non-null list to size if too long.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

prefixStore

private final MemoryTools.CacheMiniMap<TerminusKey extends java.lang.Number,java.util.LinkedList<java.lang.ref.WeakReference<Name>>> prefixStore
The lookup from prefix key to list of candidate same-prefix instances; never null. On each list may be items all of exactly one prefix or whose prefix hashes to the same value, depending on how the prefix key value is constructed.

Empty lists (or those effectively empty because all the WeakReferences have been dropped) will be purged (ie empty lists are not retained).

The lists values are of type LinkedList, with 'best' items first.

(In future, where a list is of length 1 and where the maximum length is currently 1, a list may be stored as a singleton for efficiency.)

We hope for a reasonable minimum size to have a sensible chance of any match at all across a large text base.

We size the maximum based on total heap capacity, and allow everything to be discarded in case of extreme memory stress.


suffixStore

private final MemoryTools.CacheMiniMap<TerminusKey extends java.lang.Number,java.util.LinkedList<java.lang.ref.WeakReference<Name>>> suffixStore
The lookup from suffix key to list of candidate same-suffix instances; never null. Lighter-weight than the prefixStore, and smaller, since suffix matching is a secondary activity.


MAX_LIST_LEN

private static final int MAX_LIST_LEN
Maximum list length under normal circumstances; strictly positive. Borrowing from GZIP '-6'/default experience a good value might be ~6.

See Also:
Constant Field Values

MAX_SECONDARY_LIST_LEN

private static final int MAX_SECONDARY_LIST_LEN
Maximum secondary list length under normal circumstances; strictly positive. Since suffix matching is secondary goal this is shorter than the general limit but should still probably be greater than 1.

See Also:
Constant Field Values

STRESSED_LIST_LEN

private static final int STRESSED_LIST_LEN
Maximum list length under memory stress; strictly positive, less than MAX_LIST_LEN. This will do a less good job of finding matches (ie will probably do less compaction) but will consume less memory in the ad-hoc cache.

Under stress, any entries we touch are capped to this length, thus allowing us to gracefully and incrementally free space.

Borrowing from GZIP '-1/'-fast' experience a good value might be 1.

See Also:
Constant Field Values
Constructor Detail

Name.AdHocPrefixCache

private Name.AdHocPrefixCache()
Method Detail

computeCacheMaxSize

private static int computeCacheMaxSize()
Compute maximum (prefix) cache size, partly based on heap size; strictly positive. Aim to allow ~10000 entries per 1GB of heap, with a minimum of several hundred.


findPrev

Name findPrev(java.lang.CharSequence putativeName)
Returns a suitable prev (with a shared prefix/suffix) for the supplied non-null Name of any Name subclass, else null if none found. May trim state, especially dead references.


offerNewInstance

<N extends Name> N offerNewInstance(N name)
Offer a newly constructed Name instance to the cache; returns the value passed in. Rejected if already at maximum chain length.

Returns:
the input name unchanged

trimDeadRefs

private void trimDeadRefs(java.util.List<java.lang.ref.WeakReference<Name>> l)
Trim dead references from the supplied non-null list.


trimListLength

private void trimListLength(java.util.LinkedList<java.lang.ref.WeakReference<Name>> l,
                            boolean isPrefix)
Trim the supplied non-null list to size if too long.


getMaxListLen

int getMaxListLen(boolean isPrefix)
Maximum same-prefix list length; strictly positive. This will drop to a smaller measure if memory is under stress.


DHD Multimedia Gallery V1.57.21

Copyright (c) 1996-2011, Damon Hart-Davis. All rights reserved.