1 package com.daffodilwoods.daffodildb.server.datasystem.persistentsystem; 2 3 import com.daffodilwoods.daffodildb.server.datasystem.interfaces.*; 4 import com.daffodilwoods.daffodildb.utils.byteconverter.*; 5 import com.daffodilwoods.database.resource.*; 6 import java.io.*; 7 import java.sql.*; 8 import java.lang.ref.*; 9 import com.daffodilwoods.daffodildb.server.sql99.utils._Reference; 10 import com.daffodilwoods.daffodildb.server.datasystem.interfaces._DatabaseUser; 11 import com.daffodilwoods.daffodildb.server.datasystem.persistentsystem.versioninfo.VersionHandler; 12 import com.daffodilwoods.daffodildb.server.datasystem.btree.*; 13 14 17 public class DBlob{ 18 19 22 private int lengthOfBlob=-1; 23 24 27 private WeakReference startCluster; 29 32 private ClusterCharacteristics startClusterCharacteristics; 33 34 35 38 private LobManager lobManager; 40 43 short recordNumber = -1; 44 45 48 DatabaseProperties databaseProperties; 49 50 53 VersionHandler versionHandler; 54 55 56 DBlob(ClusterCharacteristics cc,LobManager lobManager0,short recordNumber0) { 57 startClusterCharacteristics = cc; 58 startCluster = new WeakReference(null); 59 lobManager = lobManager0; 60 recordNumber = recordNumber0; 61 versionHandler = lobManager.getVersionHandler(); 62 } 63 64 68 protected void initialize() throws DException{ 69 Cluster cluster = startCluster == null ? null : (Cluster)startCluster.get(); 70 if(cluster == null && startClusterCharacteristics != null) 71 cluster = lobManager.getCluster(startClusterCharacteristics); 72 if(lengthOfBlob == -1 && startCluster != null){ 73 int startPointer = cluster.getStartPointerOfRecord(recordNumber); 74 startPointer += 2; lengthOfBlob = CCzufDpowfsufs.getIntValue(cluster.getBytes(),startPointer); 76 if(lengthOfBlob<0){ 77 ; } 79 80 } 81 else{ 82 if(lengthOfBlob<0){ 83 ; } 85 86 } 87 } 88 89 public long length() throws DException { 90 initialize(); 91 return lengthOfBlob; 92 } 93 104 105 public byte[] getBytes(long pos, int length) throws DException { 106 if(length == 0 ) return new byte[0]; 107 initialize(); 108 if(pos < 1) 109 throw new DException("DSE798",null); 110 if(pos > lengthOfBlob) 111 throw new DException("DSE939", new Object []{new Long (pos),new Integer (lengthOfBlob)}); 112 if((pos + length - 1) > lengthOfBlob) 113 throw new DException("DSE836", new Object []{new Integer (length),new Long (pos),new Integer (lengthOfBlob)}); 114 return retrieveBlobBytes((int)pos-1,length); 115 } 116 117 118 119 131 public int setBytes(_DatabaseUser user,long pos, byte[] bytes) throws DException { 132 initialize(); 133 if(pos > lengthOfBlob) 134 throw new DException("DSE939", new Object []{new Long (pos),new Integer (lengthOfBlob)}); 135 updateBlobClob(user,(int)pos,bytes); 136 return bytes.length; 137 } 138 139 140 141 142 143 144 private byte[] retrieveBlobBytes(int position,int lengthOfBytes) throws DException{ 145 try{ 146 lobManager.lock.lockRowForRead(lobManager.monitor); 147 byte[] bytes = new byte[lengthOfBytes]; 148 Cluster cluster = startCluster == null ? null : 149 (Cluster) startCluster.get(); 150 if (cluster == null && startClusterCharacteristics != null) 151 cluster = lobManager.getCluster(startClusterCharacteristics); 152 if (cluster == null) 153 return new byte[0]; 154 byte[] clusterBytes = cluster.getBytes(); 155 short recordToRetrieve = recordNumber; 156 short startPointer = cluster.getStartPointerOfRecord(recordToRetrieve); 157 if(clusterBytes[startPointer] == versionHandler.DELETE) 158 throw StaticExceptions.RECORD_DELETED_EXCEPTION ; 159 startPointer++; 160 boolean isFull = clusterBytes[startPointer++] == versionHandler.FULL; 161 startPointer += 4; 162 if (isFull) { 163 try { 164 System.arraycopy(clusterBytes, startPointer + position, bytes, 0, 165 lengthOfBytes); 166 } 167 catch (ArrayIndexOutOfBoundsException ex) { 168 throw ex; 169 170 } 171 return bytes; 172 } 173 short numberOfBytesWrittenInThisCluster = -1; while (true) { 175 numberOfBytesWrittenInThisCluster = 176 getNumberOfBytesWrittenInThisCluster(cluster, recordToRetrieve); 177 if (position > numberOfBytesWrittenInThisCluster) { 178 position = position - numberOfBytesWrittenInThisCluster; 179 cluster = lobManager.getCluster(cluster.getNextClusterCharacteristics()); 180 recordToRetrieve = 1; 181 } 182 else 183 break; 184 } 185 int sizeWhichCanAdjust = numberOfBytesWrittenInThisCluster - position; 186 sizeWhichCanAdjust = sizeWhichCanAdjust > lengthOfBytes ? lengthOfBytes : 187 sizeWhichCanAdjust; 188 int place = 0; 189 while (true) { 190 clusterBytes = cluster.getBytes(); 191 startPointer = cluster.getStartPointerOfRecord(recordToRetrieve); 192 startPointer += versionHandler.LOBACTIVEBYTE + 193 versionHandler.LOBFULLBYTE + versionHandler.LOBRECORDLENGTH; 194 System.arraycopy(clusterBytes, startPointer + position, bytes, place, 195 sizeWhichCanAdjust); 196 place += sizeWhichCanAdjust; 197 if (sizeWhichCanAdjust >= lengthOfBytes) 198 break; 199 else { 200 lengthOfBytes -= sizeWhichCanAdjust; 201 cluster = lobManager.getCluster(cluster. 202 getNextClusterCharacteristics()); 203 recordToRetrieve = 1; 204 numberOfBytesWrittenInThisCluster = 205 getNumberOfBytesWrittenInThisCluster(cluster, recordToRetrieve); 206 position = 0; 207 sizeWhichCanAdjust = numberOfBytesWrittenInThisCluster > 208 lengthOfBytes ? lengthOfBytes : numberOfBytesWrittenInThisCluster; 209 } 210 } 211 return bytes; 212 }finally { 213 lobManager.lock.releaseRowForRead(lobManager.monitor); 214 } 215 } 216 217 private short getNumberOfBytesWrittenInThisCluster(Cluster cluster,short recordToRetrieve) throws DException{ 218 short numberOfBytesWrittenInThisCluster = -1; 219 byte[] clusterBytes = cluster.getBytes(); 220 if(recordToRetrieve == cluster.actualRecordCount){ 221 numberOfBytesWrittenInThisCluster = (short)(CCzufDpowfsufs.getShortValue(clusterBytes,0) - cluster.getStartPointerOfRecord(recordToRetrieve) - versionHandler.LOBRECORDLENGTH - versionHandler.LOBACTIVEBYTE - versionHandler.LOBFULLBYTE); 222 } 223 else{ 224 numberOfBytesWrittenInThisCluster = (short)(cluster.getStartPointerOfRecord((short)(recordToRetrieve+1)) - cluster.getStartPointerOfRecord(recordToRetrieve) - versionHandler.LOBRECORDLENGTH - versionHandler.LOBACTIVEBYTE - versionHandler.LOBFULLBYTE); 225 226 } 227 return numberOfBytesWrittenInThisCluster; 228 } 229 230 231 private void updateBlobClob(_DatabaseUser user,int position,byte[] bytes) throws DException { 232 Cluster cluster = startCluster == null ? null : (Cluster)startCluster.get(); 233 if(cluster == null && startClusterCharacteristics != null) 234 cluster = lobManager.getCluster(startClusterCharacteristics); 235 short recordToRetrieve = recordNumber; 236 int start = 0; 237 int lengthOfBytes = bytes.length; 238 int totalLength = CCzufDpowfsufs.getIntValue(cluster.getBytes(),cluster.getStartPointerOfRecord(recordToRetrieve) + versionHandler.LOBACTIVEBYTE + versionHandler.LOBFULLBYTE); 239 Cluster temp = cluster; 240 int i = 0; 241 int writtenSize = 0; 242 while(true){ 243 int writtenNumberOfBytesInThisCluster = getNumberOfBytesWrittenInThisCluster(temp,recordToRetrieve); 244 int range = getFreeSpaceForUpdate(temp,recordToRetrieve); 245 if(position < writtenNumberOfBytesInThisCluster){ 246 int startPointer =cluster.getStartPointerOfRecord(recordToRetrieve) + versionHandler.LOBACTIVEBYTE + versionHandler.LOBFULLBYTE + versionHandler.LOBRECORDLENGTH + position; int rw = position + lengthOfBytes <= range ? lengthOfBytes : range - position; 248 249 lengthOfBytes -= rw; 250 writtenSize+= rw; 251 byte[] clusterBytes = new byte[rw]; 252 System.arraycopy(bytes,start,clusterBytes,0,rw); 253 temp.updateBytes(startPointer,clusterBytes); 254 if(writtenSize!=totalLength){ 255 if (rw+position > writtenNumberOfBytesInThisCluster) { 256 short insertableAddress = (short) (rw + startPointer); 257 temp.updateBytes(0, CCzufDpowfsufs.getBytes(insertableAddress)); 258 } 259 } 260 if (lengthOfBytes <= 0) 261 break; 262 start += rw; 263 i++; 264 } 265 ClusterCharacteristics next = getNextClusterCharacteristics(temp); 266 temp = lobManager.getDatabase().getClusterForWrite(user,next); 267 recordToRetrieve = 1; 268 position = position > writtenNumberOfBytesInThisCluster ? position - writtenNumberOfBytesInThisCluster : 0; 269 } 270 } 271 272 273 274 ClusterCharacteristics getNextClusterCharacteristics(Cluster cc) throws DException { 275 int startAddress = CCzufDpowfsufs.getIntValue(cc.getBytes(), 276 databaseProperties.CLUSTERSIZE - 2 * versionHandler.LENGTH); 277 return startAddress == 0 ? null : new ClusterCharacteristics(startAddress,false); 278 } 279 280 public void setDatabaseProperties(DatabaseProperties dp) { 281 databaseProperties = dp; 282 } 283 284 public LobManager getLobManager(){ 285 return lobManager; 286 } 287 288 public int getFreeSpaceForUpdate(Cluster cluster,short recordNumber) throws DException { 289 return (databaseProperties.CLUSTERSIZE - cluster.getStartPointerOfRecord(recordNumber) - versionHandler.NEWADDRESSLENGTH - cluster.actualRecordCount * versionHandler.LENGTH - versionHandler.LOBACTIVEBYTE - versionHandler.LOBFULLBYTE - versionHandler.LOBRECORDLENGTH - versionHandler.LENGTH - 1); 290 } 291 292 293 public void truncate(long len) throws DException { 294 initialize(); 295 if(len > lengthOfBlob) 296 throw new DException("DSE1017", new Object []{new Long (len), new Integer (lengthOfBlob)}); 297 if(lengthOfBlob == len) 298 return; 299 updateLengthOfBlobClob(len); 300 } 301 302 void updateLengthOfBlobClob(long truncatedLength)throws DException{ 303 initialize(); 304 Cluster cluster = startCluster == null ? null : (Cluster)startCluster.get(); 305 if(cluster == null && startClusterCharacteristics != null) 306 cluster = lobManager.getCluster(startClusterCharacteristics); 307 byte[] bytes = CCzufDpowfsufs.getBytes(new Long (truncatedLength)); 308 cluster.updateBytes(versionHandler.ADDRESSLENGTH,bytes); 309 } 310 311 } 312 | Popular Tags |