/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * 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 * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package fi.vtt.simantics.procore.internal; //package fi.vtt.simantics.procore.internal2; // //import java.util.ArrayList; //import java.util.Collection; //import java.util.HashMap; //import java.util.HashSet; //import java.util.Map; // //import org.simantics.db.ReadGraph; //import org.simantics.db.Resource; //import org.simantics.db.WriteGraph; //import org.simantics.db.common.queries.QueryProvider; //import org.simantics.db.queries.QuerySupport; //import org.simantics.utils.datastructures.Pair; // //import fi.vtt.simantics.procore.internal2.ClusteringInformation.ReclusterIterator; // //class ClusteringAlgorithmImpl implements ClusteringAlgorithm { // // HashMap assignment; // // class NewCluster { // int existing; // int root; // int size = 0; // long id = 0; // ArrayList ids = new ArrayList(); // public NewCluster(int existing, int root) { // this.existing = existing; // this.root = root; // } // public void grow(Integer id) { // size++; // assignment.put(id, this); // ids.add(id); // } // public void merge(NewCluster other) { // assert(other != this); // for(int i : other.ids) grow(i); // other.size = 0; // } // public int size() { // return size; // } // } // // class CoverageNode { // // public int seed; // public int lastCoverage = 1; // public int coverage = 1; // // public CoverageNode(int id) { // this.seed = id; // } // // } // // int instanceOf; // int consistsOf; // int dependsOn; // // HashSet properties; // HashSet depends; // HashSet unknown; // // class Statement { // final public int subject; // final public int predicate; // final public int object; // public Statement(int s, int p, int o) { // //System.out.println("new Statement(" + s + "," + p + "," + o + ")"); // subject = s; // predicate = p; // object = o; // } // }; // // private void computeCoverages(HashMap newNodes, QuerySupport core, ArrayList statements) { // // for(int i=0;i<5;i++) { // for(CoverageNode n : newNodes.values()) { // n.lastCoverage = n.coverage; // n.coverage = 1; // } // for(Statement s : statements) { // if(depends.contains(s.predicate)) { // CoverageNode sn = newNodes.get(s.subject); // CoverageNode on = newNodes.get(s.object); // if(sn != null && on != null) { // sn.coverage += on.lastCoverage; // } // } // } // } // // } // // private final int MAX_COVERAGE = 5000; // private final int MAX_CLUSTER = 5000; // private final int MAX_CLUSTER_2 = 15000; // // private void clusterNode(CoverageNode node, HashMap newNodes, QuerySupport core, HashMap> deps, HashSet visited, NewCluster topCluster, NewCluster currentCluster, ArrayList clusters) { // // assert(node != null); // // if(visited.contains(node)) return; // visited.add(node); // // if(node.coverage > MAX_COVERAGE) { // topCluster.grow(node.seed); // } else { // currentCluster.grow(node.seed); // } // // Collection dc = deps.get(node.seed); // if(dc == null) return; // // for(Integer i : dc) { // // CoverageNode sn = newNodes.get(i); // if(sn != null) { // // //System.out.println("traverse: " + node.coverage + " " + sn.coverage + " " + currentCluster.size()); // // if(node.coverage > MAX_COVERAGE && sn.coverage < MAX_COVERAGE) { // // if(currentCluster.size() > MAX_CLUSTER) { //// System.out.println("new cluster: " + node.coverage + " " + sn.coverage + " " + currentCluster.size()); // currentCluster = new NewCluster(0, node.seed); // clusters.add(currentCluster); // } else { //// System.out.println("continue cluster: " + node.coverage + " " + sn.coverage + " " + currentCluster.size()); // } // // } // // clusterNode(sn, newNodes, core, deps, visited, topCluster, currentCluster, clusters); // // } // // } // // } // // private void combineExistingSiblings(ArrayList clusters, ClusteringSupport support) { // // HashMap> siblings = new HashMap>(); // for(NewCluster cluster : clusters) { // // if(cluster.size() < MAX_CLUSTER && cluster.existing > 0) { // // ArrayList list = siblings.get(cluster.existing); // if(list == null) { // list = new ArrayList(); // siblings.put(cluster.existing, list); // } // list.add(cluster); // // } // // } // // for(ArrayList list : siblings.values()) { // // if(list.size() < 2) continue; // //// System.out.println("Processing shared root with " + list.size() + " new clusters."); // // NewCluster current = null; // // for(NewCluster cluster : list) { // // if(current == null) { // current = cluster; // } else { // //System.out.println("Merging to sibling cluster " + current.size + " <-> " + cluster.size); // current.merge(cluster); // } // // if(current.size > MAX_CLUSTER) { // current.id = support.newClusterId(); // current = null; // } // // } // // } // // } // // // private void combineRootSiblings(ArrayList clusters, ClusteringSupport support) { // // HashMap> siblings = new HashMap>(); // for(NewCluster cluster : clusters) { // // if(cluster.size() < MAX_CLUSTER) { // // ArrayList list = siblings.get(cluster.root); // if(list == null) { // list = new ArrayList(); // siblings.put(cluster.root, list); // } // list.add(cluster); // // } // // } // // for(ArrayList list : siblings.values()) { // // if(list.size() < 2) continue; // //// System.out.println("Processing shared root with " + list.size() + " new clusters."); // // NewCluster current = null; // // for(NewCluster cluster : list) { // // if(current == null) { // current = cluster; // } else { //// System.out.println("Merging to sibling cluster " + current.size + " <-> " + cluster.size); // current.merge(cluster); // } // // if(current.size > MAX_CLUSTER) { // current.id = support.newClusterId(); // current = null; // } // // } // // } // // } // // private void cluster(HashMap roots, HashMap newNodes, ClusteringSupport support, QuerySupport core, ReadGraph graph, HashMap> deps) { // // ArrayList clusters = new ArrayList(); // HashSet visited = new HashSet(); // for(Map.Entry e : roots.entrySet()) { // NewCluster topCluster = new NewCluster(e.getValue(), e.getKey()); // NewCluster currentCluster = new NewCluster(e.getValue(), e.getKey()); // clusterNode(newNodes.get(e.getKey()), newNodes, core, deps, visited, topCluster, currentCluster, clusters); // if(topCluster.size > 0) clusters.add(topCluster); // if(currentCluster.size > 0) clusters.add(currentCluster); // } // //// System.out.println("Initial clustering produced " + clusters.size() + " clusters."); // // combineRootSiblings(clusters, support); // combineExistingSiblings(clusters, support); // // for(NewCluster cluster : clusters) { // // if(cluster.size() > 0 && cluster.size() < MAX_CLUSTER) { // // if(!newNodes.containsKey(cluster.existing)) { // // Collection siblings2 = graph.getObjects(core.getResource(cluster.root), graph.getBuiltins().DependsOn); // // for(Resource sibling : siblings2) { // // if(newNodes.get(core.getId(sibling)) == null) { // // long existing = support.getCluster(sibling); // long existingSize = support.getClusterSizeCache(existing); // if(existingSize < MAX_CLUSTER_2) { // cluster.id = existing; // System.out.println("Merging to existing cluster " + existing + " with size " + existingSize); // } else { // System.out.println(" -sibling too large (" + existingSize + ")"); // } // // } // // } // // } // // } // // if(cluster.size > 0 && cluster.id == 0) { // cluster.id = support.newClusterId(); // } // // } // //// System.out.println("Clustering report:"); // // int total = 0; // int totalClusters = 0; // for(NewCluster c : clusters) { // if(c.size() > 0) { //// System.out.println("-" + c.size() + " elements - id = " + c.id); // total += c.size(); // totalClusters++; // } // } // // //System.out.println("Total of " + total + " elements in " + totalClusters + " clusters."); // // } // // @Override // public void recluster(ClusteringInformation info, ClusteringSupport clusteringSupport, ReadGraph graph, QuerySupport querySupport, QueryProvider queryProvider) { // //// Collection resources = new ArrayList(); //// ReclusterIterator it = info.getReclusterIterator(); //// if(it == null) return; //// //// while(it.hasNext()) { //// it.advance(); //// resources.add(it.getReclusterResourceId()); //// } //// //// ArrayList statements = new ArrayList(); //// AddedStatmentsIterator it2 = info.getAddedStatmentsIterator(); //// while(it2.hasNext()) { //// it2.advance(); //// statements.add(new Statement(it2.getAddedSubjectId(), it2.getAddedPredicateId(), it2.getAddedObjectId())); //// } //// //// //System.out.println("Clustering " + resources.size() + " new resources, " + statements.size() + " new statements."); //// //// try { //// //// HashMap newNodes = new HashMap(); //// //// instanceOf = querySupport.getId(graph.getBuiltins().InstanceOf); //// consistsOf = querySupport.getId(graph.getBuiltins().ConsistsOf); //// dependsOn = querySupport.getId(graph.getBuiltins().DependsOn); //// //// assignment = new HashMap(); //// properties = new HashSet(); //// depends = new HashSet(); //// unknown = new HashSet(); //// //// depends.add(consistsOf); //// //// for(Integer r : resources) { //// newNodes.put(r, new CoverageNode(r)); //// } //// //// for(Statement s : statements) { //// //// if(unknown.contains(s.predicate)) continue; //// if(depends.contains(s.predicate)) continue; //// if(properties.contains(s.predicate)) continue; //// if(s.predicate == instanceOf) continue; //// if(s.predicate == consistsOf) continue; //// //// if(graph.isSubrelationOf(querySupport.getResource(s.predicate), graph.getBuiltins().HasProperty)) { //// properties.add(s.predicate); //// } else if(graph.isSubrelationOf(querySupport.getResource(s.predicate), graph.getBuiltins().DependsOn)) { //// depends.add(s.predicate); //// } else { //// unknown.add(s.predicate); //// } //// //// } //// //// depends.addAll(properties); //// //// HashSet roots = new HashSet(); //// for(Integer r : resources) roots.add(r); //// //// HashMap> deps = new HashMap>(); //// //// for(Statement s : statements) { //// //// if(depends.contains(s.predicate)) { //// if(newNodes.containsKey(s.subject)) roots.remove(s.object); //// Collection coll = deps.get(s.subject); //// if(coll == null) { //// coll = new ArrayList(); //// deps.put(s.subject, coll); //// } //// coll.add(s.object); //// } //// //// } //// ////// System.out.println("" + roots.size() + " roots."); //// //// for(Statement s : statements) { //// //// if(roots.contains(s.object) && s.predicate == instanceOf && newNodes.containsKey(s.subject)) { //// roots.remove(s.object); //// Collection coll = deps.get(s.subject); //// if(coll == null) { //// deps.put(s.subject, new SingletonCollection(s.object)); //// } else { //// coll.add(s.object); //// } //// } //// //// } // //// System.out.println("" + roots.size() + " roots."); // //// HashMap roots2 = new HashMap(); //// for(Statement s : statements) { //// if(depends.contains(s.predicate)) { //// if(roots.contains(s.object)) { //// roots2.put(s.object, s.subject); //// } //// } //// } // //// for(Integer i : roots) { //// System.out.println("root"); //// for(StatementImpl2 s2 : statements) { //// int sub = core.getId(s2.getSubject()); //// if(sub == i) { //// System.out.println("-" + g.adapt(s2.getPredicate(), g.getBuiltins().HasStringRepresentation)); //// } //// } //// } // //// System.out.println("" + roots.size() + " roots after parent search."); // //// System.out.println("-found " + properties.size() + " property relations"); //// for(Integer i : properties) { //// System.out.println("-" + graph.adapt(querySupport.getResource(i), graph.getBuiltins().HasStringRepresentation)); //// } //// System.out.println("-found " + depends.size() + " depends on relations"); //// for(Integer i : depends) { //// System.out.println("-" + graph.adapt(querySupport.getResource(i), graph.getBuiltins().HasStringRepresentation)); //// } //// System.out.println("-found " + unknown.size() + " other relations"); //// for(Integer i : unknown) { //// System.out.println("-" + graph.adapt(querySupport.getResource(i), graph.getBuiltins().HasStringRepresentation)); //// } // //// computeCoverages(newNodes, querySupport, statements); //// cluster(roots2, newNodes, clusteringSupport, querySupport, graph, deps); // //// System.out.println("finished clustering"); // //// long cid = clusteringSupport.newClusterId(); // // long defaultCluster = 0; // ReclusterIterator it3 = info.getReclusterIterator(); // while(it3.hasNext()) { // int id = it3.getReclusterResourceId(); // // Long cluster = assignment2.get(id); // if(cluster == null) { // if(defaultCluster == 0) defaultCluster = clusteringSupport.newClusterId(); // cluster = defaultCluster; // } // // it3.setReclusterResourceCluster(cluster); //// it3.setReclusterResourceCluster(cid); // it3.advance(); // //// if(newContexts.contains(id)) { //// it3.setReclusterResourceCluster(clusteringSupport.newClusterId()); //// it3.advance(); //// } else { //// NewCluster t = assignment.get(id); //// it3.setReclusterResourceCluster(t.id); //// it3.advance(); //// } // // } // //// } catch(Throwable t) { //// //// t.printStackTrace(); //// //// } // // } // // private HashMap> contextCache = new HashMap>(); // // HashSet newContexts; // // HashMap assignment2; // // @Override // public void createContexts(HashMap newResources, WriteGraph g, QuerySupport querySupport, ClusteringSupport clusteringSupport) { // // newContexts = new HashSet(); // assignment2 = new HashMap(); // // HashMap> contexts = new HashMap>(); // for(Map.Entry entry : newResources.entrySet()) { // // assert(entry.getKey() != null); // assert(entry.getValue() != null); // // Collection coll = contexts.get(entry.getValue()); // if(coll == null) { // coll = new ArrayList(); // contexts.put(entry.getValue(), coll); // } // coll.add(entry.getKey()); // // } // //// long newClusterId = clusteringSupport.newClusterId(); //// // for(Map.Entry> entry : contexts.entrySet()) { // // Resource context = g.getBuiltins().RootLibrary; // Resource type = entry.getKey(); // // Resource typeContext = null; // long fill = 10000; // // long assignedClusterId = 0; // //// Collection ctxs = g.getObjects(context, type); // // Pair contextPair = contextCache.get(type); // if(contextPair != null) { // // typeContext = contextPair.first; // fill = contextPair.second; // assignedClusterId = clusteringSupport.getCluster(typeContext); // // } else { // //// System.out.println("No existing context found in " + context.getResourceId() + " for type " + type.getResourceId()); // // } // //// for(Resource ctx : ctxs) { //// long clusterId = clusteringSupport.getCluster(ctx); //// long size = clusteringSupport.getClusterSizeCache(clusterId); //// if(size < 500000) { //// typeContext = ctx; //// fill = (long)(10000.0 * ((double)size / 500000.0)); //// System.out.println("Append to existing context " + clusteringSupport.getCluster(ctx) + "(res=" + typeContext.getResourceId() + ") with size " + clusteringSupport.getClusterSize(clusteringSupport.getCluster(ctx))); //// assignedClusterId = clusterId; //// break; //// } else { //// System.out.println("Context cluster size was " + clusteringSupport.getClusterSize(clusteringSupport.getCluster(ctx))); //// } //// } //// //// if(ctxs.size() == 0) System.out.println("No contexts found in " + context.getResourceId() + " for type " + type.getResourceId()); // // for(Resource newResource : entry.getValue()) { // // if(fill >= 10000) { // typeContext = g.newResource(); // g.addStatement(context, type, type, typeContext); // g.addStatement(typeContext, g.getBuiltins().Inherits, g.getBuiltins().SupertypeOf, type); // newContexts.add(querySupport.getId(typeContext)); // fill = 0; // assignedClusterId = clusteringSupport.newClusterId(); // assignment2.put(querySupport.getId(typeContext), assignedClusterId); // } // // assignment2.put(querySupport.getId(newResource), assignedClusterId); // // g.addStatement(typeContext, g.getBuiltins().HasInstance, g.getBuiltins().InstanceOf, newResource); // fill++; // // } // // contextCache.put(type, new Pair(typeContext, (int)fill)); // // } // // } // //}