1 21 22 package org.apache.derby.impl.store.access.btree; 23 24 import org.apache.derby.iapi.reference.SQLState; 25 26 import org.apache.derby.iapi.services.sanity.SanityManager; 27 28 import org.apache.derby.iapi.error.StandardException; 29 30 import org.apache.derby.iapi.store.access.RowUtil; 31 import org.apache.derby.iapi.store.access.Qualifier; 32 import org.apache.derby.iapi.store.access.ScanController; 33 34 import org.apache.derby.iapi.store.raw.FetchDescriptor; 35 import org.apache.derby.iapi.store.raw.Page; 36 import org.apache.derby.iapi.store.raw.RecordHandle; 37 38 import org.apache.derby.iapi.types.DataValueDescriptor; 39 40 import org.apache.derby.iapi.types.RowLocation; 41 42 import org.apache.derby.iapi.store.access.BackingStoreHashtable; 43 44 45 56 57 65 66 public class BTreeMaxScan extends BTreeScan 67 { 68 69 73 74 79 private boolean fetchMaxRowFromBeginning( 80 BTreeRowPosition pos, 81 DataValueDescriptor[] fetch_row) 82 throws StandardException 83 { 84 int ret_row_count = 0; 85 RecordHandle max_rh = null; 86 87 DataValueDescriptor[] check_row_template = new DataValueDescriptor[1]; 91 check_row_template[0] = fetch_row[0].getClone(); 92 FetchDescriptor check_row_desc = RowUtil.getFetchDescriptorConstant(1); 93 94 reopenScan( 96 (DataValueDescriptor[]) null, 97 ScanController.NA, 98 (Qualifier[][]) null, 99 (DataValueDescriptor[]) null, 100 ScanController.NA); 101 102 positionAtStartForForwardScan(pos); 103 104 108 113 boolean nulls_not_reached = true; 114 while ((pos.current_leaf != null) && nulls_not_reached) 115 { 116 while ((pos.current_slot + 1) < pos.current_leaf.page.recordCount()) 117 { 118 if (pos.current_rh != null) 120 { 121 this.getLockingPolicy().unlockScanRecordAfterRead( 122 pos, init_forUpdate); 123 124 pos.current_rh = null; 127 } 128 129 pos.current_slot++; 131 this.stat_numrows_visited++; 132 133 RecordHandle rh = 137 pos.current_leaf.page.fetchFromSlot( 138 (RecordHandle) null, 139 pos.current_slot, 140 check_row_template, 141 null, 142 true); 143 144 boolean latch_released = 146 !this.getLockingPolicy().lockScanRow( 147 this, this.getConglomerate(), pos, 148 false, 149 init_lock_fetch_desc, 150 pos.current_lock_template, 151 pos.current_lock_row_loc, 152 false, init_forUpdate, lock_operation); 153 154 if (SanityManager.DEBUG) 156 { 157 latch_released = 158 test_errors( 159 this, 160 "BTreeMaxScan_fetchNextGroup", false, 161 this.getLockingPolicy(), 162 pos.current_leaf, latch_released); 163 } 164 165 pos.current_rh = rh; 171 172 if (latch_released) 173 { 174 if (!reposition(pos, false)) 182 { 183 if (SanityManager.DEBUG) 184 { 185 SanityManager.THROWASSERT( 187 "can not fail holding scan lock."); 188 } 189 } 190 } 191 192 193 if (pos.current_leaf.page.isDeletedAtSlot(pos.current_slot)) 194 { 195 this.stat_numdeleted_rows_visited++; 196 197 if (check_row_template[0].isNull()) 198 { 199 nulls_not_reached = false; 203 break; 204 } 205 } 206 else if (check_row_template[0].isNull()) 207 { 208 nulls_not_reached = false; 209 break; 210 } 211 else 212 { 213 214 pos.current_leaf.page.fetchFromSlot( 215 pos.current_rh, 216 pos.current_slot, fetch_row, init_fetchDesc, 217 true); 218 219 stat_numrows_qualified++; 220 max_rh = pos.current_rh; 221 } 222 } 223 224 positionAtNextPage(pos); 227 228 this.stat_numpages_visited++; 229 } 230 231 232 positionAtDoneScan(pos); 234 235 this.stat_numpages_visited--; 237 238 return(max_rh != null); 239 } 240 241 245 246 251 protected int fetchRows( 252 BTreeRowPosition pos, 253 DataValueDescriptor[][] row_array, 254 RowLocation[] rowloc_array, 255 BackingStoreHashtable hash_table, 256 long max_rowcnt, 257 int[] key_column_numbers) 258 throws StandardException 259 { 260 throw StandardException.newException( 261 SQLState.BTREE_UNIMPLEMENTED_FEATURE); 262 } 263 264 265 276 protected void positionAtStartPosition( 277 BTreeRowPosition pos) 278 throws StandardException 279 { 280 boolean exact; 281 282 if (SanityManager.DEBUG) 284 { 285 SanityManager.ASSERT(this.scan_state == SCAN_INIT); 286 SanityManager.ASSERT(pos.current_rh == null); 287 SanityManager.ASSERT(pos.current_positionKey == null); 288 SanityManager.ASSERT(pos.current_scan_pageno == 0); 289 } 290 291 while (true) 298 { 299 ControlRow root = ControlRow.Get(this, BTree.ROOTPAGEID); 302 303 stat_numpages_visited += root.getLevel() + 1; 305 306 if (init_startKeyValue == null) 307 { 308 pos.current_leaf = (LeafControlRow) root.searchRight(this); 310 311 pos.current_slot = pos.current_leaf.page.recordCount(); 312 exact = false; 313 } 314 else 315 { 316 throw StandardException.newException( 318 SQLState.BTREE_UNIMPLEMENTED_FEATURE); 319 } 320 321 331 pos.current_slot--; 332 boolean latch_released = 333 !this.getLockingPolicy().lockScanRow( 334 this, this.getConglomerate(), pos, 335 true, 336 init_lock_fetch_desc, 337 pos.current_lock_template, 338 pos.current_lock_row_loc, 339 false, init_forUpdate, lock_operation); 340 pos.current_slot++; 341 342 if (SanityManager.DEBUG) 344 { 345 latch_released = 346 test_errors( 347 this, 348 "BTreeMaxScan_positionAtStartPosition", true, 349 this.getLockingPolicy(), pos.current_leaf, latch_released); 350 } 351 352 if (latch_released) 353 { 354 pos.current_leaf = null; 356 continue; 357 } 358 else 359 { 360 break; 362 } 363 } 364 365 this.scan_state = SCAN_INPROGRESS; 366 pos.current_scan_pageno = pos.current_leaf.page.getPageNumber(); 367 368 if (SanityManager.DEBUG) 369 SanityManager.ASSERT(pos.current_leaf != null); 370 } 371 372 376 377 384 public boolean fetchMax( 385 DataValueDescriptor[] fetch_row) 386 throws StandardException 387 { 388 BTreeRowPosition pos = scan_position; 389 int ret_row_count = 0; 390 391 if (SanityManager.DEBUG) 392 { 393 SanityManager.ASSERT(this.container != null, 394 "BTreeMaxScan.fetchMax() called on a closed scan."); 395 } 396 397 398 if (this.scan_state == BTreeScan.SCAN_INPROGRESS) 399 { 400 402 if (!reposition(scan_position, true)) 409 { 410 if (SanityManager.DEBUG) 411 { 412 SanityManager.THROWASSERT( 413 "can not fail with 2nd param true."); 414 } 415 } 416 417 } 418 else if (this.scan_state == SCAN_INIT) 419 { 420 positionAtStartPosition(scan_position); 422 } 423 else 424 { 425 if (SanityManager.DEBUG) 426 SanityManager.ASSERT(this.scan_state == SCAN_DONE); 427 428 return(false); 429 } 430 431 432 436 437 boolean max_found = false; 438 439 441 if ((pos.current_slot - 1) > 0) 442 { 443 pos.current_slot--; 445 446 while (pos.current_slot > 0) 447 { 448 this.stat_numrows_visited++; 449 450 RecordHandle rh = 454 pos.current_leaf.page.fetchFromSlot( 455 (RecordHandle) null, 456 pos.current_slot, fetch_row, init_fetchDesc, 457 true); 458 459 boolean latch_released = 460 !this.getLockingPolicy().lockScanRow( 461 this, this.getConglomerate(), pos, 462 false, 463 init_lock_fetch_desc, 464 pos.current_lock_template, 465 pos.current_lock_row_loc, 466 false, init_forUpdate, lock_operation); 467 468 pos.current_rh = rh; 474 475 476 if (latch_released) 477 { 478 pos.current_leaf = null; 481 break; 482 } 483 484 if (pos.current_leaf.page.isDeletedAtSlot(pos.current_slot)) 485 { 486 this.stat_numdeleted_rows_visited++; 487 pos.current_rh_qualified = false; 488 } 489 else if (fetch_row[0].isNull()) 490 { 491 pos.current_rh_qualified = false; 492 } 493 else 494 { 495 pos.current_rh_qualified = true; 496 } 497 498 if (pos.current_rh_qualified) 499 { 500 502 ret_row_count++; 505 stat_numrows_qualified++; 506 507 pos.current_slot = Page.INVALID_SLOT_NUMBER; 509 510 max_found = true; 511 break; 512 } 513 else 514 { 515 pos.current_slot--; 516 } 517 } 518 } 519 520 if (pos.current_leaf != null) 521 { 522 pos.current_leaf.release(); 524 pos.current_leaf = null; 525 } 526 527 positionAtDoneScan(scan_position); 529 530 if (!max_found) 531 { 532 max_found = fetchMaxRowFromBeginning(scan_position, fetch_row); 534 } 535 536 return(max_found); 537 } 538 } 539 | Popular Tags |