1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.db.procore.cluster;
14 import java.io.ByteArrayInputStream;
15 import java.io.InputStream;
16 import java.util.function.Consumer;
18 import org.simantics.db.Resource;
19 import org.simantics.db.exception.DatabaseException;
20 import org.simantics.db.exception.ExternalValueException;
21 import org.simantics.db.exception.ValidationException;
22 import org.simantics.db.impl.ClusterI;
23 import org.simantics.db.impl.ClusterI.PredicateProcedure;
24 import org.simantics.db.impl.ClusterSupport;
25 import org.simantics.db.impl.ClusterTraitsBase;
26 import org.simantics.db.impl.ForEachObjectContextProcedure;
27 import org.simantics.db.impl.ForEachObjectProcedure;
28 import org.simantics.db.impl.ForPossibleRelatedValueContextProcedure;
29 import org.simantics.db.impl.ForPossibleRelatedValueProcedure;
30 import org.simantics.db.impl.Table;
31 import org.simantics.db.impl.TableHeader;
32 import org.simantics.db.impl.graph.ReadGraphImpl;
33 import org.simantics.db.impl.query.QueryProcessor;
34 import org.simantics.db.procedure.AsyncContextMultiProcedure;
35 import org.simantics.db.procedure.AsyncMultiProcedure;
36 import org.simantics.db.service.ClusterUID;
38 import fi.vtt.simantics.procore.DebugPolicy;
39 import fi.vtt.simantics.procore.internal.ClusterChange;
40 import fi.vtt.simantics.procore.internal.ClusterStream;
41 import fi.vtt.simantics.procore.internal.SessionImplSocket;
43 final public class ClusterBig extends ClusterImpl {
44 private static final int TABLE_HEADER_SIZE = TableHeader.HEADER_SIZE + TableHeader.EXTRA_SIZE;
45 private static final int RESOURCE_TABLE_OFFSET = 0;
46 private static final int PREDICATE_TABLE_OFFSET = RESOURCE_TABLE_OFFSET + TABLE_HEADER_SIZE;
47 private static final int OBJECT_TABLE_OFFSET = PREDICATE_TABLE_OFFSET + TABLE_HEADER_SIZE;
48 private static final int VALUE_TABLE_OFFSET = OBJECT_TABLE_OFFSET + TABLE_HEADER_SIZE;
49 private static final int FLAT_TABLE_OFFSET = VALUE_TABLE_OFFSET + TABLE_HEADER_SIZE;
50 private static final int COMPLETE_TABLE_OFFSET = FLAT_TABLE_OFFSET + TABLE_HEADER_SIZE;
51 private static final int FOREIGN_TABLE_OFFSET = COMPLETE_TABLE_OFFSET + TABLE_HEADER_SIZE;
52 private static final int INT_HEADER_SIZE = FOREIGN_TABLE_OFFSET + TABLE_HEADER_SIZE;
53 private final int clusterBits;
54 final private ResourceTable resourceTable;
55 //final private ResourceTable movedResourceTable;
56 final private PredicateTable predicateTable;
57 final private ObjectTable objectTable;
58 final private ValueTable valueTable;
59 final private FlatTable flatTable;
60 final private ForeignTable foreignTable;
61 final private CompleteTable completeTable;
62 final private ClusterMap clusterMap;
63 final private int[] headerTable;
64 final private ClusterSupport clusterSupport;
65 public ClusterBig(ClusterUID clusterUID, int clusterKey, ClusterSupport support) {
66 super(clusterUID, clusterKey, support);
67 if(DebugPolicy.REPORT_CLUSTER_EVENTS)
68 new Exception(getClusterUID().toString()).printStackTrace();
69 this.headerTable = new int[INT_HEADER_SIZE];
70 this.resourceTable = new ResourceTable(this, headerTable, RESOURCE_TABLE_OFFSET);
71 this.foreignTable = new ForeignTable(this, headerTable, FOREIGN_TABLE_OFFSET);
72 this.predicateTable = new PredicateTable(this, headerTable, PREDICATE_TABLE_OFFSET);
73 this.objectTable = new ObjectTable(this, headerTable, OBJECT_TABLE_OFFSET);
74 this.valueTable = new ValueTable(this, headerTable, VALUE_TABLE_OFFSET);
75 this.completeTable = new CompleteTable(this, headerTable, COMPLETE_TABLE_OFFSET);
76 this.flatTable = null;
77 this.clusterMap = new ClusterMap(foreignTable, flatTable);
78 this.clusterSupport = support;
79 this.clusterBits = ClusterTraitsBase.getClusterBits(clusterKey);
81 // clusterTable.setDirtySizeInBytes(true);
83 protected ClusterBig(long[] longs, int[] ints, byte[] bytes, ClusterSupport support, int clusterKey)
84 throws DatabaseException {
85 super(checkValidity(0, longs, ints, bytes), clusterKey, support);
86 if(DebugPolicy.REPORT_CLUSTER_EVENTS)
87 new Exception(getClusterUID().toString()).printStackTrace();
88 if (ints.length < INT_HEADER_SIZE)
89 throw new IllegalArgumentException("Too small integer table for cluster.");
90 this.headerTable = ints;
91 this.resourceTable = new ResourceTable(this, ints, RESOURCE_TABLE_OFFSET, longs);
92 this.foreignTable = new ForeignTable(this, headerTable, FOREIGN_TABLE_OFFSET, longs);
93 this.predicateTable = new PredicateTable(this, ints, PREDICATE_TABLE_OFFSET, ints);
94 this.objectTable = new ObjectTable(this, ints, OBJECT_TABLE_OFFSET, ints);
95 this.valueTable = new ValueTable(this, ints, VALUE_TABLE_OFFSET, bytes);
96 this.flatTable = null;
97 this.completeTable = new CompleteTable(this, headerTable, COMPLETE_TABLE_OFFSET, ints);
98 this.clusterMap = new ClusterMap(foreignTable, flatTable);
99 this.clusterSupport = support;
100 this.clusterBits = ClusterTraitsBase.getClusterBits(clusterKey);
101 this.importance = -clusterTable.timeCounter();
102 clusterTable.markImmutable(this, getImmutable());
105 System.out.println("Cluster " + clusterId);
106 System.out.println("-size:" + getUsedSpace());
107 System.out.println(" -rt:" + (resourceTable.getTableCapacity() * 8 + 8));
108 System.out.println(" -ft:" + foreignTable.getTableCapacity() * 8);
109 System.out.println(" -pt:" + predicateTable.getTableCapacity() * 4);
110 System.out.println(" -ot:" + objectTable.getTableCapacity() * 4);
111 System.out.println(" -ct:" + completeTable.getTableCapacity() * 4);
112 System.out.println(" -vt:" + valueTable.getTableCapacity());
114 System.out.println("-resourceTable:");
115 System.out.println(" -resourceCount=" + resourceTable.getResourceCount());
116 System.out.println(" -size=" + resourceTable.getTableSize());
117 System.out.println(" -capacity=" + resourceTable.getTableCapacity());
118 System.out.println(" -count=" + resourceTable.getTableCount());
119 System.out.println(" -size=" + resourceTable.getTableSize());
120 //resourceTable.analyse();
122 public void checkDirectReference(int dr)
123 throws DatabaseException {
124 if (!ClusterTraits.statementIndexIsDirect(dr))
125 throw new ValidationException("Reference is not direct. Reference=" + dr);
126 if (ClusterTraits.isFlat(dr))
127 throw new ValidationException("Reference is flat. Reference=" + dr);
128 if (ClusterTraits.isLocal(dr)) {
129 if (dr < 1 || dr > resourceTable.getUsedSize())
130 throw new ValidationException("Illegal local reference. Reference=" + dr);
132 int fi = ClusterTraits.getForeignIndexFromReference(dr);
133 int ri = ClusterTraits.getResourceIndexFromForeignReference(dr);
134 if (fi < 1 || fi > foreignTable.getUsedSize())
135 throw new ValidationException("Illegal foreign reference. Reference=" + dr + " foreign index=" + fi);
136 if (ri < 1 || ri > ClusterTraits.getMaxNumberOfResources())
137 throw new ValidationException("Illegal foreign reference. Reference=" + dr + " resource index=" + ri);
140 public void checkPredicateIndex(int pi)
141 throws DatabaseException {
142 predicateTable.checkPredicateSetIndex(this, pi);
144 public void checkObjectSetReference(int or)
145 throws DatabaseException {
146 if (ClusterTraits.statementIndexIsDirect(or))
147 throw new ValidationException("Illegal object set reference. Reference=" + or);
148 int oi = ClusterTraits.statementIndexGet(or);
149 this.objectTable.checkObjectSetIndex(this, oi);
152 public void checkValueInit()
153 throws DatabaseException {
154 valueTable.checkValueInit();
156 public void checkValue(int capacity, int index)
157 throws DatabaseException {
158 valueTable.checkValue(capacity, index);
160 public void checkValueFini()
161 throws DatabaseException {
162 valueTable.checkValueFini();
164 public void checkForeingIndex(int fi)
165 throws DatabaseException {
166 if (fi<1 || fi > foreignTable.getUsedSize())
167 throw new ValidationException("Illegal foreign index=" + fi);
169 public void checkCompleteSetReference(int cr)
170 throws DatabaseException {
171 if (!ClusterTraits.completeReferenceIsMultiple(cr))
172 throw new ValidationException("Illegal complete set reference. Reference=" + cr);
174 this.completeTable.checkCompleteSetIndex(this, ci);
177 throws DatabaseException {
178 this.completeTable.check(this);
179 this.objectTable.check(this);
180 // Must be after object table check.
181 this.predicateTable.check(this);
182 this.resourceTable.check(this);
185 public CompleteTypeEnum getCompleteType(int resourceKey, ClusterSupport support)
186 throws DatabaseException {
187 final int resourceRef = getLocalReference(resourceKey);
188 int completeRef = resourceTable.getCompleteObjectRef(resourceRef);
189 CompleteTypeEnum ct = ClusterTraits.completeReferenceGetType(completeRef);
191 System.out.println("Cluster.getCompleteType rk=" + resourceKey + " ct=" + ct);
192 int i = ct.getValue();
194 case 0: return CompleteTypeEnum.NotComplete;
195 case 1: return CompleteTypeEnum.InstanceOf;
196 case 2: return CompleteTypeEnum.Inherits;
197 case 3: return CompleteTypeEnum.SubrelationOf;
198 default: throw new DatabaseException("Illegal complete type enumeration.");
203 public int getCompleteObjectKey(int resourceKey, ClusterSupport support)
204 throws DatabaseException {
205 final int resourceRef = getLocalReference(resourceKey);
206 int completeRef = resourceTable.getCompleteObjectRef(resourceRef);
208 int resourceIndex = ClusterTraits.completeReferenceGetResourceIndex(completeRef);
210 ClusterI.CompleteTypeEnum completeType = ClusterTraits.completeReferenceGetType(completeRef);
211 if (completeType == ClusterI.CompleteTypeEnum.NotComplete)
212 throw new DatabaseException("Resource has multiple complete objects. Resource key=" + resourceKey + ".");
214 if (ClusterTraits.completeReferenceIsLocal(completeRef)) {
215 clusterIndex = clusterKey;
217 int foreignIndex = ClusterTraits.completeReferenceGetForeignIndex(completeRef);
218 // System.err.println("completeRef=" + completeRef + " foreignIndex=" + foreignIndex );
219 ClusterUID clusterUID = foreignTable.getResourceUID(foreignIndex).asCID();
220 ClusterI c = support.getClusterByClusterUIDOrMake(clusterUID);
221 clusterIndex = c.getClusterKey();
223 int key = ClusterTraits.createResourceKey(clusterIndex, resourceIndex);
225 System.out.println("Cluster.complete object rk=" + resourceKey + " ck=" + key);
230 public boolean isComplete(int resourceKey, ClusterSupport support)
231 throws DatabaseException {
232 final int resourceRef = getLocalReference(resourceKey);
233 int completeRef = resourceTable.getCompleteObjectRef(resourceRef);
234 ClusterI.CompleteTypeEnum completeType = ClusterTraits.completeReferenceGetType(completeRef);
235 boolean complete = completeType != ClusterI.CompleteTypeEnum.NotComplete;
237 System.out.println("Cluster.key=" + resourceKey + " isComplete=" + complete);
241 public int getSingleObject(int resourceKey, int predicateKey, int objectIndex, ClusterSupport support) throws DatabaseException {
243 System.out.println("Cluster.getSingleObject: rk=" + resourceKey + " pk=" + predicateKey);
244 if (0 == objectIndex) {
245 final int resourceIndex = getLocalReference(resourceKey);
246 final int pRef = getInternalReferenceOrZero(predicateKey, support);
247 final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
248 return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);
250 return objectTable.getSingleObject(objectIndex, support, this);
253 public void forObjects(int resourceKey, int predicateKey, int objectIndex, QueryProcessor processor, ReadGraphImpl graph, AsyncMultiProcedure<Resource> procedure,
254 ClusterSupport support) throws DatabaseException {
256 System.out.println("Cluster.forObjects1: rk=" + resourceKey + " pk=" + predicateKey);
257 if (0 == objectIndex) {
258 final int resourceIndex = getLocalReference(resourceKey);
259 final int pRef = getInternalReferenceOrZero(predicateKey, support);
260 final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
261 resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
264 objectTable.foreachObject(graph, objectIndex, procedure, this);
266 public <C> void forObjects(int resourceKey, int predicateKey, int objectIndex, QueryProcessor processor, ReadGraphImpl graph, C context, AsyncContextMultiProcedure<C, Resource> procedure,
267 ClusterSupport support) throws DatabaseException {
269 System.out.println("Cluster.forObjects1: rk=" + resourceKey + " pk=" + predicateKey);
270 if (0 == objectIndex) {
271 final int resourceIndex = getLocalReference(resourceKey);
272 final int pRef = getInternalReferenceOrZero(predicateKey, support);
273 final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
274 resourceTable.foreachObject(resourceIndex, graph, context, procedure, support, pRef, pCompleteType, completeTable, this);
277 objectTable.foreachObject(graph, objectIndex, context, procedure, this);
280 public <Context> boolean forObjects(int resourceKey, int predicateKey, int objectIndex, ObjectProcedure<Context> procedure,
281 Context context, ClusterSupport support) throws DatabaseException {
283 System.out.println("Cluster.forObjects2: rk=" + resourceKey + " pk=" + predicateKey);
284 if (0 == objectIndex) {
285 final int resourceIndex = getLocalReference(resourceKey);
286 final int pRef = getInternalReferenceOrZero(predicateKey, support);
287 final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
288 return resourceTable.foreachObject(resourceIndex, procedure, context, support, this, pRef, pCompleteType, completeTable);
290 return objectTable.foreachObject(objectIndex, procedure, context, support, this);
294 public int getSingleObject(int resourceKey, int predicateKey, ClusterSupport support) throws DatabaseException {
296 System.out.println("Cluster.getSingleObject2: rk=" + resourceKey + " pk=" + predicateKey);
297 final int resourceIndex = getLocalReference(resourceKey);
298 final int pRef = getInternalReferenceOrZero(predicateKey, support);
299 final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
300 if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType)
301 return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);
302 final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);
303 if (0 == predicateIndex)
304 return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);
305 int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);
306 return getSingleObject(resourceKey, predicateKey, objectIndex, support);
310 public <T> int getSingleObject(int resourceKey, ForPossibleRelatedValueProcedure<T> procedure, ClusterSupport support) throws DatabaseException {
311 final int predicateKey = procedure.predicateKey;
313 System.out.println("Cluster.getSingleObject2: rk=" + resourceKey + " pk=" + predicateKey);
314 final int resourceIndex = getLocalReference(resourceKey);
315 final int pRef = getInternalReferenceOrZero(predicateKey, support);
316 final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
317 if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType)
318 return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);
319 final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);
320 if (0 == predicateIndex)
321 return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);
322 int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);
323 return getSingleObject(resourceKey, predicateKey, objectIndex, support);
327 public <C, T> int getSingleObject(int resourceKey, ForPossibleRelatedValueContextProcedure<C, T> procedure, ClusterSupport support) throws DatabaseException {
328 final int predicateKey = procedure.predicateKey;
330 System.out.println("Cluster.getSingleObject2: rk=" + resourceKey + " pk=" + predicateKey);
331 final int resourceIndex = getLocalReference(resourceKey);
332 final int pRef = getInternalReferenceOrZero(predicateKey, support);
333 final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
334 if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType)
335 return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);
336 final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);
337 if (0 == predicateIndex)
338 return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);
339 int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);
340 return getSingleObject(resourceKey, predicateKey, objectIndex, support);
344 public void forObjects(ReadGraphImpl graph, int resourceKey,
345 int predicateKey, AsyncMultiProcedure<Resource> procedure)
346 throws DatabaseException {
348 SessionImplSocket session = (SessionImplSocket)graph.getSession();
349 ClusterSupport support = session.clusterTranslator;
352 System.out.println("Cluster.forObjects3: rk=" + resourceKey + " pk=" + predicateKey);
353 final int resourceIndex = getLocalReference(resourceKey);
354 final int pRef = getInternalReferenceOrZero(predicateKey, support);
355 final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
356 if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {
357 resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
360 final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);
361 if (0 == predicateIndex) {
362 resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
365 int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);
366 forObjects(resourceKey, predicateKey, objectIndex, graph.processor, graph, procedure, support);
371 public void forObjects(ReadGraphImpl graph, int resourceKey, ForEachObjectProcedure procedure) throws DatabaseException {
372 SessionImplSocket session = (SessionImplSocket)graph.getSession();
373 ClusterSupport support = session.clusterTranslator;
374 final int predicateKey = procedure.predicateKey;
376 System.out.println("Cluster.forObjects3: rk=" + resourceKey + " pk=" + predicateKey);
377 final int resourceIndex = getLocalReference(resourceKey);
378 final int pRef = getInternalReferenceOrZero(predicateKey, support);
379 final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
380 if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {
381 resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
384 final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);
385 if (0 == predicateIndex) {
386 resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
389 int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);
390 forObjects(resourceKey, predicateKey, objectIndex, graph.processor, graph, procedure, support);
394 public <C> void forObjects(ReadGraphImpl graph, int resourceKey, C context,
395 ForEachObjectContextProcedure<C> procedure) throws DatabaseException {
397 SessionImplSocket session = (SessionImplSocket)graph.getSession();
398 ClusterSupport support = session.clusterTranslator;
400 final int predicateKey = procedure.predicateKey;
403 System.out.println("Cluster.forObjects3: rk=" + resourceKey + " pk=" + predicateKey);
404 final int resourceIndex = getLocalReference(resourceKey);
405 final int pRef = getInternalReferenceOrZero(predicateKey, support);
406 final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
407 if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {
408 resourceTable.foreachObject(resourceIndex, graph, context, procedure, support, pRef, pCompleteType, completeTable, this);
411 final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);
412 if (0 == predicateIndex) {
413 resourceTable.foreachObject(resourceIndex, graph, context, procedure, support, pRef, pCompleteType, completeTable, this);
416 int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);
417 forObjects(resourceKey, predicateKey, objectIndex, graph.processor, graph, context, procedure, support);
422 public <Context> boolean forObjects(int resourceKey, int predicateKey,
423 ObjectProcedure<Context> procedure, Context context, ClusterSupport support)
424 throws DatabaseException {
426 System.out.println("Cluster.forObjects4: rk=" + resourceKey + " pk=" + predicateKey);
427 final int resourceIndex = getLocalReference(resourceKey);
428 final int pRef = getInternalReferenceOrZero(predicateKey, support);
429 final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
430 if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType)
431 return resourceTable.foreachObject(resourceIndex, procedure, context, support, this, pRef, pCompleteType, completeTable);
432 final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);
433 if (0 == predicateIndex)
434 return resourceTable.foreachObject(resourceIndex, procedure, context, support, this, pRef, pCompleteType, completeTable);
435 int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);
436 return forObjects(resourceKey, predicateKey, objectIndex, procedure, context, support);
439 public <Context> boolean forPredicates(int resourceKey,
440 PredicateProcedure<Context> procedure, Context context, ClusterSupport support)
441 throws DatabaseException {
443 System.out.println("Cluster.forPredicates: rk=" + resourceKey);
444 final int resourceIndex = getLocalReference(resourceKey);
445 final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);
446 if (0 == predicateIndex)
447 return resourceTable.foreachPredicate(resourceIndex,
448 procedure, context, support, this, completeTable);
450 boolean broken = resourceTable.foreachPredicate(resourceIndex,
451 procedure, context, support, this, completeTable);
455 return predicateTable.foreachPredicate(predicateIndex, procedure, context, support, this);
458 public ClusterI addRelation(int sResourceKey, int pResourceKey, int oResourceKey, ClusterSupport support)
459 throws DatabaseException {
461 System.out.println("add rk=" + sResourceKey + " pk=" + pResourceKey + " ok=" + oResourceKey);
462 int sri = getLocalReferenceAnd(sResourceKey, support, ClusterChange.ADD_OPERATION);
463 int pri = getReferenceOrCreateIfForeign(pResourceKey, support, ClusterStream.NULL_OPERATION);
464 int ori = getReferenceOrCreateIfForeign(oResourceKey, support, ClusterStream.NULL_OPERATION);
465 ClusterI.CompleteTypeEnum completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(pResourceKey);
466 boolean ret = addRelationInternal(sri, pri, ori, completeType);
469 support.addStatement(this);
472 support.cancelStatement(this);
477 public boolean removeRelation(int sResourceKey, int pResourceKey, int oResourceKey, ClusterSupport support)
478 throws DatabaseException {
480 int sri = getLocalReferenceAnd(sResourceKey, support, ClusterChange.REMOVE_OPERATION);
481 int pri = getInternalReferenceOrZeroAnd(pResourceKey, support, ClusterStream.NULL_OPERATION);
482 int ori = getInternalReferenceOrZeroAnd(oResourceKey, support, ClusterStream.NULL_OPERATION);
484 if (0 != pri && 0 != ori) {
485 ClusterI.CompleteTypeEnum completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(pResourceKey);
486 ret = removeRelationInternal(sri, pri, ori, completeType, support);
489 support.removeStatement(this);
491 support.cancelStatement(this);
496 public void denyRelation(int sResourceKey, int pResourceKey, int oResourceKey, ClusterSupport support)
497 throws DatabaseException {
498 int sri = checkResourceKeyIsOursAndGetResourceIndexIf(sResourceKey, support);
499 ResourceIndexAndId p = checkResourceKeyAndGetResourceIndexIf(pResourceKey, support);
500 ResourceIndexAndId o = checkResourceKeyAndGetResourceIndexIf(oResourceKey, support);
501 if (0 == sri || 0 == p.index || 0 == o.index)
504 ClusterI.CompleteTypeEnum completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(pResourceKey);
505 boolean ret = removeRelationInternal(sri, p.reference, o.reference, completeType, support);
507 support.addStatementIndex(this, sResourceKey, getClusterUID(), ClusterChange.REMOVE_OPERATION);
508 support.addStatementIndex(this, pResourceKey, p.clusterUID, ClusterStream.NULL_OPERATION);
509 support.addStatementIndex(this, oResourceKey, o.clusterUID, ClusterStream.NULL_OPERATION);
510 support.removeStatement(this);
516 public InputStream getValueStream(int rResourceId, ClusterSupport support) throws DatabaseException {
518 System.out.println("ClusterBig.getValue " + rResourceId);
519 int resourceIndex = getLocalReference(rResourceId);
521 byte[] buffer = resourceTable.getValue(valueTable, resourceIndex);
522 if(buffer == null) return null;
523 return new ByteArrayInputStream(buffer);
524 } catch (ExternalValueException e) {
525 return support.getValueStreamEx(resourceIndex, clusterId);
529 public byte[] getValue(int rResourceId, ClusterSupport support)
530 throws DatabaseException {
532 System.out.println("ClusterBig.getValue " + rResourceId);
533 int resourceIndex = getLocalReference(rResourceId);
535 return resourceTable.getValue(valueTable, resourceIndex);
536 } catch (ExternalValueException e) {
537 return support.getValueEx(resourceIndex, clusterId);
541 public boolean hasValue(int rResourceId, ClusterSupport support)
542 throws DatabaseException {
543 int resourceIndex = getLocalReference(rResourceId);
544 return resourceTable.hasValue(resourceIndex);
547 public boolean removeValue(int rResourceId, ClusterSupport support)
548 throws DatabaseException {
549 int resourceIndex = getLocalReferenceAnd(rResourceId, support, ClusterChange.DELETE_OPERATION);
550 support.removeValue(this);
551 return resourceTable.removeValue(valueTable, resourceIndex);
555 public ClusterI setValue(int rResourceId, byte[] value, int length, ClusterSupport support)
556 throws DatabaseException {
557 int resourceIndex = getLocalReferenceAnd(rResourceId, support, ClusterStream.SET_OPERATION);
558 support.setValue(this, getClusterId(), value, length);
559 resourceTable.setValue(valueTable, resourceIndex, value, length);
563 public ClusterI modiValueEx(int rResourceId, long voffset, int length, byte[] value, int offset, ClusterSupport support)
564 throws DatabaseException {
565 int resourceIndex = getLocalReferenceAnd(rResourceId, support, ClusterStream.MODI_OPERATION);
566 support.modiValue(this, getClusterId(), voffset, length, value, offset);
567 resourceTable.setValueEx(valueTable, resourceIndex);
571 public byte[] readValueEx(int rResourceId, long voffset, int length, ClusterSupport support)
572 throws DatabaseException {
573 int resourceIndex = getLocalReference(rResourceId);
574 boolean isExternal = resourceTable.isValueEx(valueTable, resourceIndex);
576 throw new DatabaseException("ClusterI.readValue supported only for external value. Resource key=" + rResourceId);
577 return support.getValueEx(resourceIndex, getClusterId(), voffset, length);
580 public long getValueSizeEx(int resourceKey, ClusterSupport support)
581 throws DatabaseException, ExternalValueException {
582 int resourceIndex = getLocalReference(resourceKey);
583 boolean isExternal = resourceTable.isValueEx(valueTable, resourceIndex);
585 throw new ExternalValueException("ClusterI.getSize supported only for external value. Resource key=" + resourceKey);
586 return support.getValueSizeEx(resourceIndex, getClusterId());
588 public boolean isValueEx(int resourceKey)
589 throws DatabaseException {
590 int resourceIndex = getLocalReference(resourceKey);
591 return resourceTable.isValueEx(valueTable, resourceIndex);
594 public void setValueEx(int resourceKey)
595 throws DatabaseException {
596 int resourceIndex = getLocalReference(resourceKey);
597 resourceTable.setValueEx(valueTable, resourceIndex);
600 public int createResource(ClusterSupport support)
601 throws DatabaseException {
602 short resourceIndex = resourceTable.createResource();
604 if(DebugPolicy.REPORT_RESOURCE_ID_ALLOCATION)
605 System.out.println("[RID_ALLOCATION]: ClusterBig[" + clusterId + "] allocates " + resourceIndex);
607 support.createResource(this, resourceIndex, clusterId);
608 return ClusterTraits.createResourceKey(clusterKey, resourceIndex);
611 public boolean hasResource(int resourceKey, ClusterSupport support) {
612 int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(resourceKey);
613 if (this.clusterKey != clusterKey) // foreign resource
617 resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);
618 } catch (DatabaseException e) {
621 if (resourceIndex > 0 & resourceIndex <= resourceTable.getTableCount())
627 public int getNumberOfResources(ClusterSupport support) {
628 return resourceTable.getUsedSize();
631 public long getUsedSpace() {
632 long rt = resourceTable.getTableCapacity() * 8 + 8; // (8 = cluster id)
633 long ft = foreignTable.getTableCapacity() * 8;
634 long pt = predicateTable.getTableCapacity() * 4;
635 long ot = objectTable.getTableCapacity() * 4;
636 long ct = completeTable.getTableCapacity() * 4;
637 long vt = valueTable.getTableCapacity() * 1;
638 long cm = clusterMap.getUsedSpace();
640 return rt + ft + pt + ot + ct + vt + cm;
641 // System.out.println("resource table " + rt);
642 // System.out.println("foreign table (non flat cluster table) " + ft);
643 // System.out.println("predicate table " + pt);
644 // long pt2 = getRealSizeOfPredicateTable() * 4;
645 // System.out.println("predicate table real size " + pt2);
646 // System.out.println("object table " + ot);
647 // long ot2 = getRealSizeOfObjectTable() * 4;
648 // System.out.println("object table real size " + ot2);
649 // System.out.println("value table " + vt);
651 int getRealSizeOfPredicateTable() throws DatabaseException {
652 SizeOfPredicateTable proc = new SizeOfPredicateTable(resourceTable, predicateTable);
653 resourceTable.foreachResource(proc, 0, null, null);
654 return proc.getSize();
656 int getRealSizeOfObjectTable() throws DatabaseException {
657 SizeOfObjectTable proc = new SizeOfObjectTable(resourceTable, predicateTable, objectTable);
658 resourceTable.foreachResource(proc, 0, null, null);
659 return proc.getSize();
662 public boolean isEmpty() {
663 return resourceTable.getTableCount() == 0;
666 public void printDebugInfo(String message, ClusterSupport support)
667 throws DatabaseException {
668 predicateTable.printDebugInfo();
669 objectTable.printDebugInfo();
670 ClusterPrintDebugInfo proc = new ClusterPrintDebugInfo(this
671 , resourceTable, predicateTable, support, objectTable);
672 resourceTable.foreachResource(proc, 0, null, null);
674 private int getInternalReferenceOrZero(int resourceKey, ClusterSupport support)
675 throws DatabaseException {
676 int clusterKey = ClusterTraits.getClusterKeyFromResourceKey(resourceKey);
677 int resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);
678 if (this.clusterKey != clusterKey) { // foreign resource
679 ClusterI foreignCluster = support.getClusterByClusterKey(clusterKey);
680 ClusterUID clusterUID = foreignCluster.getClusterUID();
681 int foreignResourceIndex = clusterMap.getForeignReferenceOrZero(resourceIndex, clusterUID);
682 return foreignResourceIndex;
684 return resourceIndex;
686 private int getInternalReferenceOrZeroAnd(int resourceKey, ClusterSupport support, byte op)
687 throws DatabaseException {
688 int clusterKey = ClusterTraits.getClusterKeyFromResourceKey(resourceKey);
689 int resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);
690 if (this.clusterKey != clusterKey) { // foreign resource
691 ClusterI foreignCluster = support.getClusterByClusterKey(clusterKey);
692 ClusterUID clusterUID = foreignCluster.getClusterUID();
693 int foreignResourceIndex = clusterMap.getForeignReferenceOrZero(resourceIndex, clusterUID);
694 support.addStatementIndex(this, resourceKey, clusterUID, op);
695 return foreignResourceIndex;
697 support.addStatementIndex(this, resourceKey, getClusterUID(), op);
698 return resourceIndex;
700 private short getLocalReference(int resourceKey) throws DatabaseException {
701 return ClusterTraitsBase.getResourceIndexFromResourceKeyNoThrow(resourceKey);
703 private int getLocalReferenceAnd(int resourceKey, ClusterSupport support, byte op)
704 throws DatabaseException {
705 int resourceIndex = getLocalReference(resourceKey);
706 support.addStatementIndex(this, resourceKey, getClusterUID(), op);
707 return resourceIndex;
709 private int checkResourceKeyIsOursAndGetResourceIndexIf(int resourceKey, ClusterSupport support)
710 throws DatabaseException {
711 int clusterShortId = ClusterTraits.getClusterKeyFromResourceKey(resourceKey);
712 if (this.clusterKey != clusterShortId)
714 int resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);
715 return resourceIndex;
717 private int getReferenceOrCreateIfForeign(int resourceKey, ClusterSupport support, byte op)
718 throws DatabaseException {
719 int clusterKey = ClusterTraits.getClusterKeyFromResourceKey(resourceKey);
720 int resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);
721 if (this.clusterKey != clusterKey) {
722 ClusterI foreignCluster = support.getClusterByClusterKey(clusterKey);
723 ClusterUID clusterUID = foreignCluster.getClusterUID();
724 support.addStatementIndex(this, resourceKey, clusterUID, op);
725 return clusterMap.getForeignReferenceOrCreateByResourceKey(resourceKey, clusterUID);
727 support.addStatementIndex(this, resourceKey, getClusterUID(), op);
728 return resourceIndex;
730 private class ResourceIndexAndId {
731 ResourceIndexAndId(int reference, int index, ClusterUID clusterUID) {
732 this.reference = reference;
734 this.clusterUID = clusterUID;
736 public final int reference;
737 public final int index;
738 public final ClusterUID clusterUID;
740 private ResourceIndexAndId checkResourceKeyAndGetResourceIndexIf(int resourceKey, ClusterSupport support)
741 throws DatabaseException {
742 int clusterKey = ClusterTraits.getClusterKeyFromResourceKey(resourceKey);
743 int resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);
744 if (this.clusterKey != clusterKey) { // foreign resource
745 ClusterI foreignCluster = support.getClusterByClusterKey(clusterKey);
746 ClusterUID clusterUID = foreignCluster.getClusterUID();
747 int ref = clusterMap.getForeignReferenceOrCreateByResourceIndex(resourceIndex, clusterUID);
748 return new ResourceIndexAndId(ref, resourceIndex, clusterUID);
750 return new ResourceIndexAndId(resourceIndex, resourceIndex, getClusterUID());
754 final public int execute(int resourceIndex) throws DatabaseException {
756 if(resourceIndex > 0) {
757 key = clusterBits | resourceIndex;
759 ClusterUID clusterUID = clusterMap.getResourceUID(resourceIndex).asCID();
760 ClusterI cluster = clusterSupport.getClusterByClusterUIDOrMake(clusterUID);
761 int foreingResourceIndex = clusterMap.getForeignResourceIndex(resourceIndex);
762 key = ClusterTraits.createResourceKey(cluster.getClusterKey(), foreingResourceIndex);
765 System.out.println("Cluster.execute key=" + key);
769 private boolean addRelationInternal(int sReference, int pReference, int oReference, ClusterI.CompleteTypeEnum completeType)
770 throws DatabaseException {
771 int predicateIndex = resourceTable.addStatement(sReference, pReference,
772 oReference, predicateTable, objectTable, completeType, completeTable);
773 if (0 == predicateIndex)
774 return true; // added to resourceTable
775 else if (0 > predicateIndex)
776 return false; // old complete statemenent
777 int newPredicateIndex = predicateTable.addPredicate(predicateIndex,
778 pReference, oReference, objectTable);
779 if (0 == newPredicateIndex)
781 if (predicateIndex != newPredicateIndex)
782 resourceTable.setPredicateIndex(sReference, newPredicateIndex);
785 private boolean removeRelationInternal(int sResourceIndex, int pResourceIndex,
786 int oResourceIndex, ClusterI.CompleteTypeEnum completeType, ClusterSupport support)
787 throws DatabaseException {
788 int predicateIndex = resourceTable.getPredicateIndex(sResourceIndex);
789 if (0 == predicateIndex || ClusterI.CompleteTypeEnum.NotComplete != completeType)
790 return resourceTable.removeStatementFromCache(sResourceIndex,
791 pResourceIndex, oResourceIndex, completeType, completeTable);
792 PredicateTable.Status ret = predicateTable.removePredicate(predicateIndex, pResourceIndex, oResourceIndex, objectTable);
796 case PredicateRemoved: {
797 if (0 == predicateTable.getPredicateSetSize(predicateIndex))
798 resourceTable.setPredicateIndex(sResourceIndex, 0);
799 // intentionally dropping to next case
803 resourceTable.removeStatement(sResourceIndex,
804 pResourceIndex, oResourceIndex,
805 completeType, completeTable,
806 predicateTable, objectTable, this, support);
811 throw new Error("Not supported.");
815 public void load(Consumer<DatabaseException> r) {
816 throw new Error("Not supported.");
819 public int makeResourceKey(int resourceIndex) throws DatabaseException {
821 // if (ClusterTraitsBase.isIllegalResourceIndex(resourceIndex))
822 // throw new DatabaseException("Illegal resource key " + resourceIndex);
823 if (resourceIndex > 0) // local resource
824 key = ClusterTraits.createResourceKey(clusterKey, resourceIndex);
826 ClusterUID clusterUID = clusterMap.getResourceUID(resourceIndex).asCID();
827 ClusterI cluster = clusterSupport.getClusterByClusterUIDOrMake(clusterUID);
828 int foreingResourceIndex = clusterMap.getForeignResourceIndex(resourceIndex);
829 key = ClusterTraits.createResourceKey(cluster.getClusterKey(), foreingResourceIndex);
832 throw new DatabaseException("Failed to make resource key from " + resourceIndex);
836 public ClusterBig toBig(ClusterSupport support) throws DatabaseException {
837 throw new Error("Not implemented");
840 public void load(ClusterSupport session, Runnable callback) {
841 throw new Error("Not implemented");
844 public ClusterI getClusterByResourceKey(int resourceKey,
845 ClusterSupport support) {
846 throw new Error("Not implemented");
849 public void increaseReferenceCount(int amount) {
850 throw new Error("Not implemented");
854 public void decreaseReferenceCount(int amount) {
855 throw new Error("Not implemented");
858 public int getReferenceCount() {
859 throw new Error("Not implemented");
862 public void releaseMemory() {
865 public void compact() {
866 clusterMap.compact();
868 public boolean contains(int resourceKey) {
869 return ClusterTraitsBase.isCluster(clusterBits, resourceKey);
872 public ClusterTypeEnum getType() {
873 return ClusterTypeEnum.BIG;
876 public boolean getImmutable() {
877 int status = resourceTable.getClusterStatus();
878 return (status & ClusterStatus.ImmutableMaskSet) == ClusterStatus.ImmutableMaskSet;
881 public void setImmutable(boolean immutable, ClusterSupport support) {
882 int status = resourceTable.getClusterStatus();
884 status |= ClusterStatus.ImmutableMaskSet;
886 status &= ClusterStatus.ImmutableMaskClear;
887 resourceTable.setClusterStatus(status);
888 support.setImmutable(this, immutable);
891 public boolean getDeleted() {
892 int status = resourceTable.getClusterStatus();
893 return (status & ClusterStatus.DeletedMaskSet) == ClusterStatus.DeletedMaskSet;
896 public void setDeleted(boolean deleted, ClusterSupport support) {
897 int status = resourceTable.getClusterStatus();
899 status |= ClusterStatus.DeletedMaskSet;
901 status &= ClusterStatus.DeletedMaskClear;
902 resourceTable.setClusterStatus(status);
903 support.setDeleted(this, deleted);
906 public Table<?> getPredicateTable() {
907 return predicateTable;
910 public Table<?> getForeignTable() {
914 public Table<?> getCompleteTable() {
915 return completeTable;
918 public Table<?> getValueTable() {
922 public Table<?> getObjectTable() {
927 class SizeOfPredicateTable implements ClusterI.ObjectProcedure<Integer> {
928 private final ResourceTable mrResourceTable;
929 private final PredicateTable mrPredicateTable;
930 private int size = 0;
931 SizeOfPredicateTable(ResourceTable resourceTable
932 , PredicateTable predicateTable) {
933 mrResourceTable = resourceTable;
934 mrPredicateTable = predicateTable;
937 public boolean execute(Integer i, int resourceRef) {
938 int predicateIndex = mrResourceTable.getPredicateIndex(resourceRef);
939 if (0 == predicateIndex)
940 return false; // continue loop
941 size += mrPredicateTable.getPredicateSetSize(predicateIndex);
942 return false; // continue loop
945 public int getSize() {
950 class SizeOfObjectTable implements ClusterI.ObjectProcedure<Integer> {
951 private final ResourceTable mrResourceTable;
952 private final PredicateTable mrPredicateTable;
953 private final ObjectTable mrObjectTable;
954 private int size = 0;
955 SizeOfObjectTable(ResourceTable resourceTable
956 , PredicateTable predicateTable, ObjectTable objectTable) {
957 mrResourceTable = resourceTable;
958 mrPredicateTable = predicateTable;
959 mrObjectTable = objectTable;
963 public boolean execute(Integer i, int resourceRef) {
964 int predicateIndex = mrResourceTable.getPredicateIndex(resourceRef);
965 if (0 == predicateIndex)
966 return false; // continue loop
967 ClusterI.PredicateProcedure<Object> procedure = new PredicateProcedure<Object>() {
969 public boolean execute(Object context, int pRef, int oIndex) {
970 if (ClusterTraits.statementIndexIsDirect(oIndex))
971 return false; // no table space reserved, continue looping
974 objectIndex = ClusterTraits.statementIndexGet(oIndex);
975 size += mrObjectTable.getObjectSetSize(objectIndex);
976 } catch (DatabaseException e) {
979 return false; // continue looping
983 mrPredicateTable.foreachPredicate(predicateIndex, procedure, null, null, null);
984 } catch (DatabaseException e) {
987 return false; // continue loop
990 public int getSize() {