Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/OpenBTree.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/OpenBTree.java?rev=754894&r1=754893&r2=754894&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/OpenBTree.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/OpenBTree.java Mon Mar 16 13:55:49 2009 @@ -110,15 +110,7 @@ **/ protected long err_containerid; - /** - In the case of splits, notify all scans in this transaction to save their - current position by key, because the split may move the row they are - positioned on. This is done by calling open_user_scans.saveScanPositions(). - Note that not all OpenBTree's will have a non-null open_user_scans. For - instance logical undo of btree operations will get a OpenBTree with a null - open_user_scans, this is all right because this operation should never need - to call saveScanPositions() (ie. it will never do a split). - **/ + /** The user transaction that opened this B-tree. */ protected TransactionManager init_open_user_scans = null; @@ -427,7 +419,6 @@ init_hold = hold; - // Remember the transaction manager so saveScanPositions() can be called this.init_open_user_scans = open_user_scans; // Logical undo class to pass to raw store, on inserts/deletes. @@ -618,6 +609,8 @@ * hard to cause paths through the code. *

* + * @param pos the current scan position if the condition simulated by + * this call would have resulted in the position being saved * @return whether the latch has been released by this routine. * * @exception StandardException Standard exception policy. @@ -625,7 +618,7 @@ public static boolean test_errors( OpenBTree open_btree, String debug_string, - boolean release_scan_lock, + BTreeRowPosition pos, BTreeLockingPolicy btree_locking_policy, LeafControlRow leaf, boolean input_latch_released) @@ -643,12 +636,12 @@ // Simulate a lost latch because of a wait for a lock. if (!latch_released) { - if (release_scan_lock) - { - btree_locking_policy.unlockScan( - leaf.page.getProtectionRecordHandle()); + if (pos != null) { + SanityManager.ASSERT(pos.current_leaf == leaf); + pos.saveMeAndReleasePage(); + } else { + leaf.release(); } - leaf.release(); latch_released = true; SanityManager.DEBUG_PRINT( Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/index/B2INoLocking.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/index/B2INoLocking.java?rev=754894&r1=754893&r2=754894&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/index/B2INoLocking.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/index/B2INoLocking.java Mon Mar 16 13:55:49 2009 @@ -83,53 +83,11 @@ /************************************************************************** * Abstract Protected lockScan*() locking methods of BTree: - * lockScan - lock the scan page - * lockScanForReclaimSpace - lock page for reclaiming deleted rows. - * lockScanRow - lock row and possibly the scan page - * unlockScan - unlock the scan page + * lockScanRow - lock row * unlockScanRecordAfterRead- unlock the scan record ************************************************************************** */ - - /** - * Lock a control row page for scan. - *

