1 21 22 package org.apache.derby.impl.store.raw.data; 23 24 import org.apache.derby.iapi.reference.SQLState; 25 26 import org.apache.derby.impl.store.raw.data.BasePage; 27 28 import org.apache.derby.iapi.services.io.FormatIdUtil; 29 import org.apache.derby.iapi.services.io.StoredFormatIds; 30 import org.apache.derby.iapi.services.io.Storable; 31 32 import org.apache.derby.iapi.store.raw.Page; 33 import org.apache.derby.iapi.store.raw.RecordHandle; 34 import org.apache.derby.iapi.store.raw.Transaction; 35 import org.apache.derby.iapi.store.raw.xact.RawTransaction; 36 37 import org.apache.derby.iapi.store.raw.log.LogInstant; 38 39 import org.apache.derby.iapi.error.StandardException; 40 import org.apache.derby.iapi.services.sanity.SanityManager; 41 42 import org.apache.derby.iapi.services.io.CompressedNumber; 43 import org.apache.derby.iapi.services.io.FormatableBitSet; 44 import org.apache.derby.iapi.util.ByteArray; 45 import org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream; 46 47 48 import java.io.OutputStream ; 49 import java.io.ObjectOutput ; 50 import java.io.ObjectInput ; 51 import java.io.IOException ; 52 import org.apache.derby.iapi.services.io.LimitObjectInput; 53 54 77 public final class PurgeOperation extends PhysicalPageOperation { 78 79 protected int slot; protected int num_rows; 84 protected int[] recordIds; 86 87 transient protected ByteArray preparedLog; 88 89 public PurgeOperation(RawTransaction t, BasePage page, int slot, int 90 num_rows, int[] recordIds, boolean needDataLogged) 91 throws StandardException 92 { 93 super(page); 94 95 this.slot = slot; 96 this.num_rows = num_rows; 97 this.recordIds = recordIds; 98 99 try { 100 writeOptionalDataToBuffer(t, needDataLogged); 101 } catch (IOException ioe) { 102 throw StandardException.newException( 103 SQLState.DATA_UNEXPECTED_EXCEPTION, ioe); 104 } 105 106 } 107 108 111 112 public PurgeOperation() { super(); } 114 115 public void writeExternal(ObjectOutput out) throws IOException 116 { 117 super.writeExternal(out); 118 119 CompressedNumber.writeInt(out, slot); 120 CompressedNumber.writeInt(out, num_rows); 121 122 for (int i = 0; i < num_rows; i++) 123 CompressedNumber.writeInt(out, recordIds[i]); 124 } 125 126 131 public void readExternal(ObjectInput in) 132 throws IOException , ClassNotFoundException 133 { 134 super.readExternal(in); 135 slot = CompressedNumber.readInt(in); 136 num_rows = CompressedNumber.readInt(in); 137 138 recordIds = new int[num_rows]; 139 for (int i = 0; i < num_rows; i++) 140 recordIds[i] = CompressedNumber.readInt(in); 141 } 142 143 146 public int getTypeFormatId() { 147 return StoredFormatIds.LOGOP_PURGE; 148 } 149 150 151 154 162 public void doMe(Transaction xact, LogInstant instant, LimitObjectInput in) 163 throws StandardException, IOException 164 { 165 169 172 for (int i = num_rows-1; i >= 0; i--) 173 { 174 this.page.purgeRecord(instant, slot+i, recordIds[i]); 175 } 176 } 177 178 181 182 190 public void undoMe(Transaction xact, BasePage undoPage, 191 LogInstant CLRInstant, LimitObjectInput in) 192 throws StandardException, IOException 193 { 194 for (int i = 0; i < num_rows; i++) 195 { 196 undoPage.storeRecord(CLRInstant, slot+i, true, in); 197 } 198 undoPage.setAuxObject(null); 199 } 200 201 202 205 206 213 public void restoreMe(Transaction xact, BasePage undoPage, 214 LogInstant CLRInstant, LimitObjectInput in) 215 throws StandardException, IOException 216 { 217 undoMe(xact, undoPage, CLRInstant, in); 218 } 219 220 225 226 public ByteArray getPreparedLog() 227 { 228 return (this.preparedLog); 229 } 230 231 237 private void writeOptionalDataToBuffer(RawTransaction t, boolean needDataLogged) 238 throws StandardException, IOException 239 { 240 241 if (SanityManager.DEBUG) { 242 SanityManager.ASSERT(this.page != null); 243 } 244 245 DynamicByteArrayOutputStream logBuffer = t.getLogBuffer(); 246 int optionalDataStart = logBuffer.getPosition(); 247 248 if (SanityManager.DEBUG) { 249 SanityManager.ASSERT(optionalDataStart == 0, 250 "Buffer for writing the optional data should start at position 0"); 251 } 252 253 for (int i = 0; i < num_rows; i++) 254 { 255 if(needDataLogged) 256 { 257 this.page.logRecord(i+slot, BasePage.LOG_RECORD_DEFAULT, 258 recordIds[i], (FormatableBitSet) null, logBuffer, 259 (RecordHandle)null); 260 }else 261 { 262 this.page.logRecord(i+slot, BasePage.LOG_RECORD_FOR_PURGE, 263 recordIds[i], (FormatableBitSet) null, logBuffer, 264 (RecordHandle)null); 265 } 266 } 267 268 int optionalDataLength = logBuffer.getPosition() - optionalDataStart; 269 270 if (SanityManager.DEBUG) { 271 if (optionalDataLength != logBuffer.getUsed()) 272 SanityManager.THROWASSERT("wrong optional data length, optionalDataLength = " 273 + optionalDataLength + ", logBuffer.getUsed() = " + logBuffer.getUsed()); 274 } 275 276 logBuffer.setPosition(optionalDataStart); 278 279 this.preparedLog = new ByteArray(logBuffer.getByteArray(), optionalDataStart, 280 optionalDataLength); 281 } 282 283 286 public String toString() 287 { 288 if (SanityManager.DEBUG) 289 { 290 String str = super.toString() + 291 "Purge : " + num_rows + " slots starting at " + slot; 292 293 for (int i = 0; i < num_rows; i++) 294 { 295 str += " (recordId=" + recordIds[i] + ")"; 296 } 297 return str; 298 } 299 else 300 return null; 301 } 302 } 303 | Popular Tags |