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 import org.apache.derby.iapi.services.io.Storable; 28 29 import org.apache.derby.iapi.error.StandardException; 30 31 import org.apache.derby.iapi.store.access.conglomerate.Conglomerate; 32 import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo; 33 import org.apache.derby.iapi.store.access.conglomerate.ScanManager; 34 import org.apache.derby.iapi.store.access.conglomerate.TransactionManager; 35 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.ScanController; 40 import org.apache.derby.iapi.store.access.ScanInfo; 41 import org.apache.derby.iapi.store.access.StaticCompiledOpenConglomInfo; 42 import org.apache.derby.iapi.store.access.TransactionController; 43 44 import org.apache.derby.iapi.store.raw.ContainerHandle; 45 import org.apache.derby.iapi.store.raw.LockingPolicy; 46 import org.apache.derby.iapi.store.raw.Page; 47 import org.apache.derby.iapi.store.raw.RecordHandle; 48 import org.apache.derby.iapi.store.raw.Transaction; 49 50 import org.apache.derby.iapi.types.DataValueDescriptor; 51 52 import org.apache.derby.iapi.types.RowLocation; 53 54 import org.apache.derby.impl.store.access.conglomerate.ConglomerateUtil; 55 import org.apache.derby.impl.store.access.conglomerate.TemplateRow; 56 57 import org.apache.derby.iapi.services.io.FormatableBitSet; 58 import org.apache.derby.iapi.store.access.BackingStoreHashtable; 59 60 71 72 public class BTreeForwardScan extends BTreeScan 73 { 74 77 78 87 protected void positionAtStartPosition( 88 BTreeRowPosition pos) 89 throws StandardException 90 { 91 positionAtStartForForwardScan(pos); 92 } 93 94 105 116 public void init( 117 TransactionManager xact_manager, 118 Transaction rawtran, 119 boolean hold, 120 int open_mode, 121 int lock_level, 122 BTreeLockingPolicy btree_locking_policy, 123 FormatableBitSet scanColumnList, 124 DataValueDescriptor[] startKeyValue, 125 int startSearchOperator, 126 Qualifier qualifier[][], 127 DataValueDescriptor[] stopKeyValue, 128 int stopSearchOperator, 129 BTree conglomerate, 130 LogicalUndo undo, 131 StaticCompiledOpenConglomInfo static_info, 132 DynamicCompiledOpenConglomInfo dynamic_info) 133 throws StandardException 134 { 135 super.init( 136 xact_manager, rawtran, hold, open_mode, lock_level, 137 btree_locking_policy, scanColumnList, startKeyValue, 138 startSearchOperator, qualifier, stopKeyValue, 139 stopSearchOperator, conglomerate, undo, static_info, dynamic_info); 140 } 141 142 145 public void close() 146 throws StandardException 147 { 148 super.close(); 149 } 150 151 152 159 protected int fetchRows( 160 BTreeRowPosition pos, 161 DataValueDescriptor[][] row_array, 162 RowLocation[] rowloc_array, 163 BackingStoreHashtable hash_table, 164 long max_rowcnt, 165 int[] key_column_numbers) 166 throws StandardException 167 { 168 169 int ret_row_count = 0; 170 DataValueDescriptor[] fetch_row = null; 171 RecordHandle rh; 172 173 if (max_rowcnt == -1) 174 max_rowcnt = Long.MAX_VALUE; 175 176 177 if (this.scan_state == BTreeScan.SCAN_INPROGRESS) 178 { 179 if (!reposition(pos, true)) 189 { 190 if (SanityManager.DEBUG) 191 { 192 SanityManager.THROWASSERT( 193 "can not fail with 2nd param true."); 194 } 195 } 196 197 } 198 else if (this.scan_state == SCAN_INIT) 199 { 200 positionAtStartPosition(pos); 202 } 203 else if (this.scan_state == SCAN_HOLD_INPROGRESS) 204 { 205 reopen(); 206 207 this.scan_state = SCAN_INPROGRESS; 208 209 if (SanityManager.DEBUG) 210 { 211 SanityManager.ASSERT(scan_position.current_positionKey != null); 212 } 213 214 if (!reposition(pos, true)) 222 { 223 if (SanityManager.DEBUG) 224 { 225 SanityManager.THROWASSERT( 226 "can not fail with 2nd param true."); 227 } 228 } 229 230 } 231 else if (this.scan_state == SCAN_HOLD_INIT) 232 { 233 reopen(); 234 235 positionAtStartForForwardScan(scan_position); 236 } 237 else 238 { 239 if (SanityManager.DEBUG) 240 SanityManager.ASSERT(this.scan_state == SCAN_DONE); 241 242 return(0); 243 } 244 245 if (SanityManager.DEBUG) 246 { 247 SanityManager.ASSERT( 248 init_template != null, "init_template is null"); 249 } 250 251 if (SanityManager.DEBUG) 252 { 253 SanityManager.ASSERT(this.container != null, 254 "BTreeScan.next() called on a closed scan."); 255 256 if (row_array != null) 257 SanityManager.ASSERT(row_array[0] != null, 258 "first array slot in fetchNextGroup() must be non-null."); 259 260 if (rowloc_array != null) 262 { 263 throw StandardException.newException( 264 SQLState.BTREE_UNIMPLEMENTED_FEATURE); 265 } 266 } 267 268 270 271 275 280 while (pos.current_leaf != null) 281 { 282 286 while ((pos.current_slot + 1) < pos.current_leaf.page.recordCount()) 287 { 288 289 294 295 if (pos.current_rh != null) 297 { 298 this.getLockingPolicy().unlockScanRecordAfterRead( 299 pos, init_forUpdate); 300 301 pos.current_rh = null; 304 } 305 306 if (fetch_row == null) 308 { 309 if (hash_table == null) 310 { 311 if (row_array[ret_row_count] == null) 313 { 314 row_array[ret_row_count] = 315 runtime_mem.get_row_for_export(); 316 } 317 318 fetch_row = row_array[ret_row_count]; 319 } 320 else 321 { 322 fetch_row = runtime_mem.get_row_for_export(); 324 } 325 } 326 327 pos.current_slot++; 329 this.stat_numrows_visited++; 330 331 rh = 332 pos.current_leaf.page.fetchFromSlot( 333 (RecordHandle) null, 334 pos.current_slot, fetch_row, 335 init_fetchDesc, 336 true); 337 338 339 pos.current_rh_qualified = true; 340 341 if (init_stopKeyValue != null) 343 { 344 int ret = ControlRow.CompareIndexRowToKey( 352 fetch_row, 353 init_stopKeyValue, 354 fetch_row.length, 355 0, this.getConglomerate().ascDescInfo); 356 357 if ((ret == 0) && 358 (init_stopSearchOperator == ScanController.GE)) 359 { 360 ret = 1; 362 } 363 364 if (ret > 0) 365 { 366 368 pos.current_leaf.release(); 369 pos.current_leaf = null; 370 positionAtDoneScan(pos); 371 372 return(ret_row_count); 373 } 374 } 375 376 377 boolean latch_released = 382 !this.getLockingPolicy().lockScanRow( 383 this, this.getConglomerate(), pos, 384 false, 385 init_lock_fetch_desc, 386 pos.current_lock_template, 387 pos.current_lock_row_loc, 388 false, init_forUpdate, lock_operation); 389 390 if (SanityManager.DEBUG) 392 { 393 latch_released = 394 test_errors( 395 this, 396 "BTreeScan_fetchNextGroup", false, 397 this.getLockingPolicy(), 398 pos.current_leaf, latch_released); 399 } 400 401 pos.current_rh = rh; 407 408 if (latch_released) 409 { 410 418 if (this.getConglomerate().isUnique()) 419 { 420 435 while (latch_released) 436 { 437 if (!reposition(pos, false)) 438 { 439 if (SanityManager.DEBUG) 440 { 441 SanityManager.THROWASSERT( 443 "can not fail holding scan lock."); 444 } 445 446 452 } 453 454 pos.current_leaf.page.fetchFromSlot( 455 (RecordHandle) null, 456 pos.current_slot, fetch_row, 457 init_fetchDesc, 458 true); 459 460 latch_released = 461 !this.getLockingPolicy().lockScanRow( 462 this, 463 this.getConglomerate(), 464 pos, 465 false, 466 init_lock_fetch_desc, 467 pos.current_lock_template, 468 pos.current_lock_row_loc, 469 false, init_forUpdate, lock_operation); 470 } 471 } 472 else 473 { 474 if (!reposition(pos, false)) 475 { 476 if (SanityManager.DEBUG) 477 { 478 SanityManager.THROWASSERT( 480 "can not fail holding scan lock."); 481 } 482 483 489 } 490 491 } 492 } 493 494 495 if (pos.current_leaf.page.isDeletedAtSlot(pos.current_slot)) 496 { 497 this.stat_numdeleted_rows_visited++; 498 pos.current_rh_qualified = false; 499 } 500 else if (init_qualifier != null) 501 { 502 pos.current_rh_qualified = 504 this.process_qualifier(fetch_row); 505 } 506 507 if (pos.current_rh_qualified) 508 { 509 511 if (SanityManager.DEBUG) 515 { 516 SanityManager.ASSERT( 517 pos.current_leaf.page.getSlotNumber(pos.current_rh) 518 == pos.current_slot); 519 } 520 521 ret_row_count++; 524 stat_numrows_qualified++; 525 526 if (hash_table != null) 527 { 528 if (hash_table.put(false, fetch_row)) 529 fetch_row = null; 530 } 531 else 532 { 533 fetch_row = null; 534 } 535 536 if (max_rowcnt <= ret_row_count) 537 { 538 pos.current_slot = Page.INVALID_SLOT_NUMBER; 540 541 pos.current_leaf.release(); 543 pos.current_leaf = null; 544 545 return(ret_row_count); 546 } 547 } 548 } 549 550 positionAtNextPage(pos); 553 554 this.stat_numpages_visited++; 555 } 556 557 positionAtDoneScan(pos); 559 560 561 this.stat_numpages_visited--; 563 564 return(ret_row_count); 565 } 566 } 567 568 | Popular Tags |