1 21 22 package org.apache.derby.impl.sql.execute; 23 24 import org.apache.derby.iapi.services.loader.GeneratedMethod; 25 26 import org.apache.derby.iapi.services.monitor.Monitor; 27 28 import org.apache.derby.iapi.services.sanity.SanityManager; 29 30 import org.apache.derby.iapi.services.io.Storable; 31 32 import org.apache.derby.iapi.services.stream.HeaderPrintWriter; 33 import org.apache.derby.iapi.services.stream.InfoStreams; 34 35 import org.apache.derby.iapi.error.StandardException; 36 37 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 38 import org.apache.derby.iapi.sql.conn.StatementContext; 39 40 41 import org.apache.derby.iapi.sql.execute.CursorResultSet; 42 import org.apache.derby.iapi.sql.execute.ExecRow; 43 import org.apache.derby.iapi.sql.execute.NoPutResultSet; 44 45 import org.apache.derby.iapi.types.DataValueDescriptor; 46 import org.apache.derby.iapi.sql.Activation; 47 import org.apache.derby.iapi.sql.ResultSet; 48 49 import org.apache.derby.iapi.store.access.Qualifier; 50 import org.apache.derby.iapi.store.access.RowSource; 51 import org.apache.derby.iapi.store.access.TransactionController; 52 53 import org.apache.derby.iapi.types.RowLocation; 54 55 import org.apache.derby.iapi.store.access.BackingStoreHashtable; 56 import org.apache.derby.iapi.services.io.FormatableArrayHolder; 57 import org.apache.derby.iapi.services.io.FormatableIntHolder; 58 import org.apache.derby.iapi.store.access.KeyHasher; 59 60 import org.apache.derby.catalog.types.ReferencedColumnsDescriptorImpl; 61 62 import java.util.Properties ; 63 import java.util.Vector ; 64 65 70 class HashTableResultSet extends NoPutResultSetImpl 71 implements CursorResultSet 72 { 73 74 public long restrictionTime; 75 public long projectionTime; 76 public int hashtableSize; 77 public Properties scanProperties; 78 79 public NoPutResultSet source; 82 public GeneratedMethod singleTableRestriction; 83 public Qualifier[][] nextQualifiers; 84 private GeneratedMethod projection; 85 private int[] projectMapping; 86 private boolean runTimeStatsOn; 87 private ExecRow mappedResultRow; 88 public boolean reuseResult; 89 public int[] keyColumns; 90 private boolean removeDuplicates; 91 private long maxInMemoryRowCount; 92 private int initialCapacity; 93 private float loadFactor; 94 private boolean skipNullKeyColumns; 95 96 private boolean firstNext = true; 98 private int numFetchedOnNext; 99 private int entryVectorSize; 100 private Vector entryVector; 101 102 private boolean hashTableBuilt; 103 private boolean firstIntoHashtable = true; 104 105 private ExecRow nextCandidate; 106 private ExecRow projRow; 107 108 private BackingStoreHashtable ht; 109 110 HashTableResultSet(NoPutResultSet s, 114 Activation a, 115 GeneratedMethod str, 116 Qualifier[][] nextQualifiers, 117 GeneratedMethod p, 118 int resultSetNumber, 119 int mapRefItem, 120 boolean reuseResult, 121 int keyColItem, 122 boolean removeDuplicates, 123 long maxInMemoryRowCount, 124 int initialCapacity, 125 float loadFactor, 126 boolean skipNullKeyColumns, 127 double optimizerEstimatedRowCount, 128 double optimizerEstimatedCost) 129 throws StandardException 130 { 131 super(a, resultSetNumber, optimizerEstimatedRowCount, optimizerEstimatedCost); 132 source = s; 133 if (SanityManager.DEBUG) 136 { 137 SanityManager.ASSERT(source != null, 138 "HTRS(), source expected to be non-null"); 139 } 140 singleTableRestriction = str; 141 this.nextQualifiers = nextQualifiers; 142 projection = p; 143 projectMapping = ((ReferencedColumnsDescriptorImpl) a.getPreparedStatement().getSavedObject(mapRefItem)).getReferencedColumnPositions(); 144 FormatableArrayHolder fah = (FormatableArrayHolder) a.getPreparedStatement().getSavedObject(keyColItem); 145 FormatableIntHolder[] fihArray = (FormatableIntHolder[]) fah.getArray(FormatableIntHolder.class); 146 keyColumns = new int[fihArray.length]; 147 for (int index = 0; index < fihArray.length; index++) 148 { 149 keyColumns[index] = fihArray[index].getInt(); 150 } 151 152 this.reuseResult = reuseResult; 153 this.removeDuplicates = removeDuplicates; 154 this.maxInMemoryRowCount = maxInMemoryRowCount; 155 this.initialCapacity = initialCapacity; 156 this.loadFactor = loadFactor; 157 this.skipNullKeyColumns = skipNullKeyColumns; 158 159 if (projection == null) 161 { 162 mappedResultRow = activation.getExecutionFactory().getValueRow(projectMapping.length); 163 } 164 constructorTime += getElapsedMillis(beginTime); 165 166 167 runTimeStatsOn = getLanguageConnectionContext().getRunTimeStatisticsMode(); 168 } 169 170 174 181 public void openCore() throws StandardException 182 { 183 TransactionController tc; 184 185 beginTime = getCurrentTimeMillis(); 186 187 if (SanityManager.DEBUG) 190 { 191 SanityManager.ASSERT(source != null, 192 "HTRS().openCore(), source expected to be non-null"); 193 } 194 195 if (SanityManager.DEBUG) 199 SanityManager.ASSERT( ! isOpen, "HashTableResultSet already open"); 200 201 tc = activation.getTransactionController(); 203 204 if (! hashTableBuilt) 205 { 206 source.openCore(); 207 208 214 ht = new BackingStoreHashtable(tc, 215 this, 216 keyColumns, 217 removeDuplicates, 218 (int) optimizerEstimatedRowCount, 219 maxInMemoryRowCount, 220 (int) initialCapacity, 221 loadFactor, 222 skipNullKeyColumns, 223 false ); 224 225 if (runTimeStatsOn) 226 { 227 hashtableSize = ht.size(); 228 229 if (scanProperties == null) 230 { 231 scanProperties = new Properties (); 232 } 233 234 try 235 { 236 if (ht != null) 237 { 238 ht.getAllRuntimeStats(scanProperties); 239 } 240 } 241 catch(StandardException se) 242 { 243 } 245 } 246 247 isOpen = true; 248 hashTableBuilt = true; 249 } 250 251 resetProbeVariables(); 252 253 numOpens++; 254 255 openTime += getElapsedMillis(beginTime); 256 } 257 258 265 public void reopenCore() throws StandardException 266 { 267 268 if (SanityManager.DEBUG) 269 { 270 SanityManager.ASSERT(isOpen, 271 "HashTableResultSet already open"); 272 } 273 274 beginTime = getCurrentTimeMillis(); 275 276 resetProbeVariables(); 277 278 numOpens++; 279 openTime += getElapsedMillis(beginTime); 280 } 281 282 private void resetProbeVariables() throws StandardException 283 { 284 firstNext = true; 285 numFetchedOnNext = 0; 286 entryVector = null; 287 entryVectorSize = 0; 288 289 if (nextQualifiers != null) 290 { 291 clearOrderableCache(nextQualifiers); 292 } 293 } 294 295 308 public ExecRow getNextRowCore() throws StandardException { 309 ExecRow result = null; 310 DataValueDescriptor[] columns = null; 311 312 beginTime = getCurrentTimeMillis(); 313 if ( isOpen ) 314 { 315 320 do 321 { 322 if (firstNext) 323 { 324 firstNext = false; 325 326 330 Object hashEntry; 331 if (keyColumns.length == 1) 332 { 333 hashEntry = ht.get(nextQualifiers[0][0].getOrderable()); 334 } 335 else 336 { 337 KeyHasher mh = 338 new KeyHasher(keyColumns.length); 339 340 for (int index = 0; index < keyColumns.length; index++) 341 { 342 mh.setObject( 345 index, nextQualifiers[0][index].getOrderable()); 346 } 347 hashEntry = ht.get(mh); 348 } 349 350 if (hashEntry instanceof Vector ) 351 { 352 entryVector = (Vector ) hashEntry; 353 entryVectorSize = entryVector.size(); 354 columns = 355 (DataValueDescriptor[]) entryVector.firstElement(); 356 } 357 else 358 { 359 entryVector = null; 360 entryVectorSize = 0; 361 columns = (DataValueDescriptor[]) hashEntry; 362 } 363 } 364 else if (numFetchedOnNext < entryVectorSize) 365 { 366 369 columns = (DataValueDescriptor[]) 370 entryVector.elementAt(numFetchedOnNext); 371 } 372 373 if (columns != null) 374 { 375 if (SanityManager.DEBUG) 376 { 377 for (int i = 0; i < columns.length; i++) 379 { 380 if (! (columns[0] instanceof Storable)) 381 { 382 SanityManager.THROWASSERT( 383 "columns[" + i + "] expected to be Storable, not " + 384 columns[i].getClass().getName()); 385 } 386 } 387 } 388 389 boolean qualifies = true; 391 392 401 402 405 if (SanityManager.DEBUG) 406 { 407 SanityManager.ASSERT(nextQualifiers.length == 1); 409 } 410 for (int index = 0; index < nextQualifiers[0].length; index++) 411 { 412 Qualifier q = nextQualifiers[0][index]; 413 414 qualifies = 415 columns[q.getColumnId()].compare( 416 q.getOperator(), 417 q.getOrderable(), 418 q.getOrderedNulls(), 419 q.getUnknownRV()); 420 421 if (q.negateCompareResult()) 422 { 423 qualifies = !(qualifies); 424 } 425 426 if (! qualifies) 428 { 429 break; 430 } 431 } 432 433 if (qualifies) 434 { 435 436 for (int index = 0; index < columns.length; index++) 437 { 438 nextCandidate.setColumn(index + 1, columns[index]); 439 } 440 441 result = doProjection(nextCandidate); 442 } 443 else 444 { 445 result = null; 446 } 447 448 numFetchedOnNext++; 449 } 450 else 451 { 452 result = null; 453 } 454 } 455 while (result == null && numFetchedOnNext < entryVectorSize); 456 } 457 458 currentRow = result; 459 setCurrentRow(result); 460 461 nextTime += getElapsedMillis(beginTime); 462 463 if (runTimeStatsOn) 464 { 465 if (! isTopResultSet) 466 { 467 468 469 StatementContext sc = activation.getLanguageConnectionContext().getStatementContext(); 470 subqueryTrackingArray = sc.getSubqueryTrackingArray(); 471 } 472 nextTime += getElapsedMillis(beginTime); 473 } 474 return result; 475 } 476 477 485 public long getTimeSpent(int type) 486 { 487 long totTime = constructorTime + openTime + nextTime + closeTime; 488 489 if (type == CURRENT_RESULTSET_ONLY) 490 { 491 return totTime - source.getTimeSpent(ENTIRE_RESULTSET_TREE); 492 } 493 else 494 { 495 return totTime; 496 } 497 } 498 499 501 507 public void close() throws StandardException 508 { 509 beginTime = getCurrentTimeMillis(); 510 if ( isOpen ) { 511 512 clearCurrentRow(); 517 518 source.close(); 519 520 super.close(); 521 522 if (hashTableBuilt) 523 { 524 ht.close(); 526 ht = null; 527 hashTableBuilt = false; 528 } 529 } 530 else 531 if (SanityManager.DEBUG) 532 SanityManager.DEBUG("CloseRepeatInfo","Close of ProjectRestrictResultSet repeated"); 533 534 closeTime += getElapsedMillis(beginTime); 535 } 536 537 541 551 public RowLocation getRowLocation() throws StandardException { 552 if (SanityManager.DEBUG) 553 SanityManager.ASSERT(source instanceof CursorResultSet, "source not instance of CursorResultSet"); 554 return ( (CursorResultSet)source ).getRowLocation(); 555 } 556 557 565 568 public ExecRow getCurrentRow() throws StandardException { 569 ExecRow candidateRow = null; 570 ExecRow result = null; 571 boolean restrict = false; 572 DataValueDescriptor restrictBoolean; 573 574 if (SanityManager.DEBUG) 575 SanityManager.ASSERT(isOpen, "PRRS is expected to be open"); 576 577 578 if (currentRow == null) 579 { 580 return null; 581 } 582 583 587 candidateRow = ((CursorResultSet) source).getCurrentRow(); 588 if (candidateRow != null) { 589 setCurrentRow(candidateRow); 590 591 restrictBoolean = (DataValueDescriptor) 592 ((singleTableRestriction == null) ? null : singleTableRestriction.invoke(activation)); 593 594 restrict = (restrictBoolean == null) || 597 ((! restrictBoolean.isNull()) && 598 restrictBoolean.getBoolean()); 599 } 600 601 if (candidateRow != null && restrict) 602 { 603 result = doProjection(candidateRow); 604 } 605 606 currentRow = result; 607 608 if (result == null) { 609 clearCurrentRow(); 610 } 611 612 return currentRow; 613 } 614 615 626 private ExecRow doProjection(ExecRow sourceRow) 627 throws StandardException 628 { 629 if (reuseResult && projRow != null) 631 { 632 return projRow; 633 } 634 635 ExecRow result; 636 637 if (projection != null) 639 { 640 result = (ExecRow) projection.invoke(activation); 641 } 642 else 643 { 644 result = mappedResultRow; 645 } 646 647 for (int index = 0; index < projectMapping.length; index++) 649 { 650 if (projectMapping[index] != -1) 651 { 652 result.setColumn(index + 1, sourceRow.getColumn(projectMapping[index])); 653 } 654 } 655 656 657 setCurrentRow(result); 658 659 660 if (reuseResult) 661 { 662 projRow = result; 663 } 664 return result; 665 } 666 667 669 673 public DataValueDescriptor[] getNextRowFromRowSource() 674 throws StandardException 675 { 676 ExecRow execRow = source.getNextRowCore(); 677 678 682 while (execRow != null) 683 { 684 boolean restrict = false; 685 DataValueDescriptor restrictBoolean; 686 687 rowsSeen++; 688 689 690 restrictBoolean = (DataValueDescriptor) 691 ((singleTableRestriction == null) ? null : singleTableRestriction.invoke(activation)); 692 693 restrict = (restrictBoolean == null) || 696 ((! restrictBoolean.isNull()) && 697 restrictBoolean.getBoolean()); 698 if (!restrict) 699 { 700 execRow = source.getNextRowCore(); 701 continue; 702 } 703 704 if (targetResultSet != null) 705 { 706 712 clonedExecRow = targetResultSet.preprocessSourceRow(execRow); 713 } 714 715 716 720 if (firstIntoHashtable) 721 { 722 nextCandidate = activation.getExecutionFactory().getValueRow(execRow.nColumns()); 723 firstIntoHashtable = false; 724 } 725 726 return execRow.getRowArray(); 727 } 728 729 return null; 730 } 731 732 737 public boolean isForUpdate() 738 { 739 if (source == null) 740 { 741 return false; 742 } 743 return source.isForUpdate(); 744 } 745 746 } 747 | Popular Tags |