1 package com.daffodilwoods.daffodildb.server.datasystem.persistentsystem; 2 3 import java.io.*; 4 import java.lang.ref.*; 5 import java.util.*; 6 import java.util.Map .*; 7 8 import com.daffodilwoods.daffodildb.server.datadictionarysystem.*; 9 import com.daffodilwoods.daffodildb.server.datasystem.interfaces.*; 10 import com.daffodilwoods.daffodildb.server.datasystem.persistentsystem.versioninfo.*; 11 import com.daffodilwoods.daffodildb.utils.byteconverter.*; 12 import com.daffodilwoods.database.general.*; 13 import com.daffodilwoods.database.resource.*; 14 15 public class PersistentDatabase 16 implements DatabaseConstants, _Database, _ClusterProvider { 17 18 21 private DRandomAccessFileUpto3_2 databaseFile; 22 23 26 27 private ClusterManager clusterManager; 28 29 32 33 private ClusterCharacteristics startClusterCharacteristics; 34 35 38 39 private TableManager tableManager; 40 41 44 45 private String databaseName; 46 47 50 51 private FreeSpaceManager freeSpaceManager; 52 53 56 private UserLock userLock; 57 58 61 private int nextAvailableAddress; 62 63 66 67 private PowerFileFactoryUpto3_2 powerFileFactory; 68 69 72 73 private long userCode; 74 75 78 79 private boolean writeInPowerFile; 80 81 84 85 public DatabaseProperties databaseProperties; 86 87 90 91 protected static String DEFAULTBTREEUPDATE = "true"; 92 93 96 private boolean closed = false; 97 98 101 VersionHandler versionHandler; 102 103 106 private String daffodilHome; 107 110 111 private boolean isReadOnlyMode = false; 112 113 123 public PersistentDatabase(DRandomAccessFileUpto3_2 file0, String databaseName0, 124 VersionHandler versionHandler0,String daffodilHome0,boolean isReadOnlyMode0) throws DException { 125 isReadOnlyMode = isReadOnlyMode0; 126 databaseFile = file0; 127 databaseName = databaseName0; 128 String databaseURL = file0.getURL(); 129 versionHandler = versionHandler0; 130 databaseProperties = versionHandler.getDatabaseProperties(); 131 tableManager = new TableManager(this, databaseProperties, versionHandler); 132 userCode = Long.MIN_VALUE; 133 startClusterCharacteristics = new ClusterCharacteristics(0, false); 134 userLock = new UserLock(); 135 daffodilHome = daffodilHome0; 136 String path = (daffodilHome + File.separator + 137 "daffodildb.ini").toLowerCase(); 138 File f = new File(path); 139 if (f.exists()) { 140 try { 141 InputStream is = new FileInputStream(f); 142 Properties p = new Properties(); 143 p.load(is); 144 String pfProperty = ("powerfile." + databaseName).trim().toLowerCase(); 145 String str = p.getProperty(pfProperty); 146 DEFAULTBTREEUPDATE = p.getProperty("defaultbtreeupdate", "true"); 147 writeInPowerFile = str == null ? true : str.equalsIgnoreCase("true"); 148 String clusterProperty = ("clusters.write."+databaseName).toLowerCase(); 149 String clusterInMemory = p.getProperty(clusterProperty); 150 151 if(clusterInMemory != null){ 152 int writeClusters = Integer.parseInt(clusterInMemory); 153 databaseProperties.setClusterInMemoryForWrite(writeClusters < 75 ? 75 : writeClusters) ; 154 } 155 clusterProperty = ("clusters.read."+databaseName).toLowerCase(); 156 clusterInMemory = p.getProperty(clusterProperty); 157 if(clusterInMemory != null){ 158 int readClusters = Integer.parseInt(clusterInMemory); 159 databaseProperties.setClusterstInMemoryForRead(readClusters < 75 ? 75 : readClusters); 160 } 161 162 163 } 164 catch (Exception ex) { 165 throw new DException("DSE0", new Object [] {ex.getMessage()}); 166 } 167 } 168 else 169 writeInPowerFile = true; 170 databaseProperties.setDatabaseName(databaseName); 171 172 173 init(databaseURL, true); 174 175 } 176 177 public PersistentDatabase(DRandomAccessFileUpto3_2 file0, String databaseName0, 178 boolean flag, VersionHandler versionHandler0,String daffodilHome0) throws 179 DException { 180 databaseFile = file0; 181 databaseName = databaseName0; 182 String databaseURL = file0.getURL(); 183 versionHandler = versionHandler0; 184 databaseProperties = versionHandler.getDatabaseProperties(); 185 tableManager = new TableManager(this, databaseProperties, versionHandler); 186 userCode = Long.MIN_VALUE; 187 startClusterCharacteristics = new ClusterCharacteristics(0, false); 188 writeInPowerFile = flag; 189 userLock = new UserLock(); 190 daffodilHome = daffodilHome0; 191 databaseProperties.setDatabaseName(databaseName); 192 databaseProperties.setClusterstInMemoryForRead(200); 193 databaseProperties.setClusterInMemoryForWrite(1000); 194 init(databaseURL, false); 195 196 } 197 198 211 212 ClusterCharacteristics createClusterCharacteristics( 213 _DatabaseUser user, QualifiedIdentifier tableName) throws DException { 214 return createClusterCharacteristics(user, tableName, false); 215 } 216 217 synchronized ClusterCharacteristics createClusterCharacteristics( 218 _DatabaseUser user, QualifiedIdentifier tableName, boolean isBTreeCluster) throws 219 DException { 220 int nextCluster = ( (TableManager) tableManager).checkFreeClusterList(user); 221 ClusterCharacteristics cla; 222 Cluster cluster; 223 if (nextCluster == -1) { 224 nextCluster = nextAvailableAddress; 225 nextAvailableAddress += 1; 226 updateNextAvailableAddress(); } 228 cla = new ClusterCharacteristics(nextCluster, isBTreeCluster); 229 cluster = clusterManager.getNewClusterForWrite(user, cla, isBTreeCluster); 230 updateNextInsertableAddressOfCluster(tableName, user, cluster); 231 cluster.initializeParameters(); 232 return cla; 233 } 234 235 240 241 DatabaseUserTable getDatabaseUserTable(QualifiedIdentifier tableName, 242 _TableList table) throws DException { 243 TableProperties tableProperties = table.getTableProperties(); 244 _RecordCluster recordCluster = versionHandler.getRecordCluster(tableProperties, databaseProperties); 245 return new DatabaseUserTable(table, recordCluster); 246 } 247 248 252 253 private void initializeNextAvailableClusterAddress() throws DException { 254 nextAvailableAddress = (int) databaseFile.readLong(0); 255 } 256 257 263 264 private void updateNextAvailableAddress() throws DException { 265 databaseFile.writeFirst(0,CCzufDpowfsufs.getBytes( (long)nextAvailableAddress)); 266 } 267 268 281 282 void updateNextInsertableAddressOfCluster(QualifiedIdentifier tableName, 283 _DatabaseUser user, Cluster cluster) throws 284 DException { 285 byte[] bytes = CCzufDpowfsufs.getBytes(versionHandler. 286 CLUSTER_STARTPOINTER); 287 byte[] zeroShortBytes = CCzufDpowfsufs.getBytes( (short) 0); 288 byte[] zeroIntBytes = CCzufDpowfsufs.getBytes(0); 289 byte[] zerolongBytes = CCzufDpowfsufs.getBytes(0L); 290 cluster.updateBytes(0, bytes); 291 cluster.updateBytes(versionHandler.LENGTH, zeroShortBytes); 292 cluster.updateBytes(2 * versionHandler.LENGTH, zeroShortBytes); 293 cluster.updateBytes(3 * versionHandler.LENGTH, zeroIntBytes); 294 cluster.updateBytes(versionHandler.ADDRESSLENGTH + versionHandler.LENGTH, 295 zerolongBytes); 296 cluster.updateBytes(2 * versionHandler.ADDRESSLENGTH + 297 versionHandler.LENGTH, zerolongBytes); 298 cluster.updateBytes(3 * versionHandler.ADDRESSLENGTH + 299 versionHandler.LENGTH, zeroIntBytes); 300 cluster.updateBytes(databaseProperties.NEXTCLUSTERADDRESS, zeroIntBytes); 301 } 302 303 308 309 private void writeDataInRespectiveClusters(HashMap map) throws DException { 310 Cluster cluster = null; 311 try { 312 Iterator entryIterator = map.entrySet().iterator(); 313 Entry entry; 314 { 315 ClusterCharacteristics cc = null; 316 while (entryIterator.hasNext()) { 317 entry = (Entry) entryIterator.next(); 318 cc = (ClusterCharacteristics) entry.getKey(); 319 cluster = (Cluster) ( (WeakReference) entry.getValue()).get(); 320 if (cluster == null) 321 cluster = getClusterForRead(cc, cc.isBtreeCluster); 322 if (cluster.isDirty()) { 323 long startAddress = (long) cc.getStartAddress() * 324 (long) databaseProperties.CLUSTERSIZE; 325 databaseFile.write(startAddress, cluster.getBytes()); 326 cluster.setDirty(false); 327 } 328 clusterManager.usedClusters.setStatusToRead(cc); 329 } 330 } 331 } 332 catch (Exception ne) { 333 throw new DException("DSE0", new Object [] {ne.getMessage()}); 334 } 335 } 336 341 public _DatabaseUser getDatabaseUser() throws DException { 342 return new DatabaseUser(this, userCode++); 343 } 344 345 353 public _DatabaseUser getDatabaseUser(ArrayList tables) throws DException { 354 return new DatabaseUser(this, userCode++, tables); 355 } 356 357 363 364 private void init(String databaseURL, boolean writeInTempFile) throws 365 DException { 366 initializeFile(databaseURL, writeInTempFile); 367 boolean flag = CCzufDpowfsufs.getBoolean(databaseFile.readFirst(new byte[1], 368 versionHandler.DATABASEINFOSTORED)).booleanValue(); 369 if (!flag) { 370 createNewDatabase(); 371 freeSpaceManager = new FreeSpaceManager(getTable(SystemTables. 372 FREESPACEINFO)); 373 tableManager.initializeSystemTableIndexes(true); 374 freeSpaceManager.setBtree(tableManager.createIndexOnSystemTable( 375 SystemTables.FREESPACEINFO, true)); 376 } 377 else{ 378 checkDataBase(databaseURL); 379 initializeNextAvailableClusterAddress(); 380 versionHandler.initializeSystemTables(tableManager, null, 381 clusterManager. 382 getClusterForReadFirst( 383 startClusterCharacteristics). 384 getBytes(), databaseName); 385 freeSpaceManager = new FreeSpaceManager(getTable(SystemTables. 386 FREESPACEINFO)); 387 tableManager.initializeSystemTableIndexes(false); 388 freeSpaceManager.setBtree(tableManager.createIndexOnSystemTable( 389 SystemTables.FREESPACEINFO, false)); 390 } 391 } 392 393 398 399 private void initializeFile(String databaseURL, boolean writeInTempFile) throws 400 DException { 401 try { 402 File ff = new File(databaseURL); 403 File ff1 = ff.getParentFile(); 404 String str = ff.getName(); 405 str = str.substring(0, str.lastIndexOf(".")); 406 if (writeInTempFile && !isReadOnlyMode) { 407 ff = new File(ff1,versionHandler.getTempFileName(str)); 408 RandomAccessFile tempFile = null; 409 tempFile = new RandomAccessFile(ff, "rw"); 410 tempFile.setLength(0); 411 clusterManager = new ClusterManager(tempFile, this, databaseProperties, 412 versionHandler,daffodilHome); 413 } 414 else{ 415 clusterManager = new ClusterManager(null, this, databaseProperties, 416 versionHandler,daffodilHome); 417 } 418 powerFileFactory = versionHandler.getPowerFileFactory(databaseURL); 419 } 420 catch (IOException fnfe) { 421 throw new DException("DSE2025", new Object [] {fnfe.getMessage()}); 422 } 423 } 424 425 426 427 428 private void checkDataBase(String databaseURL) throws DException { 429 if(isReadOnlyMode) 430 return ; 431 try { 432 File ff = new File(databaseURL); 433 File ff1 = ff.getParentFile(); 434 File[] files = ff1.listFiles(new PowerFileFilter()); 435 436 for (int i = 0; i < files.length; i++) { 437 RandomAccessFile powerFile = new RandomAccessFile(files[i], "r"); 438 powerFile.seek(versionHandler.ACTIVE_BYTE_POSITION_IN_POWERFILE); 439 if (powerFile.length() > 0 && powerFile.readByte() == versionHandler.ACTIVE) { 440 int length = powerFile.readInt(); 441 int actualClusterWritten = powerFile.readInt() ; 442 byte bytesOfStartAddress[] = new byte[actualClusterWritten*4]; 443 powerFile.read(bytesOfStartAddress); 444 byte[] bytes = new byte[databaseProperties.CLUSTERSIZE]; 445 powerFile.seek((long)((length*4)+9)) ; 446 for (int j = 0; j < actualClusterWritten; j++) { 447 int stadd = CCzufDpowfsufs.getIntValue(bytesOfStartAddress ,j*4 ); 448 powerFile.read(bytes); 449 long startAddress = (long) stadd * 450 (long) databaseProperties.CLUSTERSIZE; 451 databaseFile.write(startAddress, bytes); 452 } 453 } 454 powerFile.close(); 455 files[i].delete(); 456 } 457 } 458 catch (IOException IO) { 459 IO.printStackTrace(); 460 throw new DException("DSE2025", new Object [] {IO.getMessage()}); 461 } 462 } 463 469 private void createNewDatabase() throws DException { 470 _DatabaseUser user = getDatabaseUser(); 471 Cluster startCluster = clusterManager.getStartClusterForWriteFirst(user, 472 startClusterCharacteristics, false); 473 startCluster.updateBytes(versionHandler.DATABASEINFOSTORED, 474 CCzufDpowfsufs.getBytes(Utility.getBooleanValue("true") )); 475 nextAvailableAddress = 1; 476 versionHandler.writeInfoForSystemTables(startCluster, this); 477 versionHandler.initializeSystemTables(tableManager, user, 478 startCluster.getBytes(), databaseName); 479 user.writeToFile(); 480 updateNextAvailableAddress(); 481 } 482 489 public void writeInfoForSystemTable(int index, Cluster startCluster) throws 490 DException { 491 byte[] bytes = CCzufDpowfsufs.getBytes(new Long (nextAvailableAddress)); 492 startCluster.updateBytes(index * versionHandler.ADDRESSLENGTH, bytes); 493 startCluster.updateBytes( (index + 1) * versionHandler.ADDRESSLENGTH, bytes); 494 nextAvailableAddress += 1; 495 } 496 497 503 void writeAllClusterToFile(HashMap map) throws DException{ 504 if (closed) 505 return; 506 507 RandomAccessFile powerFile = null; 508 if (writeInPowerFile) { 509 powerFile = powerFileFactory.getFile(databaseProperties.CLUSTERSIZE,isReadOnlyMode); 510 writeDataInPowerFailureTable(map, powerFile); 511 512 writeDataInRespectiveClusters(map); 513 setPowerFailureByteNonActive(powerFile); 514 deleteDataFromPowerTable(powerFile); 515 } 516 else 517 writeDataInRespectiveClusters(map); 518 } 519 520 526 527 Cluster getClusterForRead(ClusterCharacteristics clusterCharacteristics, 528 boolean isBtreeCluster) throws DException { 529 return clusterManager.getClusterForRead(clusterCharacteristics, 530 isBtreeCluster); 531 } 532 539 Cluster getClusterForWrite(_DatabaseUser user, 540 ClusterCharacteristics clusterCharacteristics) throws 541 DException { 542 return clusterManager.getClusterForWrite(user, clusterCharacteristics); 543 } 544 545 546 552 private void setPowerFailureByteNonActive(RandomAccessFile powerFile) throws 553 DException { 554 try { 555 powerFile.seek(versionHandler.ACTIVE_BYTE_POSITION_IN_POWERFILE); 556 powerFile.write(versionHandler.POWERFILEDELETE); 557 } 558 catch (IOException ex) { 559 throw new DException("DSE0", new Object [] {ex.getMessage()}); 560 } 561 } 562 563 568 private void deleteDataFromPowerTable(RandomAccessFile powerFile) throws 569 DException { 570 powerFileFactory.addInFreePowerFileList(powerFile); 571 } 572 573 574 580 public _Table getTableInfo() throws DException { 581 return tableManager.getTableInfo(); 582 } 583 588 public void removeTable(QualifiedIdentifier tableName) { 589 tableManager.removeTable(tableName); 590 } 591 592 600 public synchronized _Table getTable(QualifiedIdentifier tableName, 601 BitSet TablesBitSet) throws DException { 602 return getTable(tableName); 603 } 604 605 606 613 public void addFreeCluster(_DatabaseUser user, int address) throws DException { 614 615 ClusterCharacteristics cc = new ClusterCharacteristics(address, false); 616 clusterManager.removeClusterBeforeAddingInFreeList(cc); 617 user.removeCluster(cc); 618 tableManager.addFreeCluster(user, address); 619 } 620 621 625 public String getDatabaseName() { 626 return databaseName; 627 } 628 629 635 636 public synchronized void createTable(QualifiedIdentifier tableName, 637 Object columnInfo) throws DException { 638 ColumnInformation ci = columnInfo instanceof TableCharacteristics ? 639 (ColumnInformation) ( (TableCharacteristics) columnInfo). 640 getColumnInformation() : (ColumnInformation) columnInfo; 641 tableManager.createTable(tableName, ci); 642 } 643 644 650 651 public synchronized void dropTable(QualifiedIdentifier tableName) throws 652 DException { 653 tableManager.dropTable(tableName); 654 } 655 656 662 663 public synchronized void renameTable(QualifiedIdentifier oldTableName, 664 QualifiedIdentifier newTableName) throws 665 DException { 666 ( (TableManager) tableManager).renameTable(oldTableName, newTableName); 667 } 668 675 public synchronized _Table getTable(QualifiedIdentifier tableName) throws 676 DException { 677 return tableManager.getTable(tableName); 678 } 679 686 byte[] getBytes(int startAddress) throws DException{ 687 long address = (long)startAddress * databaseProperties.CLUSTERSIZE; 688 return databaseFile.read(new byte[databaseProperties.CLUSTERSIZE], 689 address); 690 } 691 696 public _DatabaseUser getTempDatabaseUser() throws DException { 697 return new DatabaseUser(this, userCode++, true); 698 } 699 700 701 702 712 private void writeDataInPowerFailureTable(HashMap map,RandomAccessFile powerFile) throws 713 DException { 714 Cluster cluster = null; 715 try { 716 717 int length = map.size(); 718 byte bytes[] = new byte[length*4+8+1]; 719 int index = 0; 720 bytes[index++] = versionHandler.ACTIVE; 721 CCzufDpowfsufs.putInt(bytes,index,length ); 722 index += 4; 723 int noOfClustersForWrite = 0; 724 Iterator entryIterator = map.entrySet().iterator(); 725 Entry entry; 726 { 727 ClusterCharacteristics cc = null; 728 powerFile.seek(bytes.length); 729 while (entryIterator.hasNext()) { 730 entry = (Entry) entryIterator.next(); 731 cc = (ClusterCharacteristics) entry.getKey(); 732 cluster = (Cluster) ( (WeakReference) entry.getValue()).get(); 733 734 if (cluster == null) 735 cluster = clusterManager.getClusterForPowerFile(cc, 736 cc.isBtreeCluster); 737 if (!cluster.isDirty()) { 738 clusterManager.usedClusters.setStatusToRead(cc); 739 } 740 else { 741 noOfClustersForWrite++; 742 index += 4; 743 CCzufDpowfsufs.putInt(bytes, index, 744 cluster.clusterCharacteristics.getStartAddress()); 745 powerFile.write(cluster.getBytes()); 746 } 747 } 748 } 749 CCzufDpowfsufs.putInt(bytes,5,noOfClustersForWrite ); 750 powerFile.seek(versionHandler.ACTIVE_BYTE_POSITION_IN_POWERFILE); 751 powerFile.write(bytes) ; 752 } 753 catch (Exception E) { 754 throw new DException("DSE0", new Object [] {E.getMessage()}); 755 } 756 } 757 758 759 765 766 public void updateWriteClusters(Cluster cluster) throws DException { 767 clusterManager.updateWriteClusters(cluster); 768 } 769 773 public UserLock getUserLock() { 774 return userLock; 775 } 776 777 778 785 public void writeInFile(int address, byte[] bytes) throws DException { 786 databaseFile.writeFirst(address, bytes); 787 } 788 795 796 public byte[] readBytes(int address, int length) throws DException { 797 return databaseFile.readFirst(new byte[length], address); 798 } 799 806 byte[] getBytesFirst(int startAddress) throws DException { 807 long address = (long)startAddress * databaseProperties.CLUSTERSIZE; 808 return databaseFile.readFirst(new byte[databaseProperties.CLUSTERSIZE], 809 address); 810 } 811 812 public ClusterManager getClusterManager() { 813 return clusterManager; 814 } 815 819 public void closeFile() throws DException { 820 try { 821 powerFileFactory.close(); 822 databaseFile.close(); 823 clusterManager.closeFile(); 824 closed = true; 825 } 826 catch (IOException ex) { 827 throw new DException("DSE2025", new Object [] {ex.getMessage()}); 828 } 829 } 830 831 protected void finalize() throws DException { 832 try { 833 powerFileFactory.close(); 834 databaseFile.close(); 835 clusterManager.closeFile(); 836 } 837 catch (IOException ex) { 838 throw new DException("DSE2025", new Object [] {ex.getMessage()}); 839 } 840 } 841 848 public Cluster getNewCluster(_DatabaseUser user) throws 849 DException { 850 return getNewCluster(user, null, true); 851 } 852 853 861 public Cluster getCluster(_DatabaseUser user, ClusterCharacteristics cc) throws 862 DException { 863 return clusterManager.getClusterForWrite(user, cc, true); 864 } 865 872 public Cluster getReadCluster(ClusterCharacteristics cc) throws DException { 873 return clusterManager.getClusterForRead(cc, true); 874 } 875 876 885 static class PowerFileFilter 886 implements FilenameFilter { 887 public boolean accept(File dir, String name) { 888 return name.endsWith("PowerFile.log") ? true 889 : false; 890 } 891 } 892 893 895 896 904 public ClusterCharacteristics getControlCluster(_DatabaseUser user) throws 905 DException { 906 Cluster cluster = getNewCluster(user, null, true); 907 cluster.updateBytes(3 * versionHandler.ADDRESSLENGTH + 908 3 * versionHandler.LENGTH, CCzufDpowfsufs.getBytes(0)); 909 cluster.updateBytes(4 * versionHandler.ADDRESSLENGTH + 910 versionHandler.LENGTH, 911 CCzufDpowfsufs.getBytes( (long) 0)); 912 return cluster.getClusterCharacteristics(); 913 } 914 915 916 920 public DatabaseProperties getDatabaseProperties() { 921 return databaseProperties; 922 } 923 930 ClusterCharacteristics getLastClusterClaracteristics(QualifiedIdentifier 931 tableName) throws DException { 932 return tableManager.getLastClusterClaracteristics(tableName); 933 } 934 935 939 public DRandomAccessFileUpto3_2 getDrandomAccessFile() { 940 return databaseFile; 941 } 942 943 944 945 951 public double getTotalNumberOfUsedClusters() throws DException { 952 return clusterManager.usedClusters.size(); 953 } 954 955 959 public HashMap getTablesMap() { 960 return tableManager.getTableMap(); 961 } 962 963 public VersionHandler getVersionHandler() { 964 return versionHandler; 965 } 966 970 public boolean getPowerFileOption(){ 971 return writeInPowerFile; 972 } 973 977 public void setWriteInPowerFile(boolean flag){ 978 writeInPowerFile = flag; 979 } 980 988 Cluster getNewCluster(_DatabaseUser user, QualifiedIdentifier tableName) throws DException { 989 return getNewCluster(user, tableName, false); 990 } 991 1002 synchronized Cluster getNewCluster(_DatabaseUser user, QualifiedIdentifier tableName, boolean isBTreeCluster) throws 1003 DException { 1004 int nextCluster = ( (TableManager) tableManager).checkFreeClusterList(user); 1005 ClusterCharacteristics cla; 1006 Cluster cluster; 1007 if (nextCluster == -1) { 1008 nextCluster = nextAvailableAddress; 1009 nextAvailableAddress += 1; 1010 updateNextAvailableAddress(); } 1012 1013 cla = new ClusterCharacteristics(nextCluster, isBTreeCluster); 1014 cluster = clusterManager.getNewClusterForWrite(user, cla, isBTreeCluster); 1015 updateNextInsertableAddressOfCluster(tableName, user, cluster); 1016 cluster.initializeParameters(); 1017 return cluster; 1018 } 1019 1020 1024 public String getDaffodilHome(){ 1025 return daffodilHome; 1026} 1027 1031public void showFreeClusterList() throws DException{ 1032 tableManager.showFreeClusterList() ; 1033 } 1034 1038 public FreeClusterList getFreeClusterList(){ 1039 return tableManager.getFreeClusterList(); 1040 } 1041 1042 1169 1170 1171 1190 1191 1192 1198 1199 1200 1209 1210 1211 1212 1213 1214} 1215 | Popular Tags |