/******************************************************************************* * 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 org.simantics.acorn.cluster; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.UUID; import org.simantics.acorn.internal.Change; import org.simantics.acorn.internal.ClusterChange; import org.simantics.acorn.internal.ClusterSupport2; import org.simantics.db.common.utils.Logger; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.InvalidClusterException; import org.simantics.db.impl.ClusterBase; import org.simantics.db.impl.ClusterI; import org.simantics.db.impl.ClusterSupport; import org.simantics.db.impl.IClusterTable; import org.simantics.db.impl.Modifier; import org.simantics.db.service.ClusterCollectorPolicy.CollectorCluster; import org.simantics.db.service.ClusterUID; import org.simantics.db.service.ClusteringSupport.Id; import org.simantics.utils.strings.AlphanumComparator; public abstract class ClusterImpl extends ClusterBase implements Modifier, CollectorCluster { protected static final int LONG_HEADER_SIZE = 7; protected static final long LONG_HEADER_VERSION = 1; protected static ClusterUID checkValidity(long type, long[] longs, int[] ints, byte[] bytes) throws InvalidClusterException { if (longs.length < LONG_HEADER_SIZE) throw new InvalidClusterException("Header size mismatch. Expected=" + ClusterImpl.LONG_HEADER_SIZE + ", got=" + longs.length); if (longs[0] != type) throw new InvalidClusterException("Type mismatch. Expected=" + type + ", got=" + longs[0] + " " + ClusterUID.make(longs[2], longs[3])); if (longs[1] != ClusterImpl.LONG_HEADER_VERSION) throw new InvalidClusterException("Header size mismatch. Expected=" + ClusterImpl.LONG_HEADER_VERSION + ", got=" + longs[1]); return ClusterUID.make(longs[2], longs[3]); } protected static Id getUniqueId(long[] longs) { return new IdImpl(new UUID(longs[3], longs[4])); } static final boolean DEBUG = false; final public IClusterTable clusterTable; // This can be null iff the cluster has been converted to big public Change change = new Change(); public ClusterChange cc; public byte[] foreignLookup; private boolean dirtySizeInBytes = true; private long sizeInBytes = 0; protected ClusterImpl() { clusterTable = null; } public ClusterImpl(IClusterTable clusterTable, ClusterUID clusterUID, int clusterKey, ClusterSupport support) { super(support, clusterUID, clusterKey); // SessionImplSocket session = (SessionImplSocket)support.getSession(); // if(session != null) this.clusterTable = clusterTable; // else } public static ClusterImpl dummy() { return new ClusterSmall(); } public static ClusterImpl make(IClusterTable clusterTable, ClusterUID clusterUID, int clusterKey, ClusterSupport2 support) { return new ClusterSmall(clusterUID, clusterKey, support, clusterTable); } public static ClusterSmall proxy(IClusterTable clusterTable, ClusterUID clusterUID, int clusterKey, long clusterId, ClusterSupport2 support) { if (DEBUG) new Exception("Cluster proxy for " + clusterUID).printStackTrace(); return new ClusterSmall(null, clusterUID, clusterKey, support); } public static ClusterImpl make(IClusterTable clusterTable, long[] longs, int[] ints, byte[] bytes, ClusterSupport2 support, int clusterKey) throws DatabaseException { if (longs[0] == 0) return new ClusterBig(clusterTable, longs, ints, bytes, support, clusterKey); else return new ClusterSmall(clusterTable, longs, ints, bytes, support, clusterKey); } // public boolean virtual = false; @Override public boolean hasVirtual() { return false; // return clusterTable.hasVirtual(clusterKey); } @Override public void markVirtual() { // clusterTable.markVirtual(clusterKey); // virtual = true; } @Override public boolean isWriteOnly() { return false; } @Override public boolean isLoaded() { return true; } @Override public void resized() { dirtySizeInBytes = true; // if(clusterTable != null) // clusterTable.setDirtySizeInBytes(true); } public long getCachedSize() { if(dirtySizeInBytes) { try { sizeInBytes = getUsedSpace(); //System.err.println("recomputed size of cluster " + getClusterId() + " => " + sizeInBytes); } catch (DatabaseException e) { Logger.defaultLogError(e); } dirtySizeInBytes = false; } return sizeInBytes; } protected void calculateModifiedId() { // setModifiedId(new IdImpl(UUID.randomUUID())); } public static class ClusterTables { public byte[] bytes; public int[] ints; public long[] longs; } public byte[] storeBytes() throws IOException { throw new UnsupportedOperationException(); } public ClusterTables store() throws IOException { throw new UnsupportedOperationException(); } abstract protected int getResourceTableCount(); public String dump(final ClusterSupport support) { StringBuilder sb = new StringBuilder(); for(int i=1;i stms = new ArrayList(); try { byte[] value = getValue(i, support); if(value != null) sb.append(" bytes: " + Arrays.toString(value) + "\n"); forPredicates(i, new PredicateProcedure() { @Override public boolean execute(Integer c, final int predicateKey, int objectIndex) { try { forObjects(resourceKey, predicateKey, objectIndex, new ObjectProcedure() { @Override public boolean execute(Integer context, int objectKey) throws DatabaseException { ClusterUID puid = support.getClusterByResourceKey(predicateKey).getClusterUID(); ClusterUID ouid = support.getClusterByResourceKey(objectKey).getClusterUID(); stms.add(" " + puid + " " + (predicateKey&0xFFF) + " " + ouid + " " + (objectKey&0xFFF)); return false; } }, 0, support); } catch (DatabaseException e) { e.printStackTrace(); } return false; } },0,support); Collections.sort(stms, AlphanumComparator.COMPARATOR); for(String s : stms) { sb.append(s); sb.append("\n"); } } catch (DatabaseException e) { e.printStackTrace(); } } return sb.toString(); } abstract public boolean isValueEx(int resourceIndex) throws DatabaseException; abstract public ClusterI addRelation(int resourceKey, ClusterUID puid, int predicateKey, ClusterUID ouid, int objectKey, ClusterSupport support) throws DatabaseException; @Override public IClusterTable getClusterTable() { return clusterTable; } }