X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.datatypes%2Fsrc%2Forg%2Fsimantics%2Fdatatypes%2Futils%2FLogUtils.java;h=dbe62fc80b38fe284b130a29a345f3ee1f47a910;hb=HEAD;hp=3950518c191e685775a99f532d281c364446c9cb;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.datatypes/src/org/simantics/datatypes/utils/LogUtils.java b/bundles/org.simantics.datatypes/src/org/simantics/datatypes/utils/LogUtils.java index 3950518c1..dbe62fc80 100644 --- a/bundles/org.simantics.datatypes/src/org/simantics/datatypes/utils/LogUtils.java +++ b/bundles/org.simantics.datatypes/src/org/simantics/datatypes/utils/LogUtils.java @@ -1,495 +1,495 @@ -package org.simantics.datatypes.utils; - -import gnu.trove.map.hash.TObjectIntHashMap; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.util.Collection; -import java.util.HashMap; -import java.util.IdentityHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.simantics.databoard.Bindings; -import org.simantics.databoard.accessor.reference.ChildReference; -import org.simantics.databoard.binding.Binding; -import org.simantics.databoard.binding.error.BindingException; -import org.simantics.databoard.binding.error.RuntimeBindingConstructionException; -import org.simantics.databoard.binding.impl.BindingPrintContext; -import org.simantics.databoard.serialization.RuntimeSerializerConstructionException; -import org.simantics.databoard.serialization.Serializer; -import org.simantics.databoard.util.IdentityPair; -import org.simantics.datatypes.DatatypeResource; -import org.simantics.db.ReadGraph; -import org.simantics.db.Resource; -import org.simantics.db.WriteGraph; -import org.simantics.db.common.primitiverequest.RelatedValue; -import org.simantics.db.common.procedure.adapter.TransientCacheListener; -import org.simantics.db.common.utils.Logger; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.service.Bytes; -import org.simantics.db.service.SerialisationSupport; -import org.simantics.layer0.Layer0; -import org.simantics.utils.datastructures.Pair; - -interface LogContentManager { - - LogContentBean getContentBean(ReadGraph graph, Resource node) throws DatabaseException; - void setContentBean(WriteGraph graph, Resource node, LogContentBean bean) throws DatabaseException; - -} - -class LogContentBinding extends Binding { - - private final SerialisationSupport ss; - - public LogContentBinding(SerialisationSupport ss) { - this.ss = ss; - } - - private final Serializer serializer = new Serializer() { - - @Override - public void serialize(DataOutput out, TObjectIntHashMap identities, Object obj) throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public void serialize(DataOutput out, Object obj) throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public Object deserialize(DataInput in, List identities) - throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public Object deserialize(DataInput in) throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public void deserializeTo(DataInput in, List identities, - Object dst) throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public void deserializeTo(DataInput in, Object dst) throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public void skip(DataInput in, List identities) - throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public void skip(DataInput in) throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public Integer getConstantSize() { - throw new UnsupportedOperationException(); - } - - @Override - public int getSize(Object obj, TObjectIntHashMap identities) - throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public int getSize(Object obj) throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public int getMinSize() { - throw new UnsupportedOperationException(); - } - - public byte[] serialize(Object obj) throws IOException { - LogContentBean bean = (LogContentBean)obj; - int bytes = 1 + 4 + 4 + 8 * bean.stamps.length + 8 * bean.resources.length; - byte[] result = new byte[bytes]; - Bytes.write(result, 0, bean.leaf ? (byte)1 : (byte)0); - int byteIndex = 1; - Bytes.writeLE(result, byteIndex, bean.n); - byteIndex += 4; - Bytes.writeLE(result, byteIndex, bean.stamps.length); - byteIndex += 4; - for(long l : bean.stamps) { - Bytes.writeLE(result, byteIndex, l); - byteIndex += 8; - } - for(PossibleResource pr : bean.resources) { - Bytes.writeLE(result, byteIndex, pr.longValue()); - byteIndex += 8; - } - return result; - } - - public Object deserialize(byte[] data) throws IOException { - - LogContentBean result = new LogContentBean(); - - try { - - result.leaf = Bytes.read(data, 0) == 1 ? true : false; - int byteIndex = 1; - result.n = Bytes.readLE4(data, byteIndex); - byteIndex += 4; - int t = Bytes.readLE4(data, byteIndex); - byteIndex += 4; - - result.stamps = new long[t]; - result.resources = new PossibleResource[t]; - - for(int i=0;i T accept(Visitor v) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isInstance(Object obj) { - throw new UnsupportedOperationException(); - } - - @Override - public void readFrom(Binding srcBinding, Object src, Object dst) - throws BindingException { - throw new UnsupportedOperationException(); - } - - @Override - public void assertInstaceIsValid(Object obj, Set validInstances) - throws BindingException { - throw new UnsupportedOperationException(); - } - - @Override - public int deepHashValue(Object value, - IdentityHashMap hashedObjects) - throws BindingException { - throw new UnsupportedOperationException(); - } - - @Override - public int deepCompare(Object o1, Object o2, - Set> compareHistory) - throws BindingException { - throw new UnsupportedOperationException(); - } - - @Override - protected void toString(Object value, BindingPrintContext ctx) - throws BindingException { - throw new UnsupportedOperationException(); - } - - @Override - public int getComponentCount() { - throw new UnsupportedOperationException(); - } - - @Override - public Binding getComponentBinding(int index) { - throw new UnsupportedOperationException(); - } - - @Override - public Binding getComponentBinding(ChildReference path) { - throw new UnsupportedOperationException(); - } - - @Override - public Serializer serializer() throws RuntimeSerializerConstructionException { - return serializer; - } - -} - -final public class LogUtils implements LogContentManager { - - final public static boolean DEBUG = false; - - final public Binding CONTENT_BEAN_BINDING; - final public DatatypeResource DATA; - - public LogUtils(ReadGraph graph) throws DatabaseException { - try { - CONTENT_BEAN_BINDING = new LogContentBinding(graph.getService(SerialisationSupport.class)); - DATA = DatatypeResource.getInstance(graph); - } catch (RuntimeBindingConstructionException e) { - Logger.defaultLogError(e); - throw new DatabaseException(e); - } - } - - public Resource create(WriteGraph graph, int t, int stamp) throws DatabaseException { - Layer0 L0 = Layer0.getInstance(graph); - Resource tree = graph.newResource(); - graph.claim(tree, L0.InstanceOf, null, DATA.Log); - Resource index = createIndexNode(graph, this, stamp, t); - graph.claim(tree, DATA.Log_root, DATA.Log_root_Inverse, index); - graph.claimLiteral(tree, DATA.Log_t, t, Bindings.INTEGER); - Resource leaf = createLeafNode(graph, this, stamp, t); - graph.claim(index, DATA.BTreeNode_Content, null, leaf); - LogContentBean rContent = getContentBean(graph, index); - rContent.n = 1; - rContent.stamps[0] = stamp; - rContent.resources[0].r = leaf; - setContentBean(graph, index, rContent); - return tree; - } - - public void insert(WriteGraph graph, Resource T, int stamp, Resource v) throws DatabaseException { - - Resource r = getRoot(graph, T); - int t = getDegree(graph, T); - insertImpl(graph, this, T, r, t, stamp, v); - - } - - static class BatchContentManager implements LogContentManager { - - final private LogUtils bu; - - final Map beans = new HashMap(); - - public BatchContentManager(LogUtils bu) { - this.bu = bu; - } - - @Override - public LogContentBean getContentBean(ReadGraph graph, Resource node) throws DatabaseException { - LogContentBean bean = beans.get(node); - if(bean != null) return bean; - return bu.getContentBean(graph, node); - } - - @Override - public void setContentBean(WriteGraph graph, Resource node, LogContentBean bean) throws DatabaseException { - beans.put(node, bean); - } - - public void apply(WriteGraph graph) throws DatabaseException { - for(Map.Entry entry : beans.entrySet()) { - bu.setContentBean(graph, entry.getKey(), entry.getValue()); - } - } - - } - - public void insertAll(WriteGraph graph, Resource T, Collection> values) throws DatabaseException { - - Resource r = getRoot(graph, T); - int t = getDegree(graph, T); - BatchContentManager cm = new BatchContentManager(this); - for(Pair entry : values) { - insertImpl(graph, cm, T, r, t, entry.first, entry.second); - } - cm.apply(graph); - - } - - // Implementation - private void insertImpl(WriteGraph graph, LogContentManager manager, Resource T, Resource r, int t, int k, Resource v) throws DatabaseException { - - int code = insertImpl2(graph, manager, 0, T, r, t, k, v); - - if(code > 0) { - - LogContentBean rContent = manager.getContentBean(graph, r); - - if(DEBUG) System.err.println("[insert index code=" + code + "]"); - - Resource newRoot = createIndexNode(graph, manager, k, t); - graph.claim(newRoot, DATA.Log_Node_Contains, null, r); - setRoot(graph, T, newRoot); - - LogContentBean nContent = manager.getContentBean(graph, newRoot); - nContent.stamps[0] = rContent.stamps[0]; - nContent.resources[0].r = r; - nContent.n = 1; - manager.setContentBean(graph, newRoot, nContent); - - Resource leaf = createLeaf(graph, manager, newRoot, code, k, t); - - LogContentBean lContent = manager.getContentBean(graph, leaf); - lContent.n = 1; - lContent.stamps[0] = k; - lContent.resources[0].r = v; - - if(DEBUG) System.err.println("[insert " + k + "]: started a new branch"); - - manager.setContentBean(graph, leaf, lContent); - - } - - } - - private int insertImpl2(WriteGraph graph, LogContentManager manager, int level, Resource T, Resource r, int t, int k, Resource v) throws DatabaseException { - - LogContentBean rContent = manager.getContentBean(graph, r); - - // Index - if(!rContent.leaf) { - - Resource child = rContent.resources[rContent.n-1].r; - int code = insertImpl2(graph, manager, level+1, T, child, t, k, v); - - if(code == 0) { - - // Value was inserted successfully - return 0; - - } else { - - // The child was full - if(rContent.n < t) { - - // We can create a new child - Resource leaf = createLeaf(graph, manager, r, code-level-1, k, t); - LogContentBean lContent = manager.getContentBean(graph, leaf); - lContent.stamps[0] = k; - lContent.resources[0].r = v; - lContent.n = 1; - manager.setContentBean(graph, leaf, lContent); - - if(DEBUG) System.err.println("[insert " + k + "]: created a fresh leaf"); - - return 0; - - } else { - - // We are full, let the parent handle this - return code; - - } - - - } - - } - - // Leaf - else { - - if(rContent.n < t) { - - if(DEBUG) System.err.println("[insert " + k + "]: fit into leaf at level " + level); - - // Append - rContent.stamps[rContent.n] = k; - rContent.resources[rContent.n].r = v; - rContent.n++; - manager.setContentBean(graph, r, rContent); - return 0; - - } else { - - // This leaf is full - return level; - - } - - } - - } - - private Resource createLeaf(WriteGraph graph, LogContentManager manager, Resource r, int code, int stamp, int t) throws DatabaseException { - LogContentBean rContent = manager.getContentBean(graph, r); - if(code == 0) { - if(DEBUG) System.err.println("[insert leaf code=" + code + "]"); - Resource result = createLeafNode(graph, manager, stamp, t); - graph.claim(r, DATA.Log_Node_Contains, null, result); - rContent.stamps[rContent.n] = stamp; - rContent.resources[rContent.n].r = result; - rContent.n++; - manager.setContentBean(graph, r, rContent); - return result; - } else { - if(DEBUG) System.err.println("[insert index code=" + code + "]"); - Resource index = createIndexNode(graph, manager, stamp, t); - graph.claim(r, DATA.Log_Node_Contains, null, index); - rContent.stamps[rContent.n] = stamp; - rContent.resources[rContent.n].r = index; - rContent.n++; - manager.setContentBean(graph, r, rContent); - return createLeaf(graph, manager, index, code-1, stamp, t); - } - } - - private Resource createIndexNode(WriteGraph graph, LogContentManager manager, int stamp, int t) throws DatabaseException { - Layer0 L0 = Layer0.getInstance(graph); - Resource result = graph.newResource(); - graph.claim(result, L0.InstanceOf, null, DATA.Log_IndexNode); - manager.setContentBean(graph, result, LogContentBean.create(t, stamp, false)); - return result; - } - - private Resource createLeafNode(WriteGraph graph, LogContentManager manager, int stamp, int t) throws DatabaseException { - Layer0 L0 = Layer0.getInstance(graph); - Resource result = graph.newResource(); - graph.claim(result, L0.InstanceOf, null, DATA.Log_LeafNode); - manager.setContentBean(graph, result, LogContentBean.create(t, stamp, true)); - return result; - } - - private Resource getRoot(ReadGraph graph, Resource T) throws DatabaseException { - return graph.getPossibleObject(T, DATA.Log_root); - } - - private void setRoot(WriteGraph graph, Resource T, Resource r) throws DatabaseException { - graph.deny(T, DATA.Log_root); - graph.claim(T, DATA.Log_root, r); - } - - public void setContentBean(WriteGraph graph, Resource node, LogContentBean bean) throws DatabaseException { - graph.claimLiteral(node, DATA.Log_Node_content, DATA.Log_Content, bean, CONTENT_BEAN_BINDING ); - } - - private int getDegree(ReadGraph graph, Resource tree) throws DatabaseException { - return graph.syncRequest(new RelatedValue(tree, DATA.Log_t, Bindings.INTEGER), TransientCacheListener.instance()); - } - - public LogContentBean getContentBean(ReadGraph graph, Resource node) throws DatabaseException { - return graph.syncRequest(new RelatedValue(node, DATA.Log_Node_content, CONTENT_BEAN_BINDING), TransientCacheListener.instance()); - } - -} +package org.simantics.datatypes.utils; + +import gnu.trove.map.hash.TObjectIntHashMap; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.Collection; +import java.util.HashMap; +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.simantics.databoard.Bindings; +import org.simantics.databoard.accessor.reference.ChildReference; +import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.binding.error.BindingException; +import org.simantics.databoard.binding.error.RuntimeBindingConstructionException; +import org.simantics.databoard.binding.impl.BindingPrintContext; +import org.simantics.databoard.serialization.RuntimeSerializerConstructionException; +import org.simantics.databoard.serialization.Serializer; +import org.simantics.databoard.util.IdentityPair; +import org.simantics.datatypes.DatatypeResource; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.primitiverequest.RelatedValue; +import org.simantics.db.common.procedure.adapter.TransientCacheListener; +import org.simantics.db.common.utils.Logger; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.service.Bytes; +import org.simantics.db.service.SerialisationSupport; +import org.simantics.layer0.Layer0; +import org.simantics.utils.datastructures.Pair; + +interface LogContentManager { + + LogContentBean getContentBean(ReadGraph graph, Resource node) throws DatabaseException; + void setContentBean(WriteGraph graph, Resource node, LogContentBean bean) throws DatabaseException; + +} + +class LogContentBinding extends Binding { + + private final SerialisationSupport ss; + + public LogContentBinding(SerialisationSupport ss) { + this.ss = ss; + } + + private final Serializer serializer = new Serializer() { + + @Override + public void serialize(DataOutput out, TObjectIntHashMap identities, Object obj) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void serialize(DataOutput out, Object obj) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public Object deserialize(DataInput in, List identities) + throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public Object deserialize(DataInput in) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void deserializeTo(DataInput in, List identities, + Object dst) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void deserializeTo(DataInput in, Object dst) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void skip(DataInput in, List identities) + throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void skip(DataInput in) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public Integer getConstantSize() { + throw new UnsupportedOperationException(); + } + + @Override + public int getSize(Object obj, TObjectIntHashMap identities) + throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public int getSize(Object obj) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public int getMinSize() { + throw new UnsupportedOperationException(); + } + + public byte[] serialize(Object obj) throws IOException { + LogContentBean bean = (LogContentBean)obj; + int bytes = 1 + 4 + 4 + 8 * bean.stamps.length + 8 * bean.resources.length; + byte[] result = new byte[bytes]; + Bytes.write(result, 0, bean.leaf ? (byte)1 : (byte)0); + int byteIndex = 1; + Bytes.writeLE(result, byteIndex, bean.n); + byteIndex += 4; + Bytes.writeLE(result, byteIndex, bean.stamps.length); + byteIndex += 4; + for(long l : bean.stamps) { + Bytes.writeLE(result, byteIndex, l); + byteIndex += 8; + } + for(PossibleResource pr : bean.resources) { + Bytes.writeLE(result, byteIndex, pr.longValue()); + byteIndex += 8; + } + return result; + } + + public Object deserialize(byte[] data) throws IOException { + + LogContentBean result = new LogContentBean(); + + try { + + result.leaf = Bytes.read(data, 0) == 1 ? true : false; + int byteIndex = 1; + result.n = Bytes.readLE4(data, byteIndex); + byteIndex += 4; + int t = Bytes.readLE4(data, byteIndex); + byteIndex += 4; + + result.stamps = new long[t]; + result.resources = new PossibleResource[t]; + + for(int i=0;i T accept(Visitor v) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isInstance(Object obj) { + throw new UnsupportedOperationException(); + } + + @Override + public void readFrom(Binding srcBinding, Object src, Object dst) + throws BindingException { + throw new UnsupportedOperationException(); + } + + @Override + public void assertInstaceIsValid(Object obj, Set validInstances) + throws BindingException { + throw new UnsupportedOperationException(); + } + + @Override + public int deepHashValue(Object value, + IdentityHashMap hashedObjects) + throws BindingException { + throw new UnsupportedOperationException(); + } + + @Override + public int deepCompare(Object o1, Object o2, + Set> compareHistory) + throws BindingException { + throw new UnsupportedOperationException(); + } + + @Override + protected void toString(Object value, BindingPrintContext ctx) + throws BindingException { + throw new UnsupportedOperationException(); + } + + @Override + public int getComponentCount() { + throw new UnsupportedOperationException(); + } + + @Override + public Binding getComponentBinding(int index) { + throw new UnsupportedOperationException(); + } + + @Override + public Binding getComponentBinding(ChildReference path) { + throw new UnsupportedOperationException(); + } + + @Override + public Serializer serializer() throws RuntimeSerializerConstructionException { + return serializer; + } + +} + +final public class LogUtils implements LogContentManager { + + final public static boolean DEBUG = false; + + final public Binding CONTENT_BEAN_BINDING; + final public DatatypeResource DATA; + + public LogUtils(ReadGraph graph) throws DatabaseException { + try { + CONTENT_BEAN_BINDING = new LogContentBinding(graph.getService(SerialisationSupport.class)); + DATA = DatatypeResource.getInstance(graph); + } catch (RuntimeBindingConstructionException e) { + Logger.defaultLogError(e); + throw new DatabaseException(e); + } + } + + public Resource create(WriteGraph graph, int t, int stamp) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + Resource tree = graph.newResource(); + graph.claim(tree, L0.InstanceOf, null, DATA.Log); + Resource index = createIndexNode(graph, this, stamp, t); + graph.claim(tree, DATA.Log_root, DATA.Log_root_Inverse, index); + graph.claimLiteral(tree, DATA.Log_t, t, Bindings.INTEGER); + Resource leaf = createLeafNode(graph, this, stamp, t); + graph.claim(index, DATA.BTreeNode_Content, null, leaf); + LogContentBean rContent = getContentBean(graph, index); + rContent.n = 1; + rContent.stamps[0] = stamp; + rContent.resources[0].r = leaf; + setContentBean(graph, index, rContent); + return tree; + } + + public void insert(WriteGraph graph, Resource T, int stamp, Resource v) throws DatabaseException { + + Resource r = getRoot(graph, T); + int t = getDegree(graph, T); + insertImpl(graph, this, T, r, t, stamp, v); + + } + + static class BatchContentManager implements LogContentManager { + + final private LogUtils bu; + + final Map beans = new HashMap(); + + public BatchContentManager(LogUtils bu) { + this.bu = bu; + } + + @Override + public LogContentBean getContentBean(ReadGraph graph, Resource node) throws DatabaseException { + LogContentBean bean = beans.get(node); + if(bean != null) return bean; + return bu.getContentBean(graph, node); + } + + @Override + public void setContentBean(WriteGraph graph, Resource node, LogContentBean bean) throws DatabaseException { + beans.put(node, bean); + } + + public void apply(WriteGraph graph) throws DatabaseException { + for(Map.Entry entry : beans.entrySet()) { + bu.setContentBean(graph, entry.getKey(), entry.getValue()); + } + } + + } + + public void insertAll(WriteGraph graph, Resource T, Collection> values) throws DatabaseException { + + Resource r = getRoot(graph, T); + int t = getDegree(graph, T); + BatchContentManager cm = new BatchContentManager(this); + for(Pair entry : values) { + insertImpl(graph, cm, T, r, t, entry.first, entry.second); + } + cm.apply(graph); + + } + + // Implementation + private void insertImpl(WriteGraph graph, LogContentManager manager, Resource T, Resource r, int t, int k, Resource v) throws DatabaseException { + + int code = insertImpl2(graph, manager, 0, T, r, t, k, v); + + if(code > 0) { + + LogContentBean rContent = manager.getContentBean(graph, r); + + if(DEBUG) System.err.println("[insert index code=" + code + "]"); + + Resource newRoot = createIndexNode(graph, manager, k, t); + graph.claim(newRoot, DATA.Log_Node_Contains, null, r); + setRoot(graph, T, newRoot); + + LogContentBean nContent = manager.getContentBean(graph, newRoot); + nContent.stamps[0] = rContent.stamps[0]; + nContent.resources[0].r = r; + nContent.n = 1; + manager.setContentBean(graph, newRoot, nContent); + + Resource leaf = createLeaf(graph, manager, newRoot, code, k, t); + + LogContentBean lContent = manager.getContentBean(graph, leaf); + lContent.n = 1; + lContent.stamps[0] = k; + lContent.resources[0].r = v; + + if(DEBUG) System.err.println("[insert " + k + "]: started a new branch"); + + manager.setContentBean(graph, leaf, lContent); + + } + + } + + private int insertImpl2(WriteGraph graph, LogContentManager manager, int level, Resource T, Resource r, int t, int k, Resource v) throws DatabaseException { + + LogContentBean rContent = manager.getContentBean(graph, r); + + // Index + if(!rContent.leaf) { + + Resource child = rContent.resources[rContent.n-1].r; + int code = insertImpl2(graph, manager, level+1, T, child, t, k, v); + + if(code == 0) { + + // Value was inserted successfully + return 0; + + } else { + + // The child was full + if(rContent.n < t) { + + // We can create a new child + Resource leaf = createLeaf(graph, manager, r, code-level-1, k, t); + LogContentBean lContent = manager.getContentBean(graph, leaf); + lContent.stamps[0] = k; + lContent.resources[0].r = v; + lContent.n = 1; + manager.setContentBean(graph, leaf, lContent); + + if(DEBUG) System.err.println("[insert " + k + "]: created a fresh leaf"); + + return 0; + + } else { + + // We are full, let the parent handle this + return code; + + } + + + } + + } + + // Leaf + else { + + if(rContent.n < t) { + + if(DEBUG) System.err.println("[insert " + k + "]: fit into leaf at level " + level); + + // Append + rContent.stamps[rContent.n] = k; + rContent.resources[rContent.n].r = v; + rContent.n++; + manager.setContentBean(graph, r, rContent); + return 0; + + } else { + + // This leaf is full + return level; + + } + + } + + } + + private Resource createLeaf(WriteGraph graph, LogContentManager manager, Resource r, int code, int stamp, int t) throws DatabaseException { + LogContentBean rContent = manager.getContentBean(graph, r); + if(code == 0) { + if(DEBUG) System.err.println("[insert leaf code=" + code + "]"); + Resource result = createLeafNode(graph, manager, stamp, t); + graph.claim(r, DATA.Log_Node_Contains, null, result); + rContent.stamps[rContent.n] = stamp; + rContent.resources[rContent.n].r = result; + rContent.n++; + manager.setContentBean(graph, r, rContent); + return result; + } else { + if(DEBUG) System.err.println("[insert index code=" + code + "]"); + Resource index = createIndexNode(graph, manager, stamp, t); + graph.claim(r, DATA.Log_Node_Contains, null, index); + rContent.stamps[rContent.n] = stamp; + rContent.resources[rContent.n].r = index; + rContent.n++; + manager.setContentBean(graph, r, rContent); + return createLeaf(graph, manager, index, code-1, stamp, t); + } + } + + private Resource createIndexNode(WriteGraph graph, LogContentManager manager, int stamp, int t) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + Resource result = graph.newResource(); + graph.claim(result, L0.InstanceOf, null, DATA.Log_IndexNode); + manager.setContentBean(graph, result, LogContentBean.create(t, stamp, false)); + return result; + } + + private Resource createLeafNode(WriteGraph graph, LogContentManager manager, int stamp, int t) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + Resource result = graph.newResource(); + graph.claim(result, L0.InstanceOf, null, DATA.Log_LeafNode); + manager.setContentBean(graph, result, LogContentBean.create(t, stamp, true)); + return result; + } + + private Resource getRoot(ReadGraph graph, Resource T) throws DatabaseException { + return graph.getPossibleObject(T, DATA.Log_root); + } + + private void setRoot(WriteGraph graph, Resource T, Resource r) throws DatabaseException { + graph.deny(T, DATA.Log_root); + graph.claim(T, DATA.Log_root, r); + } + + public void setContentBean(WriteGraph graph, Resource node, LogContentBean bean) throws DatabaseException { + graph.claimLiteral(node, DATA.Log_Node_content, DATA.Log_Content, bean, CONTENT_BEAN_BINDING ); + } + + private int getDegree(ReadGraph graph, Resource tree) throws DatabaseException { + return graph.syncRequest(new RelatedValue(tree, DATA.Log_t, Bindings.INTEGER), TransientCacheListener.instance()); + } + + public LogContentBean getContentBean(ReadGraph graph, Resource node) throws DatabaseException { + return graph.syncRequest(new RelatedValue(node, DATA.Log_Node_content, CONTENT_BEAN_BINDING), TransientCacheListener.instance()); + } + +}