Commit 37ec473d by Harish Butani

decouple supertype graph setup from field setup

parent b8feeebf
......@@ -91,7 +91,48 @@ public abstract class HierarchicalType<ST extends HierarchicalType,T> extends Ab
return ( cType == this || cType.superTypePaths.containsKey(getName()) );
}
protected FieldMapping constructFieldMapping(ImmutableList<String> superTraits,
protected void setupSuperTypesGraph()
throws MetadataException {
setupSuperTypesGraph(superTypes);
}
private void setupSuperTypesGraph(ImmutableList<String> superTypes)
throws MetadataException {
Map<String, List<Path>> superTypePaths = new HashMap<String, List<Path>>();
Map<String, Path> pathNameToPathMap = new HashMap<String, Path>();
Queue<Path> queue = new LinkedList<Path>();
queue.add(new Node(getName()));
while(!queue.isEmpty()) {
Path currentPath = queue.poll();
ST superType = currentPath.typeName == getName() ? (ST) this :
(ST) typeSystem.getDataType(superTypeClass, currentPath.typeName);
pathNameToPathMap.put(currentPath.pathName, currentPath);
if ( superType != this ) {
List<Path> typePaths = superTypePaths.get(superType.getName());
if ( typePaths == null ) {
typePaths = new ArrayList<Path>();
superTypePaths.put(superType.getName(), typePaths);
}
typePaths.add(currentPath);
}
ImmutableList<String> sTs = superType == this ? superTypes : superType.superTypes;
if ( sTs != null ) {
for (String sT : sTs) {
queue.add(new Path(sT, currentPath));
}
}
}
this.superTypePaths = ImmutableMap.copyOf(superTypePaths);
this.pathNameToPathMap = ImmutableMap.copyOf(pathNameToPathMap);
}
protected FieldMapping constructFieldMapping(ImmutableList<String> superTypes,
AttributeInfo... fields)
throws MetadataException {
......@@ -114,36 +155,28 @@ public abstract class HierarchicalType<ST extends HierarchicalType,T> extends Ab
int numStructs = 0;
int numReferenceables = 0;
Map<String, List<Path>> superTypePaths = new HashMap<String, List<Path>>();
Map<String, Path> pathNameToPathMap = new HashMap<String, Path>();
Queue<Path> queue = new LinkedList<Path>();
queue.add(new Node(getName()));
while(!queue.isEmpty()) {
Path currentPath = queue.poll();
setupSuperTypesGraph(superTypes);
Iterator<Path> pathItr = pathIterator();
while(pathItr.hasNext()) {
Path currentPath = pathItr.next();
ST superType = currentPath.typeName == getName() ? (ST) this :
(ST) typeSystem.getDataType(superTypeClass, currentPath.typeName);
pathNameToPathMap.put(currentPath.pathName, currentPath);
if ( superType != this ) {
List<Path> typePaths = superTypePaths.get(superType.getName());
if ( typePaths == null ) {
typePaths = new ArrayList<Path>();
superTypePaths.put(superType.getName(), typePaths);
}
typePaths.add(currentPath);
}
ImmutableList<AttributeInfo> superTypeFields = superType == this ?
ImmutableList.<AttributeInfo>copyOf(fields) : superType.immediateAttrs;
Set<String> immediateFields = new HashSet<String>();
for(AttributeInfo i : superTypeFields) {
if ( superType == this && immediateFields.contains(i.name) ) {
throw new MetadataException(
String.format("Struct defintion cannot contain multiple fields with the same name %s",
i.name));
if ( superType == this ) {
if ( immediateFields.contains(i.name) ) {
throw new MetadataException(
String.format("Struct defintion cannot contain multiple fields with the same name %s",
i.name));
}
immediateFields.add(i.name);
}
String attrName = i.name;
......@@ -203,12 +236,6 @@ public abstract class HierarchicalType<ST extends HierarchicalType,T> extends Ab
throw new MetadataException(String.format("Unknown datatype %s", i.dataType()));
}
}
ImmutableList<String> sTs = superType == this ? superTraits : superType.superTypes;
for(String sT : sTs) {
queue.add(new Path(sT, currentPath));
}
}
this.superTypePaths = ImmutableMap.copyOf(superTypePaths);
......
......@@ -18,14 +18,9 @@
package org.apache.metadata.types;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import org.apache.metadata.MetadataException;
import javax.annotation.Nullable;
import java.lang.reflect.Constructor;
import java.util.*;
......@@ -193,7 +188,7 @@ public class TypeSystem {
/*
* Step 1:
* - validate cannot redefine types
* - for Hierarchical Types setup an empty TraitType to allow for recursive type graphs.
* - setup shallow Type instances to facilitate recursive type graphs
*/
private void step1() throws MetadataException {
for (StructTypeDefinition sDef : structDefs) {
......@@ -266,14 +261,19 @@ public class TypeSystem {
/*
* Step 2:
* - for Hierarchical Types, validate SuperTypes.
* - for each Hierarchical Type setup their SuperTypes Graph
*/
private void step2() throws MetadataException {
for (HierarchicalTypeDefinition<TraitType> traitDef : traitDefs) {
validateSuperTypes(TraitType.class, traitDef);
TraitType traitType = getDataType(TraitType.class, traitDef.typeName);
traitType.setupSuperTypesGraph();
}
for (HierarchicalTypeDefinition<ClassType> classDef : classDefs) {
validateSuperTypes(ClassType.class, classDef);
ClassType classType = getDataType(ClassType.class, classDef.typeName);
classType.setupSuperTypesGraph();
}
}
......
......@@ -121,5 +121,57 @@ public class TraitTest extends BaseTest {
"\n" +
"}\n");
}
@Test
public void testRandomOrder() throws MetadataException {
HierarchicalTypeDefinition A = createTraitTypeDef("A", null,
createRequiredAttrDef("a", DataTypes.INT_TYPE),
createOptionalAttrDef("b", DataTypes.BOOLEAN_TYPE),
createOptionalAttrDef("c", DataTypes.BYTE_TYPE),
createOptionalAttrDef("d", DataTypes.SHORT_TYPE));
HierarchicalTypeDefinition B = createTraitTypeDef("B", ImmutableList.<String>of("A"),
createOptionalAttrDef("b", DataTypes.BOOLEAN_TYPE));
HierarchicalTypeDefinition C = createTraitTypeDef("C", ImmutableList.<String>of("A"),
createOptionalAttrDef("c", DataTypes.BYTE_TYPE));
HierarchicalTypeDefinition D = createTraitTypeDef("D", ImmutableList.<String>of("B", "C"),
createOptionalAttrDef("d", DataTypes.SHORT_TYPE));
defineTraits(B, D, A, C);
TraitType DType = (TraitType) ms.getTypeSystem().getDataType(TraitType.class, "D");
Struct s1 = new Struct("D");
s1.set("d", 1);
s1.set("c", 1);
s1.set("b", true);
s1.set("a", 1);
s1.set("A.B.D.b", true);
s1.set("A.B.D.c", 2);
s1.set("A.B.D.d", 2);
s1.set("A.C.D.a", 3);
s1.set("A.C.D.b", false);
s1.set("A.C.D.c", 3);
s1.set("A.C.D.d", 3);
ITypedStruct ts = DType.convert(s1, Multiplicity.REQUIRED);
Assert.assertEquals(ts.toString(), "{\n" +
"\td : 1\n" +
"\tb : true\n" +
"\tc : 1\n" +
"\ta : 1\n" +
"\tA.B.D.b : true\n" +
"\tA.B.D.c : 2\n" +
"\tA.B.D.d : 2\n" +
"\tA.C.D.a : 3\n" +
"\tA.C.D.b : false\n" +
"\tA.C.D.c : 3\n" +
"\tA.C.D.d : 3\n" +
"\n" +
"}\n");
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment