Commit b5bd9d1a by Harish Butani

add support for MemRepo get

parent 0c46cbad
......@@ -41,7 +41,7 @@ public interface IRepository {
Id newId(String typeName);
ITypedInstance get(Id id) throws RepositoryException;
ITypedReferenceableInstance get(Id id) throws RepositoryException;
void defineClass(ClassType type) throws RepositoryException;
void defineTrait(TraitType type) throws RepositoryException;
......
......@@ -54,6 +54,28 @@ public class Id implements ITypedReferenceableInstance {
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || !ITypedReferenceableInstance.class.isAssignableFrom(o.getClass())) return false;
Id id1 = ((ITypedReferenceableInstance)o).getId();
if (id != id1.id) return false;
if (version != id1.version) return false;
if (!className.equals(id1.className)) return false;
return true;
}
@Override
public int hashCode() {
int result = (int) (id ^ (id >>> 32));
result = 31 * result + className.hashCode();
result = 31 * result + version;
return result;
}
@Override
public ImmutableList<String> getTraits() {
return null;
}
......
......@@ -142,6 +142,7 @@ public class AttributeStores {
if (val == NULL_VAL) {
instance.nullFlags[nullPos] = true;
} else {
instance.nullFlags[nullPos] = false;
load(instance, colPos, val);
}
}
......@@ -170,8 +171,9 @@ public class AttributeStores {
int colPos = instance.fieldMapping().fieldPos.get(attrName);
if (nullList.get(pos)) {
instance.nullFlags[colPos] = true;
instance.nullFlags[nullPos] = true;
} else {
instance.nullFlags[nullPos] = false;
load(instance, colPos, pos);
}
......
......@@ -19,6 +19,8 @@
package org.apache.hadoop.metadata.storage.memory;
import com.google.common.collect.ImmutableList;
import org.apache.hadoop.metadata.MetadataException;
import org.apache.hadoop.metadata.storage.Id;
import org.apache.hadoop.metadata.storage.ReferenceableInstance;
import org.apache.hadoop.metadata.storage.RepositoryException;
import org.apache.hadoop.metadata.types.ClassType;
......@@ -29,9 +31,11 @@ import java.util.ArrayList;
public class ClassStore extends HierarchicalTypeStore {
final ArrayList<ImmutableList<String>> traitNamesStore;
final ClassType classType;
public ClassStore(MemRepository repository, ClassType hierarchicalType) throws RepositoryException {
super(repository, hierarchicalType);
classType = hierarchicalType;
traitNamesStore = new ArrayList<ImmutableList<String>>();
}
......@@ -47,4 +51,43 @@ public class ClassStore extends HierarchicalTypeStore {
traitNamesStore.add(null);
}
}
boolean validate(MemRepository repo, Id id) throws RepositoryException {
if (id.isUnassigned() ) {
throw new RepositoryException(String.format("Invalid Id (unassigned) : %s", id));
}
Integer pos = idPosMap.get(id);
if (pos == null ) {
throw new RepositoryException(String.format("Invalid Id (unknown) : %s", id));
}
String typeName = typeNameList.get(pos);
if ( typeName != hierarchicalType.getName()) {
throw new RepositoryException(String.format("Invalid Id (incorrect typeName, type is %s) : %s",
typeName, id));
}
return true;
}
/*
* - assumes id is already validated
*/
ReferenceableInstance createInstance(MemRepository repo, Id id) throws RepositoryException {
Integer pos = idPosMap.get(id);
String typeName = typeNameList.get(pos);
if ( typeName != hierarchicalType.getName()) {
return repo.getClassStore(typeName).createInstance(repo, id);
}
ImmutableList<String> traitNames = traitNamesStore.get(pos);
String[] tNs = traitNames.toArray(new String[] {});
try {
ReferenceableInstance r = (ReferenceableInstance) classType.createInstance(id, tNs);
return r;
} catch ( MetadataException me) {
throw new RepositoryException(me);
}
}
}
......@@ -150,6 +150,13 @@ public abstract class HierarchicalTypeStore {
}
}
protected void loadFields(int pos, StructInstance s) throws RepositoryException {
for(Map.Entry<AttributeInfo, IAttributeStore> e : attrStores.entrySet()) {
IAttributeStore attributeStore = e.getValue();
attributeStore.load(pos, hierarchicalType, s);
}
}
/**
* - store the typeName
* - store the immediate attributes in the respective IAttributeStore
......@@ -175,10 +182,7 @@ public abstract class HierarchicalTypeStore {
*/
void load(ReferenceableInstance i) throws RepositoryException {
int pos = idPosMap.get(i.getId());
for(Map.Entry<AttributeInfo, IAttributeStore> e : attrStores.entrySet()) {
IAttributeStore attributeStore = e.getValue();
attributeStore.load(pos, hierarchicalType, i);
}
loadFields(pos, i);
for(HierarchicalTypeStore s : superTypeStores) {
s.load(i);
......
......@@ -220,13 +220,51 @@ public class MemRepository implements IRepository {
}
public ITypedReferenceableInstance get(Id id) throws RepositoryException {
throw new RepositoryException("not implemented");
try {
ReplaceIdWithInstance replacer = new ReplaceIdWithInstance(this);
ObjectGraphWalker walker = new ObjectGraphWalker(typeSystem, replacer);
replacer.setWalker(walker);
ITypedReferenceableInstance r = getDuringWalk(id, walker);
walker.walk();
return r;
} catch (MetadataException me) {
throw new RepositoryException("TypeSystem error when walking the ObjectGraph", me);
}
}
/*
* - Id must be valid; Class must be valid.
* - Ask ClassStore to createInstance.
* - Ask ClassStore to load instance.
* - load instance traits
* - add to GraphWalker
*/
ITypedReferenceableInstance getDuringWalk(Id id, ObjectGraphWalker walker) throws RepositoryException {
ClassStore cS = getClassStore(id.getTypeName());
if ( cS == null ) {
throw new RepositoryException(String.format("Unknown Class %s", id.getTypeName()));
}
cS.validate(this, id);
ReferenceableInstance r = cS.createInstance(this, id);
cS.load(r);
for(String traitName : r.getTraits()) {
HierarchicalTypeStore tt = typeStores.get(traitName);
tt.load(r);
}
walker.addRoot(r);
return r;
}
HierarchicalTypeStore getStore(String typeName) {
return typeStores.get(typeName);
}
ClassStore getClassStore(String typeName) {
return (ClassStore) getStore(typeName);
}
public void defineClass(ClassType type) throws RepositoryException {
HierarchicalTypeStore s = new ClassStore(this, type);
typeStores.put(type.getName(), s);
......
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.metadata.storage.memory;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import org.apache.hadoop.metadata.ITypedReferenceableInstance;
import org.apache.hadoop.metadata.MetadataException;
import org.apache.hadoop.metadata.storage.Id;
import org.apache.hadoop.metadata.types.DataTypes;
import org.apache.hadoop.metadata.types.Multiplicity;
import org.apache.hadoop.metadata.types.ObjectGraphWalker;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class ReplaceIdWithInstance implements ObjectGraphWalker.NodeProcessor {
final MemRepository repository;
public final Map<Id, ITypedReferenceableInstance> idToInstanceMap;
ObjectGraphWalker walker;
public ReplaceIdWithInstance(MemRepository repository) {
this.repository = repository;
idToInstanceMap = new HashMap<Id, ITypedReferenceableInstance>();
}
void setWalker(ObjectGraphWalker walker) {
this.walker = walker;
}
@Override
public void processNode(ObjectGraphWalker.Node nd) throws MetadataException {
if ( nd.attributeName == null ) {
return;
} else if (!nd.aInfo.isComposite || nd.value == null ) {
return;
} else if ( nd.aInfo.dataType().getTypeCategory() == DataTypes.TypeCategory.CLASS ) {
if ( nd.value != null && nd.value instanceof Id ) {
Id id = (Id)nd.value;
ITypedReferenceableInstance r = getInstance(id);
nd.instance.set(nd.attributeName, r);
}
} else if ( nd.aInfo.dataType().getTypeCategory() == DataTypes.TypeCategory.ARRAY ) {
DataTypes.ArrayType aT = (DataTypes.ArrayType) nd.aInfo.dataType();
nd.instance.set(nd.attributeName,
convertToInstances((ImmutableCollection)nd.value, nd.aInfo.multiplicity, aT));
} else if ( nd.aInfo.dataType().getTypeCategory() == DataTypes.TypeCategory.MAP ) {
DataTypes.MapType mT = (DataTypes.MapType) nd.aInfo.dataType();
nd.instance.set(nd.attributeName,
convertToInstances((ImmutableMap)nd.value, nd.aInfo.multiplicity, mT));
}
}
ImmutableCollection<?> convertToInstances(ImmutableCollection<?> val,
Multiplicity m, DataTypes.ArrayType arrType)
throws MetadataException {
if ( val == null || arrType.getElemType().getTypeCategory() != DataTypes.TypeCategory.CLASS ) {
return val;
}
ImmutableCollection.Builder b = m.isUnique ? ImmutableSet.builder() : ImmutableList.builder();
Iterator it = val.iterator();
while(it.hasNext()) {
Object elem = it.next();
if ( elem instanceof Id) {
Id id = (Id) elem;
elem = getInstance(id);
}
b.add(elem);
}
return b.build();
}
ImmutableMap<?, ?> convertToInstances(ImmutableMap val, Multiplicity m, DataTypes.MapType mapType)
throws MetadataException {
if ( val == null || (mapType.getKeyType().getTypeCategory() != DataTypes.TypeCategory.CLASS &&
mapType.getValueType().getTypeCategory() != DataTypes.TypeCategory.CLASS) ) {
return val;
}
ImmutableMap.Builder b = ImmutableMap.builder();
Iterator<Map.Entry> it = val.entrySet().iterator();
while(it.hasNext()) {
Map.Entry elem = it.next();
Object oldKey = elem.getKey();
Object oldValue = elem.getValue();
Object newKey = oldKey;
Object newValue = oldValue;
if ( oldKey instanceof Id ) {
Id id = (Id) elem;
ITypedReferenceableInstance r = getInstance(id);
}
if ( oldValue instanceof Id ) {
Id id = (Id) elem;
ITypedReferenceableInstance r = getInstance(id);
}
b.put(newKey, newValue);
}
return b.build();
}
ITypedReferenceableInstance getInstance(Id id) throws MetadataException {
ITypedReferenceableInstance r = idToInstanceMap.get(id);
if ( r == null ) {
r = repository.get(id);
idToInstanceMap.put(id, r);
walker.addRoot(r);
}
return r;
}
}
......@@ -41,6 +41,12 @@ public class TraitStore extends HierarchicalTypeStore {
classNameStore.set(pos, i.getTypeName());
}
void load(ReferenceableInstance i) throws RepositoryException {
int pos = idPosMap.get(i.getId());
StructInstance s = (StructInstance) i.getTrait(hierarchicalType.getName());
super.loadFields(pos, s);
}
public void ensureCapacity(int pos) throws RepositoryException {
super.ensureCapacity(pos);
while (classNameStore.size() < pos + 1) {
......
......@@ -26,14 +26,21 @@ public class ObjectGraphWalker {
final NodeProcessor nodeProcessor;
Set<Id> processedIds;
public ObjectGraphWalker(TypeSystem typeSystem, NodeProcessor nodeProcessor)
throws MetadataException {
this(typeSystem, nodeProcessor, (IReferenceableInstance)null);
}
public ObjectGraphWalker(TypeSystem typeSystem, NodeProcessor nodeProcessor, IReferenceableInstance start)
throws MetadataException {
this.typeSystem = typeSystem;
this.nodeProcessor = nodeProcessor;
queue = new LinkedList<IReferenceableInstance>();
processedIds = new HashSet<Id>();
if ( start != null ) {
visitReferenceableInstance(start);
}
}
public ObjectGraphWalker(TypeSystem typeSystem, NodeProcessor nodeProcessor,
List<? extends IReferenceableInstance> roots)
......@@ -54,6 +61,10 @@ public class ObjectGraphWalker {
}
}
public void addRoot(IReferenceableInstance root) {
visitReferenceableInstance(root);
}
void traverseValue(IDataType dT, Object val) throws MetadataException {
if (val != null) {
if (dT.getTypeCategory() == DataTypes.TypeCategory.ARRAY) {
......@@ -138,7 +149,7 @@ public class ObjectGraphWalker {
}
}
void visitReferenceableInstance(Object val) throws MetadataException {
void visitReferenceableInstance(Object val) {
if (val == null || !(val instanceof IReferenceableInstance)) {
return;
......
package org.apache.hadoop.metadata;
import com.google.common.collect.ImmutableList;
import org.apache.hadoop.metadata.storage.Id;
import org.apache.hadoop.metadata.storage.RepositoryException;
import org.apache.hadoop.metadata.types.TypeSystem;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import scala.tools.cmd.Meta;
public class StorageTest extends BaseTest {
......@@ -18,13 +23,85 @@ public class StorageTest extends BaseTest {
defineDeptEmployeeTypes(ts);
Referenceable hrDept = createDeptEg1(ts);
ITypedReferenceableInstance hrDept2 = ms.getRepository().create(hrDept);
ITypedReferenceableInstance hrDept3 = ms.getRepository().get(hrDept2.getId());
Assert.assertEquals(hrDept3.toString(), "{\n" +
"\tid : (type: Department, id: 1)\n" +
"\tname : \thr\n" +
"\temployees : \t[{\n" +
"\tid : (type: Person, id: 2)\n" +
"\tname : \tJohn\n" +
"\tdepartment : (type: Department, id: 1)\n" +
"\tmanager : (type: Manager, id: 3)\n" +
"}, {\n" +
"\tid : (type: Manager, id: 3)\n" +
"\tsubordinates : \t[(type: Person, id: 2)]\n" +
"\tname : \tJane\n" +
"\tdepartment : (type: Department, id: 1)\n" +
"\tmanager : <null>\n" +
"\n" +
"\tSecurityClearance : \t{\n" +
"\t\tlevel : \t\t1\n" +
"\t}}]\n" +
"}");
}
@Test
public void testGetPerson() throws MetadataException {
TypeSystem ts = ms.getTypeSystem();
defineDeptEmployeeTypes(ts);
Referenceable hrDept = createDeptEg1(ts);
ITypedReferenceableInstance hrDept2 = ms.getRepository().create(hrDept);
Id e1Id = new Id(2, 0, "Person");
ITypedReferenceableInstance e1 = ms.getRepository().get(e1Id);
Assert.assertEquals(e1.toString(), "{\n" +
"\tid : (type: Person, id: 2)\n" +
"\tname : \tJohn\n" +
"\tdepartment : (type: Department, id: 1)\n" +
"\tmanager : (type: Manager, id: 3)\n" +
"}");
}
@Test
public void testInvalidTypeName() throws MetadataException {
TypeSystem ts = ms.getTypeSystem();
defineDeptEmployeeTypes(ts);
Referenceable hrDept = createDeptEg1(ts);
ITypedReferenceableInstance hrDept2 = ms.getRepository().create(hrDept);
//System.out.println(hrDept2);
Id e1Id = new Id(3, 0, "Person");
try {
ITypedReferenceableInstance e1 = ms.getRepository().get(e1Id);
} catch(RepositoryException re) {
RepositoryException me = (RepositoryException) re.getCause();
Assert.assertEquals(me.getMessage(), "Invalid Id (unknown) : (type: Person, id: 3)");
}
}
@Test
public void testGetManager() throws MetadataException {
TypeSystem ts = ms.getTypeSystem();
defineDeptEmployeeTypes(ts);
Referenceable hrDept = createDeptEg1(ts);
ITypedReferenceableInstance hrDept2 = ms.getRepository().create(hrDept);
Id m1Id = new Id(3, 0, "Manager");
ITypedReferenceableInstance m1 = ms.getRepository().get(m1Id);
Assert.assertEquals(m1.toString(), "{\n" +
"\tid : (type: Manager, id: 3)\n" +
"\tsubordinates : \t[(type: Person, id: 2)]\n" +
"\tname : \tJane\n" +
"\tdepartment : (type: Department, id: 1)\n" +
"\tmanager : <null>\n" +
"\n" +
"\tSecurityClearance : \t{\n" +
"\t\tlevel : \t\t1\n" +
"\t}}");
}
}
\ No newline at end of file
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