1 package com.daffodilwoods.daffodildb.server.datasystem.persistentsystem; 2 3 import java.io.*; 4 5 import com.daffodilwoods.daffodildb.server.datasystem.interfaces.*; 6 import com.daffodilwoods.daffodildb.utils.byteconverter.*; 7 import com.daffodilwoods.database.resource.*; 8 import com.daffodilwoods.daffodildb.server.datasystem.persistentsystem. 9 versioninfo.VersionHandler; 10 import com.daffodilwoods.daffodildb.server.datasystem.utility. 11 SimpleFIFOReadWriteLocker; 12 13 18 public class LobManager { 19 20 23 24 public PersistentDatabase database; 25 26 29 30 private int[] startAddresses; 31 32 35 36 private int[] lastAddresses; 37 40 DatabaseProperties databaseProperties; 41 44 VersionHandler versionHandler; 45 49 private int MAXLENGTHFORFULLINSERT; 50 53 SimpleFIFOReadWriteLocker lock; 54 57 static Object monitor = new Object (); 58 59 private boolean isTempDatabase; 60 61 public LobManager(PersistentDatabase database0, int[] startAddresses0) throws 62 DException { 63 database = database0; 64 isTempDatabase = database.getDatabaseName().equalsIgnoreCase(DatabaseConstants.TEMPDATABASE); 65 versionHandler = database.getVersionHandler(); 66 databaseProperties = database.getDatabaseProperties(); 67 MAXLENGTHFORFULLINSERT = databaseProperties.CLUSTERSIZE - 68 versionHandler.CLUSTER_STARTPOINTER - versionHandler.NEWADDRESSLENGTH - 69 versionHandler.BLOBBYTESFORUPDATE - versionHandler.BLOBROWHEADER; 70 startAddresses = startAddresses0; 71 initializeLastClusterAddresses(); 72 lock = new SimpleFIFOReadWriteLocker(); 73 } 74 79 private void initializeLastClusterAddresses() throws DException { 80 int len = startAddresses.length; 81 lastAddresses = new int[len]; 82 for (int i = 0; i < len; i++) { 83 if (startAddresses[i] != -1) { 84 Cluster cls = database.getClusterForRead(new ClusterCharacteristics( 85 startAddresses[i], false), false); 86 lastAddresses[i] = CCzufDpowfsufs.getIntValue(cls.getBytes(), 87 3 * versionHandler.LENGTH); 88 } 89 } 90 } 91 92 103 104 public Object insertBlobBytes(_DatabaseUser user, Object dBlobUpdatable, 105 int columnIndex) throws DException { 106 try { 107 lock.lockTable(); 108 return insertBlobBytesWithoutLock(user, dBlobUpdatable,columnIndex); 109 } 110 finally { 111 lock.releaseTable(); 112 } 113 114 } 115 116 119 120 private void updateColumnPositions(Cluster cluster) throws DException { 121 cluster.addNewEntry(); 122 } 123 124 134 135 private boolean canWrite(int freeSpaceInCluster) { 136 return freeSpaceInCluster > 1 + 1 + 4 + 1 + 2; 137 } 138 139 145 private boolean canWrite(int freeSpaceInCluster, int lengthOfBytes) { 146 ; if (lengthOfBytes <= MAXLENGTHFORFULLINSERT) 148 return freeSpaceInCluster >= 149 (lengthOfBytes + versionHandler.BLOBROWHEADER) ? true : false; 150 else 151 return freeSpaceInCluster > versionHandler.BLOBROWHEADER; 152 } 153 159 public int getFreeSpaceForInsert(Cluster cluster) { 160 short spaceUsed = CCzufDpowfsufs.getShortValue(cluster.getBytes(), 0); 161 return (int) (databaseProperties.CLUSTERSIZE - spaceUsed - 162 versionHandler.NEWADDRESSLENGTH - 163 cluster.actualRecordCount * versionHandler.LENGTH - 164 versionHandler.BLOBBYTESFORUPDATE - 165 versionHandler.BLOBROWHEADER - versionHandler.LENGTH - 1); 166 } 167 168 178 179 private Object insert(_DatabaseUser user, _LobUpdatable blobUpdatabale, 180 int columnIndex) throws DException { 181 try { 182 InputStream stream = blobUpdatabale.getStream(); 183 int lastClusterId = lastAddresses[columnIndex]; 184 Cluster firstCluster = database.getCluster(user,new ClusterCharacteristics(startAddresses[ 185 columnIndex], false)); 186 ClusterCharacteristics lastCC = new ClusterCharacteristics(lastClusterId, false); 187 Cluster lastCluster = database.getCluster(user, lastCC); 188 Cluster previousCluster = null; 189 int startAddress = -1; 190 int totalLength = 0; 191 int freeSpaceInCluster = getFreeSpaceForInsert(lastCluster); 192 short recordId = (short) (lastCluster.getActualRecordCount() + 1); 193 short actualRecordId = recordId; 194 if (!canWrite(freeSpaceInCluster)) { Cluster nextCluster = database.getNewCluster(user, null); 196 lastCC= nextCluster.getClusterCharacteristics(); 197 lastCluster.setNextCluster(nextCluster); 198 manageClusters( user,lastCluster); lastCluster = nextCluster; 200 lastAddresses[columnIndex] = lastCC.getStartAddress(); 201 firstCluster.setLastCluster(lastCC); 202 freeSpaceInCluster = getFreeSpaceForInsert(lastCluster); 203 actualRecordId = recordId = 1; 204 } 205 ClusterCharacteristics totalLengthCC = lastCluster. 206 getClusterCharacteristics(); 207 startAddress = lastCC.getStartAddress(); 208 byte[] columnBytes = new byte[freeSpaceInCluster]; 209 int totalAvailableBytesInStream = stream.available(); 210 int readBytesLength = totalAvailableBytesInStream == 0 ? 0 : 211 stream.read(columnBytes); 212 int cnt = -1; 213 214 while (true) { 215 ++cnt; 216 byte[] bytes = lastCluster.getBytes(); 217 short insertableAddress = CCzufDpowfsufs.getShortValue(bytes, 0); 218 int pointer = insertableAddress; 219 totalLength += readBytesLength; 220 lastCluster.updateByte(pointer++, versionHandler.ACTIVE); 221 lastCluster.updateByte(pointer++, 222 totalLength == totalAvailableBytesInStream ? cnt > 0 ? 223 versionHandler.COMPLETE : versionHandler.FULL : 224 versionHandler.PARTIALLY); 225 pointer += 4; 226 System.arraycopy(columnBytes, 0, bytes, pointer, readBytesLength); 227 lastCluster.actualRecordCount++; 228 lastCluster.activeRecordCount++; 229 int recordStartPointer = databaseProperties.CLUSTERSIZE - 230 versionHandler.NEWADDRESSLENGTH - 231 lastCluster.actualRecordCount * versionHandler.LENGTH; 232 lastCluster.updateBytes(recordStartPointer, 233 CCzufDpowfsufs.getBytes(insertableAddress)); 234 updateColumnPositions(lastCluster); 235 lastCluster.updateColumnPositions( -1, insertableAddress); 236 lastCluster.updateClusterInformation( (short) (pointer + 237 readBytesLength)); 238 239 if (totalLength == totalAvailableBytesInStream) { 240 manageClusters(user,lastCluster); break; 242 } 243 previousCluster = lastCluster; 244 lastCluster = database.getNewCluster(user, null); 245 lastCC= lastCluster.getClusterCharacteristics(); 246 previousCluster.setNextCluster(lastCluster); 247 manageClusters(user,previousCluster); firstCluster.setLastCluster(lastCC); 249 lastAddresses[columnIndex] = lastCC.getStartAddress(); 250 freeSpaceInCluster = getFreeSpaceForInsert(lastCluster); 251 columnBytes = new byte[freeSpaceInCluster]; 252 readBytesLength = stream.read(columnBytes); 253 } 254 Cluster cls = database.getClusterForWrite(user, totalLengthCC); 255 int start = cls.getStartPointerOfRecord(actualRecordId); 256 cls.updateBytes(start + versionHandler.LENGTH, 257 CCzufDpowfsufs.getBytes(totalLength)); 258 blobUpdatabale.setStartingClusterAddress(startAddress); 259 blobUpdatabale.setRecordNumber(actualRecordId); 260 return blobUpdatabale; 261 } 262 catch (IOException ioe) { 263 throw new DException("DSE2025", new Object [] {ioe.getMessage()}); 264 } 265 } 266 267 268 276 277 public Object retrieveDataForBlob(int startClusterAddress, short recordNumber) { 278 DBlob dBlob = new DBlob(new ClusterCharacteristics(startClusterAddress, false), this, 279 recordNumber); 280 dBlob.setDatabaseProperties(databaseProperties); 281 DBlobUpdatable dBlobUpdatable = new DBlobUpdatable(dBlob); 282 dBlobUpdatable.setStartingClusterAddress(startClusterAddress); 283 dBlobUpdatable.setRecordNumber(recordNumber); 284 return dBlobUpdatable; 285 } 286 287 295 296 public Object retrieveDataForClob(int startClusterAddress, short recordNumber) { 297 DClob dClob = new DClob(new ClusterCharacteristics(startClusterAddress, false), this, 298 recordNumber); 299 dClob.setDatabaseProperties(databaseProperties); 300 DClobUpdatable dClobUpdatable = new DClobUpdatable(dClob); 301 dClobUpdatable.setStartingClusterAddress(startClusterAddress); 302 dClobUpdatable.setRecordNumber(recordNumber); 303 return dClobUpdatable; 304 } 305 306 316 317 public Object updateBlob(_DatabaseUser user, int startAddress, 318 Object dBlobUpdatable, int columnIndex, 319 short recordNumber) throws DException { 320 321 322 boolean flag = ( (_LobUpdatable) dBlobUpdatable).isStream(); if (startAddress == 0 && recordNumber == 0) return insertBlobBytes(user, (_LobUpdatable) dBlobUpdatable, 325 columnIndex); 326 if (flag) return updateStream(user, dBlobUpdatable, startAddress, columnIndex, 328 recordNumber); 329 byte[] columnBytes = ( (_LobUpdatable) dBlobUpdatable).getBytes(); 330 try { 331 lock.lockTable(); 332 ClusterCharacteristics firstCC = new ClusterCharacteristics(startAddress, false); 333 Cluster firstCluster = database.getClusterForWrite(user, firstCC); 334 byte[] clusterBytes = firstCluster.getBytes(); 335 336 short startPointer = firstCluster.getStartPointerOfRecord(recordNumber); 337 boolean isFull = clusterBytes[startPointer + 1] == versionHandler.FULL; 338 try { 339 if (isFull) { 340 updateIfFullyInserted(firstCluster, columnBytes, recordNumber, 341 startPointer, clusterBytes); 342 } 343 else { 344 updateIfPartialyInserted(user, firstCluster, columnBytes, 345 recordNumber, startPointer, columnIndex, 346 clusterBytes); 347 } 348 ( (_LobUpdatable) dBlobUpdatable).setStartingClusterAddress( 349 firstCluster.getClusterAddress()); 350 ( (_LobUpdatable) dBlobUpdatable).setRecordNumber(recordNumber); 351 return dBlobUpdatable; 352 } 353 catch (DException ex) { 354 if(!ex.getDseCode().equalsIgnoreCase("DSE0") ) 355 throw ex; 356 deleteBlobWithoutLock(user, startAddress, columnIndex, recordNumber); 357 return insertBlobBytesWithoutLock(user, dBlobUpdatable, columnIndex); 358 } 359 360 } 361 finally { 362 lock.releaseTable(); 363 } 364 365 } 366 387 private void updateIfPartialyInserted(_DatabaseUser user, Cluster cluster, 388 byte[] columnBytes, short recordNumber, 389 short startPointer, int columnIndex, 390 byte[] clusterBytes) throws DException { 391 int oldLength = CCzufDpowfsufs.getIntValue(clusterBytes, startPointer + 2); 392 int newLength = columnBytes.length; 393 int writtenSize = 0; 394 short margin = 0; 395 int remainingLength = newLength; 396 while (true) { 397 short oldLengthInThisCluster = getWrittenLengthInThisCluster(cluster, 398 recordNumber); 399 margin = newLength <= oldLength ? 0 : getMargin(cluster); 400 int lengthOfAdjustableBytes = remainingLength <= 401 oldLengthInThisCluster + margin ? remainingLength : 402 oldLengthInThisCluster + margin; 403 if (clusterBytes[startPointer + 1] != versionHandler.COMPLETE) { System.arraycopy(columnBytes, writtenSize, clusterBytes, 405 startPointer + 6, lengthOfAdjustableBytes); 406 cluster.updateBytes(startPointer + 2, 407 CCzufDpowfsufs.getBytes(columnBytes.length)); 408 cluster.updateClusterInformation( (short) (startPointer + 6 + 409 lengthOfAdjustableBytes)); 410 if (writtenSize + lengthOfAdjustableBytes >= newLength) { 411 cluster.updateByte(startPointer + 1, 412 writtenSize == 0 ? versionHandler.FULL : 413 versionHandler.COMPLETE); 414 adjustOtherClusters(user, cluster, (short) 1, columnIndex); 415 manageClusters(user,cluster); break; 417 } 418 } 419 else { 420 if (remainingLength > lengthOfAdjustableBytes) { 421 throw new DException("DSE0",new Object []{"Can't Update Here"}); 422 } 423 updateBytesOfLastRelatedCluster(cluster, recordNumber, startPointer, 424 columnBytes, writtenSize, 425 columnBytes.length); 426 break; 427 } 428 writtenSize += lengthOfAdjustableBytes; 429 remainingLength -= lengthOfAdjustableBytes; ClusterCharacteristics nextCC = cluster.getNextClusterCharacteristics(); 431 manageClusters(user,cluster); cluster = database.getClusterForWrite(user, nextCC); 433 recordNumber = 1; 434 clusterBytes = cluster.getBytes(); 435 startPointer = cluster.getStartPointerOfRecord(recordNumber); 436 } 437 } 438 439 452 453 private void updateBytesOfLastRelatedCluster(Cluster cluster, 454 short recordNumber, 455 short startPointer, 456 byte[] columnBytes, int start, 457 int end) throws DException { 458 byte[] clusterBytes = cluster.getBytes(); 459 int newLength = end - start; 460 if (recordNumber == cluster.actualRecordCount) { startPointer += 2; cluster.updateBytes(startPointer, 463 CCzufDpowfsufs.getBytes(columnBytes.length)); 464 startPointer += 4; 465 System.arraycopy(columnBytes, start, clusterBytes, startPointer, 466 newLength); startPointer += newLength; 468 cluster.updateClusterInformation(startPointer); 469 } 470 else { 471 short startPointerOfNextRecord = cluster.getStartPointerOfRecord( (short) ( 472 recordNumber + 1)); 473 short insertableAddress = CCzufDpowfsufs.getShortValue(clusterBytes, 0); 474 int tempLength = insertableAddress - startPointerOfNextRecord; 475 byte[] temp = new byte[tempLength]; 476 System.arraycopy(clusterBytes, startPointerOfNextRecord, temp, 0, 477 tempLength); 478 startPointer += 2; 479 cluster.updateBytes(startPointer, 480 CCzufDpowfsufs.getBytes(columnBytes.length)); 481 startPointer += 4; 482 System.arraycopy(columnBytes, start, clusterBytes, startPointer, 483 newLength); startPointer += newLength; 485 cluster.updateBytes(startPointer, temp); 486 487 short change = (short) (startPointer - startPointerOfNextRecord); 488 insertableAddress += change; 489 cluster.updateClusterInformation(insertableAddress); 490 int recordPointer = databaseProperties.CLUSTERSIZE - 491 versionHandler.NEWADDRESSLENGTH - 492 (recordNumber + 1) * versionHandler.LENGTH; 493 for (int i = recordNumber + 1; i <= cluster.actualRecordCount; i++) { 494 short strt = CCzufDpowfsufs.getShortValue(clusterBytes, recordPointer); 495 short now = (short) (strt + change); 496 cluster.updateBytes(recordPointer, CCzufDpowfsufs.getBytes(now)); 497 cluster.updateColumnPositions(i - 1, now); 498 recordPointer -= versionHandler.LENGTH; 499 } 500 } 501 } 502 503 513 514 private void adjustOtherClusters(_DatabaseUser user, Cluster cluster, 515 short recordNumber, int columnIndex) throws 516 DException { 517 Cluster currentCluster = cluster; 518 ClusterCharacteristics nextCC = cluster.getNextClusterCharacteristics(); 519 if (nextCC == null) 520 return; 521 522 cluster = database.getClusterForWrite(user, 523 cluster.getNextClusterCharacteristics()); 524 byte[] clusterBytes = cluster.getBytes(); 525 short startPointer = cluster.getStartPointerOfRecord(recordNumber); 526 while (clusterBytes[startPointer + 1] != versionHandler.COMPLETE) { 527 nextCC = cluster.getNextClusterCharacteristics(); 528 if (nextCC == null) 529 break; 530 database.addFreeCluster(user, cluster.getClusterAddress()); 531 cluster = database.getClusterForWrite(user, nextCC); 532 clusterBytes = cluster.getBytes(); 533 startPointer = cluster.getStartPointerOfRecord(recordNumber); 534 } 535 if (cluster.activeRecordCount == recordNumber && 536 cluster.getClusterAddress() != lastAddresses[columnIndex] && 537 cluster.getClusterAddress() != startAddresses[columnIndex]) { 538 int add = cluster.getClusterAddress(); 539 cluster = database.getClusterForWrite(user, 540 cluster.getNextClusterCharacteristics()); 541 database.addFreeCluster(user, add); 542 } 543 else { 544 } 545 currentCluster.setNextCluster(cluster); 546 } 547 548 572 575 576 private short getWrittenLengthInThisCluster(Cluster cluster, 577 short recordNumber) throws 578 DException { 579 short insertableAddress = CCzufDpowfsufs.getShortValue(cluster.getBytes(), 0); 580 short length = 0; 581 short start = cluster.getStartPointerOfRecord(recordNumber); 582 if (recordNumber == cluster.actualRecordCount) { 583 length = (short) (insertableAddress - start - 2 - 4); 584 } 585 else { 586 length = (short) (cluster.getStartPointerOfRecord( (short) (recordNumber + 587 1)) - start - 2 - 4); 588 } 589 return length; 590 } 591 592 603 604 private void updateIfFullyInserted(Cluster firstCluster, byte[] columnBytes, 605 short recordNumber, short startPointer, 606 byte[] clusterBytes) throws DException { 607 int oldLength = CCzufDpowfsufs.getIntValue(clusterBytes, startPointer + 2); 608 int newLength = columnBytes.length; 609 if (newLength <= oldLength || 610 newLength <= oldLength + getMargin(firstCluster)) { 611 updateBytesOfLastRelatedCluster(firstCluster, recordNumber, startPointer, 612 columnBytes, 0, newLength); 613 } 614 else 615 throw new DException("DSE0",new Object []{"Can't Update Here"}); 616 } 617 622 private short getMargin(Cluster cluster) { 623 short spaceUsed = CCzufDpowfsufs.getShortValue(cluster.getBytes(), 0); 624 return (short) (databaseProperties.CLUSTERSIZE - spaceUsed - 625 versionHandler.NEWADDRESSLENGTH - 626 cluster.actualRecordCount * versionHandler.LENGTH); 627 } 628 629 640 641 private Object updateStream(_DatabaseUser user, Object lobUpdatable, 642 int startAddress, int columnIndex, 643 short recordNumber) throws DException { 644 deleteBlob(user, startAddress, columnIndex, recordNumber); 645 return insertBlobBytes(user, (_LobUpdatable) lobUpdatable, columnIndex); 646 } 647 648 Cluster getCluster(ClusterCharacteristics cc) throws DException { 649 return database.getClusterForRead(cc, cc.isBtreeCluster); 650 } 651 652 PersistentDatabase getDatabase() { 653 return database; 654 } 655 656 665 666 public void deleteBlob(_DatabaseUser user, int startAddress, int columnIndex, 667 short recordNumber) throws DException { 668 try { 669 lock.lockTable(); 670 deleteBlobWithoutLock(user, startAddress, columnIndex,recordNumber); 671 } 672 finally { 673 lock.releaseTable(); 674 } 675 676 } 677 678 689 690 private void deleteBytesFromThisCluster(_DatabaseUser user, Cluster cluster, 691 short recordNumber, int columnIndex, 692 byte[] clusterBytes) throws 693 DException { 694 short startPointer = cluster.getStartPointerOfRecord(recordNumber); 695 short insertableAddress = CCzufDpowfsufs.getShortValue(clusterBytes, 0); 696 if (recordNumber == cluster.actualRecordCount) { 697 cluster.updateByte(startPointer++, versionHandler.DELETE); 698 cluster.activeRecordCount--; 699 cluster.updateClusterInformation( (short) (startPointer)); 700 } 701 else { 702 short length = getWrittenLengthInThisCluster(cluster, recordNumber); 703 short startPointerOfNextRecord = cluster.getStartPointerOfRecord( (short) ( 704 recordNumber + 1)); 705 int tempLength = insertableAddress - startPointerOfNextRecord; 706 byte[] temp = new byte[tempLength]; 707 System.arraycopy(clusterBytes, startPointerOfNextRecord, temp, 0, 708 tempLength); 709 710 cluster.updateByte(startPointer++, versionHandler.DELETE); 711 cluster.updateBytes(startPointer, temp); 712 713 cluster.activeRecordCount--; 714 short change = (short) (length + 4 + 2 - 1); 715 insertableAddress -= change; 716 cluster.updateClusterInformation(insertableAddress); 717 int i = recordNumber + 1; 718 int recordPointer = databaseProperties.CLUSTERSIZE - 719 versionHandler.NEWADDRESSLENGTH - i * versionHandler.LENGTH; 720 for (; i <= cluster.actualRecordCount; i++) { 721 short start = CCzufDpowfsufs.getShortValue(clusterBytes, recordPointer); 722 short now = (short) (start - change); 723 cluster.updateBytes(recordPointer, CCzufDpowfsufs.getBytes(now)); 724 cluster.updateColumnPositions(i - 1, now); 725 recordPointer -= versionHandler.LENGTH; 726 } 727 } 728 } 729 730 public VersionHandler getVersionHandler() { 731 return versionHandler; 732 } 733 746 public void deleteBlobWithoutLock(_DatabaseUser user, int startAddress, int columnIndex, 747 short recordNumber) throws DException { 748 if (startAddress == 0 && recordNumber == 0) { 749 return; 750 } 751 ClusterCharacteristics firstCC = new ClusterCharacteristics(startAddress, false); 752 Cluster cluster = database.getClusterForWrite(user, firstCC); 753 byte[] clusterBytes = cluster.getBytes(); 754 755 short startPointer = cluster.getStartPointerOfRecord(recordNumber); 756 boolean isFull = clusterBytes[startPointer + 1] == versionHandler.FULL; 757 if (isFull) { 758 deleteBytesFromThisCluster(user, cluster, recordNumber, columnIndex, 759 clusterBytes); 760 } 761 else { 762 deleteBytesFromThisCluster(user, cluster, recordNumber, columnIndex, 763 clusterBytes); 764 adjustOtherClusters(user,cluster,(short)1,columnIndex); 765 } 766 if (cluster.activeRecordCount == 0 && 767 cluster.getClusterAddress() != lastAddresses[columnIndex] && 768 cluster.getClusterAddress() != startAddresses[columnIndex]) { 769 ClusterCharacteristics prev = cluster.getPreviousClusterCharacteristics(); 770 if (prev != null) { 771 Cluster previousCluster = database.getClusterForWrite(user, prev); 772 previousCluster.setNextCluster(database.getClusterForWrite(user, 773 cluster.getNextClusterCharacteristics())); 774 database.addFreeCluster(user, cluster.getClusterAddress()); 775 } 776 } 777 } 778 779 794 795 public Object insertBlobBytesWithoutLock(_DatabaseUser user, Object dBlobUpdatable, 796 int columnIndex) throws DException { 797 _LobUpdatable blobUpdatable = (_LobUpdatable) dBlobUpdatable; 798 if ( ( (DBlobUpdatable) blobUpdatable).isDBlob()) { 799 return blobUpdatable; 800 } 801 802 if (blobUpdatable.isStream()) { 803 return insert(user, blobUpdatable, columnIndex); 804 } 805 806 807 Cluster previousCluster = null; 808 int startAddress = -1; 809 int lengthOfBytes = blobUpdatable.getLength(); 810 int lastClusterId = lastAddresses[columnIndex]; 811 812 Cluster firstCluster = null; 814 ClusterCharacteristics lastCC = new ClusterCharacteristics(lastClusterId, false); 815 Cluster cluster = database.getClusterForWrite(user, lastCC); 816 817 int freeSpaceInCluster = getFreeSpaceForInsert(cluster); 818 short recordId = (short) (cluster.getActualRecordCount() + 1); 819 short actualRecordId = recordId; 820 if (!canWrite(freeSpaceInCluster, lengthOfBytes)) { Cluster nextCluster = database.getNewCluster(user, null); 822 lastCC = nextCluster.getClusterCharacteristics(); 823 cluster.setNextCluster(nextCluster); 824 manageClusters(user,cluster); cluster = nextCluster; 826 lastAddresses[columnIndex] = lastCC.getStartAddress(); 827 828 829 firstCluster = database.getClusterForWrite(user, 830 new ClusterCharacteristics(startAddresses[columnIndex], false)); 831 firstCluster.setLastCluster(lastCC); 832 freeSpaceInCluster = getFreeSpaceForInsert(cluster); 833 actualRecordId = recordId = 1; 834 } 835 startAddress = lastCC.getStartAddress(); int writtenSize = 0; 837 int sizeToWrite = lengthOfBytes; 838 int size = sizeToWrite < freeSpaceInCluster ? sizeToWrite : 839 freeSpaceInCluster; 840 int cnt = -1; 841 int totalBytesWritten = 0; 842 while (true) { 843 cnt++; byte[] bytes = cluster.getBytes(); 845 short insertableAddress = CCzufDpowfsufs.getShortValue(bytes, 0); 846 int pointer = insertableAddress; 847 totalBytesWritten += size; 848 cluster.updateByte(pointer++, versionHandler.ACTIVE); 849 cluster.updateByte(pointer++, 850 totalBytesWritten == lengthOfBytes ? cnt > 0 ? 851 versionHandler.COMPLETE : versionHandler.FULL : 852 versionHandler.PARTIALLY); 853 854 cluster.updateBytes(pointer, CCzufDpowfsufs.getBytes(lengthOfBytes)); 855 pointer += 4; 856 System.arraycopy(blobUpdatable.readBytes(writtenSize, size), 0, bytes, 857 pointer, size); 858 cluster.actualRecordCount++; 859 cluster.activeRecordCount++; 860 int recordStartPointer = databaseProperties.CLUSTERSIZE - 861 versionHandler.NEWADDRESSLENGTH - 862 cluster.actualRecordCount * versionHandler.LENGTH; 863 cluster.updateBytes(recordStartPointer, 864 CCzufDpowfsufs.getBytes(insertableAddress)); 865 updateColumnPositions(cluster); 866 cluster.updateColumnPositions( -1, insertableAddress); 867 cluster.updateClusterInformation( (short) (pointer + size)); 868 writtenSize += size; 869 if (writtenSize == lengthOfBytes) { 870 manageClusters(user,cluster); break; 872 } 873 previousCluster = cluster; 874 cluster = database.getNewCluster(user, null); 875 lastCC = cluster.getClusterCharacteristics(); 876 previousCluster.setNextCluster(cluster); 877 if (firstCluster == null) 878 firstCluster = database.getClusterForWrite(user, 879 new ClusterCharacteristics(startAddresses[columnIndex], false)); 880 firstCluster.setLastCluster(lastCC); 881 manageClusters(user,previousCluster); lastAddresses[columnIndex] = lastCC.getStartAddress(); 883 freeSpaceInCluster = getFreeSpaceForInsert(cluster) + 884 versionHandler.BLOBBYTESFORUPDATE; sizeToWrite = lengthOfBytes - writtenSize; 886 size = sizeToWrite < freeSpaceInCluster ? sizeToWrite : 887 freeSpaceInCluster; 888 recordId = 1; 889 } 890 blobUpdatable.setRecordNumber(actualRecordId); 891 blobUpdatable.setStartingClusterAddress(startAddress); 892 return blobUpdatable; 893 894 } 895 907 public void manageClusters(_DatabaseUser user,Cluster cluster) throws DException{ 908 if(isTempDatabase){ 909 if(user.getSize() > 50) 910 user.writeToFileWithLock(); 911 } 912 else 913 database.updateWriteClusters(cluster); 914 915 } 916 917 927 928 929 933 934 935 936 937 938 939 943 } 944 | Popular Tags |