1 21 package com.db4o.inside.freespace; 22 23 import com.db4o.*; 24 import com.db4o.foundation.*; 25 import com.db4o.inside.ix.*; 26 27 28 public class FreespaceManagerIx extends FreespaceManager{ 29 30 private int _slotAddress; 31 32 private FreespaceIxAddress _addressIx; 33 private FreespaceIxLength _lengthIx; 34 35 private boolean _started; 36 37 private Collection4 _xBytes; 38 39 FreespaceManagerIx(YapFile file){ 40 super(file); 41 } 42 43 private void add(int address, int length){ 44 _addressIx.add(address, length); 45 _lengthIx.add(address, length); 46 } 47 48 public void beginCommit() { 49 if(! started()){ 50 return; 51 } 52 slotEntryToZeroes(_file, _slotAddress); 53 } 54 55 public void debug(){ 56 if(Debug.freespace){ 57 System.out.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); 58 System.out.println("Dumping file based address index"); 59 _addressIx.debug(); 60 System.out.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); 61 System.out.println("Dumping file based length index"); 62 _lengthIx.debug(); 63 System.out.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); 64 } 65 } 66 67 public void endCommit() { 68 if( ! started()){ 69 return; 70 } 71 if (Debug.xbytes) { 72 _xBytes = new Collection4(); 73 } 74 75 _addressIx._index.commitFreeSpace(_lengthIx._index); 76 77 YapWriter writer = new YapWriter(_file.getSystemTransaction(), _slotAddress, slotLength()); 78 _addressIx._index._metaIndex.write(writer); 79 _lengthIx._index._metaIndex.write(writer); 80 if (Debug.xbytes) { 81 writer.setID(YapConst.IGNORE_ID); } 83 if(_file.configImpl().flushFileBuffers()){ 84 _file.syncFiles(); 85 } 86 writer.writeEncrypt(); 87 88 if(Debug.xbytes){ 89 Iterator4 i = _xBytes.iterator(); 90 _xBytes = null; 91 while(i.moveNext()){ 92 int[] addressLength = (int[])i.current(); 93 writeXBytes(addressLength[0], addressLength[1]); 94 } 95 } 96 } 97 98 public int entryCount() { 99 return _addressIx.entryCount(); 100 } 101 102 public void free(int address, int length) { 103 104 if(! started()){ 105 return; 106 } 107 108 if (address <= 0) { 109 return; 110 } 111 112 if (length <= discardLimit()) { 113 return; 114 } 115 116 if(DTrace.enabled){ 117 DTrace.FREE.logLength(address, length); 118 } 119 120 length = _file.blocksFor(length); 121 122 int freedAddress = address; 123 int freedLength = length; 124 125 _addressIx.find(address); 126 127 if(_addressIx.preceding()){ 128 if(_addressIx.address() + _addressIx.length() == address){ 129 remove(_addressIx.address(), _addressIx.length()); 130 address = _addressIx.address(); 131 length += _addressIx.length(); 132 _addressIx.find(freedAddress); 133 } 134 } 135 136 if(_addressIx.subsequent()){ 137 if(freedAddress + freedLength == _addressIx.address()){ 138 remove(_addressIx.address(), _addressIx.length()); 139 length += _addressIx.length(); 140 } 141 } 142 143 add(address, length); 144 145 if (Debug.xbytes) { 146 writeXBytes(freedAddress, freedLength); 147 } 148 } 149 150 public void freeSelf() { 151 if(! started()){ 152 return; 153 } 154 _addressIx._index._metaIndex.free(_file); 155 _lengthIx._index._metaIndex.free(_file); 156 } 157 158 public int freeSize() { 159 return _addressIx.freeSize(); 160 } 161 162 public int getSlot(int length) { 163 if(! started()){ 164 return 0; 165 } 166 int address = getSlot1(length); 167 168 if(address != 0){ 169 if(DTrace.enabled){ 170 DTrace.GET_FREESPACE.logLength(address, length); 171 } 172 } 173 return address; 174 } 175 176 private int getSlot1(int length) { 177 178 if(! started()){ 179 return 0; 180 } 181 182 length = _file.blocksFor(length); 183 184 _lengthIx.find(length); 185 186 if(_lengthIx.match()){ 187 remove(_lengthIx.address(), _lengthIx.length()); 188 return _lengthIx.address(); 189 } 190 191 if(_lengthIx.subsequent()){ 192 193 int lengthRemainder = _lengthIx.length() - length; 194 int addressRemainder = _lengthIx.address() + length; 195 remove(_lengthIx.address(), _lengthIx.length()); 196 add(addressRemainder, lengthRemainder); 197 return _lengthIx.address(); 198 } 199 200 return 0; 201 } 202 203 public void migrate(final FreespaceManager newFM) { 204 if(! started()){ 205 return; 206 } 207 final IntObjectVisitor addToNewFM = new IntObjectVisitor(){ 208 public void visit(int length, Object address) { 209 newFM.free(((Integer )address).intValue(), length); 210 } 211 }; 212 Tree.traverse(_addressIx._indexTrans.getRoot(), new Visitor4() { 213 public void visit(Object a_object) { 214 IxTree ixTree = (IxTree)a_object; 215 ixTree.visitAll(addToNewFM); 216 } 217 }); 218 } 219 220 public void onNew(YapFile file) { 221 file.ensureFreespaceSlot(); 222 } 223 224 public void read(int freespaceID) { 225 } 227 228 private void remove(int address, int length){ 229 _addressIx.remove(address, length); 230 _lengthIx.remove(address, length); 231 } 232 233 public void start(int slotAddress) { 234 235 if(started()){ 236 return; 237 } 238 239 _slotAddress = slotAddress; 240 241 MetaIndex miAddress = new MetaIndex(); 242 MetaIndex miLength = new MetaIndex(); 243 244 YapReader reader = new YapReader(slotLength()); 245 reader.read(_file, slotAddress, 0); 246 miAddress.read(reader); 247 miLength.read(reader); 248 249 _addressIx = new FreespaceIxAddress(_file, miAddress); 250 _lengthIx = new FreespaceIxLength(_file, miLength); 251 252 _started = true; 253 } 254 255 256 private boolean started(){ 257 return _started; 258 } 259 260 public byte systemType() { 261 return FM_IX; 262 } 263 264 public int write(boolean shuttingDown) { 265 return 0; } 267 268 private void writeXBytes(int address, int length){ 269 if (Debug.xbytes) { 270 if(_xBytes == null){ 271 length = length * blockSize(); 272 _file.debugWriteXBytes(address, length); 273 }else{ 274 _xBytes.add(new int[] {address, length}); 275 } 276 } 277 } 278 279 } 280 | Popular Tags |