-/*******************************************************************************\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