- * See BTree.lockScan() for more info. - * - * @exception StandardException Standard exception policy. - **/ - public boolean lockScan( - LeafControlRow current_leaf, - ControlRow aux_control_row, - boolean forUpdate, - int lock_operation) - throws StandardException - { - return(true); - } - - /** - * Lock a control row page for reclaiming deleted rows. - *

- * When reclaiming deleted rows during split need to get an exclusive - * scan lock on the page, which will mean there are no other scans - * positioned on the page. If there are other scans positioned, just - * give up on reclaiming space now. - * - * @return true if lock was granted nowait, else false and not lock was - * granted. - * - * @exception StandardException Standard exception policy. - **/ - public boolean lockScanForReclaimSpace( - LeafControlRow current_leaf) - throws StandardException - { - // if doing no locking don't allow reclaiming space. - return(false); - } - /** * Lock a btree row to determine if it is a committed deleted row. *

@@ -159,22 +117,16 @@ * Lock a row as part of doing the scan. *

* Lock the row at the given slot (or the previous row if slot is 0). - * Get the scan lock on the page if "request_scan_lock" is true. *

* If this routine returns true all locks were acquired while maintaining * the latch on leaf. If this routine returns false, locks may or may * not have been acquired, and the routine should be called again after * the client has researched the tree to reget the latch on the * appropriate page. - * (p> - * As a sided effect stores the value of the record handle of the current - * scan lock. * * @return Whether locks were acquired without releasing latch on leaf. * * @param pos The position of the row to lock. - * @param request_scan_lock Whether to request the page scan lock, should - * only be requested once per page in the scan. * * @exception StandardException Standard exception policy. **/ @@ -182,7 +134,6 @@ OpenBTree open_btree, BTree btree, BTreeRowPosition pos, - boolean request_scan_lock, FetchDescriptor lock_fetch_desc, DataValueDescriptor[] lock_template, RowLocation lock_row_loc, @@ -210,16 +161,6 @@ } - /** - * Unlock the lock gotten by lockScan(). - *

- * See BTree.unlockScan() for more info. - * - **/ - public void unlockScan(RecordHandle protectionHandle) - { - } - /************************************************************************** * Abstract Protected lockNonScan*() locking methods of BTree: * Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/index/B2IRowLocking1.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/index/B2IRowLocking1.java?rev=754894&r1=754893&r2=754894&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/index/B2IRowLocking1.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/index/B2IRowLocking1.java Mon Mar 16 13:55:49 2009 @@ -79,18 +79,8 @@ /************************************************************************** * Abstract Protected lockScan*() locking methods of BTree: - * lockScan - lock the scan page - * (inherit from B2IRowLocking2, we still - * get page control locks). - * lockScanForReclaimSpace - lock page for reclaiming deleted rows. - * (inherit from B2IRowLocking2, should never - * be called while in read uncommitted). - * lockScanRow - lock row and possibly the scan page, only - * if row is forUpdate and not a previous key - * lock. - * unlockScan - unlock the scan page - * (inherit from B2IRowLocking2, should never - * be called while in read uncommitted). + * lockScanRow - lock row, only if row is forUpdate and + * not a previous key lock. * unlockScanRecordAfterRead- unlock the scan record if we locked it in * lockScanRow. * @@ -103,16 +93,12 @@ * Lock a row as part of doing the scan. *

* Lock the row at the given slot (or the previous row if slot is 0). - * Get the scan lock on the page if "request_scan_lock" is true. *

* If this routine returns true all locks were acquired while maintaining * the latch on leaf. If this routine returns false, locks may or may * not have been acquired, and the routine should be called again after * the client has researched the tree to reget the latch on the * appropriate page. - * (p> - * As a side effect stores the value of the record handle of the current - * scan lock. * * @return Whether locks were acquired without releasing latch on leaf. * @@ -120,8 +106,6 @@ * used if routine has to scan backward. * @param btree the conglomerate info. * @param pos The position of the row to lock. - * @param request_scan_lock Whether to request the page scan lock, should - * only be requested once per page in the scan. * @param lock_template A scratch area to use to read in rows. * @param previous_key_lock Is this a previous key lock call? * @param forUpdate Is the scan for update or for read only. @@ -132,7 +116,6 @@ OpenBTree open_btree, BTree btree, BTreeRowPosition pos, - boolean request_scan_lock, FetchDescriptor lock_fetch_desc, DataValueDescriptor[] lock_template, RowLocation lock_row_loc, @@ -141,7 +124,6 @@ int lock_operation) throws StandardException { - // request the scan lock if necessary. // only get the row lock if it is not a previous key lock and iff // it is an update lock. return( @@ -150,7 +132,6 @@ btree, pos, (forUpdate && !previous_key_lock), // only get update row lock - request_scan_lock, lock_fetch_desc, lock_template, lock_row_loc, previous_key_lock, forUpdate, Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/index/B2IRowLocking2.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/index/B2IRowLocking2.java?rev=754894&r1=754893&r2=754894&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/index/B2IRowLocking2.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/index/B2IRowLocking2.java Mon Mar 16 13:55:49 2009 @@ -83,8 +83,6 @@ { SanityManager.ASSERT(open_btree != null, "open_btree is null"); - SanityManager.ASSERT(pos.current_leaf != null , "leaf is null"); - SanityManager.ASSERT( pos.current_lock_row_loc != null , "pos.current_lock_row_loc is null"); Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/index/B2IRowLocking3.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/index/B2IRowLocking3.java?rev=754894&r1=754893&r2=754894&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/index/B2IRowLocking3.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/index/B2IRowLocking3.java Mon Mar 16 13:55:49 2009 @@ -29,8 +29,6 @@ import org.apache.derby.iapi.store.access.ConglomerateController; -import org.apache.derby.iapi.store.access.TransactionController; - import org.apache.derby.iapi.store.raw.FetchDescriptor; import org.apache.derby.iapi.store.raw.LockingPolicy; import org.apache.derby.iapi.store.raw.RecordHandle; @@ -77,12 +75,6 @@ protected OpenBTree open_btree; /** - * The locking policy to use to get and release the scan locks. We could - * cache this somewhere better. - **/ - private LockingPolicy scan_locking_policy; - - /** * The transaction to associate lock requests with. **/ private Transaction rawtran; @@ -101,10 +93,6 @@ this.rawtran = rawtran; this.base_cc = base_cc; this.open_btree = open_btree; - this.scan_locking_policy = - rawtran.newLockingPolicy( - LockingPolicy.MODE_RECORD, - TransactionController.ISOLATION_READ_COMMITTED, true); } /************************************************************************** @@ -112,33 +100,6 @@ ************************************************************************** */ - private boolean _lockScan( - RecordHandle rh, - boolean forUpdate, - boolean wait) - throws StandardException - { - boolean ret_val = true; - - // only get the scan lock if we are record locking. - - if (!forUpdate) - { - ret_val = - scan_locking_policy.lockRecordForRead( - rawtran, open_btree.getContainerHandle(), - rh, wait, false); - } - else - { - ret_val = - scan_locking_policy.lockRecordForWrite( - rawtran, rh, false, wait); - } - - return(ret_val); - } - /** * Lock key previous to first key in btree. *

@@ -247,8 +208,8 @@ * @param current_slot Slot of row to lock. * @param lock_fetch_desc Descriptor for fetching just the RowLocation, * used for locking. - * @param check_changed_rowloc - * whether to check for the changed rowloc or not. + * @param position The position to lock if the lock is requested + * while performing a scan, null otherwise. * @param lock_operation Whether lock is for key prev to insert or not. * @param lock_duration For what duration should the lock be held, * if INSTANT_DURATION, then the routine will @@ -265,7 +226,7 @@ LeafControlRow current_leaf, LeafControlRow aux_leaf, int current_slot, - boolean check_changed_rowloc, + BTreeRowPosition position, FetchDescriptor lock_fetch_desc, DataValueDescriptor[] lock_template, RowLocation lock_row_loc, @@ -302,6 +263,11 @@ SanityManager.ASSERT( lock_row_loc == lock_template[lock_template.length - 1], "row_loc is not the object in last column of lock_template."); + + if (position != null) { + SanityManager.ASSERT(current_leaf == position.current_leaf); + SanityManager.ASSERT(current_slot == position.current_slot); + } } // Fetch the row location to lock. @@ -321,8 +287,16 @@ { // Could not get the lock NOWAIT, release latch and wait for lock. - if (current_leaf != null) + if (position != null) { + // since we're releasing the lock in the middle of a scan, + // save the current position of the scan before releasing the + // latch + position.saveMeAndReleasePage(); + } + else if (current_leaf != null) + { + // otherwise, just release the latch current_leaf.release(); current_leaf = null; } @@ -436,7 +410,7 @@ prev_leaf, current_leaf, prev_leaf.getPage().recordCount() - 1, - false, + null, lock_fetch_desc, lock_template, lock_row_loc, @@ -535,16 +509,12 @@ * Lock a row as part of doing the scan. *

