1 21 22 package org.apache.derby.iapi.db; 23 24 import org.apache.derby.iapi.error.StandardException; 25 import org.apache.derby.iapi.error.PublicAPI; 26 27 import org.apache.derby.iapi.sql.dictionary.DataDictionaryContext; 28 import org.apache.derby.iapi.sql.dictionary.DataDictionary; 29 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor; 30 import org.apache.derby.iapi.sql.dictionary.TableDescriptor; 31 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor; 32 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList; 33 import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor; 34 import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList; 35 import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor; 36 37 import org.apache.derby.iapi.sql.depend.DependencyManager; 38 39 import org.apache.derby.iapi.sql.execute.ExecRow; 40 import org.apache.derby.iapi.sql.execute.ExecutionContext; 41 42 import org.apache.derby.iapi.types.DataValueDescriptor; 43 import org.apache.derby.iapi.types.DataValueFactory; 44 45 46 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 47 import org.apache.derby.iapi.sql.conn.ConnectionUtil; 48 49 import org.apache.derby.iapi.store.access.TransactionController; 50 import org.apache.derby.iapi.types.RowLocation; 51 import org.apache.derby.iapi.store.access.ScanController; 52 import org.apache.derby.iapi.store.access.ConglomerateController; 53 import org.apache.derby.iapi.store.access.GroupFetchScanController; 54 import org.apache.derby.iapi.store.access.RowUtil; 55 import org.apache.derby.iapi.store.access.Qualifier; 56 57 import org.apache.derby.iapi.services.sanity.SanityManager; 58 59 import org.apache.derby.iapi.reference.SQLState; 60 61 import org.apache.derby.iapi.services.io.FormatableBitSet; 62 63 import java.sql.SQLException ; 64 65 180 public class OnlineCompress 181 { 182 183 184 private OnlineCompress() { 185 } 186 187 202 public static void compressTable( 203 String schemaName, 204 String tableName, 205 boolean purgeRows, 206 boolean defragmentRows, 207 boolean truncateEnd) 208 throws SQLException 209 { 210 LanguageConnectionContext lcc = ConnectionUtil.getCurrentLCC(); 211 TransactionController tc = lcc.getTransactionExecute(); 212 213 try 214 { 215 DataDictionary data_dictionary = lcc.getDataDictionary(); 216 217 224 if (purgeRows) 225 purgeRows(schemaName, tableName, data_dictionary, tc); 226 227 if (defragmentRows) 228 defragmentRows(schemaName, tableName, data_dictionary, tc); 229 230 if (truncateEnd) 231 truncateEnd(schemaName, tableName, data_dictionary, tc); 232 } 233 catch (StandardException se) 234 { 235 throw PublicAPI.wrapStandardException(se); 236 } 237 238 } 239 240 260 private static void defragmentRows( 261 String schemaName, 262 String tableName, 263 DataDictionary data_dictionary, 264 TransactionController tc) 265 throws SQLException 266 { 267 GroupFetchScanController base_group_fetch_cc = null; 268 int num_indexes = 0; 269 270 int[][] index_col_map = null; 271 ScanController[] index_scan = null; 272 ConglomerateController[] index_cc = null; 273 DataValueDescriptor[][] index_row = null; 274 275 LanguageConnectionContext lcc = ConnectionUtil.getCurrentLCC(); 276 TransactionController nested_tc = null; 277 278 try { 279 280 SchemaDescriptor sd = 281 data_dictionary.getSchemaDescriptor( 282 schemaName, nested_tc, true); 283 TableDescriptor td = 284 data_dictionary.getTableDescriptor(tableName, sd); 285 nested_tc = 286 tc.startNestedUserTransaction(false); 287 288 if (td == null) 289 { 290 throw StandardException.newException( 291 SQLState.LANG_TABLE_NOT_FOUND, 292 schemaName + "." + tableName); 293 } 294 295 switch (td.getTableType()) 296 { 297 298 case TableDescriptor.VIEW_TYPE: 299 case TableDescriptor.VTI_TYPE: 300 return; 301 default: 304 break; 305 } 306 307 308 ConglomerateDescriptor heapCD = 309 td.getConglomerateDescriptor(td.getHeapConglomerateId()); 310 311 312 ExecRow baseRow = 313 lcc.getExecutionContext().getExecutionFactory().getValueRow( 314 td.getNumberOfColumns()); 315 316 317 318 ColumnDescriptorList cdl = td.getColumnDescriptorList(); 319 int cdlSize = cdl.size(); 320 321 for (int index = 0; index < cdlSize; index++) 322 { 323 ColumnDescriptor cd = (ColumnDescriptor) cdl.elementAt(index); 324 baseRow.setColumn(cd.getPosition(), cd.getType().getNull()); 325 } 326 327 DataValueDescriptor[][] row_array = new DataValueDescriptor[100][]; 328 row_array[0] = baseRow.getRowArray(); 329 RowLocation[] old_row_location_array = new RowLocation[100]; 330 RowLocation[] new_row_location_array = new RowLocation[100]; 331 332 343 ConglomerateDescriptor[] conglom_descriptors = 344 td.getConglomerateDescriptors(); 345 346 num_indexes = conglom_descriptors.length - 1; 349 350 if (num_indexes > 0) 352 { 353 index_col_map = new int[num_indexes][]; 355 index_scan = new ScanController[num_indexes]; 356 index_cc = new ConglomerateController[num_indexes]; 357 index_row = new DataValueDescriptor[num_indexes][]; 358 359 setup_indexes( 360 nested_tc, 361 td, 362 index_col_map, 363 index_scan, 364 index_cc, 365 index_row); 366 367 } 368 369 370 base_group_fetch_cc = 371 nested_tc.defragmentConglomerate( 372 td.getHeapConglomerateId(), 373 false, 374 true, 375 TransactionController.OPENMODE_FORUPDATE, 376 TransactionController.MODE_TABLE, 377 TransactionController.ISOLATION_SERIALIZABLE); 378 379 int num_rows_fetched = 0; 380 while ((num_rows_fetched = 381 base_group_fetch_cc.fetchNextGroup( 382 row_array, 383 old_row_location_array, 384 new_row_location_array)) != 0) 385 { 386 if (num_indexes > 0) 387 { 388 for (int row = 0; row < num_rows_fetched; row++) 389 { 390 for (int index = 0; index < num_indexes; index++) 391 { 392 fixIndex( 393 row_array[row], 394 index_row[index], 395 old_row_location_array[row], 396 new_row_location_array[row], 397 index_cc[index], 398 index_scan[index], 399 index_col_map[index]); 400 } 401 } 402 } 403 } 404 405 nested_tc.commit(); 413 414 } 415 catch (StandardException se) 416 { 417 throw PublicAPI.wrapStandardException(se); 418 } 419 finally 420 { 421 try 422 { 423 424 if (base_group_fetch_cc != null) 425 { 426 base_group_fetch_cc.close(); 427 base_group_fetch_cc = null; 428 } 429 430 if (num_indexes > 0) 431 { 432 for (int i = 0; i < num_indexes; i++) 433 { 434 if (index_scan != null && index_scan[i] != null) 435 { 436 index_scan[i].close(); 437 index_scan[i] = null; 438 } 439 if (index_cc != null && index_cc[i] != null) 440 { 441 index_cc[i].close(); 442 index_cc[i] = null; 443 } 444 } 445 } 446 447 if (nested_tc != null) 448 { 449 nested_tc.destroy(); 450 } 451 452 } 453 catch (StandardException se) 454 { 455 throw PublicAPI.wrapStandardException(se); 456 } 457 } 458 459 return; 460 } 461 462 476 private static void purgeRows( 477 String schemaName, 478 String tableName, 479 DataDictionary data_dictionary, 480 TransactionController tc) 481 throws StandardException 482 { 483 SchemaDescriptor sd = 484 data_dictionary.getSchemaDescriptor(schemaName, tc, true); 485 TableDescriptor td = 486 data_dictionary.getTableDescriptor(tableName, sd); 487 488 if (td == null) 489 { 490 throw StandardException.newException( 491 SQLState.LANG_TABLE_NOT_FOUND, 492 schemaName + "." + tableName); 493 } 494 495 switch (td.getTableType()) 496 { 497 498 case TableDescriptor.VIEW_TYPE: 499 case TableDescriptor.VTI_TYPE: 500 break; 501 default: 504 { 505 506 ConglomerateDescriptor[] conglom_descriptors = 507 td.getConglomerateDescriptors(); 508 509 for (int cd_idx = 0; cd_idx < conglom_descriptors.length; cd_idx++) 510 { 511 ConglomerateDescriptor cd = conglom_descriptors[cd_idx]; 512 513 tc.purgeConglomerate(cd.getConglomerateNumber()); 514 } 515 } 516 } 517 518 return; 519 } 520 521 535 private static void truncateEnd( 536 String schemaName, 537 String tableName, 538 DataDictionary data_dictionary, 539 TransactionController tc) 540 throws StandardException 541 { 542 SchemaDescriptor sd = 543 data_dictionary.getSchemaDescriptor(schemaName, tc, true); 544 TableDescriptor td = 545 data_dictionary.getTableDescriptor(tableName, sd); 546 547 if (td == null) 548 { 549 throw StandardException.newException( 550 SQLState.LANG_TABLE_NOT_FOUND, 551 schemaName + "." + tableName); 552 } 553 554 switch (td.getTableType()) 555 { 556 557 case TableDescriptor.VIEW_TYPE: 558 case TableDescriptor.VTI_TYPE: 559 break; 560 default: 563 { 564 ConglomerateDescriptor[] conglom_descriptors = 565 td.getConglomerateDescriptors(); 566 567 for (int cd_idx = 0; cd_idx < conglom_descriptors.length; cd_idx++) 568 { 569 ConglomerateDescriptor cd = conglom_descriptors[cd_idx]; 570 571 tc.compressConglomerate(cd.getConglomerateNumber()); 572 } 573 } 574 } 575 576 return; 577 } 578 579 private static void setup_indexes( 580 TransactionController tc, 581 TableDescriptor td, 582 int[][] index_col_map, 583 ScanController[] index_scan, 584 ConglomerateController[] index_cc, 585 DataValueDescriptor[][] index_row) 586 throws StandardException 587 { 588 589 598 ConglomerateDescriptor[] conglom_descriptors = 599 td.getConglomerateDescriptors(); 600 601 602 int index_idx = 0; 603 for (int cd_idx = 0; cd_idx < conglom_descriptors.length; cd_idx++) 604 { 605 ConglomerateDescriptor index_cd = conglom_descriptors[cd_idx]; 606 607 if (!index_cd.isIndex()) 608 { 609 continue; 611 } 612 613 index_scan[index_idx] = 615 tc.openScan( 616 index_cd.getConglomerateNumber(), 617 true, TransactionController.OPENMODE_FORUPDATE, 619 TransactionController.MODE_TABLE, 620 TransactionController.ISOLATION_SERIALIZABLE, 621 null, null, 0, null, null, 0); 629 index_cc[index_idx] = 631 tc.openConglomerate( 632 index_cd.getConglomerateNumber(), 633 true, TransactionController.OPENMODE_FORUPDATE, 635 TransactionController.MODE_TABLE, 636 TransactionController.ISOLATION_SERIALIZABLE); 637 638 int[] baseColumnPositions = 640 index_cd.getIndexDescriptor().baseColumnPositions(); 641 int[] zero_based_map = 642 new int[baseColumnPositions.length]; 643 644 for (int i = 0; i < baseColumnPositions.length; i++) 645 { 646 zero_based_map[i] = baseColumnPositions[i] - 1; 647 } 648 649 index_col_map[index_idx] = zero_based_map; 650 651 index_row[index_idx] = 654 new DataValueDescriptor[baseColumnPositions.length + 1]; 655 656 index_idx++; 657 } 658 659 return; 660 } 661 662 663 678 private static void fixIndex( 679 DataValueDescriptor[] base_row, 680 DataValueDescriptor[] index_row, 681 RowLocation old_row_loc, 682 RowLocation new_row_loc, 683 ConglomerateController index_cc, 684 ScanController index_scan, 685 int[] index_col_map) 686 throws StandardException 687 { 688 if (SanityManager.DEBUG) 689 { 690 SanityManager.ASSERT(index_col_map != null); 693 SanityManager.ASSERT(index_row != null); 694 SanityManager.ASSERT( 695 (index_col_map.length == (index_row.length - 1))); 696 } 697 698 for (int index = 0; index < index_col_map.length; index++) 700 { 701 index_row[index] = base_row[index_col_map[index]]; 702 } 703 index_row[index_row.length - 1] = old_row_loc; 705 706 index_scan.reopenScan( 710 index_row, 711 ScanController.GE, 712 (Qualifier[][]) null, 713 index_row, 714 ScanController.GT); 715 716 if (index_scan.next()) 718 { 719 index_scan.delete(); 720 } 721 else 722 { 723 if (SanityManager.DEBUG) 725 { 726 SanityManager.THROWASSERT( 727 "Did not find row to delete." + 728 "base_row = " + RowUtil.toString(base_row) + 729 "index_row = " + RowUtil.toString(index_row)); 730 } 731 } 732 733 index_row[index_row.length - 1] = new_row_loc; 735 736 index_cc.insert(index_row); 737 738 return; 739 } 740 } 741 | Popular Tags |