1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.acorn.cluster;
14 import java.io.IOException;
15 import java.util.ArrayList;
16 import java.util.Arrays;
17 import java.util.Collections;
18 import java.util.UUID;
20 import org.simantics.acorn.internal.Change;
21 import org.simantics.acorn.internal.ClusterChange;
22 import org.simantics.acorn.internal.ClusterSupport2;
23 import org.simantics.db.common.utils.Logger;
24 import org.simantics.db.exception.DatabaseException;
25 import org.simantics.db.exception.InvalidClusterException;
26 import org.simantics.db.impl.ClusterBase;
27 import org.simantics.db.impl.ClusterI;
28 import org.simantics.db.impl.ClusterSupport;
29 import org.simantics.db.impl.IClusterTable;
30 import org.simantics.db.impl.Modifier;
31 import org.simantics.db.service.ClusterCollectorPolicy.CollectorCluster;
32 import org.simantics.db.service.ClusterUID;
33 import org.simantics.db.service.ClusteringSupport.Id;
34 import org.simantics.utils.strings.AlphanumComparator;
36 public abstract class ClusterImpl extends ClusterBase implements Modifier, CollectorCluster {
37 protected static final int LONG_HEADER_SIZE = 7;
38 protected static final long LONG_HEADER_VERSION = 1;
39 protected static ClusterUID checkValidity(long type, long[] longs, int[] ints, byte[] bytes)
40 throws InvalidClusterException {
41 if (longs.length < LONG_HEADER_SIZE)
42 throw new InvalidClusterException("Header size mismatch. Expected=" + ClusterImpl.LONG_HEADER_SIZE + ", got=" + longs.length);
44 throw new InvalidClusterException("Type mismatch. Expected=" + type + ", got=" + longs[0] + " " + ClusterUID.make(longs[2], longs[3]));
45 if (longs[1] != ClusterImpl.LONG_HEADER_VERSION)
46 throw new InvalidClusterException("Header size mismatch. Expected=" + ClusterImpl.LONG_HEADER_VERSION + ", got=" + longs[1]);
47 return ClusterUID.make(longs[2], longs[3]);
49 protected static Id getUniqueId(long[] longs) {
50 return new IdImpl(new UUID(longs[3], longs[4]));
52 static final boolean DEBUG = false;
53 final public IClusterTable clusterTable;
54 // This can be null iff the cluster has been converted to big
55 public Change change = new Change();
56 public ClusterChange cc;
57 public byte[] foreignLookup;
59 private boolean dirtySizeInBytes = true;
60 private long sizeInBytes = 0;
62 protected ClusterImpl() {
66 public ClusterImpl(IClusterTable clusterTable, ClusterUID clusterUID, int clusterKey, ClusterSupport support) {
67 super(support, clusterUID, clusterKey);
68 // SessionImplSocket session = (SessionImplSocket)support.getSession();
69 // if(session != null)
70 this.clusterTable = clusterTable;
74 public static ClusterImpl dummy() {
75 return new ClusterSmall();
78 public static ClusterImpl make(IClusterTable clusterTable, ClusterUID clusterUID, int clusterKey, ClusterSupport2 support) {
79 return new ClusterSmall(clusterUID, clusterKey, support, clusterTable);
81 public static ClusterSmall proxy(IClusterTable clusterTable, ClusterUID clusterUID, int clusterKey, long clusterId, ClusterSupport2 support) {
83 new Exception("Cluster proxy for " + clusterUID).printStackTrace();
84 return new ClusterSmall(null, clusterUID, clusterKey, support);
86 public static ClusterImpl make(IClusterTable clusterTable, long[] longs, int[] ints, byte[] bytes, ClusterSupport2 support, int clusterKey)
87 throws DatabaseException {
89 return new ClusterBig(clusterTable, longs, ints, bytes, support, clusterKey);
91 return new ClusterSmall(clusterTable, longs, ints, bytes, support, clusterKey);
94 // public boolean virtual = false;
97 public boolean hasVirtual() {
99 // return clusterTable.hasVirtual(clusterKey);
103 public void markVirtual() {
104 // clusterTable.markVirtual(clusterKey);
109 public boolean isWriteOnly() {
113 public boolean isLoaded() {
118 public void resized() {
119 dirtySizeInBytes = true;
120 // if(clusterTable != null)
121 // clusterTable.setDirtySizeInBytes(true);
124 public long getCachedSize() {
125 if(dirtySizeInBytes) {
127 sizeInBytes = getUsedSpace();
128 //System.err.println("recomputed size of cluster " + getClusterId() + " => " + sizeInBytes);
129 } catch (DatabaseException e) {
130 Logger.defaultLogError(e);
132 dirtySizeInBytes = false;
137 protected void calculateModifiedId() {
138 // setModifiedId(new IdImpl(UUID.randomUUID()));
141 public static class ClusterTables {
147 public byte[] storeBytes() throws IOException {
148 throw new UnsupportedOperationException();
151 public ClusterTables store() throws IOException {
152 throw new UnsupportedOperationException();
155 abstract protected int getResourceTableCount();
157 public String dump(final ClusterSupport support) {
159 StringBuilder sb = new StringBuilder();
160 for(int i=1;i<getResourceTableCount();i++) {
161 sb.append(""+i+"\n");
162 final int resourceKey = i;
163 final ArrayList<String> stms = new ArrayList<String>();
166 byte[] value = getValue(i, support);
168 sb.append(" bytes: " + Arrays.toString(value) + "\n");
170 forPredicates(i, new PredicateProcedure<Integer>() {
173 public boolean execute(Integer c, final int predicateKey, int objectIndex) {
177 forObjects(resourceKey, predicateKey, objectIndex, new ObjectProcedure<Integer>() {
180 public boolean execute(Integer context, int objectKey) throws DatabaseException {
182 ClusterUID puid = support.getClusterByResourceKey(predicateKey).getClusterUID();
183 ClusterUID ouid = support.getClusterByResourceKey(objectKey).getClusterUID();
185 stms.add(" " + puid + " " + (predicateKey&0xFFF) + " " + ouid + " " + (objectKey&0xFFF));
192 } catch (DatabaseException e) {
202 Collections.sort(stms, AlphanumComparator.COMPARATOR);
204 for(String s : stms) {
209 } catch (DatabaseException e) {
214 return sb.toString();
218 abstract public boolean isValueEx(int resourceIndex) throws DatabaseException;
220 abstract public ClusterI addRelation(int resourceKey, ClusterUID puid, int predicateKey, ClusterUID ouid, int objectKey, ClusterSupport support) throws DatabaseException;
223 public IClusterTable getClusterTable() {