1 21 22 package org.apache.derby.impl.store.access.heap; 23 24 import org.apache.derby.iapi.services.context.ContextManager; 25 import org.apache.derby.iapi.services.daemon.Serviceable; 26 import org.apache.derby.iapi.services.monitor.Monitor; 27 import org.apache.derby.iapi.services.sanity.SanityManager; 28 import org.apache.derby.iapi.error.StandardException; 29 30 import org.apache.derby.iapi.store.access.conglomerate.TransactionManager; 31 32 import org.apache.derby.iapi.store.access.AccessFactory; 33 import org.apache.derby.iapi.store.access.AccessFactoryGlobals; 34 35 import org.apache.derby.iapi.store.access.ConglomerateController; 36 import org.apache.derby.iapi.store.access.DynamicCompiledOpenConglomInfo; 37 import org.apache.derby.iapi.store.access.Qualifier; 38 import org.apache.derby.iapi.store.access.RowUtil; 39 import org.apache.derby.iapi.store.access.TransactionController; 40 41 import org.apache.derby.iapi.store.raw.ContainerHandle; 42 import org.apache.derby.iapi.store.raw.FetchDescriptor; 43 import org.apache.derby.iapi.store.raw.LockingPolicy; 44 import org.apache.derby.iapi.store.raw.Page; 45 import org.apache.derby.iapi.store.raw.RecordHandle; 46 import org.apache.derby.iapi.store.raw.Transaction; 47 48 import org.apache.derby.iapi.reference.SQLState; 49 50 72 73 class HeapPostCommit implements Serviceable 74 { 75 79 80 private AccessFactory access_factory = null; 81 private Heap heap = null; 82 private long page_number = ContainerHandle.INVALID_PAGE_NUMBER; 83 84 85 89 HeapPostCommit( 90 AccessFactory access_factory, 91 Heap heap, 92 long input_page_number) 93 { 94 this.access_factory = access_factory; 95 this.heap = heap; 96 this.page_number = input_page_number; 97 } 98 99 103 104 122 private final void purgeCommittedDeletes( 123 HeapController heap_control, 124 long pageno) 125 throws StandardException 126 { 127 130 132 Page page = heap_control.getUserPageWait(pageno); 134 boolean purgingDone = false; 135 136 if (page != null) 137 { 138 try 139 { 140 int num_possible_commit_delete = 143 page.recordCount() - page.nonDeletedRecordCount(); 144 145 if (num_possible_commit_delete > 0) 146 { 147 for (int slot_no = page.recordCount() - 1; 151 slot_no >= 0; 152 slot_no--) 153 { 154 boolean row_is_committed_delete = 155 page.isDeletedAtSlot(slot_no); 156 157 if (row_is_committed_delete) 158 { 159 162 168 RecordHandle rh = 169 page.fetchFromSlot( 170 (RecordHandle) null, 171 slot_no, 172 RowUtil.EMPTY_ROW, 173 RowUtil.EMPTY_ROW_FETCH_DESCRIPTOR, 174 true); 175 176 row_is_committed_delete = 177 heap_control.lockRowAtSlotNoWaitExclusive(rh); 178 179 if (row_is_committed_delete) 180 { 181 purgingDone = true; 182 183 page.purgeAtSlot(slot_no, 1, false); 184 185 if (SanityManager.DEBUG) 186 { 187 if (SanityManager.DEBUG_ON( 188 "verbose_heap_post_commit")) 189 { 190 SanityManager.DEBUG_PRINT( 191 "HeapPostCommit", 192 "Purging row[" + slot_no + "]" + 193 "on page:" + pageno + ".\n"); 194 } 195 } 196 } 197 } 198 } 199 } 200 if (page.recordCount() == 0) 201 { 202 purgingDone = true; 203 204 heap_control.removePage(page); 206 207 214 if (SanityManager.DEBUG) 215 { 216 if (SanityManager.DEBUG_ON("verbose_heap_post_commit")) 217 { 218 SanityManager.DEBUG_PRINT( 219 "HeapPostCommit", 220 "Calling Heap removePage().; pagenumber="+pageno+"\n"); 221 } 222 } 223 } 224 } 225 finally 226 { 227 if (!purgingDone) 231 { 232 page.unlatch(); 233 page = null; 234 } 235 } 236 } 237 else 238 { 239 if (SanityManager.DEBUG) 240 { 241 if (SanityManager.DEBUG_ON("verbose_heap_post_commit")) 242 { 243 SanityManager.DEBUG_PRINT( 244 "HeapPostCommit", 245 "Get No Wait returned null. page num = " + 246 pageno + "\n"); 247 248 SanityManager.showTrace(new Throwable ()); 249 } 250 } 251 } 252 return; 253 } 254 255 259 260 269 public boolean serviceASAP() 270 { 271 return(true); 272 } 273 274 public boolean serviceImmediately() 276 { 277 return false; 278 } 279 280 281 295 public int performWork(ContextManager contextMgr) 296 throws StandardException 297 { 298 TransactionManager tc = (TransactionManager) 299 this.access_factory.getAndNameTransaction( 300 contextMgr, AccessFactoryGlobals.SYS_TRANS_NAME); 301 302 TransactionManager internal_xact = tc.getInternalTransaction(); 303 304 boolean requeue_work = false; 306 307 HeapController heapcontroller; 308 309 if (SanityManager.DEBUG) 310 { 311 if (SanityManager.DEBUG_ON("verbose_heap_post_commit")) 312 SanityManager.DEBUG_PRINT( 313 "HeapPostCommit", "starting internal xact\n"); 314 } 315 316 try 317 { 318 326 332 heapcontroller = (HeapController) 333 heap.open( 334 internal_xact, 335 internal_xact.getRawStoreXact(), 336 false, 337 ContainerHandle.MODE_FORUPDATE | 338 ContainerHandle.MODE_LOCK_NOWAIT, 339 TransactionController.MODE_RECORD, 340 internal_xact.getRawStoreXact().newLockingPolicy( 341 LockingPolicy.MODE_RECORD, 342 TransactionController.ISOLATION_REPEATABLE_READ, true), 343 heap, 344 (DynamicCompiledOpenConglomInfo) null); 345 346 349 purgeCommittedDeletes(heapcontroller, this.page_number); 351 352 } 353 catch (StandardException se) 354 { 355 361 if (se.getMessageId().equals(SQLState.LOCK_TIMEOUT) || 363 se.getMessageId().equals(SQLState.DEADLOCK)) 364 { 365 requeue_work = true; 366 } 367 368 } 373 374 380 internal_xact.commitNoSync(Transaction.RELEASE_LOCKS); 381 internal_xact.destroy(); 382 383 384 if (SanityManager.DEBUG) 385 { 386 if (SanityManager.DEBUG_ON("verbose_heap_post_commit")) 387 { 388 if (requeue_work) 389 SanityManager.DEBUG_PRINT( 390 "HeapPostCommit", 391 "requeueing on page num = " + page_number); 392 } 393 } 394 395 return(requeue_work ? Serviceable.REQUEUE : Serviceable.DONE); 396 } 397 } 398 399 | Popular Tags |