1 21 package com.db4o.defragment; 22 23 import java.io.*; 24 25 import com.db4o.*; 26 import com.db4o.config.*; 27 import com.db4o.ext.*; 28 import com.db4o.foundation.*; 29 import com.db4o.inside.btree.*; 30 import com.db4o.inside.classindex.*; 31 import com.db4o.inside.mapping.*; 32 import com.db4o.inside.slots.*; 33 34 37 public class DefragContextImpl implements DefragContext { 38 39 public static abstract class DbSelector { 40 DbSelector() { 41 } 42 43 abstract YapFile db(DefragContextImpl context); 44 45 Transaction transaction(DefragContextImpl context) { 46 return db(context).getSystemTransaction(); 47 } 48 } 49 50 public final static DbSelector SOURCEDB=new DbSelector() { 51 YapFile db(DefragContextImpl context) { 52 return context._sourceDb; 53 } 54 }; 55 56 public final static DbSelector TARGETDB=new DbSelector() { 57 YapFile db(DefragContextImpl context) { 58 return context._targetDb; 59 } 60 }; 61 62 private static final long CLASSCOLLECTION_POINTER_ADDRESS = 2+2*YapConst.INT_LENGTH; 63 64 public final YapFile _sourceDb; 65 final YapFile _targetDb; 66 private final ContextIDMapping _mapping; 67 private DefragmentListener _listener; 68 private Queue4 _unindexed=new Queue4(); 69 70 71 public DefragContextImpl(DefragmentConfig defragConfig,DefragmentListener listener) { 72 _listener=listener; 73 Configuration sourceConfig=defragConfig.db4oConfig(); 74 sourceConfig.weakReferences(false); 75 sourceConfig.flushFileBuffers(false); 76 sourceConfig.readOnly(true); 77 _sourceDb=(YapFile)Db4o.openFile(sourceConfig,defragConfig.backupPath()).ext(); 78 _targetDb = freshYapFile(defragConfig.origPath()); 79 _mapping=defragConfig.mapping(); 80 _mapping.open(); 81 } 82 83 static YapFile freshYapFile(String fileName) { 84 new File(fileName).delete(); 85 return (YapFile)Db4o.openFile(DefragmentConfig.vanillaDb4oConfig(),fileName).ext(); 86 } 87 88 public int mappedID(int oldID,int defaultID) { 89 int mapped=internalMappedID(oldID,false); 90 return (mapped!=0 ? mapped : defaultID); 91 } 92 93 public int mappedID(int oldID) throws MappingNotFoundException { 94 int mapped=internalMappedID(oldID,false); 95 if(mapped==0) { 96 throw new MappingNotFoundException(oldID); 97 } 98 return mapped; 99 } 100 101 public int mappedID(int id,boolean lenient) throws MappingNotFoundException { 102 if(id == 0){ 103 return 0; 104 } 105 int mapped = internalMappedID(id,lenient); 106 if(mapped==0) { 107 _listener.notifyDefragmentInfo(new DefragmentInfo("No mapping found for ID "+id)); 108 return 0; 109 } 110 return mapped; 111 } 112 113 private int internalMappedID(int oldID,boolean lenient) throws MappingNotFoundException { 114 if(oldID==0) { 115 return 0; 116 } 117 if(_sourceDb.handlers().isSystemHandler(oldID)) { 118 return oldID; 119 } 120 return _mapping.mappedID(oldID,lenient); 121 } 122 123 public void mapIDs(int oldID,int newID, boolean isClassID) { 124 _mapping.mapIDs(oldID,newID, isClassID); 125 } 126 127 public void close() { 128 _sourceDb.close(); 129 _targetDb.close(); 130 _mapping.close(); 131 } 132 133 public YapReader readerByID(DbSelector selector,int id) { 134 Slot slot=readPointer(selector, id); 135 return readerByAddress(selector,slot._address,slot._length); 136 } 137 138 public YapWriter sourceWriterByID(int id) { 139 Slot slot=readPointer(SOURCEDB, id); 140 return _sourceDb.readWriterByAddress(SOURCEDB.transaction(this),slot._address,slot._length); 141 } 142 143 public YapReader sourceReaderByAddress(int address,int length) { 144 return readerByAddress(SOURCEDB, address, length); 145 } 146 147 public YapReader targetReaderByAddress(int address,int length) { 148 return readerByAddress(TARGETDB, address, length); 149 } 150 151 public YapReader readerByAddress(DbSelector selector,int address,int length) { 152 return selector.db(this).readReaderByAddress(address,length); 153 } 154 155 public YapWriter targetWriterByAddress(int address,int length) { 156 return _targetDb.readWriterByAddress(TARGETDB.transaction(this),address,length); 157 } 158 159 public int allocateTargetSlot(int length) { 160 return _targetDb.getSlot(length); 161 } 162 163 public void targetWriteBytes(ReaderPair readers,int address) { 164 readers.write(_targetDb,address); 165 } 166 167 public void targetWriteBytes(YapReader reader,int address) { 168 _targetDb.writeBytes(reader,address,0); 169 } 170 171 public StoredClass[] storedClasses(DbSelector selector) { 172 YapFile db = selector.db(this); 173 db.showInternalClasses(true); 174 StoredClass[] classes=db.storedClasses(); 175 return classes; 176 } 177 178 public YapStringIO stringIO() { 179 return _sourceDb.stringIO(); 180 } 181 182 public void targetCommit() { 183 _targetDb.commit(); 184 } 185 186 public TypeHandler4 sourceHandler(int id) { 187 return _sourceDb.handlerByID(id); 188 } 189 190 public int sourceClassCollectionID() { 191 return _sourceDb.classCollection().getID(); 192 } 193 194 public static void targetClassCollectionID(String file,int id) throws IOException { 195 RandomAccessFile raf=new RandomAccessFile(file,"rw"); 196 try { 197 YapReader reader=new YapReader(YapConst.INT_LENGTH); 198 199 raf.seek(CLASSCOLLECTION_POINTER_ADDRESS); 200 reader._offset=0; 201 reader.writeInt(id); 202 raf.write(reader._buffer); 203 } 204 finally { 205 raf.close(); 206 } 207 } 208 209 private Hashtable4 _classIndices=new Hashtable4(16); 210 211 public int classIndexID(YapClass yapClass) { 212 return classIndex(yapClass).id(); 213 } 214 215 public void traverseAll(YapClass yapClass,Visitor4 command) { 216 if(!yapClass.hasIndex()) { 217 return; 218 } 219 yapClass.index().traverseAll(SOURCEDB.transaction(this), command); 220 } 221 222 public void traverseAllIndexSlots(YapClass yapClass,Visitor4 command) { 223 Iterator4 slotIDIter=yapClass.index().allSlotIDs(SOURCEDB.transaction(this)); 224 while(slotIDIter.moveNext()) { 225 command.visit(slotIDIter.current()); 226 } 227 } 228 229 public void traverseAllIndexSlots(BTree btree,Visitor4 command) { 230 Iterator4 slotIDIter=btree.allNodeIds(SOURCEDB.transaction(this)); 231 while(slotIDIter.moveNext()) { 232 command.visit(slotIDIter.current()); 233 } 234 } 235 236 public int databaseIdentityID(DbSelector selector) { 237 YapFile db = selector.db(this); 238 return db.identity().getID(selector.transaction(this)); 239 } 240 241 private ClassIndexStrategy classIndex(YapClass yapClass) { 242 ClassIndexStrategy classIndex=(ClassIndexStrategy)_classIndices.get(yapClass); 243 if(classIndex==null) { 244 classIndex=new BTreeClassIndexStrategy(yapClass); 245 _classIndices.put(yapClass,classIndex); 246 classIndex.initialize(_targetDb); 247 } 248 return classIndex; 249 } 250 251 public Transaction systemTrans() { 252 return SOURCEDB.transaction(this); 253 } 254 255 public void copyIdentity() { 256 _targetDb.setIdentity(_sourceDb.identity()); 257 } 258 259 public void targetClassCollectionID(int newClassCollectionID) { 260 _targetDb.systemData().classCollectionID(newClassCollectionID); 261 } 262 263 public YapReader sourceReaderByID(int sourceID) { 264 return readerByID(SOURCEDB,sourceID); 265 } 266 267 public BTree sourceUuidIndex() { 268 if(sourceUuidIndexID()==0) { 269 return null; 270 } 271 return _sourceDb.getFieldUUID().getIndex(systemTrans()); 272 } 273 274 public void targetUuidIndexID(int id) { 275 _targetDb.systemData().uuidIndexId(id); 276 } 277 278 public int sourceUuidIndexID() { 279 return _sourceDb.systemData().uuidIndexId(); 280 } 281 282 public YapClass yapClass(int id) { 283 return _sourceDb.getYapClass(id); 284 } 285 286 public void registerUnindexed(int id) { 287 _unindexed.add(new Integer (id)); 288 } 289 290 public Iterator4 unindexedIDs() { 291 return _unindexed.iterator(); 292 } 293 294 private Slot readPointer(DbSelector selector,int id) { 295 YapReader reader=readerByAddress(selector, id, YapConst.POINTER_LENGTH); 296 int address=reader.readInt(); 297 int length=reader.readInt(); 298 return new Slot(address,length); 299 } 300 301 } | Popular Tags |