KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > daffodilwoods > daffodildb > server > datasystem > persistentsystem > DBlob


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 /**
15  * It is used to retieve and update blob column values, it reads and writes bytes in Cluster
16  */

17  public class DBlob{
18
19    /**
20     * Length of data of blob object's Stream.
21     */

22    private int lengthOfBlob=-1;
23
24    /**
25     * First cluster used to store it.
26     */

27    private WeakReference startCluster; // starting cluster
28

29    /**
30     * First cluster address
31     */

32    private ClusterCharacteristics startClusterCharacteristics;
33
34
35    /**
36     * To get Cluster for read and write
37     */

38    private LobManager lobManager;//for getting next and previous cluster if required
39

40    /**
41     * Record number in first cluster from where it is to be started to save.
42     */

43    short recordNumber = -1;
44
45    /**
46     * Database properties for getting any information like cluster size etc.
47     */

48    DatabaseProperties databaseProperties;
49
50    /**
51     * It is used to get constants which are changed according to version as LOBACTIVEBYTE etc.
52     */

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   /**
65    *
66    * @throws DException
67    */

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; // Length is written after ACTIVE/DELETED and FULL/PARTIAL bytes
75
lengthOfBlob = CCzufDpowfsufs.getIntValue(cluster.getBytes(),startPointer);
76            if(lengthOfBlob<0){
77          ;//// Removed By Program ** System.out.println("Hascode "+cluster.hashCode()+" cc "+cluster.getClusterCharacteristics()+" lengthOfBlob "+lengthOfBlob+" startPointer+2 "+startPointer+" recordNumber "+recordNumber);
78
}
79
80        }
81        else{
82          if(lengthOfBlob<0){
83          ;//// Removed By Program ** System.out.println("Hascode "+cluster.hashCode()+" cc "+cluster.getClusterCharacteristics()+" lengthOfBlob "+lengthOfBlob+" recordNumber "+recordNumber);
84
}
85
86        }
87    }
88
89    public long length() throws DException {
90       initialize();
91       return lengthOfBlob;
92    }
93    /**
94     * returns bytes from specified position and of given length
95     *
96     * @param pos position from where string is required
97     * @param length length of string which is required
98     *
99     * @return bytes from specified position and of given length
100     *
101     * @throws Exception If position is more than total length of bytes inserted
102     *
103     */

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 JavaDoc[]{new Long JavaDoc(pos),new Integer JavaDoc(lengthOfBlob)});
112       if((pos + length - 1) > lengthOfBlob)
113          throw new DException("DSE836", new Object JavaDoc[]{new Integer JavaDoc(length),new Long JavaDoc(pos),new Integer JavaDoc(lengthOfBlob)});
114       return retrieveBlobBytes((int)pos-1,length);
115    }
116
117
118
119    /**
120     * Update bytes from given position
121     *
122     * @param user To perform write operations on cluster
123     * @param pos position from where bytes has to update
124     * @param bytes new bytes
125     *
126     * @return number of bytes which are updated
127     *
128     * @throws Exception If position is more than total length of bytes inserted
129
130     */

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 JavaDoc[]{new Long JavaDoc(pos),new Integer JavaDoc(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 JavaDoc ex) {
168            throw ex;
169
170          }
171          return bytes;
172        }
173        short numberOfBytesWrittenInThisCluster = -1; //exact number of DATA BYTES stored in this cluster.
174
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; //ACTIVE/DELETE + FULL/PARTIAL + LENGTH OF RECORD
247
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 JavaDoc[]{new Long JavaDoc(len), new Integer JavaDoc(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 JavaDoc(truncatedLength));
308          cluster.updateBytes(versionHandler.ADDRESSLENGTH,bytes);
309       }
310
311 }
312
Popular Tags