/* JayFX - A Fact Extractor Plug-in for Eclipse
* Copyright (C) 2006 McGill University (http://www.cs.mcgill.ca/~swevo/jayfx)
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* $Revision: 1.5 $
*/
package de.ovgu.cide.mining.database;
import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import de.ovgu.cide.mining.database.model.AElement;
import de.ovgu.cide.mining.database.model.ARelationKind;
/**
* A database storing all the relations between different program elements.
*/
class ProgramDatabase extends AbstractProgramDatabase {
/**
* Data bundle associated with an element. Contains modifier flags and a map
* linking relations to their ranges. an IElement instance.
*/
class Bundle implements Serializable {
private static final long serialVersionUID = 1L;
private final Map<ARelationKind, Set<AElement>> aRelations = new HashMap<ARelationKind, Set<AElement>>();
// int aModifier;
/**
* @return The Map of relations to range. never null.
*/
public Map<ARelationKind, Set<AElement>> getRelationMap() {
return aRelations;
}
}
// Maps IElements (unique because of the Flyweight pattern
// to bundles containing modifiers and relations
private WeakHashMap<AElement, Bundle> aElements;
private Map<String, AElement> elementIndexMap;
/**
* Creates an empty program database.
*/
public ProgramDatabase() {
aElements = new WeakHashMap<AElement, Bundle>();
elementIndexMap = new HashMap<String, AElement>();
}
/*
* (non-Javadoc)
*
* @see de.ovgu.cide.mining.database.IProgramDatabase#getAllElements()
*/
@Override
public Set<AElement> getAllElements() {
return aElements.keySet();
}
/*
* (non-Javadoc)
*
* @see
* de.ovgu.cide.mining.database.IProgramDatabase#getElement(java.lang.String
* )
*/
@Override
public AElement getElement(String id) {
return elementIndexMap.get(id);
}
/*
* (non-Javadoc)
*
* @see
* de.ovgu.cide.mining.database.IProgramDatabase#contains(de.ovgu.cide.mining
* .database.model.AIElement)
*/
@Override
public boolean contains(AElement pElement) {
assert (pElement != null);
return aElements.containsKey(pElement);
}
/*
* (non-Javadoc)
*
* @see
* de.ovgu.cide.mining.database.IProgramDatabase#addElement(de.ovgu.cide
* .mining.database.model.AIElement)
*/
@Override
public void addElement(AElement pElement) {
assert (pElement != null);
if (!aElements.containsKey(pElement)) {
aElements.put(pElement, new Bundle());
elementIndexMap.put(pElement.getId(), pElement);
}
}
/*
* (non-Javadoc)
*
* @see
* de.ovgu.cide.mining.database.IProgramDatabase#addRelation(de.ovgu.cide
* .mining.database.model.AIElement,
* de.ovgu.cide.mining.database.model.ARelation,
* de.ovgu.cide.mining.database.model.AIElement)
*/
@Override
public void addRelation(AElement pElement1, ARelationKind pRelation,
AElement pElement2) throws ElementNotFoundException {
assert (pElement1 != null);
assert (pElement2 != null);
assert (pRelation != null);
if (!contains(pElement1))
throw new ElementNotFoundException(pElement1.getId());
if (!contains(pElement2))
throw new ElementNotFoundException(pElement2.getId());
Map<ARelationKind, Set<AElement>> lRelations = (aElements
.get(pElement1)).getRelationMap();
assert (lRelations != null);
Set<AElement> lElements = lRelations.get(pRelation);
if (lElements == null) {
lElements = new HashSet<AElement>();
lRelations.put(pRelation, lElements);
}
lElements.add(pElement2);
}
/*
* (non-Javadoc)
*
* @see
* de.ovgu.cide.mining.database.IProgramDatabase#getRange(de.ovgu.cide.mining
* .database.model.AIElement, de.ovgu.cide.mining.database.model.ARelation)
*/
@Override
public Set<AElement> getRange(AElement pElement,
ARelationKind... pRelations) throws ElementNotFoundException {
assert (pElement != null);
assert (pRelations != null);
if (!contains(pElement))
throw new ElementNotFoundException(pElement.getId());
Set<AElement> lReturn = new HashSet<AElement>();
Map<ARelationKind, Set<AElement>> lRelations = (aElements.get(pElement))
.getRelationMap();
for (ARelationKind lRelation : pRelations)
if (lRelations.containsKey(lRelation)) {
lReturn.addAll(lRelations.get(lRelation));
}
return lReturn;
}
/*
* (non-Javadoc)
*
* @see
* de.ovgu.cide.mining.database.IProgramDatabase#addRelationAndTranspose
* (de.ovgu.cide.mining.database.model.AIElement,
* de.ovgu.cide.mining.database.model.ARelation,
* de.ovgu.cide.mining.database.model.AIElement)
*/
@Override
public void addRelationAndTranspose(AElement pElement1,
ARelationKind pRelation, AElement pElement2)
throws ElementNotFoundException {
assert (pElement1 != null);
assert (pElement2 != null);
assert (pRelation != null);
// if( !contains( pElement1 ))
// throw new ElementNotFoundException( pElement1.getId() );
// if( !contains( pElement2 ))
// throw new ElementNotFoundException( pElement2.getId() );
if (contains(pElement1) && contains(pElement2)) {
addRelation(pElement1, pRelation, pElement2);
addRelation(pElement2, pRelation.getInverseRelation(), pElement1);
}
}
/*
* (non-Javadoc)
*
* @see
* de.ovgu.cide.mining.database.IProgramDatabase#hasRelations(de.ovgu.cide
* .mining.database.model.AIElement)
*/
@Override
public boolean hasRelations(AElement pElement)
throws ElementNotFoundException {
assert (pElement != null);
if (!contains(pElement))
throw new ElementNotFoundException(pElement.getId());
Map lRelations = ((Bundle) aElements.get(pElement)).getRelationMap();
return !lRelations.isEmpty();
}
// /*
// * (non-Javadoc)
// *
// * @see
// *
// de.ovgu.cide.mining.database.IProgramDatabase#copyRelations(de.ovgu.cide
// * .mining.database.model.AIElement,
// * de.ovgu.cide.mining.database.model.AIElement)
// */
// @Override
// public void copyRelations(AElement pFrom, AElement pTo)
// throws ElementNotFoundException {
// assert (pFrom != null);
// assert (pTo != null);
//
// if (!contains(pFrom))
// throw new ElementNotFoundException(pFrom.getId());
// if (!contains(pTo))
// throw new ElementNotFoundException(pTo.getId());
//
// Map lRelations = ((Bundle) aElements.get(pFrom)).getRelationMap();
// for (Iterator i = lRelations.keySet().iterator(); i.hasNext();) {
// ARelationKind lNext = (ARelationKind) i.next();
// Set lElements = (Set) lRelations.get(lNext);
// for (Iterator j = lElements.iterator(); j.hasNext();) {
// addRelationAndTranspose(pTo, lNext, (AElement) j.next());
// }
// }
// }
// /**
// * Removes a relation from an element. Does not automatically remove the
// * transpose relation.
// *
// * @param pElement1
// * The element to remove the relation from. Must not be null and
// * must exist in the program database.
// * @param pRelation
// * The relation linking pElement1 with pElement2. Must not be
// * null.
// * @param pElement2
// * The range element of the relation. Must not be null and must
// * exist in the program database.
// * @throws ElementNotFoundException
// * If either pFrom or pTo is not indexed in the database.
// */
// private void removeRelation(AElement pElement1, ARelationKind pRelation,
// AElement pElement2) throws ElementNotFoundException {
// assert (pElement1 != null);
// assert (pElement2 != null);
// assert (pRelation != null);
//
// if (!contains(pElement1))
// throw new ElementNotFoundException(pElement1.getId());
// if (!contains(pElement2))
// throw new ElementNotFoundException(pElement2.getId());
//
// Map lRelations = ((Bundle) aElements.get(pElement1)).getRelationMap();
// if (!lRelations.containsKey(pRelation))
// return;
//
// Set lElements = (Set) lRelations.get(pRelation);
// lElements.remove(pElement2);
// elementIndexMap.remove(pElement2.getId());
// }
//
// /*
// * (non-Javadoc)
// *
// * @see
// *
// de.ovgu.cide.mining.database.IProgramDatabase#removeElement(de.ovgu.cide
// * .mining.database.model.AIElement)
// */
// @Override
// public void removeElement(AElement pElement)
// throws ElementNotFoundException {
// assert (pElement != null);
// if (!contains(pElement))
// throw new ElementNotFoundException(pElement.getId());
//
// Map lRelations = ((Bundle) aElements.get(pElement)).getRelationMap();
// for (Iterator i = lRelations.keySet().iterator(); i.hasNext();) {
// ARelationKind lNext = (ARelationKind) i.next();
// Set lElements = (Set) lRelations.get(lNext);
// for (Iterator j = lElements.iterator(); j.hasNext();) {
// removeRelation((AElement) j.next(), lNext.getInverseRelation(),
// pElement);
// }
// }
//
// // Remove the element
// aElements.remove(pElement);
// elementIndexMap.remove(pElement.getId());
// }
//
// /*
// * (non-Javadoc)
// *
// * @see de.ovgu.cide.mining.database.IProgramDatabase#dump()
// */
// @Override
// public void dump() {
// for (Iterator i = aElements.keySet().iterator(); i.hasNext();) {
// AElement lElement1 = (AElement) i.next();
// System.out.println(lElement1);
//
// Object obj = aElements.get(lElement1);
//
// if (obj == null)
// continue;
//
// Bundle bundle = (Bundle) obj;
//
// Map lRelations;
//
// if ((lRelations = bundle.getRelationMap()) == null)
// continue;
//
// for (Iterator j = lRelations.keySet().iterator(); j.hasNext();) {
// ARelationKind lRelation = (ARelationKind) j.next();
// System.out.println(" " + lRelation);
// for (Iterator k = ((Set) lRelations.get(lRelation)).iterator(); k
// .hasNext();) {
// System.out.println(" " + k.next());
// }
// }
// }
// }
/*
* (non-Javadoc)
*
* @see
* de.ovgu.cide.mining.database.IProgramDatabase#getModifiers(de.ovgu.cide
* .mining.database.model.AIElement)
*/
// @Override
// public int getModifiers(AElement pElement) {
// int lReturn = 0;
// if (aElements.containsKey(pElement)) {
// Bundle lBundle = (Bundle) aElements.get(pElement);
// lReturn = lBundle.aModifier;
// }
// return lReturn;
// }
public void estimateFootprint() {
System.out.println("elementIndexMap.size(): " + elementIndexMap.size());
System.out.println("aElements.size(): " + aElements.size());
int s = 0;
for (AElement a : elementIndexMap.values()) {
s += a.getId().length();
}
System.out.println("combined size of all IDs: " + s);
s = 0;
for (AElement a : elementIndexMap.values()) {
s += a.getDisplayName().length();
}
System.out.println("combined size of all displaynames: " + s);
// FileOutputStream fos = null;
// ObjectOutputStream out = null;
// try {
// // fos = new FileOutputStream("d:/tmp/aElements.dat");
// // out = new ObjectOutputStream(fos);
// // out.writeObject(aElements);
// // out.close();
// // fos = new FileOutputStream("d:/tmp/elementIndexMap.dat");
// // out = new ObjectOutputStream(fos);
// // out.writeObject(elementIndexMap);
// // out.close();
// } catch (IOException ex) {
// ex.printStackTrace();
// }
}
}