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