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
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.db.procore.cluster;
\r
14 import java.io.ByteArrayInputStream;
\r
15 import java.io.InputStream;
\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.ClusterSupport;
\r
23 import org.simantics.db.impl.ClusterTraitsBase;
\r
24 import org.simantics.db.impl.ForEachObjectContextProcedure;
\r
25 import org.simantics.db.impl.ForEachObjectProcedure;
\r
26 import org.simantics.db.impl.ForPossibleRelatedValueContextProcedure;
\r
27 import org.simantics.db.impl.ForPossibleRelatedValueProcedure;
\r
28 import org.simantics.db.impl.Table;
\r
29 import org.simantics.db.impl.TableHeader;
\r
30 import org.simantics.db.impl.graph.ReadGraphImpl;
\r
31 import org.simantics.db.procedure.AsyncContextMultiProcedure;
\r
32 import org.simantics.db.procedure.AsyncMultiProcedure;
\r
33 import org.simantics.db.service.ClusterUID;
\r
34 import org.simantics.db.service.ResourceUID;
\r
35 import org.simantics.utils.datastructures.Callback;
\r
37 import fi.vtt.simantics.procore.DebugPolicy;
\r
38 import fi.vtt.simantics.procore.internal.ClusterChange;
\r
39 import fi.vtt.simantics.procore.internal.ClusterStream;
\r
40 import fi.vtt.simantics.procore.internal.ClusterTable;
\r
41 import fi.vtt.simantics.procore.internal.SessionImplSocket;
\r
42 import gnu.trove.map.hash.TIntShortHashMap;
\r
43 import gnu.trove.procedure.TIntProcedure;
\r
44 import gnu.trove.set.hash.TIntHashSet;
\r
46 final public class ClusterSmall extends ClusterImpl {
\r
48 private static final int TABLE_HEADER_SIZE = TableHeader.HEADER_SIZE + TableHeader.EXTRA_SIZE;
\r
49 private static final int RESOURCE_TABLE_OFFSET = 0;
\r
50 private static final int PREDICATE_TABLE_OFFSET = RESOURCE_TABLE_OFFSET + TABLE_HEADER_SIZE;
\r
51 private static final int OBJECT_TABLE_OFFSET = PREDICATE_TABLE_OFFSET + TABLE_HEADER_SIZE;
\r
52 private static final int VALUE_TABLE_OFFSET = OBJECT_TABLE_OFFSET + TABLE_HEADER_SIZE;
\r
53 private static final int FLAT_TABLE_OFFSET = VALUE_TABLE_OFFSET + TABLE_HEADER_SIZE;
\r
54 private static final int COMPLETE_TABLE_OFFSET = FLAT_TABLE_OFFSET + TABLE_HEADER_SIZE;
\r
55 private static final int FOREIGN_TABLE_OFFSET = COMPLETE_TABLE_OFFSET + TABLE_HEADER_SIZE;
\r
56 private static final int INT_HEADER_SIZE = FOREIGN_TABLE_OFFSET + TABLE_HEADER_SIZE;
\r
57 private final int clusterBits;
\r
58 public final ResourceTableSmall resourceTable;
\r
59 private PredicateTable predicateTable;
\r
60 final ObjectTable objectTable;
\r
61 public final ValueTableSmall valueTable;
\r
62 public final ForeignTableSmall foreignTable;
\r
63 private final CompleteTableSmall completeTable;
\r
64 private final ClusterMapSmall clusterMap;
\r
65 private final int[] headerTable;
\r
66 private final ClusterSupport clusterSupport;
\r
67 private boolean proxy;
\r
68 private boolean deleted = false;
\r
70 public ClusterSmall(ClusterUID clusterUID, int clusterKey, ClusterTable clusterTable, ClusterSupport support) {
\r
71 super(clusterUID, clusterKey, support);
\r
72 if(DebugPolicy.REPORT_CLUSTER_EVENTS)
\r
73 new Exception(clusterUID.toString()).printStackTrace();
\r
75 this.headerTable = null;
\r
76 this.resourceTable = null;
\r
77 this.foreignTable = null;
\r
78 this.predicateTable = null;
\r
79 this.objectTable = null;
\r
80 this.valueTable = null;
\r
81 this.completeTable = null;
\r
82 this.clusterMap = null;
\r
83 this.clusterSupport = null;
\r
84 this.clusterBits = 0;
\r
85 this.importance = 0;
\r
87 public ClusterSmall(ClusterUID clusterUID, int clusterKey, ClusterSupport support) {
\r
88 super(clusterUID, clusterKey, support);
\r
89 if(DebugPolicy.REPORT_CLUSTER_EVENTS)
\r
90 new Exception(clusterUID.toString()).printStackTrace();
\r
92 this.headerTable = new int[INT_HEADER_SIZE];
\r
93 this.resourceTable = new ResourceTableSmall(this, headerTable, RESOURCE_TABLE_OFFSET);
\r
94 this.foreignTable = new ForeignTableSmall(this, headerTable, FOREIGN_TABLE_OFFSET);
\r
95 this.predicateTable = new PredicateTable(this, headerTable, PREDICATE_TABLE_OFFSET);
\r
96 this.objectTable = new ObjectTable(this, headerTable, OBJECT_TABLE_OFFSET);
\r
97 this.valueTable = new ValueTableSmall(this, headerTable, VALUE_TABLE_OFFSET);
\r
98 this.completeTable = new CompleteTableSmall(this, headerTable, COMPLETE_TABLE_OFFSET);
\r
99 this.clusterMap = new ClusterMapSmall(this, foreignTable);
\r
100 this.clusterSupport = support;
\r
101 this.clusterBits = ClusterTraitsBase.getClusterBits(clusterKey);
\r
102 this.importance = -clusterTable.timeCounter();
\r
104 protected ClusterSmall(long[] longs, int[] ints, byte[] bytes, ClusterSupport support, int clusterKey)
\r
105 throws DatabaseException {
\r
106 super(checkValidity(-1, longs, ints, bytes), clusterKey, support);
\r
107 this.proxy = false;
\r
108 if (ints.length < INT_HEADER_SIZE)
\r
109 throw new IllegalArgumentException("Too small integer table for cluster.");
\r
110 this.headerTable = ints;
\r
111 if(DebugPolicy.REPORT_CLUSTER_EVENTS) new Exception(Long.toString(clusterId)).printStackTrace();
\r
112 this.resourceTable = new ResourceTableSmall(this, ints, RESOURCE_TABLE_OFFSET, longs);
\r
113 this.foreignTable = new ForeignTableSmall(this, headerTable, FOREIGN_TABLE_OFFSET, longs);
\r
114 this.predicateTable = new PredicateTable(this, ints, PREDICATE_TABLE_OFFSET, ints);
\r
115 this.objectTable = new ObjectTable(this, ints, OBJECT_TABLE_OFFSET, ints);
\r
116 this.valueTable = new ValueTableSmall(this, ints, VALUE_TABLE_OFFSET, bytes);
\r
117 this.completeTable = new CompleteTableSmall(this, headerTable, COMPLETE_TABLE_OFFSET, ints);
\r
118 this.clusterMap = new ClusterMapSmall(this, foreignTable);
\r
119 this.clusterSupport = support;
\r
120 this.clusterBits = ClusterTraitsBase.getClusterBits(clusterKey);
\r
121 this.importance = clusterTable.timeCounter();
\r
122 clusterTable.markImmutable(this, getImmutable());
\r
125 System.out.println("Cluster " + clusterId);
\r
126 System.out.println("-size:" + getUsedSpace());
\r
127 System.out.println(" -rt:" + (resourceTable.getTableCapacity() * 8 + 8));
\r
128 System.out.println(" -ft:" + foreignTable.getTableCapacity() * 8);
\r
129 System.out.println(" -pt:" + predicateTable.getTableCapacity() * 4);
\r
130 System.out.println(" -ot:" + objectTable.getTableCapacity() * 4);
\r
131 System.out.println(" -ct:" + completeTable.getTableCapacity() * 4);
\r
132 System.out.println(" -vt:" + valueTable.getTableCapacity());
\r
134 System.out.println("-resourceTable:");
\r
135 System.out.println(" -resourceCount=" + resourceTable.getResourceCount());
\r
136 System.out.println(" -size=" + resourceTable.getTableSize());
\r
137 System.out.println(" -capacity=" + resourceTable.getTableCapacity());
\r
138 System.out.println(" -count=" + resourceTable.getTableCount());
\r
139 System.out.println(" -size=" + resourceTable.getTableSize());
\r
140 //resourceTable.analyse();
\r
142 public void checkDirectReference(int dr)
\r
143 throws DatabaseException {
\r
144 if (deleted) return;
\r
145 if (!ClusterTraits.statementIndexIsDirect(dr))
\r
146 throw new ValidationException("Reference is not direct. Reference=" + dr);
\r
147 if (ClusterTraits.isFlat(dr))
\r
148 throw new ValidationException("Reference is flat. Reference=" + dr);
\r
149 if (ClusterTraits.isLocal(dr)) {
\r
150 if (dr < 1 || dr > resourceTable.getUsedSize())
\r
151 throw new ValidationException("Illegal local reference. Reference=" + dr);
\r
153 int fi = ClusterTraits.getForeignIndexFromReference(dr);
\r
154 int ri = ClusterTraits.getResourceIndexFromForeignReference(dr);
\r
155 if (fi < 1 || fi > foreignTable.getUsedSize())
\r
156 throw new ValidationException("Illegal foreign reference. Reference=" + dr + " foreign index=" + fi);
\r
157 if (ri < 1 || ri > ClusterTraits.getMaxNumberOfResources())
\r
158 throw new ValidationException("Illegal foreign reference. Reference=" + dr + " resource index=" + ri);
\r
161 public void checkPredicateIndex(int pi)
\r
162 throws DatabaseException {
\r
163 if (deleted) return;
\r
164 // predicateTable.checkPredicateSetIndex(this, pi);
\r
166 public void checkObjectSetReference(int or)
\r
167 throws DatabaseException {
\r
168 if (deleted) return;
\r
169 if (ClusterTraits.statementIndexIsDirect(or))
\r
170 throw new ValidationException("Illegal object set reference. Reference=" + or);
\r
171 int oi = ClusterTraits.statementIndexGet(or);
\r
172 this.objectTable.checkObjectSetIndex(this, oi);
\r
175 public void checkValueInit()
\r
176 throws DatabaseException {
\r
177 valueTable.checkValueInit();
\r
179 public void checkValue(int capacity, int index)
\r
180 throws DatabaseException {
\r
181 valueTable.checkValue(capacity, index);
\r
183 public void checkValueFini()
\r
184 throws DatabaseException {
\r
185 valueTable.checkValueFini();
\r
187 public void checkForeingIndex(int fi)
\r
188 throws DatabaseException {
\r
189 if (deleted) return;
\r
190 if (fi<1 || fi > foreignTable.getUsedSize())
\r
191 throw new ValidationException("Illegal foreign index=" + fi);
\r
193 public void checkCompleteSetReference(int cr)
\r
194 throws DatabaseException {
\r
195 if (!ClusterTraits.completeReferenceIsMultiple(cr))
\r
196 throw new ValidationException("Illegal complete set reference. Reference=" + cr);
\r
198 this.completeTable.checkCompleteSetIndex(this, ci);
\r
200 public void check()
\r
201 throws DatabaseException {
\r
202 if (deleted) return;
\r
203 // this.completeTable.check(this);
\r
204 // this.objectTable.check(this);
\r
205 // // Must be after object table check.
\r
206 // this.predicateTable.check(this);
\r
207 // this.resourceTable.check(this);
\r
210 public CompleteTypeEnum getCompleteType(int resourceKey, ClusterSupport support)
\r
211 throws DatabaseException {
\r
212 if (deleted) return CompleteTypeEnum.NotComplete;
\r
213 final int resourceRef = getLocalReference(resourceKey);
\r
214 CompleteTypeEnum ct = resourceTable.getCompleteType(resourceRef);
\r
216 System.out.println("ClusterSmall.getCompleteType rk=" + resourceKey + " ct=" + ct);
\r
221 public int getCompleteObjectKey(int resourceKey, ClusterSupport support)
\r
222 throws DatabaseException {
\r
223 if (deleted) return 0;
\r
224 final int resourceIndexOld = getLocalReference(resourceKey);
\r
225 short completeRef = resourceTable.getCompleteObjectRef(resourceIndexOld);
\r
228 if (0 == completeRef)
\r
229 throw new DatabaseException("Resource's complete object refernce is null. Resource key=" + resourceKey + ".");
\r
230 ClusterI.CompleteTypeEnum completeType = resourceTable.getCompleteType(resourceIndexOld);
\r
231 if (completeType == ClusterI.CompleteTypeEnum.NotComplete)
\r
232 throw new DatabaseException("Resource has multiple complete objects. Resource key=" + resourceKey + ".");
\r
233 if (ClusterTraitsSmall.resourceRefIsLocal(completeRef)) {
\r
234 clusterIndex = clusterKey;
\r
235 resourceIndex = completeRef;
\r
236 } else { // Resource has one complete statement.
\r
237 ResourceUID resourceUID = clusterMap.getForeignResourceUID(completeRef);
\r
238 ClusterI c = support.getClusterByClusterUIDOrMake(resourceUID.asCID());
\r
239 clusterIndex = c.getClusterKey();
\r
240 resourceIndex = resourceUID.getIndex();
\r
242 int key = ClusterTraits.createResourceKey(clusterIndex, resourceIndex);
\r
244 System.out.println("ClusterSmall.complete object rk=" + resourceKey + " ck=" + key);
\r
249 public boolean isComplete(int resourceKey, ClusterSupport support)
\r
250 throws DatabaseException {
\r
251 if (deleted) return false;
\r
252 final int resourceRef = getLocalReference(resourceKey);
\r
253 final ClusterI.CompleteTypeEnum completeType = resourceTable.getCompleteType(resourceRef);
\r
254 boolean complete = completeType != ClusterI.CompleteTypeEnum.NotComplete;
\r
256 System.out.println("ClusterSmall.key=" + resourceKey + " isComplete=" + complete);
\r
259 public int getSingleObject(int resourceKey, int predicateKey, int objectIndex, ClusterSupport support) throws DatabaseException {
\r
261 System.out.println("ClusterSmall.getSingleObject: rk=" + resourceKey + " pk=" + predicateKey);
\r
262 if (deleted) return 0;
\r
263 if (0 == objectIndex) {
\r
264 final int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKeyNoThrow(resourceKey);
\r
265 final short pRef = getInternalReferenceOrZero2(predicateKey, support);
\r
266 final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
\r
267 return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);
\r
269 return objectTable.getSingleObject(objectIndex, support, this);
\r
272 public void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey, int objectIndex, AsyncMultiProcedure<Resource> procedure,
\r
273 ClusterSupport support) throws DatabaseException {
\r
274 if (deleted) return;
\r
276 System.out.println("ClusterSmall.forObjects1: rk=" + resourceKey + " pk=" + predicateKey);
\r
277 if (0 == objectIndex) {
\r
278 final int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKey(resourceKey);
\r
279 final int pRef = getInternalReferenceOrZero2(predicateKey, support);
\r
280 final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
\r
281 resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
\r
284 objectTable.foreachObject(graph, objectIndex, procedure, this);
\r
287 public <C> void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey, int objectIndex, C context, AsyncContextMultiProcedure<C, Resource> procedure,
\r
288 ClusterSupport support) throws DatabaseException {
\r
290 System.out.println("ClusterSmall.forObjects1: rk=" + resourceKey + " pk=" + predicateKey);
\r
291 if (deleted) return;
\r
292 if (0 == objectIndex) {
\r
293 final int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKey(resourceKey);
\r
294 final int pRef = getInternalReferenceOrZero2(predicateKey, support);
\r
295 final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
\r
296 resourceTable.foreachObject(resourceIndex, graph, context, procedure, support, pRef, pCompleteType, completeTable, this);
\r
299 objectTable.foreachObject(graph, objectIndex, context, procedure, this);
\r
303 public <Context> boolean forObjects(int resourceKey, int predicateKey, int objectIndex, ObjectProcedure<Context> procedure,
\r
304 Context context, ClusterSupport support) throws DatabaseException {
\r
306 System.out.println("ClusterSmall.forObjects2: rk=" + resourceKey + " pk=" + predicateKey);
\r
307 if (deleted) return false;
\r
308 if (0 == objectIndex) {
\r
309 final int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKey(resourceKey);
\r
310 final short pRef = getInternalReferenceOrZero2(predicateKey, support);
\r
311 final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
\r
312 return resourceTable.foreachObject(resourceIndex, procedure, context, support, this, pRef, pCompleteType, completeTable);
\r
314 return objectTable.foreachObject(objectIndex, procedure, context, support, this);
\r
318 public int getSingleObject(int resourceKey, int predicateKey, ClusterSupport support) throws DatabaseException {
\r
320 System.out.println("ClusterSmall.getSingleObject2: rk=" + resourceKey + " pk=" + predicateKey);
\r
321 if (deleted) return 0;
\r
322 final int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKey(resourceKey);
\r
323 final short pRef = getInternalReferenceOrZero2(predicateKey, support);
\r
324 final int completeType = ClusterTraitsBase.getCompleteTypeIntFromResourceKey(predicateKey);
\r
325 final ClusterI.CompleteTypeEnum pCompleteType = CompleteTypeEnum.make(completeType);
\r
326 if (completeType > 0)
\r
327 return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);
\r
328 final int predicateIndex = (int)resourceTable.table[(resourceIndex<<1) - 1 + resourceTable.offset] & 0xFFFFFF;
\r
329 if (0 == predicateIndex) // All relevant data is in resource table.
\r
330 return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);
\r
331 int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef & 0xFFFF);
\r
332 return getSingleObject(resourceKey, predicateKey, objectIndex, support);
\r
336 public <T> int getSingleObject(int resourceKey, ForPossibleRelatedValueProcedure<T> procedure, ClusterSupport support) throws DatabaseException {
\r
337 if (deleted) return 0;
\r
338 final short resourceIndex = (short)ClusterTraitsBase.getResourceIndexFromResourceKey(resourceKey);
\r
339 final int predicateKey = procedure.predicateKey;
\r
340 int clusterKey = ClusterTraitsBase.getClusterMaskFromResourceKey(resourceKey);
\r
342 if(procedure.clusterKey[0] == clusterKey) {
\r
343 pRef = (short)procedure.predicateReference[0];
\r
345 pRef = getInternalReferenceOrZero2(predicateKey, support);
\r
346 procedure.clusterKey[0] = clusterKey;
\r
347 procedure.predicateReference[0] = pRef;
\r
350 final ClusterI.CompleteTypeEnum pCompleteType = procedure.completeType;
\r
351 if (CompleteTypeEnum.NotComplete != pCompleteType)
\r
352 return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);
\r
353 final int predicateIndex = (int)resourceTable.table[(resourceIndex<<1) - 1 + resourceTable.offset] & 0xFFFFFF;
\r
354 if (0 == predicateIndex) // All relevant data is in resource table.
\r
355 return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);
\r
356 int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef & 0xFFFF);
\r
357 return getSingleObject(resourceKey, predicateKey, objectIndex, support);
\r
361 public <C, T> int getSingleObject(int resourceKey, ForPossibleRelatedValueContextProcedure<C, T> procedure, ClusterSupport support) throws DatabaseException {
\r
362 if (deleted) return 0;
\r
363 final short resourceIndex = (short)ClusterTraitsBase.getResourceIndexFromResourceKey(resourceKey);
\r
364 final int predicateKey = procedure.predicateKey;
\r
365 int clusterKey = ClusterTraitsBase.getClusterMaskFromResourceKey(resourceKey);
\r
367 if(procedure.clusterKey[0] == clusterKey) {
\r
368 pRef = (short)procedure.predicateReference[0];
\r
370 pRef = getInternalReferenceOrZero2(predicateKey, support);
\r
371 procedure.clusterKey[0] = clusterKey;
\r
372 procedure.predicateReference[0] = pRef;
\r
374 final ClusterI.CompleteTypeEnum pCompleteType = procedure.completeType;
\r
375 if (CompleteTypeEnum.NotComplete != pCompleteType)
\r
376 return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);
\r
377 final int predicateIndex = (int)resourceTable.table[(resourceIndex<<1) - 1 + resourceTable.offset] & 0xFFFFFF;
\r
378 if (0 == predicateIndex) // All relevant data is in resource table.
\r
379 return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);
\r
380 int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef & 0xFFFF);
\r
381 return getSingleObject(resourceKey, predicateKey, objectIndex, support);
\r
385 public void forObjects(ReadGraphImpl graph, int resourceKey,
\r
386 int predicateKey, AsyncMultiProcedure<Resource> procedure) throws DatabaseException {
\r
387 if (deleted) return;
\r
388 SessionImplSocket session = (SessionImplSocket)graph.getSession();
\r
389 ClusterSupport support = session.clusterTranslator;
\r
391 System.out.println("ClusterSmall.forObjects3: rk=" + resourceKey + " pk=" + predicateKey);
\r
392 final int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKey(resourceKey);
\r
393 final int pRef = getInternalReferenceOrZero2(predicateKey, support);
\r
394 final int completeType = ClusterTraitsBase.getCompleteTypeIntFromResourceKey(predicateKey);
\r
395 final ClusterI.CompleteTypeEnum pCompleteType = CompleteTypeEnum.make(completeType);
\r
396 if (completeType > 0) {
\r
397 resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
\r
400 final int predicateIndex = (int)resourceTable.table[(resourceIndex<<1) - 1 + resourceTable.offset] & 0xFFFFFF;
\r
401 if (0 == predicateIndex) {
\r
402 resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
\r
405 int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef & 0xFFFF);
\r
406 forObjects(graph, resourceKey, predicateKey, objectIndex, procedure, support);
\r
409 public void forObjects(ReadGraphImpl graph, int resourceKey, ForEachObjectProcedure procedure) throws DatabaseException {
\r
410 if (deleted) return;
\r
411 final int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKey(resourceKey);
\r
412 final int predicateKey = procedure.predicateKey;
\r
413 int clusterKey = ClusterTraitsBase.getClusterMaskFromResourceKey(resourceKey);
\r
415 if(procedure.clusterKey[0] == clusterKey) {
\r
416 pRef = procedure.predicateReference[0];
\r
418 SessionImplSocket session = (SessionImplSocket)graph.getSession();
\r
419 ClusterSupport support = session.clusterTranslator;
\r
420 pRef = getInternalReferenceOrZero2(predicateKey, support);
\r
421 procedure.clusterKey[0] = clusterKey;
\r
422 procedure.predicateReference[0] = pRef;
\r
424 final ClusterI.CompleteTypeEnum pCompleteType = procedure.completeType;
\r
425 if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {
\r
426 SessionImplSocket session = (SessionImplSocket)graph.getSession();
\r
427 ClusterSupport support = session.clusterTranslator;
\r
428 resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
\r
431 final int predicateIndex = (int)resourceTable.table[(resourceIndex<<1) - 1 + resourceTable.offset] & 0xFFFFFF;
\r
432 if (0 == predicateIndex) {
\r
433 SessionImplSocket session = (SessionImplSocket)graph.getSession();
\r
434 ClusterSupport support = session.clusterTranslator;
\r
435 resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
\r
438 int hashBase = predicateIndex + predicateTable.offset;
\r
439 if (predicateTable.table[hashBase-1] < 0) {
\r
440 int objectIndex = TableIntArraySet2.get(predicateTable.table, hashBase, pRef & 0xFFFF);
\r
441 //int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef & 0xFFFF);
\r
442 SessionImplSocket session = (SessionImplSocket)graph.getSession();
\r
443 ClusterSupport support = session.clusterTranslator;
\r
444 forObjects(graph, resourceKey, predicateKey, objectIndex, procedure, support);
\r
446 procedure.finished(graph);
\r
451 public <C> void forObjects(ReadGraphImpl graph, int resourceKey, C context, ForEachObjectContextProcedure<C> procedure) throws DatabaseException {
\r
452 if (deleted) return;
\r
453 final int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKey(resourceKey);
\r
454 final int predicateKey = procedure.predicateKey;
\r
455 int clusterKey = ClusterTraitsBase.getClusterMaskFromResourceKey(resourceKey);
\r
457 if(procedure.clusterKey[0] == clusterKey) {
\r
458 pRef = procedure.predicateReference[0];
\r
460 SessionImplSocket session = (SessionImplSocket)graph.getSession();
\r
461 ClusterSupport support = session.clusterTranslator;
\r
462 pRef = getInternalReferenceOrZero2(predicateKey, support);
\r
463 procedure.clusterKey[0] = clusterKey;
\r
464 procedure.predicateReference[0] = pRef;
\r
467 final ClusterI.CompleteTypeEnum pCompleteType = procedure.completeType;
\r
468 if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {
\r
469 SessionImplSocket session = (SessionImplSocket)graph.getSession();
\r
470 ClusterSupport support = session.clusterTranslator;
\r
471 resourceTable.foreachObject(resourceIndex, graph, context, procedure, support, pRef, pCompleteType, completeTable, this);
\r
474 final int predicateIndex = (int)resourceTable.table[(resourceIndex<<1) - 1 + resourceTable.offset] & 0xFFFFFF;
\r
475 if (0 == predicateIndex) {
\r
476 SessionImplSocket session = (SessionImplSocket)graph.getSession();
\r
477 ClusterSupport support = session.clusterTranslator;
\r
478 resourceTable.foreachObject(resourceIndex, graph, context, procedure, support, pRef, pCompleteType, completeTable, this);
\r
481 int hashBase = predicateIndex + predicateTable.offset;
\r
482 if(predicateTable.table[hashBase-1] < 0) {
\r
483 int objectIndex = TableIntArraySet2.get(predicateTable.table, hashBase, pRef & 0xFFFF);
\r
484 SessionImplSocket session = (SessionImplSocket)graph.getSession();
\r
485 ClusterSupport support = session.clusterTranslator;
\r
486 forObjects(graph, resourceKey, predicateKey, objectIndex, context, procedure, support);
\r
488 int objectIndex = TableIntSet2.get(predicateTable.table, hashBase, pRef & 0xFFFF);
\r
489 SessionImplSocket session = (SessionImplSocket)graph.getSession();
\r
490 ClusterSupport support = session.clusterTranslator;
\r
491 forObjects(graph, resourceKey, predicateKey, objectIndex, context, procedure, support);
\r
495 public <Context> boolean forObjects(int resourceKey, int predicateKey,
\r
496 ObjectProcedure<Context> procedure, Context context, ClusterSupport support)
\r
497 throws DatabaseException {
\r
499 System.out.println("ClusterSmall.forObjects4: rk=" + resourceKey + " pk=" + predicateKey);
\r
500 if (deleted) return false;
\r
501 final short resourceIndex = (short)ClusterTraitsBase.getResourceIndexFromResourceKey(resourceKey);
\r
502 final short pRef = getInternalReferenceOrZero2(predicateKey, support);
\r
503 final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
\r
504 // PredicateType is complete i.e. all relevant data is in resource table.
\r
505 if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {
\r
507 System.out.println("ClusterSmall.forObjects: complete type was " + pCompleteType + " cluster=" + getClusterUID());
\r
508 return resourceTable.foreachObject(resourceIndex, procedure, context, support, this, pRef, pCompleteType, completeTable);
\r
510 final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);
\r
511 if (0 == predicateIndex) { // All relevant data is in resource table.
\r
513 System.out.println("ClusterSmall.forObjects: no predicate table " + pCompleteType);
\r
514 return resourceTable.foreachObject(resourceIndex, procedure, context, support, this, pRef, pCompleteType, completeTable);
\r
516 int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef & 0xFFFF);
\r
517 return forObjects(resourceKey, predicateKey, objectIndex, procedure, context, support);
\r
520 public <Context> boolean forPredicates(int resourceKey,
\r
521 PredicateProcedure<Context> procedure, Context context, ClusterSupport support)
\r
522 throws DatabaseException {
\r
524 System.out.println("ClusterSmall.forPredicates: rk=" + resourceKey );
\r
525 if (deleted) return false;
\r
526 final int resourceIndex = getLocalReference(resourceKey);
\r
527 final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);
\r
528 if (0 == predicateIndex)
\r
529 return resourceTable.foreachPredicate(resourceIndex,
\r
530 procedure, context, support, this, completeTable);
\r
532 boolean broken = resourceTable.foreachPredicate(resourceIndex,
\r
533 procedure, context, support, this, completeTable);
\r
537 return predicateTable.foreachPredicate(predicateIndex,
\r
538 procedure, context, support, this);
\r
541 public ClusterI addRelation(int sResourceKey, int pResourceKey, int oResourceKey, ClusterSupport support)
\r
542 throws DatabaseException {
\r
544 System.out.println("add rk=" + sResourceKey + " pk=" + pResourceKey + " ok=" + oResourceKey);
\r
545 if (deleted) return null;
\r
547 ClusterImpl cluster = clusterTable.load2(clusterId, clusterKey);
\r
548 return cluster.addRelation(sResourceKey, pResourceKey, oResourceKey, support);
\r
554 short sri = getLocalReferenceAnd(sResourceKey, support, ClusterChange.ADD_OPERATION);
\r
555 short pri = getReferenceOrCreateIfForeign(pResourceKey, support, ClusterStream.NULL_OPERATION);
\r
556 short ori = getReferenceOrCreateIfForeign(oResourceKey, support, ClusterStream.NULL_OPERATION);
\r
557 ClusterI.CompleteTypeEnum completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(pResourceKey);
\r
558 ret = addRelationInternal(sri, pri, ori, completeType);
\r
559 calculateModifiedId();
\r
560 } catch (OutOfSpaceException e) {
\r
561 boolean streamOff = support.getStreamOff();
\r
563 support.cancelStatement(this);
\r
564 support.setStreamOff(true);
\r
566 ClusterI cluster = toBig(support);
\r
568 support.setStreamOff(false);
\r
569 ClusterI cluster2 = cluster.addRelation(sResourceKey, pResourceKey, oResourceKey, support);
\r
570 if (cluster != cluster2)
\r
571 throw new DatabaseException("Internal error. Contact application support.");
\r
576 support.addStatement(this);
\r
579 support.cancelStatement(this);
\r
584 public boolean removeRelation(int sResourceKey, int pResourceKey, int oResourceKey, ClusterSupport support)
\r
585 throws DatabaseException {
\r
586 if (deleted) return false;
\r
587 short sri = getLocalReferenceAnd(sResourceKey, support, ClusterChange.REMOVE_OPERATION);
\r
588 short pri = getInternalReferenceOrZeroAnd(pResourceKey, support, ClusterStream.NULL_OPERATION);
\r
589 short ori = getInternalReferenceOrZeroAnd(oResourceKey, support, ClusterStream.NULL_OPERATION);
\r
590 boolean ret = false;
\r
591 if (0 != pri && 0 != ori) {
\r
592 ClusterI.CompleteTypeEnum completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(pResourceKey);
\r
593 ret = removeRelationInternal(sri, pri, ori, completeType, support);
\r
594 calculateModifiedId();
\r
597 support.removeStatement(this);
\r
599 support.cancelStatement(this);
\r
604 public void denyRelation(int sResourceKey, int pResourceKey, int oResourceKey, ClusterSupport support)
\r
605 throws DatabaseException {
\r
606 if (deleted) return;
\r
607 short s = checkResourceKeyIsOursAndGetResourceIndexIf(sResourceKey, support);
\r
608 ResourceReferenceAndCluster p = checkResourceKeyAndGetResourceIndexIf(pResourceKey, support);
\r
609 ResourceReferenceAndCluster o = checkResourceKeyAndGetResourceIndexIf(oResourceKey, support);
\r
610 if (0 == s || 0 == p.reference || 0 == o.reference)
\r
613 ClusterI.CompleteTypeEnum completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(pResourceKey);
\r
614 boolean ret = removeRelationInternal(s, p.reference, o.reference, completeType, support);
\r
616 support.addStatementIndex(this, sResourceKey, getClusterUID(), ClusterChange.REMOVE_OPERATION);
\r
617 support.addStatementIndex(this, pResourceKey, p.clusterUID, ClusterStream.NULL_OPERATION);
\r
618 support.addStatementIndex(this, oResourceKey, o.clusterUID, ClusterStream.NULL_OPERATION);
\r
619 support.removeStatement(this);
\r
621 calculateModifiedId();
\r
626 public InputStream getValueStream(int resourceKey, ClusterSupport support) throws DatabaseException {
\r
628 System.out.println("ClusterSmall.getValue " + resourceKey);
\r
629 if (deleted) return null;
\r
630 int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKeyNoThrow(resourceKey);
\r
632 byte[] buffer = resourceTable.getValue(valueTable, resourceIndex);
\r
633 if(buffer == null) return null;
\r
634 return new ByteArrayInputStream(buffer);
\r
635 } catch (ExternalValueException e) {
\r
636 return support.getValueStreamEx(resourceIndex, clusterId);
\r
640 public byte[] getValue(int resourceKey, ClusterSupport support)
\r
641 throws DatabaseException {
\r
643 System.out.println("ClusterSmall.getValue " + resourceKey);
\r
644 if (deleted) return null;
\r
645 int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKeyNoThrow(resourceKey);
\r
647 return resourceTable.getValue(valueTable, resourceIndex);
\r
648 } catch (ExternalValueException e) {
\r
649 return support.getValueEx(resourceIndex, clusterId);
\r
653 public boolean hasValue(int resourceKey, ClusterSupport support)
\r
654 throws DatabaseException {
\r
655 if (deleted) return false;
\r
656 int resourceIndex = getLocalReference(resourceKey);
\r
657 return resourceTable.hasValue(resourceIndex);
\r
660 public boolean removeValue(int resourceKey, ClusterSupport support)
\r
661 throws DatabaseException {
\r
662 if (deleted) return false;
\r
663 int resourceIndex = getLocalReferenceAnd(resourceKey, support, ClusterChange.DELETE_OPERATION);
\r
664 support.removeValue(this);
\r
665 calculateModifiedId();
\r
666 return resourceTable.removeValue(valueTable, resourceIndex);
\r
669 public ClusterI setValue(int rResourceId, byte[] value, int length, ClusterSupport support)
\r
670 throws DatabaseException {
\r
671 if (deleted) return null;
\r
672 int resourceIndex = getLocalReferenceAnd(rResourceId, support, ClusterStream.SET_OPERATION);
\r
673 support.setValue(this, getClusterId(), value, length);
\r
675 resourceTable.setValue(valueTable, resourceIndex, value, length);
\r
676 calculateModifiedId();
\r
678 } catch (OutOfSpaceException e) {
\r
679 boolean streamOff = support.getStreamOff();
\r
681 support.setStreamOff(true);
\r
682 ClusterI cluster = toBig(support);
\r
683 cluster.setValue(rResourceId, value, length, support);
\r
685 support.setStreamOff(false);
\r
690 public ClusterI modiValueEx(int rResourceId, long voffset, int length, byte[] value, int offset, ClusterSupport support)
\r
691 throws DatabaseException {
\r
692 if (deleted) return null;
\r
693 int resourceIndex = getLocalReferenceAnd(rResourceId, support, ClusterStream.MODI_OPERATION);
\r
694 support.modiValue(this, getClusterId(), voffset, length, value, offset);
\r
695 resourceTable.setValueEx(valueTable, resourceIndex);
\r
696 calculateModifiedId();
\r
700 public byte[] readValueEx(int rResourceId, long voffset, int length, ClusterSupport support)
\r
701 throws DatabaseException {
\r
702 if (deleted) return null;
\r
703 int resourceIndex = getLocalReference(rResourceId);
\r
704 boolean isExternal = resourceTable.isValueEx(valueTable, resourceIndex);
\r
706 throw new DatabaseException("ClusterI.readValue supported only for external value. Resource key=" + rResourceId);
\r
707 return support.getValueEx(resourceIndex, getClusterId(), voffset, length);
\r
710 public long getValueSizeEx(int rResourceId, ClusterSupport support)
\r
711 throws DatabaseException, ExternalValueException {
\r
712 if (deleted) return 0;
\r
713 int resourceIndex = getLocalReference(rResourceId);
\r
714 boolean isExternal = resourceTable.isValueEx(valueTable, resourceIndex);
\r
716 throw new ExternalValueException("ClusterI.getValueSizeEx supported only for external value. Resource key=" + rResourceId);
\r
717 return support.getValueSizeEx(resourceIndex, getClusterId());
\r
720 public void setValueEx(int rResourceId)
\r
721 throws DatabaseException {
\r
722 int resourceIndex = getLocalReference(rResourceId);
\r
723 resourceTable.setValueEx(valueTable, resourceIndex);
\r
726 public int createResource(ClusterSupport support)
\r
727 throws DatabaseException {
\r
728 if (deleted) return 0;
\r
730 ClusterImpl cluster = clusterTable.load2(clusterId, clusterKey);
\r
731 return cluster.createResource(support);
\r
734 short resourceIndex = resourceTable.createResource();
\r
735 calculateModifiedId();
\r
736 if(DebugPolicy.REPORT_RESOURCE_ID_ALLOCATION)
\r
737 System.out.println("[RID_ALLOCATION]: ClusterSmall[" + clusterId + "] allocates " + resourceIndex);
\r
738 support.createResource(this, resourceIndex, getClusterId());
\r
739 return ClusterTraits.createResourceKey(clusterKey, resourceIndex);
\r
742 public boolean hasResource(int resourceKey, ClusterSupport support) {
\r
743 if (deleted) return false;
\r
744 int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(resourceKey);
\r
745 if (this.clusterKey != clusterKey) // foreign resource
\r
749 resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);
\r
750 } catch (DatabaseException e) {
\r
753 if (resourceIndex > 0 & resourceIndex <= resourceTable.getTableCount())
\r
759 public int getNumberOfResources(ClusterSupport support)
\r
760 throws DatabaseException {
\r
761 if (deleted) return 0;
\r
763 ClusterImpl cluster = clusterTable.load2(clusterId, clusterKey);
\r
764 return cluster.getNumberOfResources(support);
\r
767 return resourceTable.getUsedSize();
\r
770 public int getNumberOfResources() {
\r
771 if (deleted || proxy)
\r
773 return resourceTable.getUsedSize();
\r
777 public long getUsedSpace() {
\r
778 if (deleted) return 0;
\r
779 if(isEmpty()) return 0;
\r
780 long rt = resourceTable.getTableCapacity() * 8 + 8; // (8 = cluster id)
\r
781 long ft = foreignTable.getTableCapacity() * 8;
\r
782 long pt = predicateTable.getTableCapacity() * 4;
\r
783 long ot = objectTable.getTableCapacity() * 4;
\r
784 long ct = completeTable.getTableCapacity() * 4;
\r
785 long vt = valueTable.getTableCapacity() * 1;
\r
786 long cm = clusterMap.getUsedSpace();
\r
787 return rt + ft + pt + ot + ct + vt + cm;
\r
790 public boolean isEmpty() {
\r
791 if (deleted) return true; // Deleted cluster is always empty.
\r
792 if(resourceTable == null) return true;
\r
793 return resourceTable.getTableCount() == 0;
\r
796 public void printDebugInfo(String message, ClusterSupport support)
\r
797 throws DatabaseException {
\r
798 if (deleted) return;
\r
799 throw new DatabaseException("Not implemented!");
\r
801 private short getInternalReferenceOrZero2(int resourceKey, ClusterSupport support) throws DatabaseException {
\r
802 int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKeyNoThrow(resourceKey);
\r
803 if (!ClusterTraitsBase.isCluster(clusterBits, resourceKey)) {
\r
804 return clusterMap.getForeignReferenceOrZero(resourceKey);
\r
806 return (short)resourceIndex;
\r
809 private short getInternalReferenceOrZeroAnd(int resourceKey, ClusterSupport support, byte op)
\r
810 throws DatabaseException {
\r
811 int clusterKey = ClusterTraits.getClusterKeyFromResourceKey(resourceKey);
\r
812 int resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);
\r
813 if (this.clusterKey != clusterKey) { // foreign resource
\r
814 ClusterI foreignCluster = support.getClusterByClusterKey(clusterKey);
\r
815 ClusterUID clusterUID = foreignCluster.getClusterUID();
\r
816 short foreignRef = clusterMap.getForeignReferenceOrZero(resourceKey);
\r
817 support.addStatementIndex(this, resourceKey, clusterUID, op);
\r
820 support.addStatementIndex(this, resourceKey, getClusterUID(), op);
\r
821 return (short)resourceIndex;
\r
823 private final short getLocalReference(int resourceKey) throws DatabaseException {
\r
824 return ClusterTraits.getResourceIndexFromResourceKeyNoThrow(resourceKey);
\r
826 private final short getLocalReferenceAnd(int resourceKey, ClusterSupport support, byte op)
\r
827 throws DatabaseException {
\r
828 short resourceIndex = getLocalReference(resourceKey);
\r
829 support.addStatementIndex(this, resourceKey, getClusterUID(), op);
\r
830 return resourceIndex;
\r
832 private short checkResourceKeyIsOursAndGetResourceIndexIf(int resourceKey, ClusterSupport support)
\r
833 throws DatabaseException {
\r
834 int clusterShortId = ClusterTraits.getClusterKeyFromResourceKey(resourceKey);
\r
835 if (this.clusterKey != clusterShortId)
\r
837 int resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);
\r
838 return (short)resourceIndex;
\r
840 private short getReferenceOrCreateIfForeign(int resourceKey, ClusterSupport support, byte op)
\r
841 throws DatabaseException {
\r
842 int clusterKey = ClusterTraits.getClusterKeyFromResourceKey(resourceKey);
\r
843 short resourceIndex = (short)ClusterTraits.getResourceIndexFromResourceKey(resourceKey);
\r
844 if (this.clusterKey != clusterKey) {
\r
845 ClusterI foreignCluster = support.getClusterByClusterKey(clusterKey);
\r
846 ClusterUID clusterUID = foreignCluster.getClusterUID();
\r
847 support.addStatementIndex(this, resourceKey, clusterUID, op);
\r
848 short ref = clusterMap.getForeignReferenceOrCreateByResourceKey(resourceKey, clusterUID);
\r
851 support.addStatementIndex(this, resourceKey, getClusterUID(), op);
\r
852 return resourceIndex;
\r
854 private class ResourceReferenceAndCluster {
\r
855 ResourceReferenceAndCluster(short reference, ClusterUID clusterUID) {
\r
856 this.reference = reference;
\r
857 this.clusterUID = clusterUID;
\r
859 public final short reference;
\r
860 public final ClusterUID clusterUID;
\r
862 private ResourceReferenceAndCluster checkResourceKeyAndGetResourceIndexIf(int resourceKey, ClusterSupport support)
\r
863 throws DatabaseException {
\r
864 int clusterKey = ClusterTraits.getClusterKeyFromResourceKey(resourceKey);
\r
865 short resourceIndex = (short)ClusterTraits.getResourceIndexFromResourceKey(resourceKey);
\r
866 if (this.clusterKey != clusterKey) { // foreign resource
\r
867 ClusterI foreignCluster = support.getClusterByClusterKey(clusterKey);
\r
868 ClusterUID clusterUID = foreignCluster.getClusterUID();
\r
869 short ref = clusterMap.getForeignReferenceOrZero(resourceKey);
\r
870 return new ResourceReferenceAndCluster(ref, clusterUID);
\r
872 return new ResourceReferenceAndCluster(resourceIndex, getClusterUID());
\r
875 static long fTime = 0;
\r
877 int executeIndex = 0;
\r
878 long clusterUID1 = 0;
\r
879 long clusterUID2 = 0;
\r
882 final public int execute(int resourceReference) throws DatabaseException {
\r
884 if (deleted) return 0;
\r
885 short resourceRef = (short)resourceReference;
\r
887 if (ClusterTraitsSmall.resourceRefIsLocal(resourceRef)) {
\r
888 key = clusterBits | resourceRef;
\r
890 foreignTable.fillResourceUID(ClusterTraitsSmall.resourceRefGetForeignIndex((short)resourceRef), this);
\r
891 key = ClusterTraitsBase.createResourceKey(clusterSupport.getClusterKeyByClusterUIDOrMake(clusterUID1, clusterUID2), executeIndex);
\r
894 System.out.println("ClusterSmall.execute key=" + key);
\r
898 private boolean addRelationInternal(short sReference, short pReference, short oReference, ClusterI.CompleteTypeEnum completeType)
\r
899 throws DatabaseException {
\r
900 int predicateIndex = resourceTable.addStatement(sReference, pReference, oReference, predicateTable, objectTable, completeType, completeTable);
\r
901 if (0 == predicateIndex)
\r
902 return true; // added to resourceTable
\r
903 else if (0 > predicateIndex)
\r
904 return false; // old complete statemenent
\r
905 int newPredicateIndex = predicateTable.addPredicate(predicateIndex, 0xFFFF & pReference, 0xFFFF & oReference, objectTable);
\r
906 if (0 == newPredicateIndex)
\r
908 if (predicateIndex != newPredicateIndex)
\r
909 resourceTable.setPredicateIndex(sReference, newPredicateIndex);
\r
912 private boolean removeRelationInternal(int sResourceIndex, short pResourceIndex,
\r
913 short oResourceIndex, ClusterI.CompleteTypeEnum completeType, ClusterSupport support)
\r
914 throws DatabaseException {
\r
915 int predicateIndex = resourceTable.getPredicateIndex(sResourceIndex);
\r
916 if (0 == predicateIndex || ClusterI.CompleteTypeEnum.NotComplete != completeType)
\r
917 return resourceTable.removeStatementFromCache(sResourceIndex,
\r
918 pResourceIndex, oResourceIndex, completeType, completeTable);
\r
919 PredicateTable.Status ret = predicateTable.removePredicate(predicateIndex, 0xFFFF & pResourceIndex, 0xFFFF & oResourceIndex, objectTable);
\r
921 case NothingRemoved:
\r
923 case PredicateRemoved: {
\r
924 if (0 == predicateTable.getPredicateSetSize(predicateIndex))
\r
925 resourceTable.setPredicateIndex(sResourceIndex, 0);
\r
926 // intentionally dropping to next case
\r
930 resourceTable.removeStatement(sResourceIndex,
\r
931 pResourceIndex, oResourceIndex,
\r
932 completeType, completeTable,
\r
933 predicateTable, objectTable, support);
\r
937 public void load() {
\r
938 if (deleted) return;
\r
939 throw new Error("Not supported.");
\r
943 public void load(Callback<DatabaseException> r) {
\r
944 if (deleted) return;
\r
945 throw new Error("Not supported.");
\r
948 public boolean contains(int resourceKey) {
\r
949 if (deleted) return false;
\r
950 return ClusterTraitsBase.isCluster(clusterBits, resourceKey);
\r
953 public void load(final ClusterSupport support, final Runnable callback) {
\r
954 if (deleted) return;
\r
956 clusterTable.load2(clusterId, clusterKey);
\r
958 } catch (DatabaseException e) {
\r
959 e.printStackTrace();
\r
964 public ClusterI getClusterByResourceKey(int resourceKey,
\r
965 ClusterSupport support) {
\r
966 if (deleted) return null;
\r
970 public void increaseReferenceCount(int amount) {
\r
971 if (deleted) return;
\r
975 public void decreaseReferenceCount(int amount) {
\r
976 if (deleted) return;
\r
980 public int getReferenceCount() {
\r
981 if (deleted) return 0;
\r
985 public void releaseMemory() {
\r
988 public void compact() {
\r
989 if (deleted) return;
\r
990 clusterMap.compact();
\r
993 public boolean isLoaded() {
\r
994 return !proxy || deleted; // Deleted cluster is always loaded.
\r
997 public ClusterImpl tryLoad(SessionImplSocket sessionImpl) throws DatabaseException {
\r
998 if (deleted) return this; // Never load deleted cluster.
\r
999 return clusterTable.tryLoad(clusterId, clusterKey);
\r
1004 public ClusterBig toBig(ClusterSupport support)
\r
1005 throws DatabaseException {
\r
1007 System.out.println("DEBUG: toBig cluster=" + clusterId);
\r
1008 new Exception().printStackTrace();
\r
1010 if (deleted) return null; // Can't convert deleted cluster to big.
\r
1011 ClusterBig big = new ClusterBig(getClusterUID(), clusterKey, support);
\r
1013 big.cc.clusterImpl = this;
\r
1014 resourceTable.toBig(big, support, this);
\r
1015 big.foreignLookup = this.foreignLookup;
\r
1016 big.change = this.change;
\r
1018 this.foreignLookup = null;
\r
1019 this.change = null;
\r
1024 public ClusterTypeEnum getType() {
\r
1025 return ClusterTypeEnum.SMALL;
\r
1028 public boolean getImmutable() {
\r
1029 if (deleted) return false;
\r
1030 if (null == resourceTable)
\r
1032 int status = resourceTable.getClusterStatus();
\r
1033 return (status & ClusterStatus.ImmutableMaskSet) == ClusterStatus.ImmutableMaskSet;
\r
1036 public void setImmutable(boolean immutable, ClusterSupport support) {
\r
1037 if (deleted) return;
\r
1038 if(resourceTable != null) {
\r
1039 int status = resourceTable.getClusterStatus();
\r
1041 status |= ClusterStatus.ImmutableMaskSet;
\r
1043 status &= ClusterStatus.ImmutableMaskClear;
\r
1044 resourceTable.setClusterStatus(status);
\r
1046 support.setImmutable(this, immutable);
\r
1049 public boolean getDeleted() {
\r
1050 if (deleted) return true;
\r
1051 int status = resourceTable.getClusterStatus();
\r
1052 return (status & ClusterStatus.DeletedMaskSet) == ClusterStatus.DeletedMaskSet;
\r
1055 public void setDeleted(boolean set, ClusterSupport support) {
\r
1057 if(resourceTable != null) {
\r
1058 int status = resourceTable.getClusterStatus();
\r
1060 status |= ClusterStatus.DeletedMaskSet;
\r
1062 status &= ClusterStatus.DeletedMaskClear;
\r
1063 resourceTable.setClusterStatus(status);
\r
1065 if (null != support)
\r
1066 support.setDeleted(this, set);
\r
1069 public String toString() {
\r
1070 if (deleted) return "ClusterSmall[" + getClusterId() + " - has been deleted or hasn't been created.]";
\r
1072 final TIntHashSet set = new TIntHashSet();
\r
1073 TIntShortHashMap map = foreignTable.getResourceHashMap();
\r
1074 map.forEachKey(new TIntProcedure() {
\r
1076 public boolean execute(int value) {
\r
1077 set.add(value & 0xfffff000);
\r
1081 return "ClusterSmall[" + getClusterId() + " - " + getNumberOfResources() + " - " + foreignTable.getResourceHashMap().size() + " - " + set.size() + "]";
\r
1082 } catch (Throwable e) {
\r
1083 return "ClusterSmall[" + getNumberOfResources() + "]";
\r
1087 public Table<?> getPredicateTable() {
\r
1088 return predicateTable;
\r
1091 public Table<?> getForeignTable() {
\r
1092 return foreignTable;
\r
1095 public int makeResourceKey(int pRef) throws DatabaseException {
\r
1096 throw new UnsupportedOperationException();
\r
1099 public Table<?> getCompleteTable() {
\r
1100 return completeTable;
\r
1103 public Table<?> getValueTable() {
\r
1104 return valueTable;
\r
1107 public Table<?> getObjectTable() {
\r
1108 return objectTable;
\r
1113 class ClusterStatus {
\r
1114 public static final int ImmutableMaskClear = 0xFFFFFFFE;
\r
1115 public static final int ImmutableMaskSet = 0x00000001;
\r
1116 public static final int DeletedMaskClear = 0xFFFFFFFD;
\r
1117 public static final int DeletedMaskSet = 0x00000002;
\r