* Lock the row at the given slot (or the previous row if slot is 0). - * Get the scan lock on the page if "request_scan_lock" is true. *

* If this routine returns true all locks were acquired while maintaining * the latch on leaf. If this routine returns false, locks may or may * not have been acquired, and the routine should be called again after * the client has researched the tree to reget the latch on the * appropriate page. - * (p> - * As a sided effect stores the value of the record handle of the current - * scan lock. * * @return Whether locks were acquired without releasing latch on leaf. * @@ -554,8 +524,6 @@ * @param pos The position of the row to lock. * @param request_row_lock Whether to request the row lock, should * only be requested once per page in the scan. - * @param request_scan_lock Whether to request the page scan lock, should - * only be requested once per page in the scan. * @param lock_fetch_desc The fetch descriptor to use to fetch the * row location for the lock request. * @param lock_template A scratch area to use to read in rows. @@ -569,7 +537,6 @@ BTree btree, BTreeRowPosition pos, boolean request_row_lock, - boolean request_scan_lock, FetchDescriptor lock_fetch_desc, DataValueDescriptor[] lock_template, RowLocation lock_row_loc, @@ -617,7 +584,11 @@ latch_released = OpenBTree.test_errors( open_btree, - "B2iRowLocking3_1_lockScanRow", false, + "B2iRowLocking3_1_lockScanRow", + null, // Don't save position since the operation + // will be retried if the latch was released. + // See also comment above call to + // lockNonScanPreviousRow(). this, pos.current_leaf, latch_released); } } @@ -631,7 +602,7 @@ pos.current_leaf, (LeafControlRow) null /* no other latch currently */, pos.current_slot, - true, + pos, lock_fetch_desc, lock_template, lock_row_loc, @@ -644,40 +615,12 @@ latch_released = OpenBTree.test_errors( open_btree, - "B2iRowLocking3_2_lockScanRow", false, + "B2iRowLocking3_2_lockScanRow", pos, this, pos.current_leaf, latch_released); } } } - if (request_scan_lock && !latch_released) - { - // Get the scan lock on the start page. - - // Get shared RECORD_ID_PROTECTION_HANDLE lock to make sure that - // we wait for scans in other transactions to move off of this page - // before we split. - - - latch_released = - !lockScan( - pos.current_leaf, - (LeafControlRow) null, // no other latch currently - false, - ConglomerateController.LOCK_READ);// read scan lock position - - // special test to see if latch release code works - if (SanityManager.DEBUG) - { - /* RESOLVE - need to get a container here */ - latch_released = - OpenBTree.test_errors( - open_btree, - "B2iRowLocking3_3_lockScanRow", true, - this, pos.current_leaf, latch_released); - } - } - return(!latch_released); } @@ -689,106 +632,12 @@ /************************************************************************** * Abstract Protected lockScan*() locking methods of BTree: - * lockScan - lock the scan page - * lockScanForReclaimSpace - lock page for reclaiming deleted rows. - * lockScanRow - lock row and possibly the scan page - * unlockScan - unlock the scan page + * lockScanRow - lock row * unlockScanRecordAfterRead- unlock the scan record ************************************************************************** */ /** - * Lock a control row page for scan. - *

- * Scanners get shared lock on the page while positioned on a row within - * the page, splitter/purgers/mergers get exclusive lock on the page. - * - * See BTree.lockScan() for more info. - * - * @exception StandardException Standard exception policy. - **/ - public boolean lockScan( - LeafControlRow current_leaf, - ControlRow aux_control_row, - boolean forUpdate, - int lock_operation) - throws StandardException - { - // The scan page lock is implemented as a row lock on the reserved - // row id on the page (RecordHandle.RECORD_ID_PROTECTION_HANDLE). - RecordHandle scan_lock_rh = - current_leaf.getPage().getProtectionRecordHandle(); - - // First try to get the lock NOWAIT, while latch is held. - boolean ret_status = - _lockScan(scan_lock_rh, forUpdate, false /* NOWAIT */); - - if (!ret_status) - { - current_leaf.release(); - current_leaf = null; - - if (aux_control_row != null) - { - aux_control_row.release(); - aux_control_row = null; - } - - // Could not get the lock NOWAIT, release latch and wait - // for the lock. - _lockScan(scan_lock_rh, forUpdate, true /* WAIT */); - - // once we get the lock, give it up as we need to get the lock - // while we have the latch. When the lock manager gives us the - // ability to do instantaneous locks do that. We just wait on the - // lock to give the split a chance to finish before we interfere. - - if (!forUpdate) - { - scan_locking_policy.unlockRecordAfterRead( - rawtran, open_btree.getContainerHandle(), - scan_lock_rh, false, true); - } - else - { - // RESOLVE - need instantaneous locks as there is no way - // currently to release a write lock. This lock will only - // be requested by split, and will be released by internal - // transaction. - } - } - - return(ret_status); - } - - /** - * Lock a control row page for reclaiming deleted rows. - *

- * When reclaiming deleted rows during split need to get an exclusive - * scan lock on the page, which will mean there are no other scans - * positioned on the page. If there are other scans positioned, just - * give up on reclaiming space now. - * - * @return true if lock was granted nowait, else false and not lock was - * granted. - * - * @exception StandardException Standard exception policy. - **/ - public boolean lockScanForReclaimSpace( - LeafControlRow current_leaf) - throws StandardException - { - // The scan page lock is implemented as a row lock on the reserved - // row id on the page (RecordHandle.RECORD_ID_PROTECTION_HANDLE). - RecordHandle scan_lock_rh = - current_leaf.getPage().getProtectionRecordHandle(); - - // First try to get the lock NOWAIT, while latch is held. - return( - _lockScan(scan_lock_rh, true /* update */, false /* NOWAIT */)); - } - - /** * Lock a btree row to determine if it is a committed deleted row. *

* @see BTreeLockingPolicy#lockScanCommittedDeletedRow @@ -837,16 +686,12 @@ * Lock a row as part of doing the scan. *

* Lock the row at the given slot (or the previous row if slot is 0). - * Get the scan lock on the page if "request_scan_lock" is true. *

* If this routine returns true all locks were acquired while maintaining * the latch on leaf. If this routine returns false, locks may or may * not have been acquired, and the routine should be called again after * the client has researched the tree to reget the latch on the * appropriate page. - * (p> - * As a sided effect stores the value of the record handle of the current - * scan lock. * * @return Whether locks were acquired without releasing latch on leaf. * @@ -854,8 +699,6 @@ * used if routine has to scan backward. * @param btree the conglomerate info. * @param pos The position of the row to lock. - * @param request_scan_lock Whether to request the page scan lock, should - * only be requested once per page in the scan. * @param lock_template A scratch area to use to read in rows. * @param previous_key_lock Is this a previous key lock call? * @param forUpdate Is the scan for update or for read only. @@ -866,7 +709,6 @@ OpenBTree open_btree, BTree btree, BTreeRowPosition pos, - boolean request_scan_lock, FetchDescriptor lock_fetch_desc, DataValueDescriptor[] lock_template, RowLocation lock_row_loc, @@ -881,7 +723,6 @@ btree, pos, true, // request the row lock (always true for iso 3 ) - request_scan_lock, lock_fetch_desc, lock_template, lock_row_loc, @@ -905,32 +746,6 @@ return; } - /** - * Release the lock gotten by calling lockScan. This call can only be - * made to release read scan locks, write scan locks must be held until - * end of transaction. - *

- * See BTree.unlockScan() for more info. - * - **/ - public void unlockScan(RecordHandle scan_lock_rh) - { - // This is first row in table, lock the special key that - // represents the key previous to the first key of the table. - try - { - scan_locking_policy.unlockRecordAfterRead( - rawtran, open_btree.getContainerHandle(), - scan_lock_rh, false, true); - } - catch (StandardException se) - { - if (SanityManager.DEBUG) - SanityManager.THROWASSERT(se); - } - - } - /************************************************************************** * Abstract Protected lockNonScan*() locking methods of BTree: * @@ -976,7 +791,7 @@ btree, current_leaf, (LeafControlRow) null, current_slot - 1, - false, + null, lock_fetch_desc, lock_template, lock_row_loc, @@ -1094,7 +909,7 @@ current_leaf, null, current_slot, - false, + null, lock_fetch_desc, lock_template, lock_row_loc, Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/index/B2IRowLockingRR.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/index/B2IRowLockingRR.java?rev=754894&r1=754893&r2=754894&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/index/B2IRowLockingRR.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/index/B2IRowLockingRR.java Mon Mar 16 13:55:49 2009 @@ -69,16 +69,12 @@ * Lock a row as part of doing the scan. *

* Lock the row at the given slot (or the previous row if slot is 0). - * Get the scan lock on the page if "request_scan_lock" is true. *

* If this routine returns true all locks were acquired while maintaining * the latch on leaf. If this routine returns false, locks may or may * not have been acquired, and the routine should be called again after * the client has researched the tree to reget the latch on the * appropriate page. - * (p> - * As a side effect stores the value of the record handle of the current - * scan lock. * * @return Whether locks were acquired without releasing latch on leaf. * @@ -86,8 +82,6 @@ * used if routine has to scan backward. * @param btree the conglomerate info. * @param pos The position of the row to lock. - * @param request_scan_lock Whether to request the page scan lock, should - * only be requested once per page in the scan. * @param lock_template A scratch area to use to read in rows. * @param previous_key_lock Is this a previous key lock call? * @param forUpdate Is the scan for update or for read only. @@ -98,7 +92,6 @@ OpenBTree open_btree, BTree btree, BTreeRowPosition pos, - boolean request_scan_lock, FetchDescriptor lock_fetch_desc, DataValueDescriptor[] lock_template, RowLocation lock_row_loc, @@ -115,7 +108,6 @@ btree, pos, !previous_key_lock, // request row lock iff not prev key lock - request_scan_lock, lock_fetch_desc, lock_template, lock_row_loc, previous_key_lock, forUpdate, @@ -148,8 +140,6 @@ { if (SanityManager.DEBUG) { - SanityManager.ASSERT(pos.current_leaf != null , "leaf is null"); - SanityManager.ASSERT( pos.current_lock_row_loc != null , "row_loc is null"); } Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/heap/HeapRowLocation.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/heap/HeapRowLocation.java?rev=754894&r1=754893&r2=754894&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/heap/HeapRowLocation.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/heap/HeapRowLocation.java Mon Mar 16 13:55:49 2009 @@ -358,7 +358,12 @@ } protected void setFrom(DataValueDescriptor theValue) { if (SanityManager.DEBUG) - SanityManager.THROWASSERT("SHOULD NOT BE CALLED"); + SanityManager.ASSERT(theValue instanceof HeapRowLocation, + "Should only be set from another HeapRowLocation"); + HeapRowLocation that = (HeapRowLocation) theValue; + this.pageno = that.pageno; + this.recid = that.recid; + this.rh = that.rh; } /* ** Methods of Object Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/heap/HeapScan.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/heap/HeapScan.java?rev=754894&r1=754893&r2=754894&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/heap/HeapScan.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/heap/HeapScan.java Mon Mar 16 13:55:49 2009 @@ -34,7 +34,6 @@ import org.apache.derby.iapi.error.StandardException; -import org.apache.derby.iapi.store.access.conglomerate.Conglomerate; import org.apache.derby.iapi.store.access.conglomerate.ScanManager; import org.apache.derby.iapi.store.access.conglomerate.TransactionManager; @@ -43,7 +42,6 @@ import org.apache.derby.iapi.store.access.RowUtil; import org.apache.derby.iapi.store.access.ScanInfo; -import org.apache.derby.iapi.store.raw.Page; import org.apache.derby.iapi.store.raw.RecordHandle; import org.apache.derby.iapi.types.DataValueDescriptor; @@ -400,33 +398,4 @@ open_conglom.getContainer()), qualifier); } - - - /* - ** Methods of ScanManager - */ - - /** - * Do work necessary to maintain the current position in the scan. - *

- * The latched page in the conglomerate "congomid" is changing, do - * whatever is necessary to maintain the current position of the scan. - * For some conglomerates this may be a no-op. - *

- * - * @param conglom Conglomerate being changed. - * @param page Page in the conglomerate being changed. - * - * @exception StandardException Standard exception policy. - **/ - public void savePosition(Conglomerate conglom, Page page) - throws StandardException - { - // RESOLVE (mikem), under the current implementation all scans within - // a transaction are called rather than just the ones with the right - // conglom. For now just have heaps ignore the call. - - // throw HeapOperationException.unimplementedFeature(); - return; - } } Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/sort/Scan.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/sort/Scan.java?rev=754894&r1=754893&r2=754894&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/sort/Scan.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/sort/Scan.java Mon Mar 16 13:55:49 2009 @@ -31,13 +31,11 @@ import org.apache.derby.iapi.error.StandardException; -import org.apache.derby.iapi.store.access.conglomerate.Conglomerate; import org.apache.derby.iapi.store.access.conglomerate.ScanManager; import org.apache.derby.iapi.store.access.Qualifier; import org.apache.derby.iapi.store.access.ScanInfo; -import org.apache.derby.iapi.store.raw.Page; import org.apache.derby.iapi.types.DataValueDescriptor; @@ -330,33 +328,6 @@ } /* - ** Methods of ScanManager - */ - - /** - * Do work necessary to maintain the current position in the scan. - *

- * The latched page in the conglomerate "congomid" is changing, do - * whatever is necessary to maintain the current position of the scan. - * For some conglomerates this may be a no-op. - *

- * - * @param conglom Conglomerate object of the conglomerate being changed. - * @param page Page in the conglomerate being changed. - * - * @exception StandardException Standard exception policy. - **/ - public void savePosition(Conglomerate conglom, Page page) - throws StandardException - { - // RESOLVE (mikem), under the current implementation all scans within - // a transaction are called rather than just the ones with the right - // conglomid. For now just have sort scans ignore the call. - - return; - } - - /* * Methods of ScanInfo */ Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BasePage.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BasePage.java?rev=754894&r1=754893&r2=754894&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BasePage.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BasePage.java Mon Mar 16 13:55:49 2009 @@ -106,13 +106,6 @@ private int recordCount; /** - * A record handle that, when locked, protects all the record ids on the - * page. - * @see RecordHandle#RECORD_ID_PROTECTION_HANDLE - */ - private RecordId protectionHandle; - - /** Page owner during exclusive access. MT - mutable : single thread required, provided by Lockable single thread required. @@ -153,6 +146,14 @@ */ private LogInstant lastLog; + /** + * The oldest version where we know that any record id that was on the + * page at that version, must still be on the page. This is used by the + * B-tree code to decide whether or not it needs to reposition when + * resuming a scan. + */ + private long repositionNeededAfterVersion; + /** Version of the page. @@ -226,9 +227,9 @@ { setAuxObject(null); identity = null; - protectionHandle = null; recordCount = 0; clearLastLogInstant(); + repositionNeededAfterVersion = 0; if (SanityManager.DEBUG) { @@ -268,10 +269,11 @@ protected void fillInIdentity(PageKey key) { if (SanityManager.DEBUG) { SanityManager.ASSERT(identity == null); - SanityManager.ASSERT(protectionHandle == null); + SanityManager.ASSERT(repositionNeededAfterVersion == 0); } identity = key; + repositionNeededAfterVersion = pageVersion; } public void clearIdentity() { @@ -292,8 +294,8 @@ protected void cleanPageForReuse() { setAuxObject(null); - protectionHandle = null; recordCount = 0; + repositionNeededAfterVersion = 0; } @@ -320,29 +322,6 @@ return InvalidRecordHandle; } - /** - * Get the record id protection handle for the page. - * - * @return protection handle - * @see RecordHandle#RECORD_ID_PROTECTION_HANDLE - */ - public final RecordHandle getProtectionRecordHandle() { - // only allocate a new handle the first time the method is called - if (protectionHandle == null) { - protectionHandle = - new RecordId(getPageId(), - RecordHandle.RECORD_ID_PROTECTION_HANDLE); - } - - if (SanityManager.DEBUG) { - SanityManager.ASSERT( - getPageId().equals(protectionHandle.getPageId()), - "PageKey for cached protection handle doesn't match identity"); - } - - return protectionHandle; - } - public static final RecordHandle MakeRecordHandle(PageKey pkey, int recordHandleConstant) throws StandardException { @@ -1516,6 +1495,35 @@ return auxObj; } + /** + * Set a hint in this page to make B-tree scans positioned on it + * reposition before they continue. This method is typically called + * when rows are removed from a B-tree leaf page (for instance in a + * page split). + */ + public void setRepositionNeeded() { + if (SanityManager.DEBUG) { + SanityManager.ASSERT(isLatched()); + } + repositionNeededAfterVersion = getPageVersion(); + } + + /** + * Check if a B-tree scan positioned on this page needs to reposition. + * + * @param version the last version on which the B-tree scan had a valid + * position on this page + * @return {@code true} if a repositioning is needed because the row + * on the current position may have been removed from this page after + * the specified version; {@code false} otherwise + */ + public boolean isRepositionNeeded(long version) { + if (SanityManager.DEBUG) { + SanityManager.ASSERT(isLatched()); + } + return repositionNeededAfterVersion > version; + } + /* ** Methods of Observer. */ Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/RowLockIso.out URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/RowLockIso.out?rev=754894&r1=754893&r2=754894&view=diff ============================================================================== --- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/RowLockIso.out (original) +++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/RowLockIso.out Mon Mar 16 13:55:49 2009 @@ -591,7 +591,6 @@ USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE -APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A |B @@ -601,7 +600,6 @@ USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE -APP |UserTran|ROW |1 |S |A |(4,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A |B @@ -612,7 +610,6 @@ --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE -APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; A |B ----------------------- @@ -622,7 +619,6 @@ --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE -APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; @@ -666,7 +662,6 @@ USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE -APP |UserTran|ROW |1 |S |A |(4,1) |GRANT|ACTIVE ij> next scan_cursor; A |B ----------------------- @@ -675,7 +670,6 @@ USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE -APP |UserTran|ROW |1 |S |A |(4,1) |GRANT|ACTIVE ij> next scan_cursor; A |B ----------------------- @@ -684,7 +678,6 @@ USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE -APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; A |B ----------------------- @@ -693,7 +686,6 @@ USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE -APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname;