Skip to content

Commit

Permalink
TEIIDDES-305: Adds in statistics for performance optimisation
Browse files Browse the repository at this point in the history
* To optimise the query, the distinct value and null value counts are
  required. These properties can be set using the searches already
  conducted when displaying the child attributes in the column page tree

* Adds fields to LdapAttributeNode for the null value count, distinct value
  count and maximum length of the attribute's values.
  • Loading branch information
Paul Richardson committed Oct 11, 2013
1 parent 455dbc2 commit edd5ac2
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 23 deletions.
Expand Up @@ -39,8 +39,6 @@
* The Model Builder for creating the physical model for LDAP services.
*/
public class RelationalModelBuilder {
// private final LdapImportWizardManager importManager;

private RelationalFactory factory;

private DatatypeManager datatypeManager;
Expand Down Expand Up @@ -85,14 +83,15 @@ private void modelEntry(ILdapEntryNode entry, ModelResource entryModel) throws E
entryTable.getColumns().add(attrColumn);
attrColumn.setName(attribute.getLabel());
attrColumn.setNameInSource(attribute.getId());
attrColumn.setLength(32768);
attrColumn.setNullValueCount(attribute.getNullValueCount());
attrColumn.setDistinctValueCount(attribute.getDistinctValueCount());
attrColumn.setLength(attribute.getMaximumValueLength());

attrColumn.setType(datatypeManager.getBuiltInDatatype(DatatypeConstants.BuiltInNames.STRING));
attrColumn.setNullable(NullableType.NULLABLE_UNKNOWN_LITERAL);
attrColumn.setCaseSensitive(true);
attrColumn.setRadix(0);
attrColumn.setSigned(false);
attrColumn.setDistinctValueCount(0);
attrColumn.setNullValueCount(0);
attrColumn.setType(datatypeManager.getBuiltInDatatype(DatatypeConstants.BuiltInNames.STRING));
}
}

Expand Down
Expand Up @@ -100,6 +100,9 @@ LdapColumnsPage_description=The tree displays the selected entries and the attri
LdapColumnsPage_columnAttributesTitle=Source Model Column Attributes
LdapColumnsPage_detailColumnNameLabel=Column Name
LdapColumnsPage_detailColumnSourceNameLabel=Column Source Name
LdapColumnsPage_detailColumnDVCountLabel=Column Distinct Value Count
LdapColumnsPage_detailColumnNVCountLabel=Column Null Value Count
LdapColumnsPage_detailMaxValueLabel=Column Length
LdapColumnsPage_sourceColumnsIncomplete=Not all selected source model tables contain columns

