org.hd.d.pg2k.svrCore
Class DuplicateIDChecker<K>

java.lang.Object
  extended by org.hd.d.pg2k.svrCore.DuplicateIDChecker<K>
All Implemented Interfaces:
MemoryTools.CacheMiniMap<K,java.lang.Long>, MemoryTools.Compactable

public final class DuplicateIDChecker<K>
extends java.lang.Object
implements MemoryTools.Compactable, MemoryTools.CacheMiniMap<K,java.lang.Long>

Mechanism to check for replayed/duplicate messages by ID within a specified time window. This provides an optional fixed upper size; attempts to insert more items than the ceiling capacity will result in old items being removed in age order regardless of age.

Other after meeting any size limit, this always keeps entries for a specified minimum time. Optionally a larger time window may be used if the the system is not starved of memory.

Thread-safe.

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

Does not support the full Map interface.

This aggressively trims dead/expired entries so as to minimise footprint.


Field Summary
static float DEFAULT_LOAD_FACTOR
          Default load factor.
private static boolean EAGER_UNLOAD
          If true then be eager (super-linear) in discarding entries as free memory declines.
private  java.util.LinkedHashMap<K,java.lang.Long> lhm
          Underlying LinkedHashMap on which this is based; never null.
private  int minRetentionMs
          Maximum age that we will retain IDs for (ms); strictly positive.
private  java.lang.String name
          Name of this instance for diagnostics purposes; null if none.
private  int preferredRetentionMs
          Optional higher maximum age that we will retain IDs for when there's plenty of memory available (ms); strictly positive.
 
Constructor Summary
private DuplicateIDChecker(int minRetentionMs, int preferredRetentionMs, int maxCapacity, float loadFactor, java.lang.String name)
          Create an instance with the given parameters.
 
Method Summary
 void _compact()
          Try to trim all dead entries to reduce memory footprint.
 java.lang.Long add(K key)
          Record an ID, returning the insertion time of the previous insertion of this ID if any.
 java.lang.Long ageOfOldestEntry()
          Returns the timestamp of the oldest entry currently in this Map, or null if none.
 void clear()
          Clear the structure.
 void compact()
          Try to trim all dead entries to reduce memory footprint.
 boolean containsKey(K key)
          Returns true if we have a mapping from the supplied key (message ID), false otherwise.
static
<K> DuplicateIDChecker<K>
create(int minRetentionMs, int preferredRetentionMs, int maxCapacity, float loadFactor, java.lang.String name)
          Create an instance with the given parameters.
static
<K> DuplicateIDChecker<K>
create(int minRetentionMs, int preferredRetentionMs, java.lang.String name)
          Create an instance with the given parameters.
static
<K> DuplicateIDChecker<K>
create(int minRetentionMs, java.lang.String name)
          Create an instance with the given parameters.
 java.lang.Long get(K key)
          Get an entry from the map; null if no such element.
 java.lang.String getCompactableInstanceName()
          Get name of this container instance for tracking purposes, or null if none.
private  boolean hasExpired(java.util.Map.Entry<K,java.lang.Long> entry)
          Returns true when an entry has expired and can be removed.
private  boolean hasExpired(java.util.Map.Entry<K,java.lang.Long> entry, long thresholdTime)
          Returns true when an entry has expired and can be removed.
 java.lang.Long put(K key, java.lang.Long value)
          Put an entry in the map, returning previous value if any.
 java.lang.Long remove(K key)
          Remove an ID and return the insertion time of the removed ID, if any, else null.
 int size()
          Return the number of non-expired IDs held; non-negative.
private  long thresholdTime()
          Compute threshold time for entry expiry.
 java.lang.String toString()
          Provide a human-readable summary of status.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

DEFAULT_LOAD_FACTOR

public static final float DEFAULT_LOAD_FACTOR
Default load factor.

See Also:
Constant Field Values

lhm

private final java.util.LinkedHashMap<K,java.lang.Long> lhm
Underlying LinkedHashMap on which this is based; never null.


minRetentionMs

private final int minRetentionMs
Maximum age that we will retain IDs for (ms); strictly positive.


preferredRetentionMs

private final int preferredRetentionMs
Optional higher maximum age that we will retain IDs for when there's plenty of memory available (ms); strictly positive. Ignored unless higher than minRetentionMs.


name

private final java.lang.String name
Name of this instance for diagnostics purposes; null if none.


EAGER_UNLOAD

private static final boolean EAGER_UNLOAD
If true then be eager (super-linear) in discarding entries as free memory declines. Unless the retained items are especially large this can be false.

See Also:
Constant Field Values
Constructor Detail

DuplicateIDChecker

private DuplicateIDChecker(int minRetentionMs,
                           int preferredRetentionMs,
                           int maxCapacity,
                           float loadFactor,
                           java.lang.String name)
Create an instance with the given parameters.

