/*
* 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.ldifstructure;
import java.util.Iterator;
import java.util.TreeMap;
/**
* This class defines a data structure that holds information about a given
* attribute that may be associated with an LDIF entry type.
*
*
* @author Neil A. Wilson
*/
public class LDIFAttributeInfo
{
/**
* The maximum number of characters that will be allowed for a unique value.
*/
public static final int MAX_UNIQUE_VALUE_LENGTH = 25;
/**
* The maximum number of unique values that should be maintained.
*/
public static final int MAX_UNIQUE_VALUES = 100;
// The number of times that at least one value for this attribute was present
// in an entry of the associated type.
private int numEntries;
// The number of unique values for this attribute across all entries.
private int numUniqueValues;
// The total number of values for this attribute across all entries.
private int numValues;
// The total number of characters across all values in all entries.
private long numCharacters;
// The name of the attribute for this attribute info structure.
private String attributeName;
// A mapping between the individual values for this attribute and the number
// of occurrences for each.
private TreeMap<String,Integer> valueCounts;
/**
* Creates a new LDIF attribute info structure based on the information in
* the provided attribute.
*
* @param attribute The LDIF attribute to use to create this attribute info
* structure.
*/
public LDIFAttributeInfo(LDIFAttribute attribute)
{
attributeName = attribute.getLowerName();
valueCounts = new TreeMap<String,Integer>();
numEntries = 1;
numValues = 0;
numUniqueValues = 0;
numCharacters = 0;
Iterator iterator = attribute.getValues().iterator();
while (iterator.hasNext())
{
String s = (String) iterator.next();
String lowerValue = LDIFReader.toLowerCase(s);
numValues++;
numCharacters += s.length();
if (s.length() > MAX_UNIQUE_VALUE_LENGTH)
{
numUniqueValues = -1;
continue;
}
if (numUniqueValues >= 0)
{
Integer count = valueCounts.get(lowerValue);
if (count == null)
{
numUniqueValues++;
valueCounts.put(lowerValue, 1);
}
else
{
valueCounts.put(lowerValue, (count + 1));
}
}
}
}
/**
* Creates a new LDIF attribute info structure with the provided information.
*
* @param attributeName The name of the attribute.
* @param numEntries The number of entries in which this attribute
* exists.
* @param numValues The total number of values for this attribute
* across all entries.
* @param numCharacters The total number of characters across all values
* in all entries.
* @param numUniqueValues The number of unique values for this attribute.
* @param valueCounts The map correlating the unique values for this
* attribute with the number of occurrences for each.
*/
LDIFAttributeInfo(String attributeName, int numEntries, int numValues,
long numCharacters, int numUniqueValues,
TreeMap<String,Integer> valueCounts)
{
this.attributeName = attributeName;
this.numEntries = numEntries;
this.numValues = numValues;
this.numCharacters = numCharacters;
this.numUniqueValues = numUniqueValues;
this.valueCounts = valueCounts;
}
/**
* Updates this attribute info structure with information from the provided
* attribute.
*
* @param attribute The attribute to use to create this attribute info
* structure.
*/
public void update(LDIFAttribute attribute)
{
numEntries++;
Iterator iterator = attribute.getValues().iterator();
while (iterator.hasNext())
{
String s = (String) iterator.next();
if (s.length() > MAX_UNIQUE_VALUE_LENGTH)
{
numUniqueValues = -1;
}
if (numUniqueValues >= 0)
{
String lowerValue = LDIFReader.toLowerCase(s);
Integer count = valueCounts.get(lowerValue);
if (count == null)
{
numUniqueValues++;
if (numUniqueValues > MAX_UNIQUE_VALUES)
{
numUniqueValues = -1;
}
else
{
valueCounts.put(lowerValue, 1);
}
}
else
{
valueCounts.put(lowerValue, (count + 1));
}
}
numValues++;
numCharacters += s.length();
}
}
/**
* Retrieves the name of the attribute with which this attribute info
* structure is associated.
*
* @return The name of the attribute with which this attribute info structure
* is associated.
*/
public String getAttributeName()
{
return attributeName;
}
/**
* Retrieves the number of entries processed that have at least one value for
* this attribute.
*
* @return The number of entries processed that have at least one value for
* this attribute.
*/
public int getNumEntries()
{
return numEntries;
}
/**
* Retrieves the total number of values for the specified attribute across all
* entries processed.
*
* @return The total number of values for the specified attribute across all
* entries processed.
*/
public int getNumValues()
{
return numValues;
}
/**
* Retrieves the average number of values for this attribute in entries that
* contain at least one value (i.e., it does not take into account entries
* that do not have any values for this attribute).
*
* @return The average number of values for this attribute in entries that
* contain at least one value.
*/
public double getAverageValuesPerEntry()
{
return (1.0 * numValues / numEntries);
}
/**
* Retrieves the total number of characters contained in all values for the
* associated attribute.
*
* @return The total number of characters contained in all values for the
* associated attribute.
*/
public long getNumCharacters()
{
return numCharacters;
}
/**
* Retrieves the average number of characters contained in each value for the
* associated attribute.
*
* @return The average number of characters contained in each value for the
* associated attribute.
*/
public double getAverageCharactersPerValue()
{
return (1.0 * numCharacters / numValues);
}
/**
* Retrieves the number of unique values for this attribute.
*
* @return The number of unique values for this attribute, or -1 if the
* maximum number of allowed unique values has been exceeded.
*/
public double getNumUniqueValues()
{
return numUniqueValues;
}
/**
* Retrieves a map correlating the unique values for this attribute and the
* number of entries in which each of those values appear. The contents of
* the returned map must not be considered reliable if
* <CODE>getNumUniqueValues</CODE> returns a negative value.
*
* @return A map correlating the unique values for this attribute and the
* number of entries in which each of those values appear.
*/
public TreeMap<String,Integer> getUniqueValues()
{
return valueCounts;
}
/**
* Creates a copy of this LDIF attribute info structure.
*
* @return A copy of this LDIF attribute info struture.
*/
public Object clone()
{
TreeMap<String,Integer> mapClone = new TreeMap<String,Integer>(valueCounts);
return new LDIFAttributeInfo(attributeName, numEntries, numValues,
numCharacters, numUniqueValues, mapClone);
}
/**
* Aggregates the information in the provided attribute info structure with
* this version.
*
* @param attributeInfo The attribute info structure containing the data to
* aggregate.
*/
public void aggregate(LDIFAttributeInfo attributeInfo)
{
numEntries += attributeInfo.numEntries;
numValues += attributeInfo.numValues;
numCharacters += attributeInfo.numCharacters;
if (attributeInfo.numUniqueValues < 0)
{
numUniqueValues = -1;
}
if (numUniqueValues > 0)
{
Iterator iterator = attributeInfo.valueCounts.keySet().iterator();
while (iterator.hasNext())
{
String s = (String) iterator.next();
Integer currentCount = valueCounts.get(s);
Integer providedCount = attributeInfo.valueCounts.get(s);
if (currentCount != null)
{
valueCounts.put(s, (currentCount + providedCount));
}
else
{
numUniqueValues++;
if (numUniqueValues > MAX_UNIQUE_VALUES)
{
numUniqueValues = -1;
}
else
{
valueCounts.put(s, providedCount);
}
}
}
}
}
}