KickJava   Java API By Example, From Geeks To Geeks.

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


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  *
12  * <p>Title: Partial Variable Record Cluster</p>
13  * <p>Description: Maintains Insert, update, delete and Retrive operations on table having at least one
14  * variable type of column and the record is inserted, deleted, updated and retrieved partially.Since
15  * the length of record is not constant in this case hence it also manages the start pointers of all the
16  * records in it's cluster.
17  */

18
19
20 public class PartialVariableRecordCluster extends VariableRecordCluster{
21   public PartialVariableRecordCluster(TableProperties tp,DatabaseProperties databaseProperties0,VersionHandler versionHandler0) throws DException {
22     super(tp,databaseProperties0,versionHandler0);
23   }
24
25   /**
26   * Retrieves the bytes of Pariallly written record in current cluster and status whether
27   * record is completely retrieved or some bytes are remaining in other clusters.
28   *
29   * @param recordNumber recordNumber whose bytes has to retrieve
30   * @return record bytes and status whether record is completely retrieved or not
31   */

32
33   public Object JavaDoc[] partialRetrieve(short recordNumber) throws DException{
34    byte[] clusterBytes = cluster.getBytes();
35    short startPointer = cluster.getStartPointerOfRecord(recordNumber);
36    startPointer++;
37    byte isComplete = clusterBytes[startPointer++];
38    int size = (recordNumber == cluster.actualRecordCount) ? (CCzufDpowfsufs.getShortValue(clusterBytes,0) - startPointer)
39               : ( cluster.getStartPointerOfRecord((short)(recordNumber +1) ) - startPointer );
40    byte[] bytes = new byte[size];
41    System.arraycopy(clusterBytes,startPointer,bytes,0,size);
42    return new Object JavaDoc[] {bytes,new byte[] {isComplete} } ;
43  }
44
45  /**
46    * checks InsertType of Record whether Record can be partially Inserted or can not be
47    * inserted in current cluster, write bytes and return insertType and written number of bytes.
48    *
49    * if isUpdate is true then we mark the record in the current cluster as UPDATE and insert it in some other cluster and keep its TableKey
50    * at the current position
51    *
52    * @param bytes bytes of record which are to be written
53    *
54    * @param startPosition Position from where bytes are to be written
55    * @param isUpdate true if Updated Record has to be written else false
56    *
57    * @return InsertType (Fully, Partially or None) and written Number of Bytes in current cluster
58    */

59
60   public int[] insert(byte[] bytes, int startPosition, boolean isUpdate) throws DException {
61     int insertType = insertType(bytes,startPosition);
62     short add = getNextInsertableAddress();
63     return insertType == NONE ? new int[]{FAILED,0} : partialInsertRecord(bytes,add,startPosition,isUpdate);
64   }
65
66
67   /**
68    * Checks whether record Partially inserted or can not be inserted in current cluster
69    *
70    * @param bytes bytes of record which are to be inserted
71    *
72    * @param startPosition position from where we have to write
73    *
74    * @return type of insertion (Partially or None)
75    */

76
77
78   private int insertType(byte[] bytes, int startPosition) throws DException {
79       int recordSize = bytes.length + versionHandler.ACTIVE_DELETE + versionHandler.FULL_PARTIAL + versionHandler.LENGTH ;
80       int space = 0;
81       return startPosition > 0 ? PARTIALY : recordSize <= (space = cluster.freeSpace()) ? FULLY
82       : recordSize > databaseProperties.CLUSTERFREESPACE && space > MIN_VAR_RECORDLENGTH
83           ? PARTIALY : NONE;
84     }
85
86
87    /**
88      * Inserts record partially according to free space in Cluster,Updates actual Record Count and returns
89      * Insert Type and Total written bytes of record bytes
90      *
91      * Insert Type means : PARTIALLY or SUCCESSFULLY
92      *
93      * @param bytes total record bytes
94      * @param insertAdd inseratable address in Cluster
95      * @param startPosition Position form where bytes has to write form total bytes
96      *
97      * @return Insert Type and Total written record size
98      */

99
100     private int[] partialInsertRecord(byte[] bytes,short insertAdd, int startPosition, boolean isUpdate) throws DException {
101       short currentPointer = insertAdd;
102       short recordSizePointer = (short)(databaseProperties.CLUSTERSIZE - versionHandler.NEWADDRESSLENGTH - cluster.actualRecordCount * versionHandler.LENGTH - versionHandler.LENGTH);
103       cluster.updateBytes(recordSizePointer,CCzufDpowfsufs.getBytes(currentPointer));
104       cluster.addNewEntry(); // add another entry in column positions array
105
cluster.updateColumnPositions(-1,currentPointer); // update the newly added entry
106
byte[] clusterBytes = cluster.getBytes();
107       cluster.updateByte(currentPointer++,startPosition == 0 ? isUpdate ? versionHandler.RETRIEVE : versionHandler.ACTIVE : versionHandler.DELETE);
108
109       short range = (short)(cluster.freeSpace() - versionHandler.LENGTH - 1 - 1 - 1);
110       int recordSize =bytes.length - startPosition;
111       short writtenSize = range < recordSize ? range : (short)recordSize;
112       cluster.updateByte(currentPointer++,range < recordSize ? versionHandler.PARTIALLY : versionHandler.COMPLETE);
113       cluster.updateBytes(bytes,startPosition,currentPointer,writtenSize);
114       currentPointer += writtenSize;
115       cluster.actualRecordCount++;
116       if(startPosition == 0)
117         cluster.activeRecordCount++;
118       cluster.updateClusterInformation(currentPointer);
119       int writtenBytes = writtenSize + startPosition;
120       return writtenBytes == bytes.length ? new int[]{SUCCESSFUL,0} : new int[]{PARTIAL,writtenBytes};
121     }
122
123     /**
124       * Deletes partial written Record by shifting all next written records by Deleted Record Size in current
125       * cluster and updates insertable Address in Cluster.
126       *
127       * @param recordNumber recordNumber which has to delete
128       * @return ClusterStatus current status of cluster
129       * @throws DException if RecordNumber to be deleted exceeds actualRecordCount it throws Exception(DSE2007)
130       */

131
132      public ClusterStatus partialDelete(short recordNumber) throws DException{
133        byte [] clusterBytes = cluster.getBytes();
134        short startPointer = cluster.getStartPointerOfRecord(recordNumber);
135        boolean isComplete = clusterBytes[startPointer + 1] == versionHandler.COMPLETE;
136        if(clusterBytes[startPointer] == versionHandler.ACTIVE)
137            cluster.activeRecordCount--;
138        cluster.updateByte(startPointer,versionHandler.DELETE);
139        boolean flag = recordNumber == cluster.actualRecordCount;
140        short insertableAddress = CCzufDpowfsufs.getShortValue(clusterBytes,0);
141        short oldRecordSize = (short)(( flag ? insertableAddress
142                                        : cluster.getStartPointerOfRecord((short)(recordNumber + 1))) - startPointer);
143        if(!flag){
144          byte[] bytes = getClusterBytes((short)(recordNumber + 1),clusterBytes);
145          cluster.updateBytes(startPointer+1,bytes);
146          short s = recordNumber;
147          short recordSizePointer =(short)(databaseProperties.CLUSTERSIZE - versionHandler.NEWADDRESSLENGTH - s * versionHandler.LENGTH - versionHandler.LENGTH) ;
148          for(int len = cluster.getColumnPositions().length ; s < len ; s++ ){
149            cluster.updateColumnPositions(s,(short)(cluster.getStartPointerOfRecord((short)(s + 1)) - oldRecordSize+1));
150            cluster.updateBytes(recordSizePointer,CCzufDpowfsufs.getBytes(cluster.getColumnPositions()[s]));
151            recordSizePointer -= versionHandler.LENGTH;
152          }
153        }
154        cluster.updateClusterInformation((short)(insertableAddress - oldRecordSize+1));
155        return new ClusterStatus(cluster,cluster.activeRecordCount,cluster.actualRecordCount,clusterBytes[versionHandler.CLUSTER_STARTPOINTER+1] != versionHandler.FULL,clusterBytes[cluster.getStartPointerOfRecord(cluster.actualRecordCount) + 1] != versionHandler.FULL,isComplete);
156      }
157
158
159      /**
160        * Updates partial record in Cluster and shifts all next written records according
161        * to updated Record and returns Total number of Updated Bytes
162        *
163        * @param recordNumber recordNumber which has to update
164        * @param startPosition position from where bytes have to update
165        * @param newBytes Total new bytes
166        *
167        * @return total updated bytes
168        */

169
170       public int partialUpdate(short recordNumber, int startPosition, byte [] newBytes) throws DException{
171         short currentPointer = cluster.getStartPointerOfRecord(recordNumber);
172         byte[] clusterBytes = cluster.getBytes();
173         boolean flag = recordNumber == cluster.actualRecordCount;
174         int oldRecordSize = (flag ? CCzufDpowfsufs.getShortValue(clusterBytes,0)
175                              : cluster.getStartPointerOfRecord((short)(recordNumber + 1))) - currentPointer;
176         short range = (short)(getRange() + oldRecordSize - versionHandler.ACTIVE_DELETE - versionHandler.FULL_PARTIAL );
177         currentPointer++;
178         int recordSize = newBytes.length - startPosition;
179         short writtenSize = range < recordSize ? range : (short)recordSize;
180         if(startPosition == 0 && writtenSize == recordSize)
181           cluster.updateByte(currentPointer++,versionHandler.FULL);
182         else
183           cluster.updateByte(currentPointer++, range < recordSize ? versionHandler.PARTIALLY : versionHandler.COMPLETE );
184         byte[] bytes = flag ? null : getClusterBytes((short)(recordNumber + 1),clusterBytes);
185         short pointer = bytes == null ? 0 : cluster.getStartPointerOfRecord((short)(recordNumber + 1));
186         cluster.updateBytes(newBytes,startPosition,currentPointer,writtenSize);
187         currentPointer += writtenSize;
188         short changeInStartPositions = (short) (currentPointer - pointer);
189         if(!flag){
190           cluster.updateBytes(currentPointer,bytes);
191           short s = recordNumber;
192           if(changeInStartPositions != 0){
193             short recordSizePointer = (short)(databaseProperties.CLUSTERSIZE - versionHandler.NEWADDRESSLENGTH - s * versionHandler.LENGTH - versionHandler.LENGTH) ;
194             for(short len = (short)cluster.getColumnPositions().length ; s < len ; s++ ){
195               cluster.updateColumnPositions(s,(short) (cluster.getStartPointerOfRecord((short)(s +1)) + changeInStartPositions));
196               cluster.updateBytes(recordSizePointer,CCzufDpowfsufs.getBytes(cluster.getColumnPositions()[s]));
197               recordSizePointer -= versionHandler.LENGTH;
198             }
199           }
200         }
201          cluster.updateBytes(0,CCzufDpowfsufs.getBytes(pointer == 0 ? currentPointer : (short)(currentPointer + bytes.length)));
202         return writtenSize + startPosition;
203       }
204       /**
205        * returns Length of partial Record In that Cluster
206        * @param recordNumber recordNumber whose Length has to calculate
207        * @return Length of partial Record In that Cluster
208        */

209
210       public int getLength0fPartialRecord(short recordNumber) throws DException{
211           return (recordNumber == cluster.actualRecordCount ? CCzufDpowfsufs.getShortValue(cluster.getBytes(), 0)
212                   : cluster.getStartPointerOfRecord( (short) (recordNumber + 1))) - cluster.getStartPointerOfRecord(recordNumber);
213
214       }
215
216       /**
217        * Marks Record Deleted and shifts all next written records by Deleted Record size and updates
218        * activeRecordCount and insertableAddress in Cluster.
219        *
220        * If current record is marked as UPDATE in the curent cluster then gets
221        * TableKey of record from this cluster and deletes this key from current location
222        *
223        * If the current record is PARTIALLY written here then it throws exception( DSE2006 ) which
224        * is catched by persistent table which gives call to PartialDelete
225        *
226        * If the current record status is UPDATE then it gets the newLocation from here deletes the key present here
227        * throws exception( DSE2005) which is catched by persistent table
228        * which gives call to Delete for the newLocation
229        *
230        * @param recordNumber recordNumber which has to delete
231        *
232        * @return ClusterStatus current cluster status
233        *
234        * @throws DException if current Record is greater than actual Record Count
235        *
236        */

237
238       public ClusterStatus delete(short recordNumber, boolean checkKeyValidity) throws DException{
239
240         if(recordNumber > cluster.actualRecordCount)
241           throw new DException("DSE2007", new Object JavaDoc[]{new Integer JavaDoc(recordNumber)});
242         byte[] clusterBytes = cluster.getBytes();
243         if(checkKeyValidity)
244           checkValidity1(recordNumber,clusterBytes);
245
246         short startPointer = cluster.getStartPointerOfRecord(recordNumber);
247         boolean curre = clusterBytes[startPointer+1] == versionHandler.PARTIALLY;
248         if (curre)
249            throw StaticExceptions.PARTIAL_RECORD_EXCEPTION ;
250         Object JavaDoc tk = null;
251         if(clusterBytes[startPointer] == versionHandler.UPDATE){
252           tk = getNewLocation(recordNumber,startPointer,clusterBytes);
253           curre = true;
254         }
255         cluster.updateByte(startPointer,versionHandler.DELETE);
256         cluster.activeRecordCount--;
257         boolean flag = recordNumber == cluster.actualRecordCount;
258         short insertableAddress = CCzufDpowfsufs.getShortValue(clusterBytes,0);
259         short oldRecordSize = (short) ((flag ? insertableAddress : cluster.getStartPointerOfRecord((short)(recordNumber + 1))) - startPointer);
260         if(!flag){
261           byte[] bytes = getClusterBytes( (short)(recordNumber + 1),clusterBytes );
262           cluster.updateBytes(startPointer+1,bytes);
263           short changeInStartPointer = (short)(oldRecordSize - 1);
264           short s = (short)(recordNumber+1);
265           int recordSizePointer = databaseProperties.CLUSTERSIZE - versionHandler.NEWADDRESSLENGTH - s*versionHandler.LENGTH ;
266           if(cluster.getActualRecordCount() != cluster.getColumnPositions().length)
267             Thread.dumpStack();
268           for(int len = cluster.getActualRecordCount() ; s <= len ; s++ ){
269             short index = (short)(s-1);
270             short start = cluster.getStartPointerOfRecord(s);
271             short now = (short)(start - changeInStartPointer);
272             cluster.updateColumnPositions(index,now);
273             cluster.updateBytes(recordSizePointer,CCzufDpowfsufs.getBytes(now));
274             recordSizePointer -= versionHandler.LENGTH;
275           }
276         }
277         cluster.updateClusterInformation((short)(insertableAddress - oldRecordSize + 1));
278         if(curre){
279           throw new DException("DSE2005",new Object JavaDoc[]{tk});
280         }
281        return new ClusterStatus(cluster,cluster.activeRecordCount,cluster.actualRecordCount,clusterBytes[versionHandler.CLUSTER_STARTPOINTER+1] != versionHandler.FULL,clusterBytes[cluster.getStartPointerOfRecord(cluster.actualRecordCount) + 1] != versionHandler.FULL,curre);
282       }
283
284
285       /**
286          * Updates Record if Record can be updated in that Cluster and shifts all next written records
287          * according to updated Record size otherwise throws DException that Record can not be updated in current
288          * cluster.
289          * If current record is marked as UPDATE in the curent cluster then gets
290          * TableKey of record from this cluster and throws exception(DSE2005)
291          * which is catched by the persistent table and call to update is given for the newLocation
292          * If the current record is PARTIALLY written here then it throws exception( DSE2006 ) which
293          * is catched by persistent table which gives call to PartialUpdate
294          * If the record cannot be upadted in the current cluster then it throw exception RECORD_CANNOT_UPDATED
295          * which is catched by the persistent table and it calls its method insertOld which returns a table key at which this record is inserted
296          * and updates the current cluster by giving call to method updateNewAddress which places this tableKey at the current cluster
297          *
298          * @param recordNumber recordnumber which has to update
299          * @param newBytes new bytes of Record
300          *
301          * @throws DException if current Record is marked as DELETE then throws exception(DSE2003)
302          */

303
304      public void update(short recordNumber,byte[] newBytes) throws DException {
305      byte[] clusterBytes = cluster.getBytes();
306      int freeSpace = getRange();
307      short startPointer = cluster.getStartPointerOfRecord(recordNumber);
308      boolean flag = recordNumber == cluster.actualRecordCount;
309      short startOfNext = 0;
310      int oldRecordSize = (flag ? CCzufDpowfsufs.getShortValue(clusterBytes,0)
311                           : (startOfNext = cluster.getStartPointerOfRecord( (short)(recordNumber+1)))) - startPointer;
312      if(clusterBytes[startPointer] == versionHandler.DELETE )
313        throw new DException("DSE2003",new Object JavaDoc[]{new Integer JavaDoc(recordNumber)});
314      if(clusterBytes[startPointer] == versionHandler.UPDATE){
315        Object JavaDoc tk = getNewLocation(recordNumber,startPointer,clusterBytes);
316        throw new DException("DSE2005",new Object JavaDoc[]{tk});
317      }
318      if(clusterBytes[startPointer+1] == versionHandler.PARTIALLY)
319        throw new DException("DSE2006",new Object JavaDoc[] {new Integer JavaDoc(oldRecordSize),new Integer JavaDoc((int)freeSpace)} );
320      if(newBytes.length + versionHandler.ACTIVE_DELETE + versionHandler.FULL_PARTIAL <= freeSpace + oldRecordSize){
321        byte[] bytes = flag ? null : getClusterBytes((short)(recordNumber+1),clusterBytes);
322        short pointer = flag ? 0 : startOfNext;
323        short currentPointer = (short)(startPointer+2);
324        cluster.updateBytes(currentPointer,newBytes);
325        currentPointer += newBytes.length;
326        short changeInStartPositions = (short)(currentPointer - pointer);
327        if(!flag){
328          cluster.updateBytes(currentPointer,bytes);
329          if(changeInStartPositions != 0){
330            short s = recordNumber;
331            short recordSizePointer = (short) (databaseProperties.CLUSTERSIZE - 2 * versionHandler.LENGTH - s * versionHandler.LENGTH - versionHandler.LENGTH) ;
332            for(short len = (short)cluster.getColumnPositions().length ; s < len ; s++ ){
333              cluster.updateColumnPositions(s,((short) (cluster.getStartPointerOfRecord((short)(s+1)) + changeInStartPositions)));
334              cluster.updateBytes(recordSizePointer,CCzufDpowfsufs.getBytes(cluster.getColumnPositions()[s]));
335              recordSizePointer -= versionHandler.LENGTH;
336            }
337          }
338        }
339         cluster.updateClusterInformation(pointer == 0 ? currentPointer :(short)(currentPointer + bytes.length));
340      }
341      else
342        throw DatabaseConstants.RECORD_CANNOT_UPDATED;
343    }
344
345
346         /**
347           * Returns a BufferRange of record which conatins the NULL/NOT NULL bytes and the record's actual bytes
348           *
349           * If current record is marked as UPDATE in the curent cluster then gets
350           * TableKey of record from this cluster and throws exception(DSE2005)
351           * which is catched by the persistent table and call to retrieveBufferRange is given for the newLocation
352           *
353           * If the current record is PARTIALLY written here then it throws exception( DSE2006 ) which
354           * is catched by persistent table which gives call to PartialRetrieve
355           *
356           * @param recordNumber record number for which bufferRange is to be retrieved
357           * @return bufferRange
358           *
359           * @throws DException if current Record is marked as DELETE then throws RECORD_DELETED_EXCEPTION
360           */

361
362
363          public BufferRange retrieveBufferRange(short recordNumber) throws DException{
364            byte[] clusterBytes = cluster.getBytes();
365            short startPointer = cluster.getStartPointerOfRecord(recordNumber);
366
367            if(clusterBytes[startPointer] == versionHandler.DELETE ){
368              throw StaticExceptions.RECORD_DELETED_EXCEPTION ;
369            }
370            if(clusterBytes[startPointer] == versionHandler.UPDATE){
371              Object JavaDoc tk = getNewLocation(recordNumber,(short)(startPointer),clusterBytes);
372              throw new DException("DSE2005",new Object JavaDoc[]{tk});
373            }
374            startPointer++;
375            byte isComplete = clusterBytes[startPointer++];
376            int size = (recordNumber == cluster.actualRecordCount) ? (CCzufDpowfsufs.getShortValue(clusterBytes,0) - startPointer)
377                       : ( cluster.getStartPointerOfRecord((short)(recordNumber + 1)) - startPointer );
378            byte[] recordBytes = new byte[size];
379            System.arraycopy(clusterBytes, startPointer, recordBytes, 0, size);
380            BufferRange bufferRange = new BufferRange(recordBytes,0,size);
381            if( isComplete == versionHandler.PARTIALLY)
382              throw new DException("DSE2006",new Object JavaDoc[]{bufferRange});
383            return bufferRange ;
384          }
385  /*
386    private int insertType1(byte[] bytes, int startPosition) throws DException {
387     int recordSize = bytes.length + versionHandler.ACTIVE_DELETE + versionHandler.FULL_PARTIAL + versionHandler.LENGTH ;
388     return startPosition > 0 ? PARTIALY : recordSize > databaseProperties.CLUSTERFREESPACE && (cluster.freeSpace()) > MIN_VAR_RECORDLENGTH
389         ? PARTIALY : NONE;
390   }
391
392      */

393 }
394
Popular Tags