1 21 22 package org.apache.derby.impl.store.raw.data; 23 24 import org.apache.derby.impl.store.raw.data.BasePage; 25 import org.apache.derby.impl.store.raw.data.ReclaimSpace; 26 27 28 import org.apache.derby.iapi.services.daemon.DaemonService; 29 import org.apache.derby.iapi.services.daemon.Serviceable; 30 import org.apache.derby.iapi.services.sanity.SanityManager; 31 import org.apache.derby.iapi.error.StandardException; 32 33 import org.apache.derby.iapi.store.access.TransactionController; 34 35 import org.apache.derby.iapi.store.raw.ContainerKey; 36 import org.apache.derby.iapi.store.raw.ContainerHandle; 37 import org.apache.derby.iapi.store.raw.LockingPolicy; 38 import org.apache.derby.iapi.store.raw.Page; 39 import org.apache.derby.iapi.store.raw.PageKey; 40 import org.apache.derby.iapi.store.raw.RecordHandle; 41 import org.apache.derby.iapi.store.raw.Transaction; 42 43 import org.apache.derby.iapi.store.raw.xact.RawTransaction; 44 import org.apache.derby.iapi.store.raw.data.RawContainerHandle; 45 46 47 218 public class ReclaimSpaceHelper 219 { 220 223 public static int reclaimSpace(BaseDataFileFactory dataFactory, 224 RawTransaction tran, 225 ReclaimSpace work) 226 throws StandardException 227 { 228 229 if (work.reclaimWhat() == ReclaimSpace.CONTAINER) 230 return reclaimContainer(dataFactory, tran, work); 231 232 236 LockingPolicy container_rlock = 237 tran.newLockingPolicy(LockingPolicy.MODE_RECORD, 238 TransactionController.ISOLATION_SERIALIZABLE, 239 true ); 240 241 if (SanityManager.DEBUG) 242 SanityManager.ASSERT(container_rlock != null); 243 244 ContainerHandle containerHdl = 245 openContainerNW(tran, container_rlock, work.getContainerId()); 246 247 if (containerHdl == null) 248 { 249 tran.abort(); 250 251 if (SanityManager.DEBUG) 252 { 253 if (SanityManager.DEBUG_ON(DaemonService.DaemonTrace)) 254 { 255 SanityManager.DEBUG( 256 DaemonService.DaemonTrace, " aborted " + work + 257 " because container is locked or dropped"); 258 } 259 } 260 261 if (work.incrAttempts() < 3) return Serviceable.REQUEUE; 263 else 264 return Serviceable.DONE; 265 } 266 267 269 if (work.reclaimWhat() == ReclaimSpace.PAGE) 270 { 271 Page p = containerHdl.getPageNoWait(work.getPageId().getPageNumber()); 277 if (p != null) 278 containerHdl.removePage(p); 279 280 tran.commit(); 281 return Serviceable.DONE; 282 } 283 284 RecordHandle headRecord = work.getHeadRowHandle(); 287 288 if (!container_rlock.lockRecordForWrite( 289 tran, headRecord, false , false )) 290 { 291 tran.abort(); 293 if (work.incrAttempts() < 3) 294 return Serviceable.REQUEUE; 295 else 296 return Serviceable.DONE; 297 } 298 299 301 if (work.reclaimWhat() == ReclaimSpace.ROW_RESERVE) 302 { 303 containerHdl.compactRecord(headRecord); 305 306 tran.commitNoSync(Transaction.RELEASE_LOCKS); 322 323 return Serviceable.DONE; 324 } 325 else 326 { 327 if (SanityManager.DEBUG) 328 SanityManager.ASSERT(work.reclaimWhat() == ReclaimSpace.COLUMN_CHAIN); 329 330 long headPageId = ((PageKey)headRecord.getPageId()).getPageNumber(); 335 StoredPage headRowPage = 336 (StoredPage)containerHdl.getPageNoWait(headPageId); 337 338 if (headRowPage == null) 339 { 340 tran.abort(); 342 if (work.incrAttempts() < 3) 343 return Serviceable.REQUEUE; 344 else 345 return Serviceable.DONE; 346 } 347 348 try 349 { 350 headRowPage.removeOrphanedColumnChain(work, containerHdl); 351 } 352 finally 353 { 354 headRowPage.unlatch(); 355 } 356 357 tran.commitNoSync(Transaction.RELEASE_LOCKS); 373 374 return Serviceable.DONE; 375 } 376 } 377 378 private static int reclaimContainer(BaseDataFileFactory dataFactory, 379 RawTransaction tran, 380 ReclaimSpace work) 381 throws StandardException 382 { 383 386 LockingPolicy container_xlock = 387 tran.newLockingPolicy(LockingPolicy.MODE_CONTAINER, 388 TransactionController.ISOLATION_SERIALIZABLE, 389 true ); 390 391 if (SanityManager.DEBUG) 392 SanityManager.ASSERT(container_xlock != null); 393 394 RawContainerHandle containerHdl = tran.openDroppedContainer( 397 work.getContainerId(), 398 container_xlock); 399 400 if (containerHdl == null || 403 containerHdl.getContainerStatus() == RawContainerHandle.NORMAL || 404 containerHdl.getContainerStatus() == RawContainerHandle.COMMITTED_DROP) 405 { 406 if (containerHdl != null) 407 containerHdl.close(); 408 tran.abort(); 410 if (SanityManager.DEBUG) 411 { 412 if (SanityManager.DEBUG_ON(DaemonService.DaemonTrace)) 413 { 414 SanityManager.DEBUG( 415 DaemonService.DaemonTrace, " aborted " + work); 416 } 417 } 418 } 419 else 420 { 421 ContainerOperation lop = new 424 ContainerOperation(containerHdl, ContainerOperation.REMOVE); 425 426 containerHdl.preDirty(true); 430 try 431 { 432 tran.logAndDo(lop); 433 } 434 finally 435 { 436 containerHdl.preDirty(false); 439 } 440 441 442 containerHdl.close(); 443 tran.commit(); 444 445 if (SanityManager.DEBUG) 446 { 447 if (SanityManager.DEBUG_ON(DaemonService.DaemonTrace)) 448 { 449 SanityManager.DEBUG( 450 DaemonService.DaemonTrace, " committed " + work); 451 } 452 } 453 } 454 455 return Serviceable.DONE; 456 457 } 458 459 460 463 private static ContainerHandle openContainerNW(Transaction tran, 464 LockingPolicy rlock, ContainerKey containerId) 465 throws StandardException 466 { 467 ContainerHandle containerHdl = tran.openContainer 468 (containerId, rlock, 469 ContainerHandle.MODE_FORUPDATE | 470 ContainerHandle.MODE_LOCK_NOWAIT); 471 472 return containerHdl; 473 } 474 475 } 476 | Popular Tags |