KickJava   Java API By Example, From Geeks To Geeks.

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


1 package com.daffodilwoods.daffodildb.server.datasystem.persistentsystem;
2
3 import com.daffodilwoods.daffodildb.server.datasystem.persistentsystem.versioninfo.*;
4 import com.daffodilwoods.daffodildb.utils.*;
5 import com.daffodilwoods.daffodildb.utils.byteconverter.*;
6 import com.daffodilwoods.database.resource.*;
7 import com.daffodilwoods.daffodildb.server.datasystem.btree.*;
8
9 /**
10  *
11  * <p>Title: Fixed Record Cluster</p>
12  * <p>Description: Maintains -insert, delete, update and retrieve operations on table having all Columns of
13  * fixed type
14  * </p>
15  */

16 public class PartialFixedRecordCluster extends FixedRecordCluster{
17
18   /**
19    * Minimum space that we required to store a record it includes Active/Delete + Full/Partial + 2 bytes for length of bytes
20    * stored in this cluster + 2 bytes for insertable address pointer + 4 bytes for next cluster address + 1 byte as data bit its usage not defined yet.
21    */

22   int MINRECORDLENGTH;
23
24     public PartialFixedRecordCluster(TableProperties tp,DatabaseProperties databaseProperties0,VersionHandler versionHandler0) throws DException {
25         super(tp,databaseProperties0,versionHandler0);
26         MINRECORDLENGTH = versionHandler.ACTIVE_DELETE + versionHandler.FULL_PARTIAL + versionHandler.LENGTH + 7;
27     }
28
29     /**
30      * checks InsertType of Record whether Record can be fully Inserted, partially Inserted or can not be
31      * inserted in current cluster, write bytes and return insertType and written number of bytes if record
32      * is partially inserted.
33      *
34      * @param bytes bytes of record which has to write
35      *
36      * @param startColumnIndex Position from where bytes has to write
37      * @return InsertType and written Number of Bytes
38      */

39
40     public int[] insert(byte[] bytes,int startColumnIndex, boolean isUpdate) throws DException {
41
42         int insertType = insertType(bytes, startColumnIndex);
43         return insertType == NONE ? new int[]{FAILED,0} : partialInsertRecord(bytes,getNextInsertableAddress(),startColumnIndex,isUpdate);
44     }
45
46     /**
47      * Checks whether record can be Fully or Partailly inserted or can not be inserted in current cluster
48      *
49      * @param bytes bytes of record which has to insert
50      *
51      * @param startPosition position from where have to write
52      *
53      * @return type of insertion (Fully, Partially or None)
54      */

55     private int insertType(byte[] bytes,int startPosition) throws DException {
56         int recordSize = bytes.length + versionHandler.ACTIVE_DELETE + versionHandler.FULL_PARTIAL + versionHandler.LENGTH ;
57         return startPosition > 0 ? PARTIALY : recordSize <= freeSpace() ? FULLY
58         : recordSize > databaseProperties.CLUSTERSIZE && freeSpace() > MINRECORDLENGTH
59                 ? PARTIALY : NONE;
60     }
61
62     /**
63      * Inserts record partially according to free space in Cluster,Updates actual Record Count and returns
64      * Insert Type and Total written bytes of record bytes
65      *
66      * @param bytes total record bytes
67      *
68      * @param insertAdd inseratable address in Cluster
69      *
70      * @param startPosition Position form where bytes has to write form total bytes
71      * @return Insert Type and Total written record size
72      */

73
74     private int[] partialInsertRecord(byte[] bytes,short insertAdd,int startPosition, boolean isUpdate) throws DException {
75         short position = insertAdd;
76         cluster.updateByte(position++,startPosition == 0 ? versionHandler.ACTIVE : versionHandler.DELETE);
77         short recordSizePointer = (short)(databaseProperties.CLUSTERSIZE -
78                 versionHandler.NEWADDRESSLENGTH - cluster.actualRecordCount * versionHandler.LENGTH - versionHandler.LENGTH);
79         int range = freeSpace() - cluster.actualRecordCount * versionHandler.LENGTH - versionHandler.LENGTH - 1 - 1 -1 ;
80         int bytesTowrite = bytes.length - startPosition;
81         int possibleLength = range > bytesTowrite ? bytesTowrite : range;
82         cluster.updateByte(position++,range > bytesTowrite ? versionHandler.COMPLETE : versionHandler.PARTIALLY);
83         cluster.updateBytes(bytes,startPosition,position,possibleLength);
84         if(startPosition == 0)
85             cluster.activeRecordCount++;
86         cluster.actualRecordCount++;
87         cluster.updateClusterInformation((short)(position+possibleLength));
88         cluster.updateBytes(recordSizePointer,CCzufDpowfsufs.getBytes( (short)(possibleLength)));
89         int writtenSize = possibleLength + startPosition;
90         return writtenSize == bytes.length ? new int[]{SUCCESSFUL,0} : new int[]{PARTIAL,writtenSize};
91     }
92
93     /**
94      * To retrieve bytes of specified record.
95      *
96      * Firstly we move our pointer to recordNumber.
97      * check that is record deleted. After than check it is fully inserted.
98      * if partially than we read its recordSize pointer and get how many bytes
99      * written in this cluster and than read and throw an exception for partial
100      * read and also pass bytes read with this exception.
101      * else we doesn't read anything returns an empty bufferrange
102      * by making its isNull true.
103      *
104      *
105      * @param recordNumber short - whose bytes to be retrived.
106      * @throws DException
107      * @return BufferRange - bytes of record.
108      */

109     public BufferRange retrieveBufferRange(short recordNumber ) throws DException {
110                byte[] clusterBytes = cluster.getBytes();
111                int pointer = moveToRecordNumber(clusterBytes,recordNumber);
112                if(clusterBytes[pointer++] == versionHandler.DELETE )
113                    throw new DException("DSE2003",new Object JavaDoc[] {new Integer JavaDoc(recordNumber)});
114                byte isComplete = clusterBytes[pointer++];
115                if( isComplete == versionHandler.PARTIALLY){
116                    int recordSizePointer = databaseProperties.CLUSTERSIZE -
117                            2 * versionHandler.LENGTH - recordNumber * versionHandler.LENGTH ;
118                    short sad = CCzufDpowfsufs.getShortValue(clusterBytes,recordSizePointer) ;
119                    byte[] dd = new byte[sad];
120                    System.arraycopy(clusterBytes,pointer,dd,0,sad);
121                    BufferRange bf = new BufferRange(dd,0,sad);
122                    throw new DException("DSE2006",new Object JavaDoc[]{bf});
123                }
124                return new BufferRange(true);
125     }
126
127
128     /**
129      * Retrieves Pariallly written record , it returns bytes written in current cluster and status whether
130      * record is completely retrieved or some bytes are in next cluster
131      *
132      * @param recordNumber recordNumber whose bytes has to retrieve
133      * @return record bytes and status whether record is completely retrieved or not
134      *
135      */

136
137     public Object JavaDoc [] partialRetrieve(short recordNumber ) throws DException {
138         byte[] clusterBytes = cluster.getBytes();
139         int pointer = moveToRecordNumber(clusterBytes,recordNumber);
140         pointer++;
141         byte isComplete = clusterBytes[pointer++];
142         int recordSizePointer = databaseProperties.CLUSTERSIZE -
143                                 2 * versionHandler.LENGTH - recordNumber * versionHandler.LENGTH ;
144         short sad = CCzufDpowfsufs.getShortValue(clusterBytes,recordSizePointer);
145         byte[] dd = new byte[sad];
146         System.arraycopy(clusterBytes,pointer,dd,0,sad);
147         return new Object JavaDoc[] {dd,new byte[] {isComplete}};
148
149     }
150
151
152     /**
153      * Marks Record Deleted and shifts all next written records by Deleted Record size and updates active
154      * record Count and insertable Address in Cluster.
155      *
156      * @param recordNumber recordNumber which has to delete
157      * @return ClusterStatus current cluster status
158      *
159      * @throws DException if Record is partially written or already deleted,
160      */

161
162     public ClusterStatus delete(short recordNumber, boolean checkKeyValidity) throws DException{
163
164         if(recordNumber > cluster.actualRecordCount )
165             throw new DException("DSE2007", new Object JavaDoc[]{cluster.toString() });
166           byte [] clusterBytes = cluster.getBytes();
167         short skip = moveToRecordNumber(clusterBytes,recordNumber);
168         boolean curre = clusterBytes[skip+1] == versionHandler.PARTIALLY;
169         if( curre)
170             throw new DException("DSE2006",new Object JavaDoc[]{});
171         cluster.updateByte(skip,versionHandler.DELETE);
172         cluster.activeRecordCount--;
173         cluster.updateBytes(2*versionHandler.LENGTH,CCzufDpowfsufs.getBytes(cluster.activeRecordCount));
174         return new ClusterStatus(cluster,cluster.activeRecordCount,cluster.actualRecordCount,clusterBytes[versionHandler.CLUSTER_STARTPOINTER+1] != versionHandler.FULL,clusterBytes[moveToRecordNumber(clusterBytes,cluster.actualRecordCount)+1] != versionHandler.FULL,curre);
175     }
176
177     /**
178      * Updates specifed RecordNumber in current Cluster
179      *
180      * @param recordNumber recordnumber which has to update
181      * @param newBytes new bytes of Record
182      *
183      * @throws DException if record is partially
184      */

185
186
187     public void update(short recordNumber,byte[] newBytes) throws DException {
188         throw new DException("DSE2006",new Object JavaDoc[]{});
189
190     }
191
192     /**
193      * Initializes cluster actualRecordCount, activeRecordCount and insertableAddress
194      *
195      * @param isPartial whether Record is partial or not
196      */

197
198
199
200     /**
201      * Returns actual records inserted in this cluster.
202      *
203      * @throws DException
204      * @return short - number of actual records cluster.
205      */

206     public short getRecordCount() throws DException {
207         return cluster.actualRecordCount;
208     }
209
210
211     /**
212      * calcualtes free space in this cluster.
213      *
214      *
215      * @throws DException
216      * @return int
217      */

218     public int freeSpace() throws DException {
219         return databaseProperties.CLUSTERSIZE - CCzufDpowfsufs.getShortValue(cluster.getBytes(),0) - versionHandler.NEWADDRESSLENGTH;
220     }
221
222     /**
223      * returns current cluster seted.
224      * @return Cluster
225      */

226     public Cluster getCluster(){
227         return cluster;
228     }
229
230     /**
231      * Sets current cluster.
232      *
233      * @param cluster0 Cluster to be seted.
234      * @throws DException
235      */

236     public void setCluster(Cluster cluster0) throws DException{
237         cluster = cluster0;
238     }
239
240
241     /**
242      * returns next free address to store a new record.
243      *
244      * @throws DException
245      * @return short
246      */

247     protected short getNextInsertableAddress() throws DException {
248         return CCzufDpowfsufs.getShortValue(cluster.getBytes(),0);
249     }
250
251     /**
252      * returns start position of specified record in cluster.
253      *
254      * we get record size of all records previose to it and retuns its total.
255      *
256      * @param clusterBytes byte[] - bytes in which we have to find start position of given record number.
257      * @param recordNumber short - record number whose start pointer is to be returned.
258      * @throws DException
259      * @return short - start pointer of record specified.
260      */

261     protected short moveToRecordNumber(byte[] clusterBytes,short recordNumber) throws DException {
262         short skip = versionHandler.CLUSTER_STARTPOINTER ;//+ ADDRESSLENGTH + ADDRESSLENGTH + ADDRESSLENGTH + ADDRESSLENGTH;
263
for(int i = 1 , rec = recordNumber ; i < rec ; i++){
264             int recordSizePointer = databaseProperties.CLUSTERSIZE -
265                     2 * versionHandler.LENGTH - i * versionHandler.LENGTH ;
266             skip += (short)(CCzufDpowfsufs.getShortValue(clusterBytes,recordSizePointer) + 2);
267         }
268         return skip;
269     }
270
271     /**
272      * Checks whether given recordNumber is deleted or active
273      *
274      * @param recordNumber recordNumber whose validity has to check
275      *
276      * @throws DException if RecordNumber is deleted
277      */

278
279     public void checkValidity(short recordNumber)throws DException{
280         byte[] clusterBytes = cluster.getBytes();
281         short pointer = moveToRecordNumber(clusterBytes,recordNumber);
282         if(clusterBytes[pointer++] == versionHandler.DELETE)
283          throw StaticExceptions.RECORD_DELETED_EXCEPTION;
284     }
285
286     /**
287      * returns Length of partial Record In that Cluster
288      * @param recordNumber recordNumber whose Length has to calculate
289      * @return Length of partial Record In that Cluster
290      */

291
292     public int getLength0fPartialRecord(short recordNumber) throws DException{
293       /**@todo: Implement this com.daffodilwoods.daffodildb.server.datasystem.persistentsystem._RecordCluster method*/
294       throw new java.lang.UnsupportedOperationException JavaDoc("Method getLength0fPartialRecord() not yet implemented.");
295     }
296
297     /**
298      * returns whether that record is completely Written or not
299      * @param recordNumber RecordNumber
300      * @return whether that record is completely Written or not
301      */

302
303     public boolean isComplete(short recordNumber)throws DException {
304       /**@todo: Implement this com.daffodilwoods.daffodildb.server.datasystem.persistentsystem._RecordCluster method*/
305         throw new java.lang.UnsupportedOperationException JavaDoc("Method isComplete() not yet implemented.");
306     }
307
308     /**
309      * To delete a partial record.
310      *
311      * we move to record bytes of record number to delete and check it is complete
312      * in it or not and than if it is active here than we marjk it delete and
313      * decreases its active record count.
314      *
315      * @param recordNumber short - record number to delete.
316      * @throws DException
317      * @return ClusterStatus - status which can be used for its status and isRecord complete here or not.
318      * last record is partial or not etc.
319      */

320     public ClusterStatus partialDelete(short recordNumber) throws DException{
321         byte [] clusterBytes = cluster.getBytes();
322         short skip = moveToRecordNumber(clusterBytes,recordNumber);
323         boolean curre = clusterBytes[skip+1] == versionHandler.COMPLETE;
324         if(clusterBytes[skip] == versionHandler.ACTIVE){
325             cluster.updateByte(skip,versionHandler.DELETE);
326             cluster.activeRecordCount--;
327             cluster.updateBytes(2*versionHandler.LENGTH,CCzufDpowfsufs.getBytes(cluster.activeRecordCount));
328         }
329         return new ClusterStatus(cluster,cluster.activeRecordCount,cluster.actualRecordCount,clusterBytes[versionHandler.CLUSTER_STARTPOINTER+1] != versionHandler.FULL,clusterBytes[moveToRecordNumber(clusterBytes,cluster.actualRecordCount)+1] != versionHandler.FULL,curre);
330     }
331
332     public String JavaDoc toString() {
333         return "Fixed RecordCluster " ;//+ cluster.clusterCharacteristics+" --- "+hashCode();
334
}
335
336     /**
337      * It calculates free space in current seted cluster.
338      * @throws DException
339      * @return int
340      */

341     public int getRange() throws DException {
342           return databaseProperties.CLUSTERSIZE - CCzufDpowfsufs.getShortValue(cluster.getBytes(),0) - versionHandler.LENGTH * cluster.actualRecordCount - 2*versionHandler.LENGTH;
343     }
344     /**
345      * It replaces all old bytes of record in this cluster with new bytes without checking active/delete
346      * because it is checked in delete and than partial delete is called if some bytes are written in other cluster.
347      *
348      * @param recordNumber short - recordNumber to delete.
349      * @param startPosition int - start position in new bytes from where to start replacing old.
350      * @param newBytes byte[] - new bytes of record.
351      * @throws DException
352      * @return int - number of bytes written upto this cluster by adding its start index in number of bytes written here.
353      */

354     public int partialUpdate(short recordNumber, int startPosition, byte[] newBytes) throws DException {
355         byte [] bytes = cluster.getBytes();
356         short pointer = (short)(moveToRecordNumber(bytes,recordNumber) + 2);
357         int recordSizePointer = databaseProperties.CLUSTERSIZE -
358                                 2*versionHandler.LENGTH - recordNumber * versionHandler.LENGTH ;
359         short sad = CCzufDpowfsufs.getShortValue(bytes,recordSizePointer) ;
360         cluster.updateBytes(newBytes,startPosition,pointer,sad);
361         return sad + startPosition;
362     }
363
364
365
366 }
367
Popular Tags