X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.graph%2Fsrc%2Forg%2Fsimantics%2Fgraph%2Fstore%2FIdentityStore.java;fp=bundles%2Forg.simantics.graph%2Fsrc%2Forg%2Fsimantics%2Fgraph%2Fstore%2FIdentityStore.java;h=5ed32c0786bde4778a2125eb358be6a461020232;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hp=c84358cb077b37fff57c57a572c85298b4ef421a;hpb=24e2b34260f219f0d1644ca7a138894980e25b14;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.graph/src/org/simantics/graph/store/IdentityStore.java b/bundles/org.simantics.graph/src/org/simantics/graph/store/IdentityStore.java index c84358cb0..5ed32c078 100644 --- a/bundles/org.simantics.graph/src/org/simantics/graph/store/IdentityStore.java +++ b/bundles/org.simantics.graph/src/org/simantics/graph/store/IdentityStore.java @@ -1,430 +1,430 @@ -package org.simantics.graph.store; - -import gnu.trove.list.array.TIntArrayList; -import gnu.trove.map.hash.THashMap; -import gnu.trove.map.hash.TIntIntHashMap; -import gnu.trove.map.hash.TIntObjectHashMap; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.procedure.TIntProcedure; -import gnu.trove.procedure.TObjectIntProcedure; -import gnu.trove.procedure.TObjectObjectProcedure; -import gnu.trove.procedure.TObjectProcedure; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - -import java.util.ArrayList; -import java.util.regex.Pattern; - -import org.simantics.graph.query.Path; -import org.simantics.graph.query.PathChild; -import org.simantics.graph.query.PathRoot; -import org.simantics.graph.representation.External; -import org.simantics.graph.representation.Identity; -import org.simantics.graph.representation.Internal; -import org.simantics.graph.representation.Root; - -public class IdentityStore implements IStore { - - private static int[] EMPTY_INT_ARRAY = new int[0]; - - public static class ConsistsOf { - public int parent; - public String name; - public int child; - - public ConsistsOf(int parent, String name, int child) { - //System.out.println(parent + "." + name + " = " + child); - this.parent = parent; - this.name = name; - this.child = child; - } - } - - TObjectIntHashMap roots = new TObjectIntHashMap(); - TIntObjectHashMap invRoots = new TIntObjectHashMap(); - TIntObjectHashMap> parentMap = - new TIntObjectHashMap>(); - TIntObjectHashMap childMap = new TIntObjectHashMap(); - TIntHashSet newResources = new TIntHashSet(); - int resourceCount = 0; - TIntIntHashMap unifications = new TIntIntHashMap(); - TIntHashSet collisions = new TIntHashSet(); - - public int newResource() { - return resourceCount++; - } - - public boolean markNew(int resource) { - return newResources.add(resource); - } - - public int[] getNewResources() { - return newResources.toArray(); - } - - public int getResourceCount() { - return resourceCount; - } - - public void setResourceCount(int newCount) { - resourceCount = newCount; - } - - public void defineRoot(String name, int root) { - if(roots.contains(name)) - unify(root, roots.get(name)); - roots.put(name, root); - invRoots.put(root, name); - } - - public void defineChild(int parent, String name, int child) { - THashMap map = parentMap.get(parent); - if(map == null) { - map = new THashMap(); - parentMap.put(parent, map); - } - ConsistsOf consistsOf = new ConsistsOf(parent, name, child); - ConsistsOf oldC = map.put(name, consistsOf); - if(oldC != null) - unify(child, oldC.child); - childMap.put(child, consistsOf); - } - - public boolean hasChild(int parent, String name) { - THashMap map = parentMap.get(parent); - if(map == null) - return false; - else - return map.contains(name); - } - - public int getChild(int parent, String name) { - THashMap map = parentMap.get(parent); - if(map == null) { - map = new THashMap(); - parentMap.put(parent, map); - } - else if(map.contains(name)) - return map.get(name).child; - int child = newResource(); - ConsistsOf consistsOf = new ConsistsOf(parent, name, child); - map.put(name, consistsOf); - childMap.put(child, consistsOf); - return child; - } - - public int getChildIfExists(int parent, String name) { - THashMap map = parentMap.get(parent); - if(map != null && map.contains(name)) - return map.get(name).child; - return -1; - } - - public int getRoot(String uri) { - if(roots.contains(uri)) - return roots.get(uri); - else { - int root = newResource(); - roots.put(uri, root); - invRoots.put(root, uri); - return root; - } - } - - public int getRootIfExists(String uri) { - if(roots.contains(uri)) - return roots.get(uri); - return -1; - } - - public int[] getChildren(int id) { - THashMap map = parentMap.get(id); - if(map == null) - return EMPTY_INT_ARRAY; - final int[] result = new int[map.size()]; - map.forEachValue(new TObjectProcedure() { - int i=0; - @Override - public boolean execute(ConsistsOf object) { - result[i++] = object.child; - return true; - } - }); - return result; - } - - public THashMap getChildMap(int parent) { - return parentMap.get(parent); - } - - private void collectIdentities(final int parent, final ArrayList identities) { - THashMap map = parentMap.get(parent); - if(map != null) { - map.forEachEntry(new TObjectObjectProcedure() { - - @Override - public boolean execute(String a, ConsistsOf b) { - if(newResources.contains(b.child)) - identities.add(new Identity(b.child, new Internal(parent, a))); - else - identities.add(new Identity(b.child, new External(parent, a))); - collectIdentities(b.child, identities); - return true; - } - }); - } - } - - private void collectIdentities(final ArrayList identities) { - roots.forEachEntry(new TObjectIntProcedure() { - @Override - public boolean execute(String a, int b) { - identities.add(new Identity(b, new Root(a, ""))); - collectIdentities(b, identities); - return true; - } - }); - } - - @Override - public void map(final TIntIntHashMap map) { - collisions = IndexMappingUtils.map(map, collisions); - newResources = IndexMappingUtils.map(map, newResources); - IndexMappingUtils.map(map, roots); - invRoots = IndexMappingUtils.map(map, invRoots, collisions); - - final ArrayList consistsOfs = new ArrayList(childMap.size()); - childMap.forEachValue(new TObjectProcedure() { - @Override - public boolean execute(ConsistsOf c) { - if(map.contains(c.parent)) - c.parent = map.get(c.parent); - if(map.contains(c.child)) - c.child = map.get(c.child); - consistsOfs.add(c); - return true; - } - }); - - childMap.clear(); - parentMap.clear(); - assert(unifications.isEmpty()); - - for(ConsistsOf c : consistsOfs) { - THashMap m = parentMap.get(c.parent); - if(m == null) { - m = new THashMap(); - parentMap.put(c.parent, m); - } - ConsistsOf oldC = m.put(c.name, c); - ConsistsOf childC = childMap.put(c.child, c); - if(childC != null && (childC.parent != c.parent || !childC.name.equals(c.name))) - collisions.add(c.child); - - if(oldC != null) - unify(oldC.child, c.child); - } - } - - public int pathToId(Path path) { - if(path instanceof PathChild) { - PathChild child = (PathChild)path; - int parent = pathToId(child.parent); - if(parent < 0) - return -1; - return getChildIfExists(parent, child.name); - } - else if(path instanceof PathRoot) - return getRootIfExists(((PathRoot)path).name); - else - throw new IllegalArgumentException(); - } - - public int createPathToId(Path path) { - if(path instanceof PathChild) { - PathChild child = (PathChild)path; - return getChild(createPathToId(child.parent), child.name); - } - else if(path instanceof PathRoot) - return getRoot(((PathRoot)path).name); - else - throw new IllegalArgumentException(); - } - - public Path idToPath(int id) { - ConsistsOf consistsOf = childMap.get(id); - if(consistsOf == null) { - String root = invRoots.get(id); - if(root == null) - return null; - else - return new PathRoot(root); - } - /*System.out.println("ConsistsOf(" + - consistsOf.parent + "." + consistsOf.name + - " = " + consistsOf.child + ")"); - */ - //if(consistsOf.parent == consistsOf.child) - // return null; - Path parentPath = idToPath(consistsOf.parent); - if(parentPath == null) - return null; - return new PathChild(consistsOf.name, parentPath); - } - - public boolean contains(Path path) { - return pathToId(path) >= 0; - } - - public boolean isNewResource(int id) { - return newResources.contains(id); - } - - public Identity[] toArray() { - final ArrayList identities = new ArrayList(); - collectIdentities(identities); - return identities.toArray(new Identity[identities.size()]); - } - - public void collectReferences(final boolean[] set) { - TIntProcedure proc = new TIntProcedure() { - @Override - public boolean execute(int value) { - set[value] = true; - return true; - } - }; - - roots.forEachValue(proc); - childMap.forEach(proc); - parentMap.forEach(proc); - } - - public int removeIdentity(int id) { - ConsistsOf c = childMap.remove(id); - if(c != null) { - parentMap.get(c.parent).remove(c.name); - return c.parent; - } - return -1; - } - - public boolean hasIdentity(int id) { - return childMap.containsKey(id); - } - - public void definePath(Path path, int resource) { - if(path instanceof PathChild) { - PathChild child = (PathChild)path; - int parent = createPathToId(child.parent); - defineChild(parent, child.name, resource); - } - else if(path instanceof PathRoot) { - defineRoot(((PathRoot)path).name, resource); - } - else - throw new IllegalArgumentException(); - } - - public void printChildMap() { - System.out.println("ChildMap:"); - childMap.forEachValue(new TObjectProcedure() { - - @Override - public boolean execute(ConsistsOf c) { - System.out.println(" " + - c.child + " = " + c.parent + "." + c.name); - return true; - } - - }); - } - - private int canonical(int a) { - if(unifications.contains(a)) { - int b = unifications.get(a); - if(unifications.contains(b)) { - int c = canonical(b); - unifications.put(a, c); - unifications.put(b, c); - return c; - } - else - return b; - } - else - return a; - } - - public TIntIntHashMap extractUnifications() { - // This normalizes the map - for(int a : unifications.keys()) - canonical(a); - - TIntIntHashMap result = unifications; - unifications = new TIntIntHashMap(); - - return result; - } - - public void unify(int a, int b) { - if(a != b) { - a = canonical(a); - b = canonical(b); - if(a != b) - unifications.put(a, b); - } - } - - public TIntHashSet getCollisions() { - return collisions; - } - - public String[] getRoots() { - return roots.keys(new String[roots.size()]); - } - - void findChildren(int id, final Path path, final String suffix, - final Pattern pattern, final THashSet result) { - if(pattern.matcher(suffix).matches()) - result.add(path); - THashMap map = parentMap.get(id); - if(map != null) - map.forEachValue(new TObjectProcedure() { - @Override - public boolean execute(ConsistsOf consistsOf) { - findChildren(consistsOf.child, new PathChild(consistsOf.name, path), - suffix + "/" + consistsOf.name, pattern, result); - return true; - } - }); - } - - public int[] getUnfoundedIdentities() { - TIntArrayList result = new TIntArrayList(); - for(int resource : parentMap.keys()) { - if(!childMap.containsKey(resource) && !invRoots.containsKey(resource)) { - result.add(resource); - } - } - return result.toArray(); - } - - public void forEachChild(TObjectProcedure proc) { - childMap.forEachValue(proc); - } - - public void setIdentity(int child, int parent, String name) { - THashMap map = parentMap.get(parent); - if(map == null) { - map = new THashMap(); - parentMap.put(parent, map); - } - else if(map.contains(name)) - throw new IllegalStateException(); - ConsistsOf consistsOf = new ConsistsOf(parent, name, child); - map.put(name, consistsOf); - childMap.put(child, consistsOf); - } - -} +package org.simantics.graph.store; + +import gnu.trove.list.array.TIntArrayList; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TIntIntHashMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.procedure.TIntProcedure; +import gnu.trove.procedure.TObjectIntProcedure; +import gnu.trove.procedure.TObjectObjectProcedure; +import gnu.trove.procedure.TObjectProcedure; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + +import java.util.ArrayList; +import java.util.regex.Pattern; + +import org.simantics.graph.query.Path; +import org.simantics.graph.query.PathChild; +import org.simantics.graph.query.PathRoot; +import org.simantics.graph.representation.External; +import org.simantics.graph.representation.Identity; +import org.simantics.graph.representation.Internal; +import org.simantics.graph.representation.Root; + +public class IdentityStore implements IStore { + + private static int[] EMPTY_INT_ARRAY = new int[0]; + + public static class ConsistsOf { + public int parent; + public String name; + public int child; + + public ConsistsOf(int parent, String name, int child) { + //System.out.println(parent + "." + name + " = " + child); + this.parent = parent; + this.name = name; + this.child = child; + } + } + + TObjectIntHashMap roots = new TObjectIntHashMap(); + TIntObjectHashMap invRoots = new TIntObjectHashMap(); + TIntObjectHashMap> parentMap = + new TIntObjectHashMap>(); + TIntObjectHashMap childMap = new TIntObjectHashMap(); + TIntHashSet newResources = new TIntHashSet(); + int resourceCount = 0; + TIntIntHashMap unifications = new TIntIntHashMap(); + TIntHashSet collisions = new TIntHashSet(); + + public int newResource() { + return resourceCount++; + } + + public boolean markNew(int resource) { + return newResources.add(resource); + } + + public int[] getNewResources() { + return newResources.toArray(); + } + + public int getResourceCount() { + return resourceCount; + } + + public void setResourceCount(int newCount) { + resourceCount = newCount; + } + + public void defineRoot(String name, int root) { + if(roots.contains(name)) + unify(root, roots.get(name)); + roots.put(name, root); + invRoots.put(root, name); + } + + public void defineChild(int parent, String name, int child) { + THashMap map = parentMap.get(parent); + if(map == null) { + map = new THashMap(); + parentMap.put(parent, map); + } + ConsistsOf consistsOf = new ConsistsOf(parent, name, child); + ConsistsOf oldC = map.put(name, consistsOf); + if(oldC != null) + unify(child, oldC.child); + childMap.put(child, consistsOf); + } + + public boolean hasChild(int parent, String name) { + THashMap map = parentMap.get(parent); + if(map == null) + return false; + else + return map.contains(name); + } + + public int getChild(int parent, String name) { + THashMap map = parentMap.get(parent); + if(map == null) { + map = new THashMap(); + parentMap.put(parent, map); + } + else if(map.contains(name)) + return map.get(name).child; + int child = newResource(); + ConsistsOf consistsOf = new ConsistsOf(parent, name, child); + map.put(name, consistsOf); + childMap.put(child, consistsOf); + return child; + } + + public int getChildIfExists(int parent, String name) { + THashMap map = parentMap.get(parent); + if(map != null && map.contains(name)) + return map.get(name).child; + return -1; + } + + public int getRoot(String uri) { + if(roots.contains(uri)) + return roots.get(uri); + else { + int root = newResource(); + roots.put(uri, root); + invRoots.put(root, uri); + return root; + } + } + + public int getRootIfExists(String uri) { + if(roots.contains(uri)) + return roots.get(uri); + return -1; + } + + public int[] getChildren(int id) { + THashMap map = parentMap.get(id); + if(map == null) + return EMPTY_INT_ARRAY; + final int[] result = new int[map.size()]; + map.forEachValue(new TObjectProcedure() { + int i=0; + @Override + public boolean execute(ConsistsOf object) { + result[i++] = object.child; + return true; + } + }); + return result; + } + + public THashMap getChildMap(int parent) { + return parentMap.get(parent); + } + + private void collectIdentities(final int parent, final ArrayList identities) { + THashMap map = parentMap.get(parent); + if(map != null) { + map.forEachEntry(new TObjectObjectProcedure() { + + @Override + public boolean execute(String a, ConsistsOf b) { + if(newResources.contains(b.child)) + identities.add(new Identity(b.child, new Internal(parent, a))); + else + identities.add(new Identity(b.child, new External(parent, a))); + collectIdentities(b.child, identities); + return true; + } + }); + } + } + + private void collectIdentities(final ArrayList identities) { + roots.forEachEntry(new TObjectIntProcedure() { + @Override + public boolean execute(String a, int b) { + identities.add(new Identity(b, new Root(a, ""))); + collectIdentities(b, identities); + return true; + } + }); + } + + @Override + public void map(final TIntIntHashMap map) { + collisions = IndexMappingUtils.map(map, collisions); + newResources = IndexMappingUtils.map(map, newResources); + IndexMappingUtils.map(map, roots); + invRoots = IndexMappingUtils.map(map, invRoots, collisions); + + final ArrayList consistsOfs = new ArrayList(childMap.size()); + childMap.forEachValue(new TObjectProcedure() { + @Override + public boolean execute(ConsistsOf c) { + if(map.contains(c.parent)) + c.parent = map.get(c.parent); + if(map.contains(c.child)) + c.child = map.get(c.child); + consistsOfs.add(c); + return true; + } + }); + + childMap.clear(); + parentMap.clear(); + assert(unifications.isEmpty()); + + for(ConsistsOf c : consistsOfs) { + THashMap m = parentMap.get(c.parent); + if(m == null) { + m = new THashMap(); + parentMap.put(c.parent, m); + } + ConsistsOf oldC = m.put(c.name, c); + ConsistsOf childC = childMap.put(c.child, c); + if(childC != null && (childC.parent != c.parent || !childC.name.equals(c.name))) + collisions.add(c.child); + + if(oldC != null) + unify(oldC.child, c.child); + } + } + + public int pathToId(Path path) { + if(path instanceof PathChild) { + PathChild child = (PathChild)path; + int parent = pathToId(child.parent); + if(parent < 0) + return -1; + return getChildIfExists(parent, child.name); + } + else if(path instanceof PathRoot) + return getRootIfExists(((PathRoot)path).name); + else + throw new IllegalArgumentException(); + } + + public int createPathToId(Path path) { + if(path instanceof PathChild) { + PathChild child = (PathChild)path; + return getChild(createPathToId(child.parent), child.name); + } + else if(path instanceof PathRoot) + return getRoot(((PathRoot)path).name); + else + throw new IllegalArgumentException(); + } + + public Path idToPath(int id) { + ConsistsOf consistsOf = childMap.get(id); + if(consistsOf == null) { + String root = invRoots.get(id); + if(root == null) + return null; + else + return new PathRoot(root); + } + /*System.out.println("ConsistsOf(" + + consistsOf.parent + "." + consistsOf.name + + " = " + consistsOf.child + ")"); + */ + //if(consistsOf.parent == consistsOf.child) + // return null; + Path parentPath = idToPath(consistsOf.parent); + if(parentPath == null) + return null; + return new PathChild(consistsOf.name, parentPath); + } + + public boolean contains(Path path) { + return pathToId(path) >= 0; + } + + public boolean isNewResource(int id) { + return newResources.contains(id); + } + + public Identity[] toArray() { + final ArrayList identities = new ArrayList(); + collectIdentities(identities); + return identities.toArray(new Identity[identities.size()]); + } + + public void collectReferences(final boolean[] set) { + TIntProcedure proc = new TIntProcedure() { + @Override + public boolean execute(int value) { + set[value] = true; + return true; + } + }; + + roots.forEachValue(proc); + childMap.forEach(proc); + parentMap.forEach(proc); + } + + public int removeIdentity(int id) { + ConsistsOf c = childMap.remove(id); + if(c != null) { + parentMap.get(c.parent).remove(c.name); + return c.parent; + } + return -1; + } + + public boolean hasIdentity(int id) { + return childMap.containsKey(id); + } + + public void definePath(Path path, int resource) { + if(path instanceof PathChild) { + PathChild child = (PathChild)path; + int parent = createPathToId(child.parent); + defineChild(parent, child.name, resource); + } + else if(path instanceof PathRoot) { + defineRoot(((PathRoot)path).name, resource); + } + else + throw new IllegalArgumentException(); + } + + public void printChildMap() { + System.out.println("ChildMap:"); + childMap.forEachValue(new TObjectProcedure() { + + @Override + public boolean execute(ConsistsOf c) { + System.out.println(" " + + c.child + " = " + c.parent + "." + c.name); + return true; + } + + }); + } + + private int canonical(int a) { + if(unifications.contains(a)) { + int b = unifications.get(a); + if(unifications.contains(b)) { + int c = canonical(b); + unifications.put(a, c); + unifications.put(b, c); + return c; + } + else + return b; + } + else + return a; + } + + public TIntIntHashMap extractUnifications() { + // This normalizes the map + for(int a : unifications.keys()) + canonical(a); + + TIntIntHashMap result = unifications; + unifications = new TIntIntHashMap(); + + return result; + } + + public void unify(int a, int b) { + if(a != b) { + a = canonical(a); + b = canonical(b); + if(a != b) + unifications.put(a, b); + } + } + + public TIntHashSet getCollisions() { + return collisions; + } + + public String[] getRoots() { + return roots.keys(new String[roots.size()]); + } + + void findChildren(int id, final Path path, final String suffix, + final Pattern pattern, final THashSet result) { + if(pattern.matcher(suffix).matches()) + result.add(path); + THashMap map = parentMap.get(id); + if(map != null) + map.forEachValue(new TObjectProcedure() { + @Override + public boolean execute(ConsistsOf consistsOf) { + findChildren(consistsOf.child, new PathChild(consistsOf.name, path), + suffix + "/" + consistsOf.name, pattern, result); + return true; + } + }); + } + + public int[] getUnfoundedIdentities() { + TIntArrayList result = new TIntArrayList(); + for(int resource : parentMap.keys()) { + if(!childMap.containsKey(resource) && !invRoots.containsKey(resource)) { + result.add(resource); + } + } + return result.toArray(); + } + + public void forEachChild(TObjectProcedure proc) { + childMap.forEachValue(proc); + } + + public void setIdentity(int child, int parent, String name) { + THashMap map = parentMap.get(parent); + if(map == null) { + map = new THashMap(); + parentMap.put(parent, map); + } + else if(map.contains(name)) + throw new IllegalStateException(); + ConsistsOf consistsOf = new ConsistsOf(parent, name, child); + map.put(name, consistsOf); + childMap.put(child, consistsOf); + } + +}