/*
* Sun Public License
*
* The contents of this file are subject to the Sun Public License Version
* 1.0 (the "License"). You may not use this file except in compliance with
* the License. A copy of the License is available at http://www.sun.com/
*
* The Original Code is the SLAMD Distributed Load Generation Engine.
* The Initial Developer of the Original Code is Neil A. Wilson.
* Portions created by Neil A. Wilson are Copyright (C) 2004-2010.
* Some preexisting portions Copyright (C) 2002-2006 Sun Microsystems, Inc.
* All Rights Reserved.
*
* Contributor(s): Neil A. Wilson
*/
package com.slamd.tools.makeldif;
import java.util.HashMap;
import java.util.TreeSet;
/**
* This class maintains up to four lists of string values (one each for the
* equality, subInitial, subAny, and subFinal values). The values will be
* sorted automatically by the underlying implementation.
*
*
* @author Neil A. Wilson
*/
public class UniqueSortedList
{
// Indicates whether an equality list will be maintained.
private boolean maintainEqualityList;
// Indicates whether the list will need to keep track of the number of
// entries that match a given filter.
private boolean maintainMatchCount;
// Indicates whether a subAny list will be maintained.
private boolean maintainSubAnyList;
// Indicates whether a subInitial list will be maintained.
private boolean maintainSubInitialList;
// Indicates whether a subFinal list will be maintained.
private boolean maintainSubFinalList;
// Indicates whether all substring types will be maintained.
private boolean maintainSubstringList;
// The hash map used to count the number of entries matching each equality
// filter.
private HashMap<String,Integer> eqMatchCount;
// The hash map used to count the number of entries matching each subAny
// filter.
private HashMap<String,Integer> subAnyMatchCount;
// The hash map used to count the number of entries matching each subInitial
// filter.
private HashMap<String,Integer> subInitialMatchCount;
// The hash map used to count the number of entries matching each subFinal
// filter.
private HashMap<String,Integer> subFinalMatchCount;
// The maximum number of matches required before a filter will be included in
// the filter list.
private int maxMatches;
// The minimum number of matches required before a filter will be included in
// the filter list.
private int minMatches;
// The number of characters to include in substring filters.
private int substringLength;
// The set that will be used to hold the equality values.
private TreeSet<String> eqValues;
// The set that will be used to hold the subAny values.
private TreeSet<String> subAnyValues;
// The set that will be used to hold the subInitial values.
private TreeSet<String> subInitialValues;
// The set that will be used to hold the subFinal values.
private TreeSet<String> subFinalValues;
/**
* Creates a new unique sorted list with no elements.
*
* @param maintainEqualityList Indicates whether the equality list will be
* maintained.
* @param maintainSubstringList Indicates whether the all substring types
* will be maintained.
* @param maintainSubInitialList Indicates whether the subInitial list will
* be maintained.
* @param maintainSubAnyList Indicates whether the subAny list will be
* maintained.
* @param maintainSubFinalList Indicates whether the subFinal list will be
* maintained.
*/
public UniqueSortedList(boolean maintainEqualityList,
boolean maintainSubstringList,
boolean maintainSubInitialList,
boolean maintainSubAnyList,
boolean maintainSubFinalList)
{
this.maintainEqualityList = maintainEqualityList;
this.maintainSubstringList = maintainSubstringList;
this.maintainSubInitialList = maintainSubInitialList;
this.maintainSubAnyList = maintainSubAnyList;
this.maintainSubFinalList = maintainSubFinalList;
this.eqValues = new TreeSet<String>();
this.subInitialValues = new TreeSet<String>();
this.subAnyValues = new TreeSet<String>();
this.subFinalValues = new TreeSet<String>();
}
/**
* Specifies the criteria to use when determining how to create the filters.
*
* @param substringLength The number of characters to include in
* substring filters.
* @param minMatches The minimum number of entries that will
* need to match a filter before it should be
* output.
* @param maxMatches The maximum number of entries that will be
* allowed to match a filter for it to be
* output.
*/
public void setMatchCriteria(int substringLength, int minMatches,
int maxMatches)
{
if (substringLength < 1)
{
substringLength = 3;
}
this.substringLength = substringLength;
if (minMatches < 1)
{
minMatches = 1;
}
this.minMatches = minMatches;
if (maxMatches <= minMatches)
{
maxMatches = Integer.MAX_VALUE;
}
this.maxMatches = maxMatches;
if ((minMatches > 1) || (maxMatches > 0))
{
maintainMatchCount = true;
eqMatchCount = new HashMap<String,Integer>();
subAnyMatchCount = new HashMap<String,Integer>();
subInitialMatchCount = new HashMap<String,Integer>();
subFinalMatchCount = new HashMap<String,Integer>();
}
}
/**
* Adds the specified string value to this list if it is not already present.
*
* @param stringValue The string value to be added to this list.
*/
public void addString(String stringValue)
{
if (maintainEqualityList)
{
if (maintainMatchCount)
{
Integer currentCount = eqMatchCount.get(stringValue);
int count;
if (currentCount == null)
{
count = 1;
}
else
{
count = currentCount + 1;
}
eqMatchCount.put(stringValue, count);
if ((count >= minMatches) && (count <= maxMatches))
{
eqValues.add(stringValue);
}
else
{
eqValues.remove(stringValue);
}
}
else
{
eqValues.add(stringValue);
}
}
if (stringValue.length() >= substringLength)
{
if (maintainSubInitialList)
{
if (maintainMatchCount)
{
String subInitialValue = stringValue.substring(0, substringLength);
Integer currentCount = subInitialMatchCount.get(subInitialValue);
int count;
if (currentCount == null)
{
count = 1;
}
else
{
count = currentCount + 1;
}
subInitialMatchCount.put(subInitialValue, count);
if ((count >= minMatches) && (count <= maxMatches))
{
subInitialValues.add(subInitialValue);
}
else
{
subInitialValues.remove(subInitialValue);
}
}
else
{
subInitialValues.add(stringValue.substring(0, substringLength));
}
}
if (maintainSubFinalList)
{
if (maintainMatchCount)
{
String subFinalValue = stringValue.substring(stringValue.length() -
substringLength,
stringValue.length());
Integer currentCount = subFinalMatchCount.get(subFinalValue);
int count;
if (currentCount == null)
{
count = 1;
}
else
{
count = currentCount + 1;
}
subFinalMatchCount.put(subFinalValue, count);
if ((count >= minMatches) && (count <= maxMatches))
{
subFinalValues.add(subFinalValue);
}
else
{
subFinalValues.remove(subFinalValue);
}
}
else
{
subFinalValues.add(stringValue.substring(stringValue.length() -
substringLength,
stringValue.length()));
}
}
if (maintainSubAnyList)
{
int endPos = stringValue.length() - substringLength;
for (int j=0,k=substringLength; j <= endPos; j++,k++)
{
if (maintainMatchCount)
{
String subString = stringValue.substring(j, k);
Integer currentCount = subAnyMatchCount.get(subString);
int count;
if (currentCount == null)
{
count = 1;
}
else
{
count = currentCount + 1;
}
subAnyMatchCount.put(subString, count);
if ((count >= minMatches) && (count <= maxMatches))
{
subAnyValues.add(subString);
}
else
{
subAnyValues.remove(subString);
}
}
else
{
subAnyValues.add(stringValue.substring(j, k));
}
}
}
}
}
/**
* Indicates whether the equality list is maintained.
*
* @return <CODE>true</CODE> if the equality list is maintained, or
* <CODE>false</CODE> if not.
*/
public boolean maintainEqualityList()
{
return maintainEqualityList;
}
/**
* Indicates whether the lists for all substring types are maintained.
*
* @return <CODE>true</CODE> if the lists for all substring types are
* maintained, or <CODE>false</CODE> if not.
*/
public boolean maintainSubstringList()
{
return maintainSubstringList;
}
/**
* Indicates whether the subInitial list is maintained.
*
* @return <CODE>true</CODE> if the subInitial list is maintained, or
* <CODE>false</CODE> if not.
*/
public boolean maintainSubInitialList()
{
return maintainSubInitialList;
}
/**
* Indicates whether the subAny list is maintained.
*
* @return <CODE>true</CODE> if the subAny list is maintained, or
* <CODE>false</CODE> if not.
*/
public boolean maintainSubAnyList()
{
return maintainSubAnyList;
}
/**
* Indicates whether the subFinal list is maintained.
*
* @return <CODE>true</CODE> if the subFinal list is maintained, or
* <CODE>false</CODE> if not.
*/
public boolean maintainSubFinalList()
{
return maintainSubFinalList;
}
/**
* Retrieves the string values contained in the equality list.
*
* @return The string values contained in the equality list.
*/
public String[] getEqualityValues()
{
String[] values = new String[eqValues.size()];
eqValues.toArray(values);
return values;
}
/**
* Retrieves the string values contained in the subInitial list.
*
* @return The string values contained in the subInitial list.
*/
public String[] getSubInitialValues()
{
String[] values = new String[subInitialValues.size()];
subInitialValues.toArray(values);
return values;
}
/**
* Retrieves the string values contained in the subAny list.
*
* @return The string values contained in the subAny list.
*/
public String[] getSubAnyValues()
{
String[] values = new String[subAnyValues.size()];
subAnyValues.toArray(values);
return values;
}
/**
* Retrieves the string values contained in the subFinal list.
*
* @return The string values contained in the subFinal list.
*/
public String[] getSubFinalValues()
{
String[] values = new String[subFinalValues.size()];
subFinalValues.toArray(values);
return values;
}
}