Parameters:
minRetentionMs - the minimum time that we will keep an ID for (ms); strictly positive
preferredRetentionMs - preferred time to retain entries if there is lots of free memory and ineffective/ignored unless larger than minRetentionMs; strictly positive
maxCapacity - the maximum capacity; strictly positive
loadFactor - the load factor of the underlying hash table; in the range 0.0f to 1.0f exclusive (typically ~0.7f)
Method Detail

getCompactableInstanceName

public java.lang.String getCompactableInstanceName()
Get name of this container instance for tracking purposes, or null if none.

Specified by:
getCompactableInstanceName in interface MemoryTools.Compactable

create

public static <K> DuplicateIDChecker<K> create(int minRetentionMs,
                                               java.lang.String name)
Create an instance with the given parameters. The standard default is used for the load factor, and the map size is effectively unlimited.

Parameters:
minRetentionMs - the minimum time that we will keep an ID for (ms); strictly positive
name - name of this instance for diagnostics purposes; null if none

create

public static <K> DuplicateIDChecker<K> create(int minRetentionMs,
                                               int preferredRetentionMs,
                                               java.lang.String name)
Create an instance with the given parameters. The standard default is used for the load factor, and the map size is effectively unlimited.

Parameters:
minRetentionMs - the minimum time that we will keep an ID for (ms); strictly positive
preferredRetentionMs - preferred time to retain entries if there is plenty of free memory and ineffective/ignored unless larger than minRetentionMs; strictly positive
name - name of this instance for diagnostics purposes; null if none

create

public static <K> DuplicateIDChecker<K> create(int minRetentionMs,
                                               int preferredRetentionMs,
                                               int maxCapacity,
                                               float loadFactor,
                                               java.lang.String name)
Create an instance with the given parameters.

Parameters:
minRetentionMs - the minimum time that we will keep an ID for (ms); strictly positive
preferredRetentionMs - preferred time to retain entries if there is plenty of free memory and ineffective/ignored unless larger than minRetentionMs; strictly positive
maxCapacity - the maximum capacity; strictly positive
loadFactor - the load factor of the underlying hash table; in the range 0.0f to 1.0f exclusive (typically ~0.7f)
name - name of this instance for diagnostics purposes; null if none

compact

public void compact()
Try to trim all dead entries to reduce memory footprint. Will attempt to minimise memory footprint.

Specified by:
compact in interface MemoryTools.Compactable

_compact

public void _compact()
Try to trim all dead entries to reduce memory footprint. Will attempt to minimise memory footprint.

Must only be called while the instance lock is held.


containsKey

public boolean containsKey(K key)
Returns true if we have a mapping from the supplied key (message ID), false otherwise. This is equivalent to checking if this is a duplicate message.

This ignores expired values and does not add anything to the collection.


add

public java.lang.Long add(K key)
Record an ID, returning the insertion time of the previous insertion of this ID if any.


remove

public java.lang.Long remove(K key)
Remove an ID and return the insertion time of the removed ID, if any, else null.

Specified by:
remove in interface MemoryTools.CacheMiniMap<K,java.lang.Long>

ageOfOldestEntry

public java.lang.Long ageOfOldestEntry()
Returns the timestamp of the oldest entry currently in this Map, or null if none.


clear

public void clear()
Clear the structure.

Specified by:
clear in interface MemoryTools.CacheMiniMap<K,java.lang.Long>

size

public int size()
Return the number of non-expired IDs held; non-negative.

Specified by:
size in interface MemoryTools.CacheMiniMap<K,java.lang.Long>

toString

public java.lang.String toString()
Provide a human-readable summary of status. Useful for debugging/tuning, for example.

Overrides:
toString in class java.lang.Object

hasExpired

private boolean hasExpired(java.util.Map.Entry<K,java.lang.Long> entry,
                           long thresholdTime)
Returns true when an entry has expired and can be removed.

Parameters:
entry - full entry including the timestamp; never null
thresholdTime - expiry threshold time to use, an older entry should be expired

thresholdTime

private long thresholdTime()
Compute threshold time for entry expiry. Lifetime drops as free space falls beneath our target.

This retains more entries if there is more visibly-free heap (though this may give up entries eagerly, ie faster than linear) so that transients are less likely to discard a slow-to-recover window.


hasExpired

private boolean hasExpired(java.util.Map.Entry<K,java.lang.Long> entry)
Returns true when an entry has expired and can be removed. Computes the expiry threshold itself, so is suitable for one-off expiry attempts.

Parameters:
entry - full entry including the timestamp; never null

get

public java.lang.Long get(K key)
Description copied from interface: MemoryTools.CacheMiniMap
Get an entry from the map; null if no such element.

Specified by:
get in interface MemoryTools.CacheMiniMap<K,java.lang.Long>

put

public java.lang.Long put(K key,
                          java.lang.Long value)
Description copied from interface: MemoryTools.CacheMiniMap
Put an entry in the map, returning previous value if any.

Specified by:
put in interface MemoryTools.CacheMiniMap<K,java.lang.Long>

DHD Multimedia Gallery V1.57.21

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