Changeset 19672
- Timestamp:
- 02/07/12 21:22:20 (4 months ago)
- Location:
- trunk/Jav_Orient
- Files:
-
- 25 added
- 24 edited
-
src/eu/scenari/orient/recordstruct/IStruct.java (modified) (1 diff)
-
src/eu/scenari/orient/recordstruct/IStructList.java (added)
-
src/eu/scenari/orient/recordstruct/IValueList.java (added)
-
src/eu/scenari/orient/recordstruct/IValueSubRecord.java (modified) (1 diff)
-
src/eu/scenari/orient/recordstruct/impl/IStructWriter.java (modified) (2 diffs)
-
src/eu/scenari/orient/recordstruct/impl/StructWriter.java (modified) (3 diffs)
-
src/eu/scenari/orient/recordstruct/impl/StructWriterXml.java (modified) (1 diff)
-
src/eu/scenari/orient/recordstruct/lib/base/StructList.java (modified) (2 diffs)
-
src/eu/scenari/orient/recordstruct/lib/base/StructListAsciiFixed.java (added)
-
src/eu/scenari/orient/recordstruct/lib/base/StructListLong.java (added)
-
src/eu/scenari/orient/recordstruct/lib/base/StructListRID.java (added)
-
src/eu/scenari/orient/recordstruct/lib/base/ValueList.java (modified) (6 diffs)
-
src/eu/scenari/orient/recordstruct/lib/base/ValueListAsciiFixed.java (added)
-
src/eu/scenari/orient/recordstruct/lib/base/ValueListLong.java (added)
-
src/eu/scenari/orient/recordstruct/lib/base/ValueListRID.java (added)
-
src/eu/scenari/orient/recordstruct/lib/base/ValueSet.java (modified) (1 diff)
-
src/eu/scenari/orient/recordstruct/lib/base/ValueSortedSet.java (modified) (1 diff)
-
src/eu/scenari/orient/recordstruct/lib/base/ValueSubRecord.java (modified) (2 diffs)
-
src/eu/scenari/orient/recordstruct/lib/tree (added)
-
src/eu/scenari/orient/recordstruct/lib/tree/ITreeStorageConfig.java (added)
-
src/eu/scenari/orient/recordstruct/lib/tree/StructTree.java (added)
-
src/eu/scenari/orient/recordstruct/lib/tree/StructTreeRake.java (added)
-
src/eu/scenari/orient/recordstruct/lib/tree/StructTreeSlotKV.java (added)
-
src/eu/scenari/orient/recordstruct/lib/tree/TreeStorageConfig.java (added)
-
src/eu/scenari/orient/recordstruct/lib/tree/ValueTree.java (added)
-
src/eu/scenari/orient/recordstruct/lib/tree/ValueTreeNode.java (added)
-
src/eu/scenari/orient/recordstruct/lib/tree/ValueTreeRake.java (added)
-
src/eu/scenari/orient/recordstruct/lib/tree/ValueTreeSlotKV.java (added)
-
src/eu/scenari/orient/recordstruct/struct/ExtendedStructId.java (modified) (1 diff)
-
src/eu/scenari/orient/recordstruct/struct/StructAbstract.java (modified) (5 diffs)
-
src/eu/scenari/orient/recordstruct/types/TypesBase.java (modified) (5 diffs)
-
src/eu/scenari/orient/recordstruct/value/ValueCollectionAbstract.java (modified) (1 diff)
-
src/eu/scenari/orient/recordstruct/value/ValueListImmutableFixed.java (added)
-
src/eu/scenari/orient/tree/impl/BalancedLayout.java (modified) (9 diffs)
-
src/eu/scenari/orient/tree/impl/IBalancingLayout.java (modified) (2 diffs)
-
src/eu/scenari/orient/tree/impl/Tree.java (modified) (13 diffs)
-
src/eu/scenari/orient/tree/impl/TreeNode.java (modified) (6 diffs)
-
src/eu/scenari/orient/tree/impl/TreeRake.java (modified) (11 diffs)
-
src/eu/scenari/orient/tree/impl/TreeSlot.java (modified) (2 diffs)
-
src/eu/scenari/orient/tree/provider/ITreeNodeProvider.java (modified) (6 diffs)
-
src/eu/scenari/orient/tree/provider/ITreeProvider.java (modified) (2 diffs)
-
src/eu/scenari/orient/tree/provider/ITreeRakeProvider.java (modified) (1 diff)
-
src/eu/scenari/orient/tree/provider/ITreeSlotProvider.java (modified) (1 diff)
-
test/eu/scenari/orient/tree (added)
-
test/eu/scenari/orient/tree/FactorySequentialLong.java (added)
-
test/eu/scenari/orient/tree/IKeyFactory.java (added)
-
test/eu/scenari/orient/tree/IValueFactory.java (added)
-
test/eu/scenari/orient/tree/TreeBasicTest.java (added)
-
test/eu/scenari/orient/tree/perf (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Jav_Orient/src/eu/scenari/orient/recordstruct/IStruct.java
r17752 r19672 103 103 104 104 /** 105 * If {@link #getPredefinedLentgh()} is fixed (positive value), return the full serialized length 106 * including struct identifier overhead. 107 */ 108 public int getFullSerializedLentgh(); 109 110 /** 105 111 * Generic method for instanciate struct's value. 106 112 * -
trunk/Jav_Orient/src/eu/scenari/orient/recordstruct/IValueSubRecord.java
r17961 r19672 39 39 package eu.scenari.orient.recordstruct; 40 40 41 42 41 public interface IValueSubRecord extends IValueOwner { 43 42 44 43 /** 44 * Méthode appelée par le subRecord. 45 45 * Informe le IValueSubRecord que son subRecord est dirty. 46 46 */ 47 47 public void onSubRecordDirty(); 48 48 49 /** 50 * Méthode appelée par le subRecord pour informer que l'id 51 * du subRecord a changé (à la création du record). 52 */ 53 public void onSubrecordRidChanged(IRecordStruct<IValue<?>> pRecord); 54 55 /** 56 * Mathéode appelé par le record détenant ce IValueSubRecord pour 57 * forcer l'enregistrement des subRecords. 58 */ 49 59 public void saveSubRecord(); 50 51 public void onSubrecordRidChanged(IRecordStruct<IValue<?>> pRecord);52 60 } -
trunk/Jav_Orient/src/eu/scenari/orient/recordstruct/impl/IStructWriter.java
r18481 r19672 41 41 import eu.scenari.orient.recordstruct.IStruct; 42 42 import eu.scenari.orient.recordstruct.IValue; 43 import eu.scenari.orient.recordstruct.IValueLazyLoading;44 43 45 44 public interface IStructWriter { … … 68 67 * Push already serialized value. 69 68 */ 70 public void addAsValue(IValue LazyLoading<?> pValue, final byte[] pBuffer, final int pOffset, final int pLength);69 public void addAsValue(IValue<?> pValue, final byte[] pBuffer, final int pOffset, final int pLength); 71 70 72 71 /** -
trunk/Jav_Orient/src/eu/scenari/orient/recordstruct/impl/StructWriter.java
r19091 r19672 48 48 import eu.scenari.orient.recordstruct.IStruct; 49 49 import eu.scenari.orient.recordstruct.IValue; 50 import eu.scenari.orient.recordstruct.IValueLazyLoading;51 50 import eu.scenari.orient.recordstruct.lib.primitive.ValueNull; 52 51 import eu.scenari.orient.recordstruct.struct.ExtendedStructId; … … 109 108 ExtendedStructId extendedStructId = pStruct.getExtendedStructId(); 110 109 if (extendedStructId != null) { 111 int len = extendedStructId.get Length();110 int len = extendedStructId.getExtendedIdLength(); 112 111 assureSpaceFor(len); 113 112 for (int i = 0; i < len; i++) { … … 163 162 * Push already serialized value. 164 163 */ 165 public void addAsValue(IValue LazyLoading<?> pValue, final byte[] pBuffer, final int pOffset, final int pLength) {164 public void addAsValue(IValue<?> pValue, final byte[] pBuffer, final int pOffset, final int pLength) { 166 165 startValue(pValue.getStruct(), pLength); 167 166 write(pBuffer, pOffset, pLength); -
trunk/Jav_Orient/src/eu/scenari/orient/recordstruct/impl/StructWriterXml.java
r18986 r19672 172 172 } 173 173 174 public void addAsValue(IValue LazyLoading<?> pValue, byte[] pBuffer, int pOffset, int pLength) {174 public void addAsValue(IValue<?> pValue, byte[] pBuffer, int pOffset, int pLength) { 175 175 try { 176 176 fValueStarted = false; 177 pValue.unmarshall();177 if (pValue instanceof IValueLazyLoading) ((IValueLazyLoading) pValue).unmarshall(); 178 178 pValue.writeValue(this); 179 179 } catch (Exception e) { -
trunk/Jav_Orient/src/eu/scenari/orient/recordstruct/lib/base/StructList.java
r17887 r19672 42 42 43 43 import eu.scenari.orient.recordstruct.IStruct; 44 import eu.scenari.orient.recordstruct.IStructList; 45 import eu.scenari.orient.recordstruct.IValue.CopyObjective; 44 46 import eu.scenari.orient.recordstruct.IValueOwner; 45 import eu.scenari.orient.recordstruct.IValue.CopyObjective;46 47 import eu.scenari.orient.recordstruct.impl.StructReader; 47 48 import eu.scenari.orient.recordstruct.struct.ConversionException; 48 49 import eu.scenari.orient.recordstruct.struct.StructAbstract; 49 50 50 public class StructList extends StructAbstract<ValueList> {51 public class StructList extends StructAbstract<ValueList> implements IStructList<ValueList> { 51 52 52 53 public StructList(int pCoreStructId) { … … 61 62 } 62 63 64 public ValueList newValue(int pDefaultCapacity, IValueOwner pOwner) { 65 return new ValueList(pDefaultCapacity, pOwner); 66 } 67 63 68 public ValueList readValue(StructReader pReader, int pLen, IValueOwner pOwner) { 64 69 return new ValueList(pReader, pReader.getPosition(), pLen, pOwner); -
trunk/Jav_Orient/src/eu/scenari/orient/recordstruct/lib/base/ValueList.java
r19336 r19672 50 50 import eu.scenari.orient.recordstruct.IStruct; 51 51 import eu.scenari.orient.recordstruct.IValue; 52 import eu.scenari.orient.recordstruct.IValueList; 52 53 import eu.scenari.orient.recordstruct.IValueOwner; 53 54 import eu.scenari.orient.recordstruct.IValueVisitor; … … 59 60 import eu.scenari.orient.recordstruct.value.ValueCollectionAbstract; 60 61 61 public class ValueList<E extends IValue<?>> extends ValueCollectionAbstract<List<E>, E> implements List<E> {62 public class ValueList<E extends IValue<?>> extends ValueCollectionAbstract<List<E>, E> implements IValueList<E> { 62 63 63 64 protected static final boolean[] EMPTY_BOOLARRAY = new boolean[0]; … … 73 74 } 74 75 76 public ValueList(int pCapacity, IValueOwner pOwner) { 77 super(pOwner); 78 createUnderlying(pCapacity); 79 } 80 75 81 public ValueList(List<?> pValue, IValueOwner pOwner) { 76 82 super(pOwner); 77 createUnderlying( );83 createUnderlying(pValue.size() + 10); 78 84 for (Object vItem : pValue) { 79 85 fPojo.add((E) StructProvider.findStruct(vItem).toValue(vItem, this)); … … 96 102 // XXX append or replace ? 97 103 for (E vValue : vFrom.getUnderlying()) { 98 this.add((E) vValue.copy(this, pObjective));104 add((E) vValue.copy(this, pObjective)); 99 105 } 100 106 return (RET) this; … … 246 252 } 247 253 248 public Object[] toArray() {249 return getUnderlying().toArray();250 }251 252 public <T> T[] toArray(T[] pA) {253 return getUnderlying().toArray(pA);254 }255 256 254 @Override 257 255 public void onPersist(PersistStep pStep, IRecordStruct<?> pRecord, boolean pRemovedValue) { … … 323 321 } 324 322 323 protected void createUnderlying(int pCapacity) { 324 fPojo = new ArrayList<E>(pCapacity); 325 } 326 325 327 protected void startRecording() { 326 328 fRemovedItems = null; -
trunk/Jav_Orient/src/eu/scenari/orient/recordstruct/lib/base/ValueSet.java
r19348 r19672 118 118 } 119 119 120 public Object[] toArray() {121 return getUnderlying().toArray();122 }123 124 public <T> T[] toArray(T[] pA) {125 return getUnderlying().toArray(pA);126 }127 128 120 public <RET extends IValue<Set<E>>> RET copyFrom(IValue<?> pFromValue, CopyObjective pObjective) { 129 121 ValueSet<E> vFrom = (ValueSet) pFromValue; -
trunk/Jav_Orient/src/eu/scenari/orient/recordstruct/lib/base/ValueSortedSet.java
r19337 r19672 146 146 } 147 147 148 public Object[] toArray() {149 return getUnderlying().toArray();150 }151 152 public <T> T[] toArray(T[] pA) {153 return getUnderlying().toArray(pA);154 }155 156 148 public <RET extends IValue<SortedSet<E>>> RET copyFrom(IValue<?> pFromValue, CopyObjective pObjective) { 157 149 ValueSortedSet<E> vFrom = (ValueSortedSet) pFromValue; -
trunk/Jav_Orient/src/eu/scenari/orient/recordstruct/lib/base/ValueSubRecord.java
r19333 r19672 103 103 @Override 104 104 public void onPersist(PersistStep pStep, IRecordStruct<?> pRecord, boolean pRemovedValue) { 105 //getStruct().onTrigger(this, pType, pRecord, pRemovedValue);106 105 if (pStep.isAfterSave()) { 107 106 unsetDirty(); … … 115 114 } 116 115 } 117 return;118 116 } 119 117 -
trunk/Jav_Orient/src/eu/scenari/orient/recordstruct/struct/ExtendedStructId.java
r17873 r19672 111 111 } 112 112 113 public int get Length() {113 public int getExtendedIdLength() { 114 114 return fLenght; 115 115 } -
trunk/Jav_Orient/src/eu/scenari/orient/recordstruct/struct/StructAbstract.java
r18113 r19672 66 66 private ExtendedStructId fExtendedStructId; 67 67 68 protected int fPred finedLength;68 protected int fPredefinedLength; 69 69 70 70 /** … … 93 93 94 94 public int getExtendedIdLength() { 95 return fPred finedLength;95 return fPredefinedLength; 96 96 } 97 97 … … 162 162 assert (StructProvider.STRUCT_CORE_INDEX[pCoreStructId] == null); 163 163 StructProvider.STRUCT_CORE_INDEX[pCoreStructId] = this; 164 fPred finedLength = pPredefinedLength;164 fPredefinedLength = pPredefinedLength; 165 165 fExtendedStructId = null; 166 166 fName = getDefaultStructName(pName); … … 168 168 169 169 protected StructAbstract(ExtendedStructId pExtendedId, int pPredefinedLength, String pName) { 170 CoreExtStruct vCoreStruct = lookForCoreStruct(pExtendedId.get Length(), pPredefinedLength);170 CoreExtStruct vCoreStruct = lookForCoreStruct(pExtendedId.getExtendedIdLength(), pPredefinedLength); 171 171 fMainStructId = vCoreStruct.getCoreStructId(); 172 fPred finedLength = pPredefinedLength;172 fPredefinedLength = pPredefinedLength; 173 173 fExtendedStructId = pExtendedId; 174 174 vCoreStruct.registerExtendedStruct(this); … … 189 189 190 190 public int getPredefinedLentgh() { 191 return fPredfinedLength; 191 return fPredefinedLength; 192 } 193 194 public int getFullSerializedLentgh() { 195 if (fPredefinedLength < 0) return fPredefinedLength; 196 int vOverhead = fExtendedStructId != null ? 1 + fExtendedStructId.getExtendedIdLength() : 1; 197 return vOverhead + fPredefinedLength; 192 198 } 193 199 -
trunk/Jav_Orient/src/eu/scenari/orient/recordstruct/types/TypesBase.java
r19581 r19672 42 42 import eu.scenari.orient.recordstruct.lib.base.StructDictionary; 43 43 import eu.scenari.orient.recordstruct.lib.base.StructList; 44 import eu.scenari.orient.recordstruct.lib.base.StructListLong; 45 import eu.scenari.orient.recordstruct.lib.base.StructListRID; 44 46 import eu.scenari.orient.recordstruct.lib.base.StructMap; 45 47 import eu.scenari.orient.recordstruct.lib.base.StructRID; … … 56 58 import eu.scenari.orient.recordstruct.lib.bigable.StructBigableString; 57 59 import eu.scenari.orient.recordstruct.lib.link.ValueLinkTiny; 60 import eu.scenari.orient.recordstruct.lib.tree.StructTreeRake; 61 import eu.scenari.orient.recordstruct.lib.tree.StructTreeSlotKV; 58 62 import eu.scenari.orient.recordstruct.link.IStructLink; 59 63 import eu.scenari.orient.recordstruct.link.StructLink; … … 69 73 public static final StructSubRecord SUBRECORD = new StructSubRecord(129); 70 74 75 public static final StructListRID LIST_RID = new StructListRID(130); 76 71 77 public static final IStructLink<ValueLinkTiny> LINK_TINY = new StructLink(131, ValueLinkTiny.class); 72 78 73 79 public static final IStructLink<ValueLinkTiny> LINK_TINY_LINKEDSLAVE = new StructLink(132, ValueLinkTiny.class).setLinkedIsSlave(true); 80 81 //**** Tree struct... 82 public static final StructTreeRake TREE_RAKE = new StructTreeRake(157); 83 84 public static final StructTreeSlotKV TREE_SLOT_KV = new StructTreeSlotKV(158); 74 85 75 86 //**** Bigable struct... … … 90 101 public static final StructBlob BLOB = new StructBlob(170); 91 102 92 //**** List, set , map ....103 //**** List, set , map, dictionary de IValue.... 93 104 94 105 public static final StructList LIST = new StructList(180); … … 105 116 106 117 public static final StructSortedSet SORTED_SET = new StructSortedSet(186); 118 119 //**** List de pojo .... 120 121 public static final StructListLong LIST_LONG = new StructListLong(195); 122 107 123 } -
trunk/Jav_Orient/src/eu/scenari/orient/recordstruct/value/ValueCollectionAbstract.java
r19333 r19672 115 115 } 116 116 117 public Object[] toArray() { 118 return getUnderlying().toArray(); 119 } 120 121 public <T> T[] toArray(T[] pA) { 122 return getUnderlying().toArray(pA); 123 } 124 117 125 /** 118 126 * -
trunk/Jav_Orient/src/eu/scenari/orient/tree/impl/BalancedLayout.java
r19310 r19672 1 1 package eu.scenari.orient.tree.impl; 2 2 3 import eu.scenari. commons.util.lang.ScException;3 import eu.scenari.orient.tree.provider.ITreeRakeProvider; 4 4 import eu.scenari.orient.tree.provider.ITreeSlotProvider; 5 5 6 6 public class BalancedLayout implements IBalancingLayout { 7 7 8 /** Accept to absorb entries from sibling if current fill rate is less than <code>fFillingThreshold</code>. */ 8 /** 9 * Accept to absorb entries from sibling if current fill rate is less than <code>fFillingThreshold</code>. 10 * If 0.0, entries are never moved between slots or rakes for finding spaces, 11 * but only when new rakes and slots are inserted : useful when keys are mainly incremental values (ID, timestamp, ...). 12 **/ 9 13 protected float fFillingThreshold = 0.5f; 10 14 … … 14 18 /** 15 19 * Target fillRate on the rightNode when a node is splitted. 16 * If Keys are incremental ID or Timestamp, it would better to set 0.1.20 * If keys are incremental values (ID, timestamp, ...), it would better to set 0.1. 17 21 */ 18 22 protected float fTargetFillRateForNewRightNode = 0.5f; 19 23 20 protected int fComputedSizeThresholdToOptimize = -1; 21 24 public BalancedLayout() { 25 super(); 26 } 27 28 public BalancedLayout(float pFillingThreshold, float pOptimizeThreshold, float pTargetFillRateForNewRightNode) { 29 super(); 30 fFillingThreshold = pFillingThreshold; 31 fOptimizeThreshold = pOptimizeThreshold; 32 fTargetFillRateForNewRightNode = pTargetFillRateForNewRightNode; 33 } 34 35 /** 36 * @param pOffset replace position (if>=0) or insert position if negative value. 37 */ 22 38 public <K, V> void addSpaceAndPut(TreeSlot<K, V> pSlot, int pOffset, K pKey, V pValue) { 23 39 Tree<K, V> vTree = pSlot.fTree; … … 25 41 ITreeSlotProvider<K, V> vSlotProvider = vSlot.getProvider(); 26 42 int vCurrentOffset = pOffset; 27 //First step : try to move entries in right slot.28 43 if (fFillingThreshold > 0) { 29 TreeSlot<K, V> vRightSlot = vSlot.findNextSlot(); 44 //First step : try to move entries in right slot. 45 TreeSlot<K, V> vRightSlot = vSlot.findRightSlot(); 30 46 if (vRightSlot != null && vRightSlot.getProvider().getFillRate() < fFillingThreshold) { 31 47 int vMoved = vRightSlot.adoptEntriesFromLeft(vSlot, (vRightSlot.getProvider().getFillRate() + vSlotProvider.getFillRate()) / 2); 32 48 if (vMoved > 0) { 33 //Some entries ha ve beenmoved.49 //Some entries has moved. 34 50 if (vCurrentOffset >= 0) { 35 51 if (vCurrentOffset >= vSlotProvider.getSize()) { … … 39 55 vSlot = vRightSlot; 40 56 } 41 switch (vSlotProvider.replace(vCurrentOffset, pKey, pValue)) { 42 case doneNewlyDirty: 43 vTree.markDirty(vSlotProvider); 44 case done: 45 return; 46 case failedNodeFull: 47 //goto third step. 48 } 57 if (vSlotProvider.replace(vCurrentOffset, pKey, pValue)) return; 49 58 } else { 50 59 if (-vCurrentOffset - 1 > vSlotProvider.getSize()) { 51 60 //Must insert in the other slot. 52 vCurrentOffset = vCurrentOffset -vSlotProvider.getSize();61 vCurrentOffset = vCurrentOffset + vSlotProvider.getSize(); 53 62 vSlotProvider = vRightSlot.getProvider(); 54 63 vSlot = vRightSlot; 55 64 } 56 switch (vSlotProvider.insert(-vCurrentOffset - 1, pKey, pValue)) { 57 case doneNewlyDirty: 58 vTree.markDirty(vSlotProvider); 59 case done: 60 return; 61 case failedNodeFull: 62 //goto third step. 63 } 64 } 65 } 66 } else { 67 //Second step : try to move entries in previous slot. 68 TreeSlot<K, V> vLeftSlot = vSlot.findPreviousSlot(); 65 if (vSlotProvider.insert(-vCurrentOffset - 1, pKey, pValue)) return; 66 } 67 } 68 } 69 //Second step : try to move entries in left slot if current slot has not change. 70 if (vSlot == pSlot) { 71 TreeSlot<K, V> vLeftSlot = vSlot.findLeftSlot(); 69 72 if (vLeftSlot != null && vLeftSlot.getProvider().getFillRate() < fFillingThreshold) { 70 73 ITreeSlotProvider<K, V> vLeftSlotProvider = vLeftSlot.getProvider(); 71 74 int vMoved = vLeftSlot.adoptEntriesFromRight(vSlot, (vLeftSlot.getProvider().getFillRate() + vSlotProvider.getFillRate()) / 2); 72 75 if (vMoved > 0) { 73 //Some entries ha ve beenmoved.76 //Some entries has moved. 74 77 if (vCurrentOffset >= 0) { 75 78 vCurrentOffset -= vMoved; … … 80 83 vSlot = vLeftSlot; 81 84 } 82 switch (vSlotProvider.replace(vCurrentOffset, pKey, pValue)) { 83 case doneNewlyDirty: 84 vTree.markDirty(vSlotProvider); 85 case done: 86 return; 87 case failedNodeFull: 88 //goto third step. 89 } 85 if (vSlotProvider.replace(vCurrentOffset, pKey, pValue)) return; 90 86 } else { 91 87 vCurrentOffset += vMoved; 92 88 if (vCurrentOffset >= -1) { 93 89 //Must insert in the other slot. 94 vCurrentOffset = vCurrentOffset +vLeftSlotProvider.getSize();90 vCurrentOffset = vCurrentOffset - vLeftSlotProvider.getSize(); 95 91 vSlotProvider = vLeftSlotProvider; 96 92 vSlot = vLeftSlot; 97 93 } 98 switch (vSlotProvider.insert(-vCurrentOffset - 1, pKey, pValue)) { 99 case doneNewlyDirty: 100 vTree.markDirty(vSlotProvider); 101 case done: 102 return; 103 case failedNodeFull: 104 //goto third step. 105 } 106 } 107 } 108 } 109 } 110 } 94 if (vSlotProvider.insert(-vCurrentOffset - 1, pKey, pValue)) return; 95 } 96 } 97 } 98 } 99 } 100 111 101 //Third step : need to insert new slot. 112 102 TreeSlot<K, V> vNewSlot; … … 119 109 if (vNewSlot == null) { 120 110 //parent is full, 121 vNewSlot = addSpaceAndInsertNewSlot(vSlot.fParent, vSlot.fOffsetInParent + 1); 122 } 123 } 111 vNewSlot = splitRakeAndInsertNewSlot(vSlot.fParent, vSlot.fOffsetInParent + 1); 112 } 113 } 114 115 //Fourth step : balance slot contents 124 116 vNewSlot.adoptEntriesFromLeft(vSlot, fTargetFillRateForNewRightNode); 117 118 //Fifth step : replace or insert K, V 125 119 if (vCurrentOffset >= 0) { 126 120 if (vCurrentOffset >= vSlotProvider.getSize()) { … … 130 124 vSlot = vNewSlot; 131 125 } 132 switch (vSlotProvider.replace(vCurrentOffset, pKey, pValue)) { 133 case doneNewlyDirty: 134 vTree.markDirty(vSlotProvider); 135 case done: 136 return; 137 case failedNodeFull: 138 //try again 139 vTree.put(pKey, pValue); 140 } 126 if (vSlotProvider.replace(vCurrentOffset, pKey, pValue)) return; 127 //failed, try again, more spaces will be added. 128 vTree.put(pKey, pValue); 141 129 } else { 142 130 if (-vCurrentOffset - 1 > vSlotProvider.getSize()) { 143 131 //Must insert in the other slot. 144 vCurrentOffset = vCurrentOffset -vSlotProvider.getSize();132 vCurrentOffset = vCurrentOffset + vSlotProvider.getSize(); 145 133 vSlotProvider = vNewSlot.getProvider(); 146 134 vSlot = vNewSlot; 147 135 } 148 switch (vSlotProvider.insert(-vCurrentOffset - 1, pKey, pValue)) { 149 case doneNewlyDirty: 150 vTree.markDirty(vSlotProvider); 151 case done: 152 return; 153 case failedNodeFull: 154 //try again 155 vTree.put(pKey, pValue); 156 } 136 if (vSlotProvider.insert(-vCurrentOffset - 1, pKey, pValue)) return; 137 //failed, try again, more spaces will be added. 138 vTree.put(pKey, pValue); 157 139 } 158 140 } … … 165 147 } 166 148 167 public <K, V> void onTreeSizeReduced(Tree<K, V> pTree) {168 tryToOptimizeDepth(pTree);169 }170 171 149 public <K, V> void onNewRoot(TreeNode<K, V> pNode) { 172 fComputedSizeThresholdToOptimize = -1; 150 173 151 } 174 152 … … 205 183 } 206 184 207 protected <K, V> void tryToOptimizeDepth(Tree<K, V> pTree) {208 if (fComputedSizeThresholdToOptimize == -1) {209 int vDepth = getDepthRake(pTree);210 if (vDepth > 0) {211 fComputedSizeThresholdToOptimize = (pTree.fProvider.getDefaultRakeCapacity() ^ vDepth) * pTree.fProvider.getDefaultSlotCapacity();212 fComputedSizeThresholdToOptimize *= fOptimizeThreshold;213 } else {214 fComputedSizeThresholdToOptimize = 0;215 }216 }217 if (fComputedSizeThresholdToOptimize > 0 && pTree.fProvider.getSize() < fComputedSizeThresholdToOptimize) {218 //TODO try to remove one depth...219 System.out.println("TODO try to remove one depth...");220 }221 }222 223 185 protected <K, V> int getDepthRake(Tree<K, V> pTree) { 224 186 return pTree.fRoot.getDepthRake(); 225 187 } 226 188 227 protected <K, V> TreeRake<K, V> addSpaceAndInsertNewRake(TreeRake<K, V> pRake, int pOffset) { 228 //First step : try to move entries in right rake. 229 230 //Second step : try to move entries in left rake. 231 232 //Third step : need to insert new rake or slot. 233 //return null; 234 throw new ScException("TODO addSpaceAndInsertNewRake"); 235 } 236 237 protected <K, V> TreeSlot<K, V> addSpaceAndInsertNewSlot(TreeRake<K, V> pParent, int pOffset) { 238 //First step : try to move entries in right rake. 239 240 //Second step : try to move entries in left rake. 241 242 //Third step : need to insert new rake or slot. 243 //return null; 244 throw new ScException("TODO addSpaceAndInsertNewSlot"); 189 protected <K, V> TreeRake<K, V> splitRakeAndInsertNewRake(TreeRake<K, V> pRakeToSplit, int pInsertPoint) { 190 Tree<K, V> vTree = pRakeToSplit.fTree; 191 TreeRake<K, V> vRake = pRakeToSplit; 192 ITreeRakeProvider<K, V> vRakeProvider = vRake.getProvider(); 193 int vInsertPoint = pInsertPoint; 194 if (fFillingThreshold > 0) { 195 //First step : try to move entries in right cousin rake. 196 TreeNode<K, V> vCousin = vRake.findRightCousin(vInsertPoint); 197 if (vCousin != null && vCousin.isRake() && vCousin.getProvider().getFillRate() < fFillingThreshold) { 198 TreeRake<K, V> vRightRake = (TreeRake) vCousin; 199 int vMoved = vRightRake.adoptEntriesFromLeft(vRake, (vRightRake.getProvider().getFillRate() + vRakeProvider.getFillRate()) / 2); 200 if (vMoved > 0) { 201 //Some entries has moved. 202 if (vInsertPoint > vRakeProvider.getSize()) { 203 //Must insert in the other rake. 204 vInsertPoint = vInsertPoint - vRakeProvider.getSize(); 205 vRakeProvider = vRightRake.getProvider(); 206 vRake = vRightRake; 207 } 208 TreeRake<K, V> vNewRake = vRake.insertNewRake(vInsertPoint); 209 if (vNewRake != null) return vNewRake; 210 } 211 } 212 //Second step : try to move entries in left cousin rake if current rake has not change. 213 if (vRake == pRakeToSplit) { 214 vCousin = vRake.findLeftCousin(vInsertPoint); 215 if (vCousin != null && vCousin.isRake() && vCousin.getProvider().getFillRate() < fFillingThreshold) { 216 TreeRake<K, V> vLeftRake = (TreeRake) vCousin; 217 ITreeRakeProvider<K, V> vLeftProvider = vLeftRake.getProvider(); 218 int vMoved = vLeftRake.adoptEntriesFromRight(vRake, (vLeftProvider.getFillRate() + vRakeProvider.getFillRate()) / 2); 219 if (vMoved > 0) { 220 //Some entries has moved. 221 vInsertPoint -= vMoved; 222 if (vInsertPoint < 0) { 223 //Must insert in the other rake. 224 vInsertPoint = vInsertPoint + vLeftProvider.getSize(); 225 vRakeProvider = vLeftProvider; 226 vRake = vLeftRake; 227 } 228 TreeRake<K, V> vNewRake = vRake.insertNewRake(vInsertPoint); 229 if (vNewRake != null) return vNewRake; 230 } 231 } 232 } 233 } 234 235 //Third step : need to insert new rake in parent context. 236 TreeRake<K, V> vNewRake; 237 if (vRake.fParent == null) { 238 vTree.createRakeAsRoot(vRake); 239 TreeRake<K, V> vParent = (TreeRake) vTree.fRoot; 240 vNewRake = vParent.insertNewRake(1); 241 } else { 242 vNewRake = vRake.fParent.insertNewRake(vRake.fOffsetInParent + 1); 243 if (vNewRake == null) { 244 //parent is full, 245 vNewRake = splitRakeAndInsertNewRake(vRake.fParent, vRake.fOffsetInParent + 1); 246 } 247 } 248 249 //Fourth step : balance rake contents 250 vNewRake.adoptEntriesFromLeft(vRake, fTargetFillRateForNewRightNode); 251 if (vInsertPoint >= vRakeProvider.getSize()) { 252 //Must replace in the other rake. 253 vInsertPoint = vInsertPoint - vRakeProvider.getSize(); 254 vRakeProvider = vNewRake.getProvider(); 255 vRake = vNewRake; 256 } 257 258 //Fifth step : insert new rake 259 return vRake.insertNewRake(vInsertPoint); 260 } 261 262 protected <K, V> TreeSlot<K, V> splitRakeAndInsertNewSlot(TreeRake<K, V> pRakeToSplit, int pInsertPoint) { 263 Tree<K, V> vTree = pRakeToSplit.fTree; 264 TreeRake<K, V> vRake = pRakeToSplit; 265 ITreeRakeProvider<K, V> vRakeProvider = vRake.getProvider(); 266 int vInsertPoint = pInsertPoint; 267 if (fFillingThreshold > 0) { 268 //First step : try to move entries in right cousin rake. 269 TreeNode<K, V> vCousin = vRake.findRightCousin(vInsertPoint); 270 if (vCousin != null && vCousin.isRake() && vCousin.getProvider().getFillRate() < fFillingThreshold) { 271 TreeRake<K, V> vRightRake = (TreeRake) vCousin; 272 int vMoved = vRightRake.adoptEntriesFromLeft(vRake, (vRightRake.getProvider().getFillRate() + vRakeProvider.getFillRate()) / 2); 273 if (vMoved > 0) { 274 //Some entries has moved. 275 if (vInsertPoint > vRakeProvider.getSize()) { 276 //Must insert in the other rake. 277 vInsertPoint = vInsertPoint - vRakeProvider.getSize(); 278 vRakeProvider = vRightRake.getProvider(); 279 vRake = vRightRake; 280 } 281 TreeSlot<K, V> vNewSlot = vRake.insertNewSlot(vInsertPoint); 282 if (vNewSlot != null) return vNewSlot; 283 } 284 } 285 //Second step : try to move entries in left cousin rake if current rake has not change. 286 if (vRake == pRakeToSplit) { 287 vCousin = vRake.findLeftCousin(vInsertPoint); 288 if (vCousin != null && vCousin.isRake() && vCousin.getProvider().getFillRate() < fFillingThreshold) { 289 TreeRake<K, V> vLeftRake = (TreeRake) vCousin; 290 ITreeRakeProvider<K, V> vLeftProvider = vLeftRake.getProvider(); 291 int vMoved = vLeftRake.adoptEntriesFromRight(vRake, (vLeftProvider.getFillRate() + vRakeProvider.getFillRate()) / 2); 292 if (vMoved > 0) { 293 //Some entries has moved. 294 vInsertPoint -= vMoved; 295 if (vInsertPoint < 0) { 296 //Must insert in the other rake. 297 vInsertPoint = vInsertPoint + vLeftProvider.getSize(); 298 vRakeProvider = vLeftProvider; 299 vRake = vLeftRake; 300 } 301 TreeSlot<K, V> vNewSlot = vRake.insertNewSlot(vInsertPoint); 302 if (vNewSlot != null) return vNewSlot; 303 } 304 } 305 } 306 } 307 308 //Third step : need to insert new rake in parent context. 309 TreeRake<K, V> vNewRake; 310 if (vRake.fParent == null) { 311 vTree.createRakeAsRoot(vRake); 312 TreeRake<K, V> vParent = (TreeRake) vTree.fRoot; 313 vNewRake = vParent.insertNewRake(1); 314 } else { 315 vNewRake = vRake.fParent.insertNewRake(vRake.fOffsetInParent + 1); 316 if (vNewRake == null) { 317 //parent is full, 318 vNewRake = splitRakeAndInsertNewRake(vRake.fParent, vRake.fOffsetInParent + 1); 319 } 320 } 321 322 //Fourth step : balance rake contents 323 vNewRake.adoptEntriesFromLeft(vRake, fTargetFillRateForNewRightNode); 324 if (vInsertPoint >= vRakeProvider.getSize()) { 325 //Must replace in the other rake. 326 vInsertPoint = vInsertPoint - vRakeProvider.getSize(); 327 vRakeProvider = vNewRake.getProvider(); 328 vRake = vNewRake; 329 } 330 331 //Fifth step : insert new slot 332 return vRake.insertNewSlot(vInsertPoint); 245 333 } 246 334 } -
trunk/Jav_Orient/src/eu/scenari/orient/tree/impl/IBalancingLayout.java
r19310 r19672 2 2 3 3 public interface IBalancingLayout { 4 5 public final IBalancingLayout DEFAULT_BALANCED_RANDOM_INSERT = new BalancedLayout(); 6 7 public final IBalancingLayout DEFAULT_BALANCED_INCREMENTAL_INSERT = new BalancedLayout(0.0f, 0.2f, 0.1f); 4 8 5 9 /** Call on a put if the target slot is full. */ … … 9 13 public <K, V> void onRemovedEntry(TreeNode<K, V> pNode); 10 14 11 /** Call when the tree size is reduced. */12 public <K, V> void onTreeSizeReduced(Tree<K, V> pTree);13 14 15 /** Call when the root is changed. */ 15 16 public <K, V> void onNewRoot(TreeNode<K, V> pNode); -
trunk/Jav_Orient/src/eu/scenari/orient/tree/impl/Tree.java
r19310 r19672 41 41 import java.util.AbstractMap; 42 42 import java.util.AbstractSet; 43 import java.util.ArrayList;44 43 import java.util.Comparator; 45 44 import java.util.ConcurrentModificationException; 46 45 import java.util.Iterator; 47 import java.util.List;48 46 import java.util.Map; 49 47 import java.util.NoSuchElementException; … … 54 52 import eu.scenari.orient.tree.provider.ITreeRakeProvider; 55 53 import eu.scenari.orient.tree.provider.ITreeSlotProvider; 56 import eu.scenari.orient.tree.provider.ITreeNodeProvider.UpdateResult;57 54 58 55 public class Tree<K, V> extends AbstractMap<K, V> { … … 71 68 72 69 protected EntrySet fEntrySet; 73 74 protected List<ITreeNodeProvider<K, V>> fDirtyNodes = new ArrayList();75 70 76 71 protected transient int fModCount; … … 92 87 protected TreeSlot<K, V> fSlot; 93 88 94 protected int fOffset ;89 protected int fOffset = -1; 95 90 96 91 protected int fExpectedModCount; … … 103 98 public boolean hasNext() { 104 99 if (fSlot == null) return false; 105 if (fOffset < fSlot.getSize() - 1) return true; 106 fSlot = fSlot.findNextSlot(); 100 if (++fOffset < fSlot.getSize()) return true; 107 101 fOffset = 0; 108 return fSlot != null; 102 do { 103 fSlot = fSlot.findRightSlot(); 104 if (fSlot == null) return false; 105 if (fSlot.getSize() > 0) return true; 106 } while (true); 109 107 } 110 108 … … 212 210 213 211 public int size() { 214 return fProvider.getSize(); 212 int vSize = fProvider.getSize(); 213 if (vSize >= 0) return vSize; 214 //Size unknown, we compute size. 215 vSize = 0; 216 for (TreeSlot<K, V> vSlot = findFirstSlot(); vSlot != null; vSlot = vSlot.findRightSlot()) { 217 vSize += vSlot.getSize(); 218 } 219 //We keep it in memory 220 fProvider.setSize(vSize); 221 return vSize; 215 222 } 216 223 … … 233 240 int vCurrentOffset = vSlot.indexOf(pKey); 234 241 V vOldValue = vCurrentOffset >= 0 ? vSlotProvider.getValue(vCurrentOffset) : null; 235 UpdateResultvResult;242 boolean vResult; 236 243 if (vCurrentOffset >= 0) { 237 244 vResult = vSlotProvider.replace(vCurrentOffset, pKey, pValue); … … 239 246 vResult = vSlotProvider.insert(-vCurrentOffset - 1, pKey, pValue); 240 247 } 241 switch (vResult) { 242 case doneNewlyDirty: 243 markDirty(vSlotProvider); 244 case done: 245 if (vCurrentOffset < 0) { 246 //It was an insertion 247 fProvider.setSize(fProvider.getSize() + 1); 248 } 249 break; 250 case failedNodeFull: 248 if (!vResult) { 251 249 // We need spaces 252 250 fBalancingLayout.addSpaceAndPut(vSlot, vCurrentOffset, pKey, pValue); 251 } 252 if (vCurrentOffset < 0) { 253 //It was an insertion 254 fProvider.setSizeByDelta(1); 253 255 } 254 256 return vOldValue; … … 262 264 V vOldValue = vSlotProvider.getValue(vOffset); 263 265 vSlot.removeEntry(vOffset); 264 fProvider.setSize(fProvider.getSize() - 1); 265 fBalancingLayout.onTreeSizeReduced(this); 266 fProvider.setSizeByDelta(-1); 266 267 return vOldValue; 267 268 } … … 273 274 protected TreeSlot<K, V> findSlot(Object pKey) { 274 275 return fRoot.findSlot(pKey); 275 }276 277 protected void markDirty(ITreeNodeProvider<K, V> pNode) {278 fDirtyNodes.add(pNode);279 }280 281 protected void deleteFromDirtyNodes(ITreeNodeProvider<K, V> pNode) {282 for (int i = 0; i < fDirtyNodes.size(); i++) {283 if (fDirtyNodes.get(0) == pNode) {284 fDirtyNodes.remove(i);285 }286 }287 276 } 288 277 … … 291 280 if (vRoot == null) { 292 281 vRoot = fProvider.createSlotAsRoot(); 293 if (vRoot.isDirty()) markDirty(vRoot);294 282 } 295 283 setRootNode(vRoot); … … 298 286 protected void createSlotAsRoot() { 299 287 ITreeNodeProvider<K, V> vRoot = fProvider.createSlotAsRoot(); 300 if (vRoot.isDirty()) markDirty(vRoot);301 288 setRootNode(vRoot); 302 289 } … … 304 291 protected void createRakeAsRoot(TreeNode<K, V> pChild) { 305 292 ITreeRakeProvider<K, V> vRoot = fProvider.createRakeAsRoot(pChild.getProvider()); 306 if (vRoot.isDirty()) markDirty(vRoot); 307 setRootNode(vRoot); 293 fRoot = new TreeRake<K, V>(this, vRoot, pChild); 308 294 pChild.setParent((TreeRake) fRoot, 0); 309 295 } -
trunk/Jav_Orient/src/eu/scenari/orient/tree/impl/TreeNode.java
r19310 r19672 2 2 3 3 import eu.scenari.orient.tree.provider.ITreeNodeProvider; 4 import eu.scenari.orient.tree.provider.ITreeNodeProvider.UpdateResult;5 4 6 5 public abstract class TreeNode<K, V> { … … 61 60 62 61 public void deleteNode() { 63 // remove from dirty list64 if (fProvider.isDirty()) {65 fTree.deleteFromDirtyNodes(fProvider);66 }67 62 // remove form parent 68 63 if (fParent != null) { … … 77 72 public int adoptEntriesFromLeft(TreeNode<K, V> pLeftNode, float pTargetFillRate) { 78 73 ITreeNodeProvider<K, V> vLeftNodeProvider = pLeftNode.getProvider(); 79 boolean vNodeWasDirty = fProvider.isDirty();80 boolean vLeftNodeWasDirty = vLeftNodeProvider.isDirty();81 74 int vMoved = fProvider.adoptEntriesFromLeft(vLeftNodeProvider, pTargetFillRate); 82 75 if (vMoved > 0) { 83 76 //Some entries have been moved. 84 if (!vNodeWasDirty) fTree.markDirty(fProvider);85 if (!vLeftNodeWasDirty) fTree.markDirty(vLeftNodeProvider);86 77 if (fParent != null) fParent.updateKey(fOffsetInParent, getProvider().getKey(0)); 87 78 } … … 91 82 public int adoptEntriesFromRight(TreeNode<K, V> pRightNode, float pTargetFillRate) { 92 83 ITreeNodeProvider<K, V> vRightSlotProvider = pRightNode.getProvider(); 93 boolean vNodeWasDirty = fProvider.isDirty();94 boolean vRightNodeWasDirty = vRightSlotProvider.isDirty();95 84 int vOldSize = getProvider().getSize(); 96 85 int vMoved = fProvider.adoptEntriesFromRight(vRightSlotProvider, pTargetFillRate); 97 86 if (vMoved > 0) { 98 87 //Some entries have been moved. 99 if (!vNodeWasDirty) fTree.markDirty(fProvider);100 if (!vRightNodeWasDirty) fTree.markDirty(vRightSlotProvider);101 88 TreeRake<K, V> vParent = pRightNode.getParent(); 102 89 if (vParent != null) vParent.updateKey(pRightNode.getOffsetInParent(), vRightSlotProvider.getKey(0)); … … 107 94 108 95 public boolean adoptAllEntriesFromLeft(TreeNode<K, V> pLeftNodeToKill) { 109 UpdateResult vResult = fProvider.adoptAllEntriesFromLeft(pLeftNodeToKill.getProvider()); 110 switch (vResult) { 111 case doneNewlyDirty: 112 fTree.markDirty(fProvider); 113 case done: 96 if (fProvider.adoptAllEntriesFromLeft(pLeftNodeToKill.getProvider())) { 114 97 if (fParent != null) fParent.updateKey(fOffsetInParent, getKey(0)); 115 98 return true; 116 case failedNodeFull:117 //cancel118 99 } 119 100 return false; … … 121 102 122 103 public boolean adoptAllEntriesFromRight(TreeNode<K, V> pRightNodeToKill) { 123 UpdateResult vResult = fProvider.adoptAllEntriesFromRight(pRightNodeToKill.getProvider()); 124 int vOldSize = getProvider().getSize(); 125 switch (vResult) { 126 case doneNewlyDirty: 127 fTree.markDirty(fProvider); 128 case done: 104 if (fProvider.adoptAllEntriesFromRight(pRightNodeToKill.getProvider())) { 105 int vOldSize = getProvider().getSize(); 129 106 if (vOldSize == 0 && fParent != null) fParent.updateKey(fOffsetInParent, getKey(0)); 130 107 return true; 131 case failedNodeFull:132 //cancel133 108 } 134 109 return false; -
trunk/Jav_Orient/src/eu/scenari/orient/tree/impl/TreeRake.java
r19333 r19672 3 3 import eu.scenari.commons.util.lang.ScException; 4 4 import eu.scenari.orient.tree.provider.ITreeNodeProvider; 5 import eu.scenari.orient.tree.provider.ITreeNodeProvider.UpdateResult;6 5 import eu.scenari.orient.tree.provider.ITreeRakeProvider; 7 6 import eu.scenari.orient.tree.provider.ITreeSlotProvider; … … 11 10 protected TreeNode<K, V>[] fChildren; 12 11 12 /** Constructor for root tree node. */ 13 13 public TreeRake(Tree<K, V> pTree, ITreeRakeProvider<K, V> pProvider) { 14 14 super(pTree, pProvider); … … 16 16 } 17 17 18 /** Constructor for root tree node in creation context. */ 19 public TreeRake(Tree<K, V> pTree, ITreeRakeProvider<K, V> pProvider, TreeNode<K, V> pFirstChild) { 20 super(pTree, pProvider); 21 setup(); 22 fChildren[0] = pFirstChild; 23 24 } 25 18 26 public TreeRake(TreeRake<K, V> pParent, int pOffset, ITreeRakeProvider<K, V> pProvider) { 19 27 super(pParent, pOffset, pProvider); … … 22 30 23 31 protected void setup() { 24 fChildren = new TreeNode[ fTree.fProvider.getDefaultRakeCapacity()];32 fChildren = new TreeNode[Math.max(fTree.fProvider.getDefaultRakeCapacity(), getProvider().getSize())]; 25 33 } 26 34 … … 33 41 } 34 42 43 /** 44 * Warning : bounds are not checked. 45 * @see #getFirstNode() 46 * @see #getLastNode() 47 */ 35 48 public TreeNode<K, V> getNode(int pOffset) { 49 assert (pOffset < getProvider().getSize()); 36 50 TreeNode<K, V> vResult = fChildren[pOffset]; 37 51 if (vResult == null) { … … 43 57 } 44 58 59 /** 60 * Warning : bounds are not checked. 61 * @see #getFirstNode() 62 * @see #getLastNode() 63 */ 64 public TreeNode<K, V> getNodeIfLoaded(int pOffset) { 65 assert (pOffset < getProvider().getSize()); 66 return fChildren[pOffset]; 67 } 68 69 public TreeNode<K, V> getFirstNode() { 70 int vSize = getProvider().getSize(); 71 return (vSize > 0) ? getNode(0) : null; 72 } 73 74 public TreeNode<K, V> getLastNode() { 75 int vSize = getProvider().getSize(); 76 return (vSize > 0) ? getNode(vSize - 1) : null; 77 } 78 45 79 public TreeRake<K, V> insertNewRake(int pOffset) { 80 int vCurrentSize = getProvider().getSize(); 81 assert (pOffset <= vCurrentSize); 46 82 ITreeRakeProvider<K, V> vNewRake = getProvider().insertNewRake(pOffset); 47 83 if (vNewRake == null) return null; 48 if (vNewRake.isDirty()) fTree.markDirty(vNewRake); 49 return (TreeRake) createChildNode(vNewRake, pOffset); 84 ensureSize(vCurrentSize + 1); 85 TreeRake vRake = (TreeRake) createChildNode(vNewRake, pOffset); 86 int vCountToMove = vCurrentSize - pOffset - 1; 87 if (vCountToMove > 0) { 88 //move 89 System.arraycopy(fChildren, pOffset, fChildren, pOffset + 1, vCountToMove); 90 } 91 fChildren[pOffset] = vRake; 92 return vRake; 50 93 } 51 94 52 95 public TreeSlot<K, V> insertNewSlot(int pOffset) { 96 int vCurrentSize = getProvider().getSize(); 97 assert (pOffset <= getProvider().getSize()); 53 98 ITreeSlotProvider<K, V> vNewSlot = getProvider().insertNewSlot(pOffset); 54 99 if (vNewSlot == null) return null; 55 if (vNewSlot.isDirty()) fTree.markDirty(vNewSlot); 56 return (TreeSlot) createChildNode(vNewSlot, pOffset); 57 } 58 59 public TreeNode<K, V> getNodeIfLoaded(int pOffset) { 60 return fChildren[pOffset]; 100 ensureSize(vCurrentSize + 1); 101 TreeSlot vNode = (TreeSlot) createChildNode(vNewSlot, pOffset); 102 int vCountToMove = vCurrentSize - pOffset - 1; 103 if (vCountToMove > 0) { 104 //move 105 System.arraycopy(fChildren, pOffset, fChildren, pOffset + 1, vCountToMove); 106 } 107 fChildren[pOffset] = vNode; 108 return vNode; 109 } 110 111 public int adoptEntriesFromRight(TreeNode<K, V> pRightNode, float pTargetFillRate) { 112 int vMoved = super.adoptEntriesFromRight(pRightNode, pTargetFillRate); 113 if (vMoved > 0) { 114 //Move TreeNode children instances. 115 int vNewSize = getProvider().getSize(); 116 ensureSize(vNewSize); 117 TreeRake<K, V> vRight = (TreeRake) pRightNode; 118 TreeNode<K, V>[] vRightChildren = vRight.fChildren; 119 System.arraycopy(vRightChildren, 0, fChildren, vNewSize - vMoved, vMoved); 120 System.arraycopy(vRightChildren, vMoved, vRightChildren, 0, vRightChildren.length - vMoved); 121 for (int i = vNewSize - vMoved; i < vNewSize; i++) { 122 fChildren[i].setParent(this, i); 123 } 124 } 125 return vMoved; 126 } 127 128 public int adoptEntriesFromLeft(TreeNode<K, V> pLeftNode, float pTargetFillRate) { 129 int vMoved = super.adoptEntriesFromLeft(pLeftNode, pTargetFillRate); 130 if (vMoved > 0) { 131 //Move TreeNode children instances. 132 int vNewSize = getProvider().getSize(); 133 ensureSize(vNewSize); 134 TreeRake<K, V> vLeft = (TreeRake) pLeftNode; 135 TreeNode<K, V>[] vLeftChildren = vLeft.fChildren; 136 System.arraycopy(fChildren, 0, fChildren, vMoved, vNewSize - vMoved); 137 System.arraycopy(vLeftChildren, vLeft.getProvider().getSize(), fChildren, 0, vMoved); 138 for (int i = 0; i < vMoved; i++) { 139 fChildren[i].setParent(this, i); 140 } 141 } 142 return vMoved; 143 } 144 145 public boolean adoptAllEntriesFromRight(TreeNode<K, V> pRightNodeToKill) { 146 int vOldSize = getProvider().getSize(); 147 if (super.adoptAllEntriesFromRight(pRightNodeToKill)) { 148 //Move TreeNode children instances. 149 int vNewSize = getProvider().getSize(); 150 ensureSize(vNewSize); 151 TreeRake<K, V> vRight = (TreeRake) pRightNodeToKill; 152 TreeNode<K, V>[] vRightChildren = vRight.fChildren; 153 System.arraycopy(vRightChildren, 0, fChildren, vOldSize, vNewSize - vOldSize); 154 for (int i = vOldSize; i < vNewSize; i++) { 155 fChildren[i].setParent(this, i); 156 } 157 return true; 158 } 159 return false; 160 } 161 162 public boolean adoptAllEntriesFromLeft(TreeNode<K, V> pLeftNodeToKill) { 163 int vMoved = pLeftNodeToKill.getProvider().getSize(); 164 if (super.adoptAllEntriesFromLeft(pLeftNodeToKill)) { 165 //Move TreeNode children instances. 166 int vNewSize = getProvider().getSize(); 167 ensureSize(vNewSize); 168 TreeRake<K, V> vLeft = (TreeRake) pLeftNodeToKill; 169 TreeNode<K, V>[] vLeftChildren = vLeft.fChildren; 170 System.arraycopy(fChildren, 0, fChildren, vMoved, vNewSize - vMoved); 171 System.arraycopy(vLeftChildren, 0, fChildren, 0, vMoved); 172 for (int i = 0; i < vMoved; i++) { 173 fChildren[i].setParent(this, i); 174 } 175 return true; 176 } 177 return false; 61 178 } 62 179 … … 72 189 int vLow = 0; 73 190 int vHigh = fProvider.getSize() - 1; 74 while (vLow < =vHigh) {191 while (vLow < vHigh) { 75 192 int vMid = (vLow + vHigh) >>> 1; 76 193 K vMidKey = getKey(vMid); … … 88 205 } 89 206 90 public TreeSlot<K, V> findNextSlot(int pOffsetInParent) { 91 if (pOffsetInParent < getProvider().getSize() - 1) return getNode(pOffsetInParent + 1).findFirstSlot(); 92 return fParent != null ? fParent.findNextSlot(fOffsetInParent) : null; 93 } 94 95 public TreeSlot<K, V> findPreviousSlot(int pOffsetInParent) { 96 if (pOffsetInParent > 0) return getNode(pOffsetInParent - 1).findLastSlot(); 97 return fParent != null ? fParent.findPreviousSlot(fOffsetInParent) : null; 207 public TreeSlot<K, V> findRightSlot(int pFrom) { 208 if (pFrom < getProvider().getSize() - 1) return getNode(pFrom + 1).findFirstSlot(); 209 return fParent != null ? fParent.findRightSlot(fOffsetInParent) : null; 210 } 211 212 public TreeSlot<K, V> findLeftSlot(int pFrom) { 213 if (pFrom > 0) return getNode(pFrom - 1).findLastSlot(); 214 return fParent != null ? fParent.findLeftSlot(fOffsetInParent) : null; 215 } 216 217 /** Find the right next node (slot or rake) with the same level. */ 218 public TreeNode<K, V> findRightCousin(int pFrom) { 219 if (pFrom < getProvider().getSize() - 1) return getNode(pFrom + 1); 220 if (fParent == null) return null; 221 TreeNode<K, V> vParentCousin = fParent.findRightCousin(fOffsetInParent); 222 return vParentCousin != null && vParentCousin.isRake() ? ((TreeRake) vParentCousin).getFirstNode() : null; 223 } 224 225 /** Find the left previous node (slot or rake) with the same level. */ 226 public TreeNode<K, V> findLeftCousin(int pFrom) { 227 if (pFrom > 0) return getNode(pFrom - 1); 228 if (fParent == null) return null; 229 TreeNode<K, V> vParentCousin = fParent.findLeftCousin(fOffsetInParent); 230 return vParentCousin != null && vParentCousin.isRake() ? ((TreeRake) vParentCousin).getLastNode() : null; 98 231 } 99 232 … … 110 243 111 244 public void updateKey(int pOffset, K pKey) { 112 UpdateResult vResult = getProvider().updateKey(pOffset, pKey); 113 switch (vResult) { 114 case doneNewlyDirty: 115 fTree.markDirty(fProvider); 116 case done: 117 break; 118 case failedNodeFull: 245 assert (pOffset < getProvider().getSize()); 246 if (!getProvider().updateKey(pOffset, pKey)) { 119 247 //TODO failedNodeFull on updateKey 120 248 throw new ScException("TODO failedNodeFull on updateKey"); … … 144 272 } else { 145 273 // Remove this entry. 146 if (fProvider.remove(vOffsetEntry)) { 147 fTree.markDirty(fProvider); 148 } 274 fProvider.remove(vOffsetEntry); 149 275 // Update start key. 150 276 if (vOffsetEntry == 0 && fParent != null) { … … 163 289 } 164 290 } 291 292 protected void ensureSize(int pTargetSize) { 293 if (fChildren.length < pTargetSize) { 294 TreeNode<K, V>[] vNew = new TreeNode[pTargetSize + 10]; 295 System.arraycopy(fChildren, 0, vNew, 0, fChildren.length); 296 fChildren = vNew; 297 } 298 } 165 299 } -
trunk/Jav_Orient/src/eu/scenari/orient/tree/impl/TreeSlot.java
r19310 r19672 78 78 } 79 79 80 public TreeSlot<K, V> find NextSlot() {80 public TreeSlot<K, V> findRightSlot() { 81 81 if (fParent == null) return null; 82 return fParent.find NextSlot(fOffsetInParent);82 return fParent.findRightSlot(fOffsetInParent); 83 83 } 84 84 85 public TreeSlot<K, V> find PreviousSlot() {85 public TreeSlot<K, V> findLeftSlot() { 86 86 if (fParent == null) return null; 87 return fParent.find PreviousSlot(fOffsetInParent);87 return fParent.findLeftSlot(fOffsetInParent); 88 88 } 89 89 … … 93 93 94 94 public void removeEntry(int pOffset) { 95 assert (pOffset < getProvider().getSize()); 95 96 if (pOffset == 0 && fProvider.getSize() == 1) { 96 97 //cleanup 97 98 deleteNode(); 98 99 } else { 99 if (fProvider.remove(pOffset)) { 100 fTree.markDirty(fProvider); 101 } 100 fProvider.remove(pOffset); 102 101 if (pOffset == 0 && fParent != null) { 103 102 fParent.updateKey(fOffsetInParent, getKey(0)); -
trunk/Jav_Orient/src/eu/scenari/orient/tree/provider/ITreeNodeProvider.java
r19310 r19672 2 2 3 3 public interface ITreeNodeProvider<K, V> { 4 5 public static enum UpdateResult {6 done, doneNewlyDirty, failedNodeFull7 }8 4 9 5 /** Is it a rake or a slot. */ … … 21 17 * @return <code>true</code> this node is newly dirty. 22 18 */ 23 public booleanremove(int pOffset);19 public void remove(int pOffset); 24 20 25 21 /** … … 31 27 * Move all entries from left node for merging 2 nodes. 32 28 * 33 * @return {@link UpdateResult#failedNodeFull} if all entries can not be moved. 29 * @param pLeftNodeToKill Node to merge. pLeftNodeToKill is the same type as this one (rake / slot). 30 * @return <code>false</code> if the move has been cancelled because the node has not enough space. 34 31 */ 35 public UpdateResultadoptAllEntriesFromLeft(ITreeNodeProvider<K, V> pLeftNodeToKill);32 public boolean adoptAllEntriesFromLeft(ITreeNodeProvider<K, V> pLeftNodeToKill); 36 33 37 34 /** 38 35 * Move all entries from right node for merging 2 nodes. 39 36 * 40 * @return {@link UpdateResult#failedNodeFull} if all entries can not be moved. 37 * @param pRightNodeToKill Node to merge. pLeftNodeToKill is the same type as this one (rake / slot). 38 * @return <code>false</code> if the move has been cancelled because the node has not enough space. 41 39 */ 42 public UpdateResultadoptAllEntriesFromRight(ITreeNodeProvider<K, V> pRightNodeToKill);40 public boolean adoptAllEntriesFromRight(ITreeNodeProvider<K, V> pRightNodeToKill); 43 41 44 42 /** … … 46 44 * pLeftNode must always have at least one entry. 47 45 * 48 * @param pLeftNode node from moving entries 46 * @param pLeftNode node from moving entries. pLeftNode is the same type as this one (rake / slot) 49 47 * @param pTargetFillRate target fill rate for this node 50 48 * @return number of entries moved. … … 56 54 * pRightNode must always have at least one entry. 57 55 * 58 * @param pRightNode node from moving entries 56 * @param pRightNode node from moving entries. pRightNode is the same type as this one (rake / slot) 59 57 * @param pTargetFillRate target fill rate for this node 60 58 * @return number of entries moved. … … 62 60 public int adoptEntriesFromRight(ITreeNodeProvider<K, V> pRightNode, float pTargetFillRate); 63 61 64 /** Delete this node.*/ 62 /** 63 * This node will not be used any more by the tree, it must be deleted in the storage layer. 64 */ 65 65 public void deleteNode(); 66 66 67 /** Indicate that this node is dirty and will not be garbage collected by the Tree. */ 67 68 public boolean isDirty(); 68 69 public void save();70 69 } -
trunk/Jav_Orient/src/eu/scenari/orient/tree/provider/ITreeProvider.java
r19310 r19672 3 3 public interface ITreeProvider<K, V> { 4 4 5 /** Tree size (number of entries). */ 5 /** 6 * Tree size (number of entries). 7 * A provider can not store the current size and then return -1. 8 * 9 * @return tree size or -1 if size unknown. 10 */ 6 11 public int getSize(); 7 12 8 public void setSize(int pSize); 13 /** 14 * Add or substract pDelta to the current size. 15 */ 16 public void setSizeByDelta(int pDelta); 9 17 18 /** 19 * Set size. 20 * Can be called when {@link #getSize()} has returned -1 and the size 21 * has been computed by iterating the tree. 22 * The size should then be kept in memory for performance. 23 */ 24 public void setSize(int pComputedSize); 25 26 /** Load root node. */ 10 27 public ITreeNodeProvider<K, V> loadRoot(); 11 28 29 /** Update root node. */ 12 30 public void setRoot(ITreeNodeProvider<K, V> pNewRoot); 13 31 32 /** Create a new rake as a root. */ 14 33 public ITreeRakeProvider<K, V> createRakeAsRoot(ITreeNodeProvider<K, V> pFirstChild); 15 34 35 /** Create a new slot as a root. */ 16 36 public ITreeSlotProvider<K, V> createSlotAsRoot(); 17 37 … … 22 42 public int getDefaultSlotCapacity(); 23 43 24 public boolean isDirty();25 26 public void save();27 28 44 } -
trunk/Jav_Orient/src/eu/scenari/orient/tree/provider/ITreeRakeProvider.java
r19310 r19672 23 23 public ITreeSlotProvider<K, V> insertNewSlot(int pOffset); 24 24 25 public UpdateResult updateKey(int pOffset, K pKey); 25 /** 26 * Update the key. 27 * 28 * @return <code>false</code> if the update has been cancelled because the node has not enough space. 29 */ 30 public boolean updateKey(int pOffset, K pKey); 26 31 27 32 } -
trunk/Jav_Orient/src/eu/scenari/orient/tree/provider/ITreeSlotProvider.java
r19333 r19672 15 15 * 16 16 * @param pValue not used for a Set implementation. 17 * @return <code>false</code> if the insertion has been cancelled because the node has not enough space. 17 18 */ 18 public UpdateResultinsert(int pOffset, K pKey, V pValue);19 public boolean insert(int pOffset, K pKey, V pValue); 19 20 20 21 /** 21 22 * 22 23 * @param pValue not used for a Set implementation. 23 * @return <code> true</code> if succeed. <code>false</code> if slot is full.24 * @return <code>false</code> if the insertion has been cancelled because the node has not enough space. 24 25 */ 25 public UpdateResultreplace(int pOffset, K pKey, V pValue);26 public boolean replace(int pOffset, K pKey, V pValue); 26 27 27 28 }
Note: See TracChangeset
for help on using the changeset viewer.