1 21 package com.db4o.inside.classindex; 22 23 import com.db4o.*; 24 import com.db4o.foundation.*; 25 26 29 public class OldClassIndexStrategy extends AbstractClassIndexStrategy implements TransactionParticipant { 30 31 private ClassIndex _index; 32 33 private final Hashtable4 _perTransaction = new Hashtable4(); 34 35 public OldClassIndexStrategy(YapClass yapClass) { 36 super(yapClass); 37 } 38 39 public void read(YapStream stream, int indexID) { 40 _index = createClassIndex(stream); 41 if (indexID > 0) { 42 _index.setID(indexID); 43 } 44 _index.setStateDeactivated(); 45 } 46 47 private ClassIndex getActiveIndex(Transaction transaction) { 48 if (null != _index) { 49 _index.ensureActive(transaction); 50 } 51 return _index; 52 } 53 54 public int entryCount(Transaction transaction) { 55 if (_index != null) { 56 return _index.entryCount(transaction); 57 } 58 return 0; 59 } 60 61 public void initialize(YapStream stream) { 62 _index = createClassIndex(stream); 63 } 64 65 public void purge() { 66 if (_index != null) { 67 if (!_index.isDirty()) { 68 _index.clear(); 69 _index.setStateDeactivated(); 70 } 71 } 72 } 73 74 public int write(Transaction transaction) { 75 if(_index == null){ 76 return 0; 77 } 78 _index.write(transaction); 79 return _index.getID(); 80 } 81 82 private void flushContext(final Transaction transaction) { 83 TransactionState context = getState(transaction); 84 85 final ClassIndex index = getActiveIndex(transaction); 86 context.traverseAdded(new Visitor4() { 87 public void visit(Object a_object) { 88 index.add(idFromValue(a_object)); 89 } 90 }); 91 92 context.traverseRemoved(new Visitor4() { 93 public void visit(Object a_object) { 94 int id = idFromValue(a_object); 95 final YapStream stream = transaction.stream(); 96 YapObject yo = stream.getYapObject(id); 97 if (yo != null) { 98 stream.removeReference(yo); 99 } 100 index.remove(id); 101 } 102 }); 103 } 104 105 private void writeIndex(Transaction transaction) { 106 _index.setStateDirty(); 107 _index.write(transaction); 108 } 109 110 final static class TransactionState { 111 112 private Tree i_addToClassIndex; 113 114 private Tree i_removeFromClassIndex; 115 116 public void add(int id) { 117 i_removeFromClassIndex = Tree.removeLike(i_removeFromClassIndex, new TreeInt(id)); 118 i_addToClassIndex = Tree.add(i_addToClassIndex, new TreeInt(id)); 119 } 120 121 public void remove(int id) { 122 i_addToClassIndex = Tree.removeLike(i_addToClassIndex, new TreeInt(id)); 123 i_removeFromClassIndex = Tree.add(i_removeFromClassIndex, new TreeInt(id)); 124 } 125 126 public void dontDelete(int id) { 127 i_removeFromClassIndex = Tree.removeLike(i_removeFromClassIndex, new TreeInt(id)); 128 } 129 130 void traverse(Tree node, Visitor4 visitor) { 131 if (node != null) { 132 node.traverse(visitor); 133 } 134 } 135 136 public void traverseAdded(Visitor4 visitor4) { 137 traverse(i_addToClassIndex, visitor4); 138 } 139 140 public void traverseRemoved(Visitor4 visitor4) { 141 traverse(i_removeFromClassIndex, visitor4); 142 } 143 } 144 145 protected void internalAdd(Transaction transaction, int id) { 146 getState(transaction).add(id); 147 } 148 149 private TransactionState getState(Transaction transaction) { 150 synchronized (_perTransaction) { 151 TransactionState context = (TransactionState)_perTransaction.get(transaction); 152 if (null == context) { 153 context = new TransactionState(); 154 _perTransaction.put(transaction, context); 155 transaction.enlist(this); 156 } 157 return context; 158 } 159 } 160 161 private Tree getAll(Transaction transaction) { 162 ClassIndex ci = getActiveIndex(transaction); 163 if (ci == null) { 164 return null; 165 } 166 167 final Tree.ByRef tree = new Tree.ByRef(Tree.deepClone(ci.getRoot(), null)); 168 TransactionState context = getState(transaction); 169 context.traverseAdded(new Visitor4() { 170 public void visit(Object obj) { 171 tree.value = Tree.add(tree.value, new TreeInt(idFromValue(obj))); 172 } 173 }); 174 context.traverseRemoved(new Visitor4() { 175 public void visit(Object obj) { 176 tree.value = Tree.removeLike(tree.value, (TreeInt) obj); 177 } 178 }); 179 return tree.value; 180 } 181 182 protected void internalRemove(Transaction transaction, int id) { 183 getState(transaction).remove(id); 184 } 185 186 public void traverseAll(Transaction transaction, final Visitor4 command) { 187 Tree tree = getAll(transaction); 188 if (tree != null) { 189 tree.traverse(new Visitor4() { 190 public void visit(Object obj) { 191 command.visit(new Integer (idFromValue(obj))); 192 } 193 }); 194 } 195 } 196 197 public int idFromValue(Object value) { 198 return ((TreeInt) value)._key; 199 } 200 201 private ClassIndex createClassIndex(YapStream stream) { 202 if (stream.isClient()) { 203 return new ClassIndexClient(_yapClass); 204 } 205 return new ClassIndex(_yapClass); 206 } 207 208 public void dontDelete(Transaction transaction, int id) { 209 getState(transaction).dontDelete(id); 210 } 211 212 public void commit(Transaction trans) { 213 if (null != _index) { 214 flushContext(trans); 215 writeIndex(trans); 216 } 217 } 218 219 public void dispose(Transaction transaction) { 220 synchronized (_perTransaction) { 221 _perTransaction.remove(transaction); 222 } 223 } 224 225 public void rollback(Transaction transaction) { 226 } 228 229 public void defragReference(YapClass yapClass, ReaderPair readers,int classIndexID) { 230 } 231 232 public int id() { 233 return _index.getID(); 234 } 235 236 237 public Iterator4 allSlotIDs(Transaction trans){ 238 throw new NotImplementedException(); 239 } 240 241 public void defragIndex(ReaderPair readers) { 242 } 243 } 244 | Popular Tags |