1 21 22 package org.apache.derby.impl.store.access.btree; 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.AccessFactory; 31 import org.apache.derby.iapi.store.access.AccessFactoryGlobals; 32 import org.apache.derby.iapi.store.access.ConglomerateController; 33 import org.apache.derby.iapi.store.access.DynamicCompiledOpenConglomInfo; 34 import org.apache.derby.iapi.store.access.TransactionController; 35 import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo; 36 import org.apache.derby.iapi.store.access.conglomerate.TransactionManager; 37 38 import org.apache.derby.iapi.store.access.Qualifier; 39 40 import org.apache.derby.iapi.store.raw.ContainerHandle; 41 import org.apache.derby.iapi.store.raw.FetchDescriptor; 42 import org.apache.derby.iapi.store.raw.LockingPolicy; 43 import org.apache.derby.iapi.store.raw.Page; 44 import org.apache.derby.iapi.store.raw.RecordHandle; 45 import org.apache.derby.iapi.store.raw.Transaction; 46 47 import org.apache.derby.iapi.types.DataValueDescriptor; 48 49 import org.apache.derby.iapi.services.io.FormatableBitSet; 50 import org.apache.derby.iapi.reference.SQLState; 51 52 65 66 class BTreePostCommit implements Serviceable 67 { 68 private AccessFactory access_factory = null; 69 private long page_number = ContainerHandle.INVALID_PAGE_NUMBER; 70 71 protected BTree btree = null; 72 73 74 BTreePostCommit( 75 AccessFactory access_factory, 76 BTree btree, 77 long input_page_number) 78 { 79 this.access_factory = access_factory; 80 this.btree = btree; 81 this.page_number = input_page_number; 82 } 83 84 85 86 87 88 89 90 99 public boolean serviceASAP() 100 { 101 return(true); 102 } 103 104 105 public boolean serviceImmediately() 107 { 108 return false; 109 } 110 111 private final void doShrink( 112 OpenBTree open_btree, 113 DataValueDescriptor[] shrink_row) 114 throws StandardException 115 { 116 ControlRow root = null; 117 118 123 124 root = ControlRow.Get(open_btree, BTree.ROOTPAGEID); 127 128 root.shrinkFor(open_btree, shrink_row); 129 130 root = null; 131 132 136 return; 137 } 138 139 154 public int performWork(ContextManager contextMgr) 155 throws StandardException 156 { 157 158 boolean requeue_work = false; 160 161 TransactionManager tc = (TransactionManager) 162 this.access_factory.getAndNameTransaction( 163 contextMgr, AccessFactoryGlobals.SYS_TRANS_NAME); 164 165 TransactionManager internal_xact = tc.getInternalTransaction(); 166 167 if (SanityManager.DEBUG) 168 { 169 if (SanityManager.DEBUG_ON("verbose_btree_post_commit")) 170 System.out.println("starting internal xact\n"); 171 } 172 173 OpenBTree open_btree = new OpenBTree(); 174 175 try 176 { 177 179 ConglomerateController base_cc = 193 btree.lockTable( 194 internal_xact, 195 (ContainerHandle.MODE_FORUPDATE | 196 ContainerHandle.MODE_LOCK_NOWAIT), 197 TransactionController.MODE_TABLE, 198 TransactionController.ISOLATION_REPEATABLE_READ); 199 200 open_btree.init( 201 (TransactionManager) null, 202 internal_xact, 203 (ContainerHandle) null, internal_xact.getRawStoreXact(), 205 false, 206 ContainerHandle.MODE_FORUPDATE, 207 TransactionController.MODE_TABLE, 208 btree.getBtreeLockingPolicy( 209 internal_xact.getRawStoreXact(), 210 TransactionController.MODE_TABLE, 211 LockingPolicy.MODE_CONTAINER, 212 TransactionController.ISOLATION_REPEATABLE_READ, 213 base_cc, 214 open_btree), 215 btree, 216 (LogicalUndo) null, (DynamicCompiledOpenConglomInfo) null); 218 219 DataValueDescriptor[] shrink_key = 220 purgeCommittedDeletes(open_btree, this.page_number); 221 222 if (shrink_key != null) 224 doShrink(open_btree, shrink_key); 225 226 open_btree.close(); 227 } 228 catch (StandardException se) 229 { 230 231 232 238 240 if (se.getMessageId().equals(SQLState.LOCK_TIMEOUT) || 241 se.getMessageId().equals(SQLState.DEADLOCK)) 242 { 243 requeue_work = true; 244 } 245 246 252 253 } 254 finally 255 { 256 internal_xact.commit(); 257 internal_xact.destroy(); 258 } 259 260 return(requeue_work ? Serviceable.REQUEUE : Serviceable.DONE); 261 } 262 263 private final DataValueDescriptor[] getShrinkKey( 264 OpenBTree open_btree, 265 ControlRow control_row, 266 int slot_no) 267 throws StandardException 268 { 269 DataValueDescriptor[] shrink_key = 270 open_btree.getConglomerate().createTemplate(); 271 272 control_row.page.fetchFromSlot( 273 (RecordHandle) null, 274 slot_no, shrink_key, 275 (FetchDescriptor) null, 276 true); 277 278 return(shrink_key); 279 } 280 281 298 private final DataValueDescriptor[] purgeCommittedDeletes( 299 OpenBTree open_btree, 300 long pageno) 301 throws StandardException 302 { 303 ControlRow control_row = null; 304 DataValueDescriptor[] shrink_key = null; 305 306 try 307 { 308 control_row = ControlRow.GetNoWait(open_btree, pageno); 312 313 if (control_row != null) 314 { 315 Page page = control_row.page; 316 317 int num_possible_commit_delete = 320 page.recordCount() - 1 - page.nonDeletedRecordCount(); 321 322 if (num_possible_commit_delete > 0) 323 { 324 for (int slot_no = page.recordCount() - 1; 328 slot_no > 0; 329 slot_no--) 330 { 331 if (page.isDeletedAtSlot(slot_no)) 332 { 333 334 if (page.recordCount() == 2) 335 { 336 shrink_key = this.getShrinkKey( 340 open_btree, control_row, slot_no); 341 } 342 343 page.purgeAtSlot(slot_no, 1, true); 344 345 if (SanityManager.DEBUG) 346 { 347 if (SanityManager.DEBUG_ON( 348 "verbose_btree_post_commit")) 349 { 350 System.out.println( 351 "Purging row[" + slot_no + "]" + 352 "on page:" + pageno + ".\n"); 353 } 354 } 355 } 356 } 357 } 358 359 if (page.recordCount() == 1) 360 { 361 if (SanityManager.DEBUG) 362 { 363 if (SanityManager.DEBUG_ON("verbose_btree_post_commit")) 364 { 365 System.out.println("Chance to shrink.\n"); 366 } 367 } 368 } 369 } 370 else 371 { 372 if (SanityManager.DEBUG) 373 { 374 if (SanityManager.DEBUG_ON("verbose_btree_post_commit")) 375 { 376 System.out.println( 377 "Get No Wait returned null. page num = " + pageno + 378 "\n"); 379 } 380 } 381 } 382 } 383 finally 384 { 385 if (control_row != null) 386 control_row.release(); 387 } 388 389 return(shrink_key); 390 } 391 392 } 393 | Popular Tags |