/* * Copyright (c) 2006 Thomas Weise * * E-Mail : tweise@gmx.de * Creation Date : 2006-03-30 15:26:54 * Original Filename: org.dgpf.search.api.SearchCache.java * Version : 2.0.0 * Last modification: 2006-05-08 * by: Thomas Weise * * License : GNU LESSER GENERAL PUBLIC LICENSE * Version 2.1, February 1999 * You should have received a copy of this license along * with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307, USA or download the license under * http://www.gnu.org/copyleft/lesser.html. * * Warranty : This software is provided "as is" without any * warranty; without even the implied warranty of * merchantability or fitness for a particular purpose. * See the Gnu Lesser General Public License for more * details. */ package org.dgpf.search.api; import org.sfc.collections.Arrays; /** *
* Instances of this class represent a simple, synchronized set of objects.
* It helps you to find out if objects already exist by performing
* comparisons only based the equals
-method without using any
* hashcode or such and such.
*
* This simple set has a high parallelization potential. *
* TODO: revisit the set_size method * * @author Thomas Weise */ final class SearchCache { /** * The object cache. */ private Object[] m_cache ; /** * The insertion pointer. */ private int m_insert_ptr ; /** * The counter. */ private boolean m_full ; /** * The size parameter. */ private int m_size ; /** * Create a new object set/cache of the specified size. * @param p_size The size suggested for the cache. (This must be at least * 1). */ public SearchCache (int p_size) { super(); if(p_size < 1) p_size = 1; this.m_cache = new Object[p_size]; this.m_size = p_size; } /** * Check if a object has already been checked. * This method browses the internal cache to find the specified object. * If it could be found, the return value isfalse
.
* The object will be cached otherwise and true
will be
* returned.
*
* @param p_object The object to be checked.
* @return true
only if p_object
is likely to be
* a new object not checked already.
*/
public final boolean check (final Object p_object)
{
final int l_l;
final Object[] l_list;
int l_i, l_ip;
if(p_object == null) return false;
l_list = this.m_cache;
l_l = this.m_size;
synchronized(l_list)
{
l_ip = this.m_insert_ptr;
l_i = (this.m_full ? (l_l-1) : (l_ip-1));
}
for(; l_i >= 0; l_i--)
{
if(p_object.equals(l_list[l_i])) return false;
}
synchronized(l_list)
{
l_ip = this.m_insert_ptr;
if(l_ip >= l_l)
{
l_ip = 0;
this.m_full = true;
}
l_list[l_ip] = p_object;
this.m_insert_ptr = (l_ip+1);
}
return true;
}
/**
* Flush the cache; remove all its entries.
*/
public synchronized final void flush ()
{
Arrays.fill(this.m_cache, null);
this.m_insert_ptr = 0;
this.m_full = false;
}
/**
* Set the size of the simple set.
* @param p_size The new size parameter.
*/
public synchronized final void set_size (final int p_size)
{
int l_ci, l_cs, l_vi;
Object[] l_b;
l_b = this.m_cache;
l_ci = this.m_insert_ptr;
l_vi = (this.m_full ? this.m_size : l_ci);
if(p_size <= 0)
{
Arrays.fill(l_b, null, 0, l_vi);
this.m_size = 0;
this.m_full = false;
this.m_insert_ptr = 0;
}
else
{
l_cs = this.m_size;
if(l_cs != p_size)
{
if(p_size > l_cs)
{
if(p_size > l_b.length)
{
l_b = new Object[p_size << 1];
System.arraycopy(this.m_cache, 0, l_b, 0, l_vi);
this.m_cache = l_b;
}
if(this.m_full)
{
this.m_insert_ptr = l_vi;
this.m_full = false;
}
}
else
{
if(l_b.length > (3*p_size))
{
l_b = new Object[p_size];
System.arraycopy(this.m_cache, 0, l_b, 0, Math.min(p_size, l_vi));
this.m_cache = l_b;
}
this.m_insert_ptr = Math.min(l_ci, p_size);
}
this.m_size = p_size;
}
}
}
}