]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ClusterBig.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.db.procore / src / org / simantics / db / procore / cluster / ClusterBig.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.db.procore.cluster;\r
13 \r
14 import java.io.ByteArrayInputStream;\r
15 import java.io.InputStream;\r
16 \r
17 import org.simantics.db.Resource;\r
18 import org.simantics.db.exception.DatabaseException;\r
19 import org.simantics.db.exception.ExternalValueException;\r
20 import org.simantics.db.exception.ValidationException;\r
21 import org.simantics.db.impl.ClusterI;\r
22 import org.simantics.db.impl.ClusterI.PredicateProcedure;\r
23 import org.simantics.db.impl.ClusterSupport;\r
24 import org.simantics.db.impl.ClusterTraitsBase;\r
25 import org.simantics.db.impl.ForEachObjectContextProcedure;\r
26 import org.simantics.db.impl.ForEachObjectProcedure;\r
27 import org.simantics.db.impl.ForPossibleRelatedValueContextProcedure;\r
28 import org.simantics.db.impl.ForPossibleRelatedValueProcedure;\r
29 import org.simantics.db.impl.Table;\r
30 import org.simantics.db.impl.TableHeader;\r
31 import org.simantics.db.impl.graph.ReadGraphImpl;\r
32 import org.simantics.db.impl.query.QueryProcessor;\r
33 import org.simantics.db.procedure.AsyncContextMultiProcedure;\r
34 import org.simantics.db.procedure.AsyncMultiProcedure;\r
35 import org.simantics.db.service.ClusterUID;\r
36 import org.simantics.utils.datastructures.Callback;\r
37 \r
38 import fi.vtt.simantics.procore.DebugPolicy;\r
39 import fi.vtt.simantics.procore.internal.ClusterChange;\r
40 import fi.vtt.simantics.procore.internal.ClusterStream;\r
41 import fi.vtt.simantics.procore.internal.SessionImplSocket;\r
42 \r
43 final public class ClusterBig extends ClusterImpl {\r
44     private static final int TABLE_HEADER_SIZE = TableHeader.HEADER_SIZE + TableHeader.EXTRA_SIZE;\r
45     private static final int RESOURCE_TABLE_OFFSET = 0;\r
46     private static final int PREDICATE_TABLE_OFFSET = RESOURCE_TABLE_OFFSET + TABLE_HEADER_SIZE;\r
47     private static final int OBJECT_TABLE_OFFSET = PREDICATE_TABLE_OFFSET + TABLE_HEADER_SIZE;\r
48     private static final int VALUE_TABLE_OFFSET = OBJECT_TABLE_OFFSET + TABLE_HEADER_SIZE;\r
49     private static final int FLAT_TABLE_OFFSET = VALUE_TABLE_OFFSET + TABLE_HEADER_SIZE;\r
50     private static final int COMPLETE_TABLE_OFFSET = FLAT_TABLE_OFFSET + TABLE_HEADER_SIZE;\r
51     private static final int FOREIGN_TABLE_OFFSET = COMPLETE_TABLE_OFFSET + TABLE_HEADER_SIZE;\r
52     private static final int INT_HEADER_SIZE = FOREIGN_TABLE_OFFSET + TABLE_HEADER_SIZE;\r
53     private final int clusterBits;\r
54     final private ResourceTable resourceTable;\r
55     //final private ResourceTable movedResourceTable;\r
56     final private PredicateTable predicateTable;\r
57     final private ObjectTable objectTable;\r
58     final private ValueTable valueTable;\r
59     final private FlatTable flatTable;\r
60     final private ForeignTable foreignTable;\r
61     final private CompleteTable completeTable;\r
62     final private ClusterMap clusterMap;\r
63     final private int[] headerTable;\r
64     final private ClusterSupport clusterSupport;\r
65     public ClusterBig(ClusterUID clusterUID, int clusterKey, ClusterSupport support) {\r
66         super(clusterUID, clusterKey, support);\r
67         if(DebugPolicy.REPORT_CLUSTER_EVENTS)\r
68             new Exception(getClusterUID().toString()).printStackTrace();\r
69         this.headerTable = new int[INT_HEADER_SIZE];\r
70         this.resourceTable = new ResourceTable(this, headerTable, RESOURCE_TABLE_OFFSET);\r
71         this.foreignTable = new ForeignTable(this, headerTable, FOREIGN_TABLE_OFFSET);\r
72         this.predicateTable = new PredicateTable(this, headerTable, PREDICATE_TABLE_OFFSET);\r
73         this.objectTable = new ObjectTable(this, headerTable, OBJECT_TABLE_OFFSET);\r
74         this.valueTable = new ValueTable(this, headerTable, VALUE_TABLE_OFFSET);\r
75         this.completeTable = new CompleteTable(this, headerTable, COMPLETE_TABLE_OFFSET);\r
76         this.flatTable = null;\r
77         this.clusterMap = new ClusterMap(foreignTable, flatTable);\r
78         this.clusterSupport = support;\r
79         this.clusterBits = ClusterTraitsBase.getClusterBits(clusterKey);\r
80         this.importance = 0;\r
81 //        clusterTable.setDirtySizeInBytes(true);\r
82     }\r
83     protected ClusterBig(long[] longs, int[] ints, byte[] bytes, ClusterSupport support, int clusterKey)\r
84     throws DatabaseException {\r
85         super(checkValidity(0, longs, ints, bytes), clusterKey, support);\r
86         if(DebugPolicy.REPORT_CLUSTER_EVENTS)\r
87             new Exception(getClusterUID().toString()).printStackTrace();\r
88         if (ints.length < INT_HEADER_SIZE)\r
89             throw new IllegalArgumentException("Too small integer table for cluster.");\r
90         this.headerTable = ints;\r
91         this.resourceTable = new ResourceTable(this, ints, RESOURCE_TABLE_OFFSET, longs);\r
92         this.foreignTable = new ForeignTable(this, headerTable, FOREIGN_TABLE_OFFSET, longs);\r
93         this.predicateTable = new PredicateTable(this, ints, PREDICATE_TABLE_OFFSET, ints);\r
94         this.objectTable = new ObjectTable(this, ints, OBJECT_TABLE_OFFSET, ints);\r
95         this.valueTable = new ValueTable(this, ints, VALUE_TABLE_OFFSET, bytes);\r
96         this.flatTable = null;\r
97         this.completeTable = new CompleteTable(this, headerTable, COMPLETE_TABLE_OFFSET, ints);\r
98         this.clusterMap = new ClusterMap(foreignTable, flatTable);\r
99         this.clusterSupport = support;\r
100         this.clusterBits = ClusterTraitsBase.getClusterBits(clusterKey);\r
101         this.importance = clusterTable.timeCounter();\r
102         clusterTable.markImmutable(this, getImmutable());\r
103     }\r
104     void analyse() {\r
105         System.out.println("Cluster " + clusterId);\r
106         System.out.println("-size:" + getUsedSpace());\r
107         System.out.println(" -rt:" + (resourceTable.getTableCapacity() * 8 + 8));\r
108         System.out.println(" -ft:" + foreignTable.getTableCapacity() * 8);\r
109         System.out.println(" -pt:" + predicateTable.getTableCapacity() * 4);\r
110         System.out.println(" -ot:" + objectTable.getTableCapacity() * 4);\r
111         System.out.println(" -ct:" + completeTable.getTableCapacity() * 4);\r
112         System.out.println(" -vt:" + valueTable.getTableCapacity());\r
113 \r
114         System.out.println("-resourceTable:");\r
115         System.out.println(" -resourceCount=" + resourceTable.getResourceCount());\r
116         System.out.println(" -size=" + resourceTable.getTableSize());\r
117         System.out.println(" -capacity=" + resourceTable.getTableCapacity());\r
118         System.out.println(" -count=" + resourceTable.getTableCount());\r
119         System.out.println(" -size=" + resourceTable.getTableSize());\r
120         //resourceTable.analyse();\r
121     }\r
122     public void checkDirectReference(int dr)\r
123     throws DatabaseException {\r
124         if (!ClusterTraits.statementIndexIsDirect(dr))\r
125             throw new ValidationException("Reference is not direct. Reference=" + dr);\r
126         if (ClusterTraits.isFlat(dr))\r
127             throw new ValidationException("Reference is flat. Reference=" + dr);\r
128         if (ClusterTraits.isLocal(dr)) {\r
129             if (dr < 1 || dr > resourceTable.getUsedSize())\r
130                 throw new ValidationException("Illegal local reference. Reference=" + dr);\r
131         } else {\r
132             int fi = ClusterTraits.getForeignIndexFromReference(dr);\r
133             int ri = ClusterTraits.getResourceIndexFromForeignReference(dr);\r
134             if (fi < 1 || fi > foreignTable.getUsedSize())\r
135                 throw new ValidationException("Illegal foreign reference. Reference=" + dr + " foreign index=" + fi);\r
136             if (ri < 1 || ri > ClusterTraits.getMaxNumberOfResources())\r
137                 throw new ValidationException("Illegal foreign reference. Reference=" + dr + " resource index=" + ri);\r
138         }\r
139     }\r
140     public void checkPredicateIndex(int pi)\r
141     throws DatabaseException {\r
142         predicateTable.checkPredicateSetIndex(this, pi);\r
143     }\r
144     public void checkObjectSetReference(int or)\r
145     throws DatabaseException {\r
146         if (ClusterTraits.statementIndexIsDirect(or))\r
147             throw new ValidationException("Illegal object set reference. Reference=" + or);\r
148         int oi = ClusterTraits.statementIndexGet(or);\r
149         this.objectTable.checkObjectSetIndex(this, oi);\r
150     }\r
151 \r
152     public void checkValueInit()\r
153     throws DatabaseException {\r
154         valueTable.checkValueInit();\r
155     }\r
156     public void checkValue(int capacity, int index)\r
157     throws DatabaseException {\r
158         valueTable.checkValue(capacity, index);\r
159     }\r
160     public void checkValueFini()\r
161     throws DatabaseException {\r
162         valueTable.checkValueFini();\r
163     }\r
164     public void checkForeingIndex(int fi)\r
165     throws DatabaseException {\r
166         if (fi<1 || fi > foreignTable.getUsedSize())\r
167             throw new ValidationException("Illegal foreign index=" + fi);\r
168     }\r
169     public void checkCompleteSetReference(int cr)\r
170     throws DatabaseException {\r
171         if (!ClusterTraits.completeReferenceIsMultiple(cr))\r
172             throw new ValidationException("Illegal complete set reference. Reference=" + cr);\r
173         int ci = cr;\r
174         this.completeTable.checkCompleteSetIndex(this, ci);\r
175     }\r
176     public void check()\r
177     throws DatabaseException {\r
178         this.completeTable.check(this);\r
179         this.objectTable.check(this);\r
180         // Must be after object table check.\r
181         this.predicateTable.check(this);\r
182         this.resourceTable.check(this);\r
183     }\r
184     @Override\r
185     public CompleteTypeEnum getCompleteType(int resourceKey, ClusterSupport support)\r
186     throws DatabaseException {\r
187         final int resourceRef = getLocalReference(resourceKey);\r
188         int completeRef = resourceTable.getCompleteObjectRef(resourceRef);\r
189         CompleteTypeEnum ct = ClusterTraits.completeReferenceGetType(completeRef);\r
190         if (DEBUG)\r
191             System.out.println("Cluster.getCompleteType rk=" + resourceKey + " ct=" + ct);\r
192         int i = ct.getValue();\r
193         switch (i) {\r
194             case 0: return CompleteTypeEnum.NotComplete;\r
195             case 1: return CompleteTypeEnum.InstanceOf;\r
196             case 2: return CompleteTypeEnum.Inherits;\r
197             case 3: return CompleteTypeEnum.SubrelationOf;\r
198             default: throw new DatabaseException("Illegal complete type enumeration.");\r
199         }\r
200     }\r
201 \r
202     @Override\r
203     public int getCompleteObjectKey(int resourceKey, ClusterSupport support)\r
204     throws DatabaseException {\r
205         final int resourceRef = getLocalReference(resourceKey);\r
206         int completeRef = resourceTable.getCompleteObjectRef(resourceRef);\r
207         int clusterIndex;\r
208         int resourceIndex = ClusterTraits.completeReferenceGetResourceIndex(completeRef);\r
209 \r
210         ClusterI.CompleteTypeEnum completeType = ClusterTraits.completeReferenceGetType(completeRef);\r
211         if (completeType == ClusterI.CompleteTypeEnum.NotComplete)\r
212             throw new DatabaseException("Resource has multiple complete objects. Resource key=" + resourceKey + ".");\r
213 \r
214         if (ClusterTraits.completeReferenceIsLocal(completeRef)) {\r
215             clusterIndex = clusterKey;\r
216         } else {\r
217             int foreignIndex = ClusterTraits.completeReferenceGetForeignIndex(completeRef);\r
218 //            System.err.println("completeRef=" + completeRef + " foreignIndex=" + foreignIndex );\r
219             ClusterUID clusterUID = foreignTable.getResourceUID(foreignIndex).asCID();\r
220             ClusterI c = support.getClusterByClusterUIDOrMake(clusterUID);\r
221             clusterIndex = c.getClusterKey();\r
222         }\r
223         int key = ClusterTraits.createResourceKey(clusterIndex, resourceIndex);\r
224         if (DEBUG)\r
225             System.out.println("Cluster.complete object rk=" + resourceKey + " ck=" + key);\r
226         return key;\r
227     }\r
228 \r
229     @Override\r
230     public boolean isComplete(int resourceKey, ClusterSupport support)\r
231     throws DatabaseException {\r
232         final int resourceRef = getLocalReference(resourceKey);\r
233         int completeRef = resourceTable.getCompleteObjectRef(resourceRef);\r
234         ClusterI.CompleteTypeEnum completeType = ClusterTraits.completeReferenceGetType(completeRef);\r
235         boolean complete = completeType != ClusterI.CompleteTypeEnum.NotComplete;\r
236         if (DEBUG)\r
237             System.out.println("Cluster.key=" + resourceKey + " isComplete=" + complete);\r
238         return complete;\r
239     }\r
240 \r
241     public int getSingleObject(int resourceKey, int predicateKey, int objectIndex, ClusterSupport support) throws DatabaseException {\r
242         if (DEBUG)\r
243             System.out.println("Cluster.getSingleObject: rk=" + resourceKey + " pk=" + predicateKey);\r
244         if (0 == objectIndex) {\r
245             final int resourceIndex = getLocalReference(resourceKey);\r
246             final int pRef = getInternalReferenceOrZero(predicateKey, support);\r
247             final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);\r
248             return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);\r
249         }\r
250         return objectTable.getSingleObject(objectIndex, support, this);\r
251     }\r
252 \r
253     public void forObjects(int resourceKey, int predicateKey, int objectIndex, QueryProcessor processor, ReadGraphImpl graph, AsyncMultiProcedure<Resource> procedure,\r
254             ClusterSupport support) throws DatabaseException {\r
255         if (DEBUG)\r
256             System.out.println("Cluster.forObjects1: rk=" + resourceKey + " pk=" + predicateKey);\r
257         if (0 == objectIndex) {\r
258             final int resourceIndex = getLocalReference(resourceKey);\r
259             final int pRef = getInternalReferenceOrZero(predicateKey, support);\r
260             final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);\r
261             resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);\r
262             return;\r
263         }\r
264         objectTable.foreachObject(graph, objectIndex, procedure, this);\r
265     }\r
266     public <C> void forObjects(int resourceKey, int predicateKey, int objectIndex, QueryProcessor processor, ReadGraphImpl graph, C context, AsyncContextMultiProcedure<C, Resource> procedure,\r
267             ClusterSupport support) throws DatabaseException {\r
268         if (DEBUG)\r
269             System.out.println("Cluster.forObjects1: rk=" + resourceKey + " pk=" + predicateKey);\r
270         if (0 == objectIndex) {\r
271             final int resourceIndex = getLocalReference(resourceKey);\r
272             final int pRef = getInternalReferenceOrZero(predicateKey, support);\r
273             final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);\r
274             resourceTable.foreachObject(resourceIndex, graph, context, procedure, support, pRef, pCompleteType, completeTable, this);\r
275             return;\r
276         }\r
277         objectTable.foreachObject(graph, objectIndex, context, procedure, this);\r
278     }\r
279     @Override\r
280     public <Context> boolean forObjects(int resourceKey, int predicateKey, int objectIndex, ObjectProcedure<Context> procedure,\r
281             Context context, ClusterSupport support) throws DatabaseException {\r
282         if (DEBUG)\r
283             System.out.println("Cluster.forObjects2: rk=" + resourceKey + " pk=" + predicateKey);\r
284         if (0 == objectIndex) {\r
285             final int resourceIndex = getLocalReference(resourceKey);\r
286             final int pRef = getInternalReferenceOrZero(predicateKey, support);\r
287             final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);\r
288             return resourceTable.foreachObject(resourceIndex, procedure, context, support, this, pRef, pCompleteType, completeTable);\r
289         }\r
290         return objectTable.foreachObject(objectIndex, procedure, context, support, this);\r
291     }\r
292 \r
293     @Override\r
294     public int getSingleObject(int resourceKey, int predicateKey, ClusterSupport support) throws DatabaseException {\r
295         if (DEBUG)\r
296             System.out.println("Cluster.getSingleObject2: rk=" + resourceKey + " pk=" + predicateKey);\r
297         final int resourceIndex = getLocalReference(resourceKey);\r
298         final int pRef = getInternalReferenceOrZero(predicateKey, support);\r
299         final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);\r
300         if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType)\r
301             return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);\r
302         final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);\r
303         if (0 == predicateIndex)\r
304             return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);\r
305         int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);\r
306         return getSingleObject(resourceKey, predicateKey, objectIndex, support);\r
307     }\r
308 \r
309     @Override\r
310     public <T> int getSingleObject(int resourceKey, ForPossibleRelatedValueProcedure<T> procedure, ClusterSupport support) throws DatabaseException {\r
311         final int predicateKey = procedure.predicateKey;\r
312         if (DEBUG)\r
313             System.out.println("Cluster.getSingleObject2: rk=" + resourceKey + " pk=" + predicateKey);\r
314         final int resourceIndex = getLocalReference(resourceKey);\r
315         final int pRef = getInternalReferenceOrZero(predicateKey, support);\r
316         final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);\r
317         if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType)\r
318             return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);\r
319         final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);\r
320         if (0 == predicateIndex)\r
321             return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);\r
322         int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);\r
323         return getSingleObject(resourceKey, predicateKey, objectIndex, support);\r
324     }\r
325 \r
326     @Override\r
327     public <C, T> int getSingleObject(int resourceKey, ForPossibleRelatedValueContextProcedure<C, T> procedure, ClusterSupport support) throws DatabaseException {\r
328         final int predicateKey = procedure.predicateKey;\r
329         if (DEBUG)\r
330             System.out.println("Cluster.getSingleObject2: rk=" + resourceKey + " pk=" + predicateKey);\r
331         final int resourceIndex = getLocalReference(resourceKey);\r
332         final int pRef = getInternalReferenceOrZero(predicateKey, support);\r
333         final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);\r
334         if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType)\r
335             return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);\r
336         final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);\r
337         if (0 == predicateIndex)\r
338             return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);\r
339         int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);\r
340         return getSingleObject(resourceKey, predicateKey, objectIndex, support);\r
341     }\r
342 \r
343     @Override\r
344     public void forObjects(ReadGraphImpl graph, int resourceKey,\r
345             int predicateKey, AsyncMultiProcedure<Resource> procedure)\r
346             throws DatabaseException {\r
347 \r
348         SessionImplSocket session = (SessionImplSocket)graph.getSession();\r
349         ClusterSupport support = session.clusterTranslator;\r
350 \r
351         if (DEBUG)\r
352             System.out.println("Cluster.forObjects3: rk=" + resourceKey + " pk=" + predicateKey);\r
353         final int resourceIndex = getLocalReference(resourceKey);\r
354         final int pRef = getInternalReferenceOrZero(predicateKey, support);\r
355         final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);\r
356         if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {\r
357             resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);\r
358             return;\r
359         }\r
360         final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);\r
361         if (0 == predicateIndex) {\r
362             resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);\r
363             return;\r
364         }\r
365         int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);\r
366         forObjects(resourceKey, predicateKey, objectIndex, graph.processor, graph, procedure, support);\r
367 \r
368     }\r
369 \r
370     @Override\r
371     public void forObjects(ReadGraphImpl graph, int resourceKey, ForEachObjectProcedure procedure) throws DatabaseException {\r
372         SessionImplSocket session = (SessionImplSocket)graph.getSession();\r
373         ClusterSupport support = session.clusterTranslator;\r
374         final int predicateKey = procedure.predicateKey;\r
375         if (DEBUG)\r
376             System.out.println("Cluster.forObjects3: rk=" + resourceKey + " pk=" + predicateKey);\r
377         final int resourceIndex = getLocalReference(resourceKey);\r
378         final int pRef = getInternalReferenceOrZero(predicateKey, support);\r
379         final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);\r
380         if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {\r
381             resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);\r
382             return;\r
383         }\r
384         final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);\r
385         if (0 == predicateIndex) {\r
386             resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);\r
387             return;\r
388         }\r
389         int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);\r
390         forObjects(resourceKey, predicateKey, objectIndex, graph.processor, graph, procedure, support);\r
391 \r
392     }\r
393     @Override\r
394     public <C> void forObjects(ReadGraphImpl graph, int resourceKey, C context,\r
395             ForEachObjectContextProcedure<C> procedure) throws DatabaseException {\r
396 \r
397         SessionImplSocket session = (SessionImplSocket)graph.getSession();\r
398         ClusterSupport support = session.clusterTranslator;\r
399 \r
400         final int predicateKey = procedure.predicateKey;\r
401 \r
402         if (DEBUG)\r
403             System.out.println("Cluster.forObjects3: rk=" + resourceKey + " pk=" + predicateKey);\r
404         final int resourceIndex = getLocalReference(resourceKey);\r
405         final int pRef = getInternalReferenceOrZero(predicateKey, support);\r
406         final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);\r
407         if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {\r
408             resourceTable.foreachObject(resourceIndex, graph, context, procedure, support, pRef, pCompleteType, completeTable, this);\r
409             return;\r
410         }\r
411         final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);\r
412         if (0 == predicateIndex) {\r
413             resourceTable.foreachObject(resourceIndex, graph, context, procedure, support, pRef, pCompleteType, completeTable, this);\r
414             return;\r
415         }\r
416         int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);\r
417         forObjects(resourceKey, predicateKey, objectIndex, graph.processor, graph, context, procedure, support);\r
418 \r
419     }\r
420 \r
421     @Override\r
422     public <Context> boolean forObjects(int resourceKey, int predicateKey,\r
423             ObjectProcedure<Context> procedure, Context context, ClusterSupport support)\r
424     throws DatabaseException {\r
425         if (DEBUG)\r
426             System.out.println("Cluster.forObjects4: rk=" + resourceKey + " pk=" + predicateKey);\r
427         final int resourceIndex = getLocalReference(resourceKey);\r
428         final int pRef = getInternalReferenceOrZero(predicateKey, support);\r
429         final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);\r
430         if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType)\r
431             return resourceTable.foreachObject(resourceIndex, procedure, context, support, this, pRef, pCompleteType, completeTable);\r
432         final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);\r
433         if (0 == predicateIndex)\r
434             return resourceTable.foreachObject(resourceIndex, procedure, context, support, this, pRef, pCompleteType, completeTable);\r
435         int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);\r
436         return forObjects(resourceKey, predicateKey, objectIndex, procedure, context, support);\r
437     }\r
438     @Override\r
439     public <Context> boolean forPredicates(int resourceKey,\r
440             PredicateProcedure<Context> procedure, Context context, ClusterSupport support)\r
441     throws DatabaseException {\r
442         if (DEBUG)\r
443             System.out.println("Cluster.forPredicates: rk=" + resourceKey);\r
444         final int resourceIndex = getLocalReference(resourceKey);\r
445         final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);\r
446         if (0 == predicateIndex)\r
447             return resourceTable.foreachPredicate(resourceIndex,\r
448                     procedure, context, support, this, completeTable);\r
449         else {\r
450             boolean broken = resourceTable.foreachPredicate(resourceIndex,\r
451                     procedure, context, support, this, completeTable);\r
452             if (broken)\r
453                 return true;\r
454         }\r
455         return predicateTable.foreachPredicate(predicateIndex, procedure, context, support, this);\r
456     }\r
457     @Override\r
458     public ClusterI addRelation(int sResourceKey, int pResourceKey, int oResourceKey, ClusterSupport support)\r
459     throws DatabaseException {\r
460         if (DEBUG)\r
461             System.out.println("add rk=" + sResourceKey + " pk=" + pResourceKey + " ok=" + oResourceKey);\r
462         int sri = getLocalReferenceAnd(sResourceKey, support, ClusterChange.ADD_OPERATION);\r
463         int pri = getReferenceOrCreateIfForeign(pResourceKey, support, ClusterStream.NULL_OPERATION);\r
464         int ori = getReferenceOrCreateIfForeign(oResourceKey, support, ClusterStream.NULL_OPERATION);\r
465         ClusterI.CompleteTypeEnum completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(pResourceKey);\r
466         boolean ret = addRelationInternal(sri, pri, ori, completeType);\r
467 //      check();\r
468         if (ret) {\r
469             support.addStatement(this);\r
470             return this;\r
471         } else {\r
472             support.cancelStatement(this);\r
473             return null;\r
474         }\r
475     }\r
476     @Override\r
477     public boolean removeRelation(int sResourceKey, int pResourceKey, int oResourceKey, ClusterSupport support)\r
478     throws DatabaseException {\r
479 //        check();\r
480         int sri = getLocalReferenceAnd(sResourceKey, support, ClusterChange.REMOVE_OPERATION);\r
481         int pri = getInternalReferenceOrZeroAnd(pResourceKey, support, ClusterStream.NULL_OPERATION);\r
482         int ori = getInternalReferenceOrZeroAnd(oResourceKey, support, ClusterStream.NULL_OPERATION);\r
483         boolean ret = false;\r
484         if (0 != pri && 0 != ori) {\r
485             ClusterI.CompleteTypeEnum completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(pResourceKey);\r
486             ret = removeRelationInternal(sri, pri, ori, completeType, support);\r
487         }\r
488         if (ret)\r
489             support.removeStatement(this);\r
490         else\r
491             support.cancelStatement(this);\r
492 //        check();\r
493         return ret;\r
494     }\r
495     @Override\r
496     public void denyRelation(int sResourceKey, int pResourceKey, int oResourceKey, ClusterSupport support)\r
497     throws DatabaseException {\r
498         int sri = checkResourceKeyIsOursAndGetResourceIndexIf(sResourceKey, support);\r
499         ResourceIndexAndId p = checkResourceKeyAndGetResourceIndexIf(pResourceKey, support);\r
500         ResourceIndexAndId o = checkResourceKeyAndGetResourceIndexIf(oResourceKey, support);\r
501         if (0 == sri || 0 == p.index || 0 == o.index)\r
502             return;\r
503 //        check();\r
504         ClusterI.CompleteTypeEnum completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(pResourceKey);\r
505         boolean ret = removeRelationInternal(sri, p.reference, o.reference, completeType, support);\r
506         if (ret) {\r
507             support.addStatementIndex(this, sResourceKey, getClusterUID(), ClusterChange.REMOVE_OPERATION);\r
508             support.addStatementIndex(this, pResourceKey, p.clusterUID, ClusterStream.NULL_OPERATION);\r
509             support.addStatementIndex(this, oResourceKey, o.clusterUID, ClusterStream.NULL_OPERATION);\r
510             support.removeStatement(this);\r
511         }\r
512 //        check();\r
513         return;\r
514     }\r
515     @Override\r
516     public InputStream getValueStream(int rResourceId, ClusterSupport support) throws DatabaseException {\r
517         if (DEBUG)\r
518             System.out.println("ClusterBig.getValue " + rResourceId);\r
519         int resourceIndex = getLocalReference(rResourceId);\r
520         try {\r
521             byte[] buffer = resourceTable.getValue(valueTable, resourceIndex);\r
522             if(buffer == null) return null;\r
523             return new ByteArrayInputStream(buffer);\r
524         } catch (ExternalValueException e) {\r
525             return support.getValueStreamEx(resourceIndex, clusterId);\r
526         }\r
527     }\r
528     @Override\r
529     public byte[] getValue(int rResourceId, ClusterSupport support)\r
530     throws DatabaseException {\r
531         if (DEBUG)\r
532             System.out.println("ClusterBig.getValue " + rResourceId);\r
533         int resourceIndex = getLocalReference(rResourceId);\r
534         try {\r
535             return resourceTable.getValue(valueTable, resourceIndex);\r
536         } catch (ExternalValueException e) {\r
537             return support.getValueEx(resourceIndex, clusterId);\r
538         }\r
539     }\r
540     @Override\r
541     public boolean hasValue(int rResourceId, ClusterSupport support)\r
542     throws DatabaseException {\r
543         int resourceIndex = getLocalReference(rResourceId);\r
544         return resourceTable.hasValue(resourceIndex);\r
545     }\r
546     @Override\r
547     public boolean removeValue(int rResourceId, ClusterSupport support)\r
548     throws DatabaseException {\r
549         int resourceIndex = getLocalReferenceAnd(rResourceId, support, ClusterChange.DELETE_OPERATION);\r
550         support.removeValue(this);\r
551         return resourceTable.removeValue(valueTable, resourceIndex);\r
552     }\r
553 \r
554     @Override\r
555     public ClusterI setValue(int rResourceId, byte[] value, int length, ClusterSupport support)\r
556     throws DatabaseException {\r
557         int resourceIndex = getLocalReferenceAnd(rResourceId, support, ClusterStream.SET_OPERATION);\r
558         support.setValue(this, getClusterId(), value, length);\r
559         resourceTable.setValue(valueTable, resourceIndex, value, length);\r
560         return this;\r
561     }\r
562     @Override\r
563     public ClusterI modiValueEx(int rResourceId, long voffset, int length, byte[] value, int offset, ClusterSupport support)\r
564     throws DatabaseException {\r
565         int resourceIndex = getLocalReferenceAnd(rResourceId, support, ClusterStream.MODI_OPERATION);\r
566         support.modiValue(this, getClusterId(), voffset, length, value, offset);\r
567         resourceTable.setValueEx(valueTable, resourceIndex);\r
568         return this;\r
569     }\r
570     @Override\r
571     public byte[] readValueEx(int rResourceId, long voffset, int length, ClusterSupport support)\r
572     throws DatabaseException {\r
573         int resourceIndex = getLocalReference(rResourceId);\r
574         boolean isExternal = resourceTable.isValueEx(valueTable, resourceIndex);\r
575         if (!isExternal)\r
576             throw new DatabaseException("ClusterI.readValue supported only for external value. Resource key=" + rResourceId);\r
577         return support.getValueEx(resourceIndex, getClusterId(), voffset, length);\r
578     }\r
579     @Override\r
580     public long getValueSizeEx(int resourceKey, ClusterSupport support)\r
581     throws DatabaseException, ExternalValueException {\r
582         int resourceIndex = getLocalReference(resourceKey);\r
583         boolean isExternal = resourceTable.isValueEx(valueTable, resourceIndex);\r
584         if (!isExternal)\r
585             throw new ExternalValueException("ClusterI.getSize supported only for external value. Resource key=" + resourceKey);\r
586         return support.getValueSizeEx(resourceIndex, getClusterId());\r
587     }\r
588     public boolean isValueEx(int resourceKey)\r
589     throws DatabaseException {\r
590         int resourceIndex = getLocalReference(resourceKey);\r
591         return resourceTable.isValueEx(valueTable, resourceIndex);\r
592     }\r
593     @Override\r
594     public void setValueEx(int resourceKey)\r
595     throws DatabaseException {\r
596         int resourceIndex = getLocalReference(resourceKey);\r
597         resourceTable.setValueEx(valueTable, resourceIndex);\r
598     }\r
599     @Override\r
600     public int createResource(ClusterSupport support)\r
601     throws DatabaseException {\r
602         short resourceIndex = resourceTable.createResource();\r
603 \r
604         if(DebugPolicy.REPORT_RESOURCE_ID_ALLOCATION)\r
605             System.out.println("[RID_ALLOCATION]: ClusterBig[" + clusterId + "] allocates " + resourceIndex);\r
606 \r
607         support.createResource(this, resourceIndex, clusterId);\r
608         return ClusterTraits.createResourceKey(clusterKey, resourceIndex);\r
609     }\r
610     @Override\r
611     public boolean hasResource(int resourceKey, ClusterSupport support) {\r
612         int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(resourceKey);\r
613         if (this.clusterKey != clusterKey) // foreign resource\r
614             return false;\r
615         int resourceIndex;\r
616         try {\r
617             resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);\r
618         } catch (DatabaseException e) {\r
619             return false;\r
620         }\r
621         if (resourceIndex > 0 & resourceIndex <= resourceTable.getTableCount())\r
622             return true;\r
623         else\r
624             return false;\r
625     }\r
626     @Override\r
627     public int getNumberOfResources(ClusterSupport support) {\r
628         return resourceTable.getUsedSize();\r
629     }\r
630     @Override\r
631     public long getUsedSpace() {\r
632         long rt = resourceTable.getTableCapacity() * 8 + 8; // (8 = cluster id)\r
633         long ft = foreignTable.getTableCapacity() * 8;\r
634         long pt = predicateTable.getTableCapacity() * 4;\r
635         long ot = objectTable.getTableCapacity() * 4;\r
636         long ct = completeTable.getTableCapacity() * 4;\r
637         long vt = valueTable.getTableCapacity() * 1;\r
638         long cm = clusterMap.getUsedSpace();\r
639 \r
640         return rt + ft + pt + ot + ct + vt + cm;\r
641 //        System.out.println("resource table " + rt);\r
642 //        System.out.println("foreign table (non flat cluster table) " + ft);\r
643 //        System.out.println("predicate table " + pt);\r
644 //        long pt2 = getRealSizeOfPredicateTable() * 4;\r
645 //        System.out.println("predicate table real size " + pt2);\r
646 //        System.out.println("object table " + ot);\r
647 //        long ot2 = getRealSizeOfObjectTable() * 4;\r
648 //        System.out.println("object table real size " + ot2);\r
649 //        System.out.println("value table " + vt);\r
650     }\r
651     int getRealSizeOfPredicateTable() throws DatabaseException {\r
652         SizeOfPredicateTable proc = new SizeOfPredicateTable(resourceTable, predicateTable);\r
653         resourceTable.foreachResource(proc, 0, null, null);\r
654         return proc.getSize();\r
655     }\r
656     int getRealSizeOfObjectTable() throws DatabaseException {\r
657         SizeOfObjectTable proc = new SizeOfObjectTable(resourceTable, predicateTable, objectTable);\r
658         resourceTable.foreachResource(proc, 0, null, null);\r
659         return proc.getSize();\r
660     }\r
661     @Override\r
662     public boolean isEmpty() {\r
663         return resourceTable.getTableCount() == 0;\r
664     }\r
665     @Override\r
666     public void printDebugInfo(String message, ClusterSupport support)\r
667     throws DatabaseException {\r
668         predicateTable.printDebugInfo();\r
669         objectTable.printDebugInfo();\r
670         ClusterPrintDebugInfo proc = new ClusterPrintDebugInfo(this\r
671                 , resourceTable, predicateTable, support, objectTable);\r
672         resourceTable.foreachResource(proc, 0, null, null);\r
673     }\r
674     private int getInternalReferenceOrZero(int resourceKey, ClusterSupport support)\r
675     throws DatabaseException {\r
676         int clusterKey = ClusterTraits.getClusterKeyFromResourceKey(resourceKey);\r
677         int resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);\r
678         if (this.clusterKey != clusterKey) { // foreign resource\r
679             ClusterI foreignCluster = support.getClusterByClusterKey(clusterKey);\r
680             ClusterUID clusterUID = foreignCluster.getClusterUID();\r
681             int foreignResourceIndex = clusterMap.getForeignReferenceOrZero(resourceIndex, clusterUID);\r
682             return foreignResourceIndex;\r
683         }\r
684         return resourceIndex;\r
685     }\r
686     private int getInternalReferenceOrZeroAnd(int resourceKey, ClusterSupport support, byte op)\r
687     throws DatabaseException {\r
688         int clusterKey = ClusterTraits.getClusterKeyFromResourceKey(resourceKey);\r
689         int resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);\r
690         if (this.clusterKey != clusterKey) { // foreign resource\r
691             ClusterI foreignCluster = support.getClusterByClusterKey(clusterKey);\r
692             ClusterUID clusterUID = foreignCluster.getClusterUID();\r
693             int foreignResourceIndex = clusterMap.getForeignReferenceOrZero(resourceIndex, clusterUID);\r
694             support.addStatementIndex(this, resourceKey, clusterUID, op);\r
695             return foreignResourceIndex;\r
696         }\r
697         support.addStatementIndex(this, resourceKey, getClusterUID(), op);\r
698         return resourceIndex;\r
699     }\r
700     private short getLocalReference(int resourceKey) throws DatabaseException {\r
701         return ClusterTraitsBase.getResourceIndexFromResourceKeyNoThrow(resourceKey);\r
702     }\r
703     private int getLocalReferenceAnd(int resourceKey, ClusterSupport support, byte op)\r
704     throws DatabaseException {\r
705         int resourceIndex = getLocalReference(resourceKey);\r
706         support.addStatementIndex(this, resourceKey, getClusterUID(), op);\r
707         return resourceIndex;\r
708     }\r
709     private int checkResourceKeyIsOursAndGetResourceIndexIf(int resourceKey, ClusterSupport support)\r
710     throws DatabaseException {\r
711         int clusterShortId = ClusterTraits.getClusterKeyFromResourceKey(resourceKey);\r
712         if (this.clusterKey != clusterShortId)\r
713             return 0;\r
714         int resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);\r
715         return resourceIndex;\r
716     }\r
717     private int getReferenceOrCreateIfForeign(int resourceKey, ClusterSupport support, byte op)\r
718     throws DatabaseException {\r
719         int clusterKey = ClusterTraits.getClusterKeyFromResourceKey(resourceKey);\r
720         int resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);\r
721         if (this.clusterKey != clusterKey) {\r
722             ClusterI foreignCluster = support.getClusterByClusterKey(clusterKey);\r
723             ClusterUID clusterUID = foreignCluster.getClusterUID();\r
724             support.addStatementIndex(this, resourceKey, clusterUID, op);\r
725             return clusterMap.getForeignReferenceOrCreateByResourceKey(resourceKey, clusterUID);\r
726         }\r
727         support.addStatementIndex(this, resourceKey, getClusterUID(), op);\r
728         return resourceIndex;\r
729     }\r
730     private class ResourceIndexAndId {\r
731         ResourceIndexAndId(int reference, int index, ClusterUID clusterUID) {\r
732             this.reference = reference;\r
733             this.index = index;\r
734             this.clusterUID = clusterUID;\r
735         }\r
736         public final int reference;\r
737         public final int index;\r
738         public final ClusterUID clusterUID;\r
739     }\r
740     private ResourceIndexAndId checkResourceKeyAndGetResourceIndexIf(int resourceKey, ClusterSupport support)\r
741     throws DatabaseException {\r
742         int clusterKey = ClusterTraits.getClusterKeyFromResourceKey(resourceKey);\r
743         int resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);\r
744         if (this.clusterKey != clusterKey) { // foreign resource\r
745             ClusterI foreignCluster = support.getClusterByClusterKey(clusterKey);\r
746             ClusterUID clusterUID = foreignCluster.getClusterUID();\r
747             int ref = clusterMap.getForeignReferenceOrCreateByResourceIndex(resourceIndex, clusterUID);\r
748             return new ResourceIndexAndId(ref, resourceIndex, clusterUID);\r
749         }\r
750         return new ResourceIndexAndId(resourceIndex, resourceIndex, getClusterUID());\r
751     }\r
752 \r
753     @Override\r
754     final public int execute(int resourceIndex) throws DatabaseException {\r
755         int key;\r
756         if(resourceIndex > 0) {\r
757             key = clusterBits | resourceIndex;\r
758         } else {\r
759             ClusterUID clusterUID = clusterMap.getResourceUID(resourceIndex).asCID();\r
760             ClusterI cluster = clusterSupport.getClusterByClusterUIDOrMake(clusterUID);\r
761             int foreingResourceIndex =  clusterMap.getForeignResourceIndex(resourceIndex);\r
762             key = ClusterTraits.createResourceKey(cluster.getClusterKey(), foreingResourceIndex);\r
763         }\r
764         if (DEBUG)\r
765             System.out.println("Cluster.execute key=" + key);\r
766         return key;\r
767     }\r
768 \r
769     private boolean addRelationInternal(int sReference, int pReference, int oReference, ClusterI.CompleteTypeEnum completeType)\r
770     throws DatabaseException {\r
771         int predicateIndex = resourceTable.addStatement(sReference, pReference,\r
772                 oReference, predicateTable, objectTable, completeType, completeTable);\r
773         if (0 == predicateIndex)\r
774             return true; // added to resourceTable\r
775         else if (0 > predicateIndex)\r
776             return false; // old complete statemenent\r
777         int newPredicateIndex = predicateTable.addPredicate(predicateIndex,\r
778                 pReference, oReference, objectTable);\r
779         if (0 == newPredicateIndex)\r
780             return false;\r
781         if (predicateIndex != newPredicateIndex)\r
782             resourceTable.setPredicateIndex(sReference, newPredicateIndex);\r
783         return true;\r
784     }\r
785     private boolean removeRelationInternal(int sResourceIndex, int pResourceIndex,\r
786             int oResourceIndex, ClusterI.CompleteTypeEnum completeType, ClusterSupport support)\r
787     throws DatabaseException {\r
788         int predicateIndex = resourceTable.getPredicateIndex(sResourceIndex);\r
789         if (0 == predicateIndex || ClusterI.CompleteTypeEnum.NotComplete != completeType)\r
790             return resourceTable.removeStatementFromCache(sResourceIndex,\r
791                     pResourceIndex, oResourceIndex, completeType, completeTable);\r
792         PredicateTable.Status ret = predicateTable.removePredicate(predicateIndex, pResourceIndex, oResourceIndex, objectTable);\r
793         switch (ret) {\r
794             case NothingRemoved:\r
795                 return false;\r
796             case PredicateRemoved: {\r
797                 if (0 == predicateTable.getPredicateSetSize(predicateIndex))\r
798                     resourceTable.setPredicateIndex(sResourceIndex, 0);\r
799                 // intentionally dropping to next case\r
800             } default:\r
801                 break;\r
802         }\r
803         resourceTable.removeStatement(sResourceIndex,\r
804                 pResourceIndex, oResourceIndex,\r
805                 completeType, completeTable,\r
806                 predicateTable, objectTable, this, support);\r
807         return true;\r
808     }\r
809     @Override\r
810     public void load() {\r
811         throw new Error("Not supported.");\r
812     }\r
813 \r
814     @Override\r
815     public void load(Callback<DatabaseException> r) {\r
816         throw new Error("Not supported.");\r
817     }\r
818 \r
819     public int makeResourceKey(int resourceIndex) throws DatabaseException {\r
820         int key = 0;\r
821 //        if (ClusterTraitsBase.isIllegalResourceIndex(resourceIndex))\r
822 //            throw new DatabaseException("Illegal resource key " + resourceIndex);\r
823         if (resourceIndex > 0) // local resource\r
824             key = ClusterTraits.createResourceKey(clusterKey, resourceIndex);\r
825         else {\r
826             ClusterUID clusterUID = clusterMap.getResourceUID(resourceIndex).asCID();\r
827             ClusterI cluster = clusterSupport.getClusterByClusterUIDOrMake(clusterUID);\r
828             int foreingResourceIndex =  clusterMap.getForeignResourceIndex(resourceIndex);\r
829             key = ClusterTraits.createResourceKey(cluster.getClusterKey(), foreingResourceIndex);\r
830         }\r
831         if (0 == key)\r
832             throw new DatabaseException("Failed to make resource key from " + resourceIndex);\r
833         return key;\r
834     }\r
835     @Override\r
836     public ClusterBig toBig(ClusterSupport support) throws DatabaseException {\r
837         throw new Error("Not implemented");\r
838     }\r
839     @Override\r
840     public void load(ClusterSupport session, Runnable callback) {\r
841         throw new Error("Not implemented");\r
842     }\r
843     @Override\r
844     public ClusterI getClusterByResourceKey(int resourceKey,\r
845             ClusterSupport support) {\r
846         throw new Error("Not implemented");\r
847     }\r
848     @Override\r
849     public void increaseReferenceCount(int amount) {\r
850         throw new Error("Not implemented");\r
851     }\r
852     @Override\r
853 \r
854     public void decreaseReferenceCount(int amount) {\r
855         throw new Error("Not implemented");\r
856     }\r
857     @Override\r
858     public int getReferenceCount() {\r
859         throw new Error("Not implemented");\r
860     }\r
861     @Override\r
862     public void releaseMemory() {\r
863     }\r
864     @Override\r
865     public void compact() {\r
866         clusterMap.compact();\r
867     }\r
868     public boolean contains(int resourceKey) {\r
869         return ClusterTraitsBase.isCluster(clusterBits, resourceKey);\r
870     }\r
871     @Override\r
872     public ClusterTypeEnum getType() {\r
873         return ClusterTypeEnum.BIG;\r
874     }\r
875     @Override\r
876     public boolean getImmutable() {\r
877         int status = resourceTable.getClusterStatus();\r
878         return (status & ClusterStatus.ImmutableMaskSet) == ClusterStatus.ImmutableMaskSet;\r
879     }\r
880     @Override\r
881     public void setImmutable(boolean immutable, ClusterSupport support) {\r
882         int status = resourceTable.getClusterStatus();\r
883         if (immutable)\r
884             status |= ClusterStatus.ImmutableMaskSet;\r
885         else\r
886             status &= ClusterStatus.ImmutableMaskClear;\r
887         resourceTable.setClusterStatus(status);\r
888         support.setImmutable(this, immutable);\r
889     }\r
890     @Override\r
891     public boolean getDeleted() {\r
892         int status = resourceTable.getClusterStatus();\r
893         return (status & ClusterStatus.DeletedMaskSet) == ClusterStatus.DeletedMaskSet;\r
894     }\r
895     @Override\r
896     public void setDeleted(boolean deleted, ClusterSupport support) {\r
897         int status = resourceTable.getClusterStatus();\r
898         if (deleted)\r
899             status |= ClusterStatus.DeletedMaskSet;\r
900         else\r
901             status &= ClusterStatus.DeletedMaskClear;\r
902         resourceTable.setClusterStatus(status);\r
903         support.setDeleted(this, deleted);\r
904     }\r
905     @Override\r
906     public Table<?> getPredicateTable() {\r
907         return predicateTable;\r
908     }\r
909     @Override\r
910     public Table<?> getForeignTable() {\r
911         return foreignTable;\r
912     }\r
913     @Override\r
914     public Table<?> getCompleteTable() {\r
915         return completeTable;\r
916     }\r
917     @Override\r
918     public Table<?> getValueTable() {\r
919         return valueTable;\r
920     }\r
921     @Override\r
922     public Table<?> getObjectTable() {\r
923         return objectTable;\r
924     }\r
925 }\r
926 \r
927 class SizeOfPredicateTable implements ClusterI.ObjectProcedure<Integer> {\r
928     private final ResourceTable mrResourceTable;\r
929     private final PredicateTable mrPredicateTable;\r
930     private int size = 0;\r
931     SizeOfPredicateTable(ResourceTable resourceTable\r
932             , PredicateTable predicateTable) {\r
933         mrResourceTable = resourceTable;\r
934         mrPredicateTable = predicateTable;\r
935     }\r
936     @Override\r
937     public boolean execute(Integer i, int resourceRef) {\r
938         int predicateIndex = mrResourceTable.getPredicateIndex(resourceRef);\r
939         if (0 == predicateIndex)\r
940             return false; // continue loop\r
941         size += mrPredicateTable.getPredicateSetSize(predicateIndex);\r
942         return false; // continue loop\r
943     }\r
944 \r
945     public int getSize() {\r
946         return size;\r
947     }\r
948 }\r
949 \r
950 class SizeOfObjectTable implements ClusterI.ObjectProcedure<Integer> {\r
951     private final ResourceTable mrResourceTable;\r
952     private final PredicateTable mrPredicateTable;\r
953     private final ObjectTable mrObjectTable;\r
954     private int size = 0;\r
955     SizeOfObjectTable(ResourceTable resourceTable\r
956             , PredicateTable predicateTable, ObjectTable objectTable) {\r
957         mrResourceTable = resourceTable;\r
958         mrPredicateTable = predicateTable;\r
959         mrObjectTable = objectTable;\r
960     }\r
961 \r
962     @Override\r
963     public boolean execute(Integer i, int resourceRef) {\r
964         int predicateIndex = mrResourceTable.getPredicateIndex(resourceRef);\r
965         if (0 == predicateIndex)\r
966             return false; // continue loop\r
967         ClusterI.PredicateProcedure<Object> procedure = new PredicateProcedure<Object>() {\r
968             @Override\r
969             public boolean execute(Object context, int pRef, int oIndex) {\r
970                 if (ClusterTraits.statementIndexIsDirect(oIndex))\r
971                     return false; // no table space reserved, continue looping\r
972                 int objectIndex;\r
973                 try {\r
974                     objectIndex = ClusterTraits.statementIndexGet(oIndex);\r
975                     size += mrObjectTable.getObjectSetSize(objectIndex);\r
976                 } catch (DatabaseException e) {\r
977                     e.printStackTrace();\r
978                 }\r
979                 return false; // continue looping\r
980             }\r
981         };\r
982         try {\r
983             mrPredicateTable.foreachPredicate(predicateIndex, procedure, null, null, null);\r
984         } catch (DatabaseException e) {\r
985             e.printStackTrace();\r
986         }\r
987         return false; // continue loop\r
988     }\r
989 \r
990     public int getSize() {\r
991         return size;\r
992     }\r
993 \r
994 }