/******************************************************************************* * 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.db.procore.cluster; import java.util.UUID; 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.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 fi.vtt.simantics.procore.internal.Change; import fi.vtt.simantics.procore.internal.ClusterChange; import fi.vtt.simantics.procore.internal.ClusterTable; import fi.vtt.simantics.procore.internal.SessionImplSocket; public abstract class ClusterImpl extends ClusterBase implements Modifier, CollectorCluster { private static final int LONG_HEADER_SIZE = 7; private 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]); 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; // 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 ClusterTable clusterTable; public ClusterImpl(ClusterUID clusterUID, int clusterKey, ClusterSupport support) { super(support, clusterUID, clusterKey); this.clusterTable = ((SessionImplSocket)support.getSession()).clusterTable; } public static ClusterImpl make(ClusterUID clusterUID, int clusterKey, ClusterSupport support) { return new ClusterSmall(clusterUID, clusterKey, support); } public static ClusterSmall proxy(ClusterUID clusterUID, int clusterKey, long clusterId, ClusterSupport support) { if (DEBUG) new Exception("Cluster proxy for " + clusterUID).printStackTrace(); return new ClusterSmall(clusterUID, clusterKey, ((SessionImplSocket)support.getSession()).clusterTable, support); } public static ClusterImpl make(long[] longs, int[] ints, byte[] bytes, ClusterSupport support, int clusterKey) throws DatabaseException { if (longs[0] == 0) return new ClusterBig(longs, ints, bytes, support, clusterKey); else return new ClusterSmall(longs, ints, bytes, support, clusterKey); } public abstract ClusterBig toBig(ClusterSupport support) throws DatabaseException; public abstract void checkDirectReference(int dr) throws DatabaseException; public abstract void checkForeingIndex(int fi) throws DatabaseException; public abstract void checkObjectSetReference(int or) throws DatabaseException; // public boolean virtual = false; @Override public boolean hasVirtual() { 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; 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())); } @Override public IClusterTable getClusterTable() { return clusterTable; } }