#=================================================================================================================================
Expand Down
Expand Up @@ -12,6 +12,11 @@
*/
public interface ILdapAttributeNode {

/**
* Value used for the default length
*/
int DEFAULT_VALUE_LENGTH = 32768;

/**
* @return the id
*/
Expand All @@ -31,4 +36,31 @@ public interface ILdapAttributeNode {
* @param label
*/
void setLabel(String label);

/**
* @return distinct value count
*/
int getDistinctValueCount();

/**
* Increment the null value count
*/
void incrementNullValueCount();

/**
* @return null value count
*/
int getNullValueCount();

/**
* Add a value of this attribute. Used for calculation of a distinct value count
*
* @param value
*/
void addValue(Object value);

/**
* @return the length of the longest value
*/
int getMaximumValueLength();
}
Expand Up @@ -7,6 +7,8 @@
*/
package org.teiid.designer.modelgenerator.ldap.ui.wizards.impl;

import java.util.HashSet;
import java.util.Set;
import javax.naming.directory.Attribute;
import org.teiid.designer.modelgenerator.ldap.ui.wizards.ILdapAttributeNode;
import org.teiid.designer.modelgenerator.ldap.ui.wizards.ILdapEntryNode;
Expand All @@ -22,6 +24,12 @@ public class LdapAttributeNode implements ILdapAttributeNode {

private final ILdapEntryNode associatedEntry;

private int nullValueCount;

private Set<Object> values = new HashSet<Object>();

private int maxValueLength = 0;

/**
* @param associatedEntry
* @param attribute
Expand Down Expand Up @@ -58,6 +66,42 @@ public void setLabel(String label) {
this.label = label;
}

@Override
public void incrementNullValueCount() {
++nullValueCount;
}

@Override
public int getNullValueCount() {
if (nullValueCount == 0)
return -1; // Supposed to return this for no null values

return this.nullValueCount;
}

@Override
public void addValue(Object value) {
if (value == null)
return;

boolean added = values.add(value);
if(added)
maxValueLength = Math.max(maxValueLength, value.toString().length());
}

@Override
public int getDistinctValueCount() {
return values.size();
}

@Override
public int getMaximumValueLength() {
if (maxValueLength == 0)
return DEFAULT_VALUE_LENGTH;

return maxValueLength ;
}

@Override
public int hashCode() {
final int prime = 31;
Expand Down
Expand Up @@ -33,6 +33,7 @@
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
Expand All @@ -58,6 +59,8 @@ public class LdapColumnsPage extends WizardPage
implements IChangeListener, ModelGeneratorLdapUiConstants, ModelGeneratorLdapUiConstants.Images,
ModelGeneratorLdapUiConstants.HelpContexts {

private static final String NULL_STRING = ""; //$NON-NLS-1$

private static final int[] SPLITTER_WEIGHTS = new int[] {30, 70};

private final LdapImportWizardManager importManager;
Expand All @@ -73,6 +76,12 @@ public class LdapColumnsPage extends WizardPage

private Text columnSourceNameText;

private Text columnDVCountText;

private Text columnNVCountText;

private Text columnMaxValueText;

private boolean synchronising;

/**
Expand Down Expand Up @@ -109,10 +118,16 @@ private void nodeSelected( final Object node ) {
columnNameText.setText(attributeNode.getLabel());
columnNameText.setEditable(true);
columnSourceNameText.setText(attributeNode.getId());
columnDVCountText.setText(Integer.toString(attributeNode.getDistinctValueCount()));
columnNVCountText.setText(Integer.toString(attributeNode.getNullValueCount()));
columnMaxValueText.setText(Integer.toString(attributeNode.getMaximumValueLength()));
} else {
columnNameText.setText(""); //$NON-NLS-1$
columnNameText.setText(NULL_STRING);
columnNameText.setEditable(false);
columnSourceNameText.setText(""); //$NON-NLS-1$
columnSourceNameText.setText(NULL_STRING);
columnDVCountText.setText(NULL_STRING);
columnNVCountText.setText(NULL_STRING);
columnMaxValueText.setText(NULL_STRING);
}
}

Expand Down Expand Up @@ -160,6 +175,16 @@ private void deselectAllButtonSelected() {
}
}

private void setNonEditable(Text control) {
if (control == null)
return;

Display display = control.getDisplay();
control.setForeground(display.getSystemColor(SWT.COLOR_DARK_BLUE));
control.setBackground(display.getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW));
control.setEditable(false);
}

@Override
public void createControl(Composite parent) {
// Create page
Expand Down Expand Up @@ -270,8 +295,8 @@ public void treeExpanded(TreeExpansionEvent e) {

detailsView.setContent(detailsGroup);

Label tableNameLabel = new Label(detailsGroup, SWT.NONE);
tableNameLabel.setText(getString("detailColumnNameLabel")); //$NON-NLS-1$
Label columnNameLabel = new Label(detailsGroup, SWT.NONE);
columnNameLabel.setText(getString("detailColumnNameLabel")); //$NON-NLS-1$

columnNameText = new Text(detailsGroup, SWT.BORDER | SWT.SINGLE);
GridDataFactory.fillDefaults().grab(true, false).applyTo(columnNameText);
Expand All @@ -297,14 +322,33 @@ public void modifyText(ModifyEvent e) {
}
});

Label tableSourceNameLabel = new Label(detailsGroup, SWT.NONE);
tableSourceNameLabel.setText(getString("detailColumnSourceNameLabel")); //$NON-NLS-1$
Label columnSourceNameLabel = new Label(detailsGroup, SWT.NONE);
columnSourceNameLabel.setText(getString("detailColumnSourceNameLabel")); //$NON-NLS-1$

columnSourceNameText = new Text(detailsGroup, SWT.BORDER | SWT.SINGLE);
GridDataFactory.fillDefaults().grab(true, false).applyTo(columnSourceNameText);
columnSourceNameText.setForeground(columnSourceNameText.getDisplay().getSystemColor(SWT.COLOR_DARK_BLUE));
columnSourceNameText.setBackground(columnSourceNameText.getDisplay().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW));
columnSourceNameText.setEditable(false);
setNonEditable(columnSourceNameText);

Label columnDVCountLabel = new Label(detailsGroup, SWT.NONE);
columnDVCountLabel.setText(getString("detailColumnDVCountLabel")); //$NON-NLS-1$

columnDVCountText = new Text(detailsGroup, SWT.BORDER | SWT.SINGLE);
GridDataFactory.fillDefaults().grab(true, false).applyTo(columnDVCountText);
setNonEditable(columnDVCountText);

Label columnNVCountLabel = new Label(detailsGroup, SWT.NONE);
columnNVCountLabel.setText(getString("detailColumnNVCountLabel")); //$NON-NLS-1$

columnNVCountText = new Text(detailsGroup, SWT.BORDER | SWT.SINGLE);
GridDataFactory.fillDefaults().grab(true, false).applyTo(columnNVCountText);
setNonEditable(columnNVCountText);

Label maxValueLabel = new Label(detailsGroup, SWT.NONE);
maxValueLabel.setText(getString("detailMaxValueLabel")); //$NON-NLS-1$

columnMaxValueText = new Text(detailsGroup, SWT.BORDER | SWT.SINGLE);
GridDataFactory.fillDefaults().grab(true, false).applyTo(columnMaxValueText);
setNonEditable(columnMaxValueText);

this.splitter.setWeights(SPLITTER_WEIGHTS);

Expand Down
Expand Up @@ -7,8 +7,9 @@
*/
package org.teiid.designer.modelgenerator.ldap.ui.wizards.pages.columns;

import java.util.HashSet;
import java.util.Set;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
Expand Down Expand Up @@ -64,33 +65,67 @@ private String getObjectClassFilter(ILdapEntryNode contextNode) {
*
* @throws NamingException
*/
private Set<ILdapAttributeNode> findChildAttributes(ILdapEntryNode contextNode) throws NamingException {
private Collection<ILdapAttributeNode> findChildAttributes(ILdapEntryNode contextNode) throws NamingException {
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
searchControls.setReturningAttributes(null);

String filter = getObjectClassFilter(contextNode);
NamingEnumeration<?> searchEnumeration = getLdapContext().search(contextNode.getSourceName(), filter, searchControls);
Set<ILdapAttributeNode> childAttributes = new HashSet<ILdapAttributeNode>();
Map<Integer, ILdapAttributeNode> childAttributes = new HashMap<Integer, ILdapAttributeNode>();

/*
* For each child entry in the enumeration, find their attributes
*/
while (searchEnumeration != null && searchEnumeration.hasMore()) {
SearchResult searchResult = (SearchResult) searchEnumeration.next();
Attributes resultAttrs = searchResult.getAttributes();
if (resultAttrs.size() == 0)
continue;

try {
NamingEnumeration<? extends Attribute> attrEnum = resultAttrs.getAll();
NamingEnumeration<? extends Attribute> attrEnum = resultAttrs.getAll();

/*
* Enumerate through each attribute in order to build an ldapAttributeNode
* to display and store in the import manager
*/
while(attrEnum.hasMore()) {
Attribute attribute = attrEnum.next();
childAttributes.add(getImportManager().newAttribute(contextNode, attribute));
ILdapAttributeNode newAttribute = getImportManager().newAttribute(contextNode, attribute);

/*
* Check whether this attribute has already been added to the
* child attribute map. We want the existing attribute in the set
* in order to increment its cost statistics
*/
ILdapAttributeNode childAttribute = childAttributes.get(newAttribute.hashCode());
if (childAttribute == null) {
childAttributes.put(newAttribute.hashCode(), newAttribute);
childAttribute = newAttribute;
}

NamingEnumeration<?> valuesEnum = attribute.getAll();
if (valuesEnum == null) {
childAttribute.incrementNullValueCount();
continue;
}

/*
* Need to apply the values of this attribute in order
* to determine the number of distinct values.
*/
while (valuesEnum.hasMore()) {
Object value = valuesEnum.next();
childAttribute.addValue(value);
}
}
} catch (NamingException ex) {
ModelGeneratorLdapUiConstants.UTIL.log(ex);
}
}

return childAttributes;
return childAttributes.values();
}

@Override
Expand All @@ -103,7 +138,7 @@ public Object[] getChildren(Object parentElement) {

try {
ILdapEntryNode parentNode = (ILdapEntryNode) parentElement;
Set<ILdapAttributeNode> childAttributes = findChildAttributes(parentNode);
Collection<ILdapAttributeNode> childAttributes = findChildAttributes(parentNode);
return childAttributes.toArray();

} catch (NamingException ex) {
Expand Down

0 comments on commit edd5ac2

Please sign in to comment.