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 16 17 public class VariableRecordCluster 18 extends FixedRecordCluster { 19 20 25 protected int MIN_VAR_RECORDLENGTH; 26 27 public VariableRecordCluster(TableProperties tp,DatabaseProperties databaseProperties0,VersionHandler versionHandler0) throws 28 DException { 29 super(tp, databaseProperties0,versionHandler0); 30 MIN_VAR_RECORDLENGTH = versionHandler.ACTIVE_DELETE + versionHandler.FULL_PARTIAL + versionHandler.LENGTH + 7; } 32 33 39 40 protected Object getNewLocation(short recordNumber, short startPointer, 41 byte[] clusterBytes) throws 42 DException { 43 startPointer += 2; 44 int add = CCzufDpowfsufs.getIntValue(clusterBytes, startPointer); 45 startPointer += versionHandler.NEWADDRESSLENGTH; 46 short rec = CCzufDpowfsufs.getShortValue(clusterBytes, startPointer); 47 return new TableKey(add, rec); 48 } 49 50 56 57 public void checkValidity(short recordNumber) throws DException { 58 checkValidity1(recordNumber, cluster.getBytes()); 59 } 60 61 protected void checkValidity1(short recordNumber, byte[] clusterBytes) throws 62 DException { 63 short pointer = cluster.getStartPointerOfRecord(recordNumber); 64 if (clusterBytes[pointer] ==versionHandler.DELETE) { 65 throw StaticExceptions.RECORD_DELETED_EXCEPTION ; 66 } 67 } 68 69 84 85 public int[] insert(byte[] bytes, int startPosition, boolean isUpdate) throws 86 DException { 87 int insertType = insertType(bytes, startPosition); 88 return insertType == NONE ? new int[] { 89 FAILED, 0} 90 : insertRecord(bytes, getNextInsertableAddress(), isUpdate); 91 } 92 93 102 103 private int insertType(byte[] bytes, int startPosition) throws DException { 104 int recordSize = bytes.length + versionHandler.ACTIVE_DELETE + versionHandler.FULL_PARTIAL + 105 versionHandler.LENGTH; 106 return recordSize <= cluster.freeSpace() ? FULLY : NONE; 107 } 108 109 118 119 protected int[] insertRecord(byte[] bytes, short insertAdd, boolean isUpdate) throws 120 DException { 121 short currentPointer = insertAdd; 122 short recordSizePointer = (short) (databaseProperties.CLUSTERSIZE - 123 versionHandler.NEWADDRESSLENGTH - 124 cluster.actualRecordCount * versionHandler.LENGTH - 125 versionHandler.LENGTH); 126 cluster.updateBytes(recordSizePointer, 127 CCzufDpowfsufs.getBytes(currentPointer)); 128 cluster.addNewEntry(); 129 cluster.updateColumnPositions( -1, currentPointer); 130 cluster.updateByte(currentPointer++, 131 isUpdate ? versionHandler.RETRIEVE : 132 versionHandler.ACTIVE); 133 cluster.updateByte(currentPointer++, versionHandler.FULL); 134 cluster.updateBytes(currentPointer, bytes); 135 currentPointer += bytes.length; 136 cluster.actualRecordCount++; 137 cluster.activeRecordCount++; 138 cluster.recordsToBeShifted++; 139 cluster.updateClusterInformation(currentPointer); 140 return new int[] { 141 SUCCESSFUL, 0}; 142 } 143 144 165 166 public ClusterStatus deleteNew(short recordNumber, boolean checkKeyValidity) throws 167 DException { 168 169 if (recordNumber > cluster.actualRecordCount) 170 throw new DException("DSE2007", new Object [] {new Integer (recordNumber)}); 171 byte[] clusterBytes = cluster.getBytes(); 172 if (checkKeyValidity) 173 checkValidity1(recordNumber, clusterBytes); 174 short startPointer = cluster.getStartPointerOfRecord(recordNumber); 175 boolean curre = false; 176 Object tk = null; 177 if (clusterBytes[startPointer] == versionHandler.UPDATE) { 178 tk = getNewLocation(recordNumber, startPointer, clusterBytes); 179 curre = true; 180 } 181 182 cluster.activeRecordCount--; 183 184 cluster.updateByte(startPointer, versionHandler.DELETE); 185 boolean flag = recordNumber == cluster.actualRecordCount; 186 short insertableAddress = (short) CCzufDpowfsufs.getShortValue(clusterBytes,0); 187 short oldRecordSize = (short) ( (flag ? insertableAddress :cluster.getStartPointerOfRecord( (short) (recordNumber + 1))) - startPointer); 188 if (curre) { 189 throw new DException("DSE2005", new Object [] {tk}); 190 } 191 if(flag) 192 cluster.updateClusterInformation((short) (insertableAddress - oldRecordSize + 1)); 193 else if(cluster.activeRecordCount < cluster.recordsToBeShifted/2 ) { 194 shiftClusterBytes(clusterBytes); 195 cluster.recordsToBeShifted = cluster.activeRecordCount; 196 } 197 return new ClusterStatus(cluster, cluster.activeRecordCount,cluster.actualRecordCount,clusterBytes[versionHandler.CLUSTER_STARTPOINTER + 1] != versionHandler.FULL, 198 clusterBytes[cluster.getStartPointerOfRecord(cluster.actualRecordCount) + 1] != versionHandler.FULL, curre); 199 } 200 201 204 205 protected byte[] getClusterBytes(short recordNumber, byte[] clusterBytes) throws 206 DException { 207 short startPointer = cluster.getStartPointerOfRecord(recordNumber); 208 short len = (short) (CCzufDpowfsufs.getShortValue(clusterBytes, 0) - 209 startPointer); 210 byte[] bytes = new byte[len]; 211 System.arraycopy(clusterBytes, startPointer, bytes, 0, len); 212 return bytes; 213 } 214 215 233 234 public void update(short recordNumber, byte[] newBytes) throws DException { 235 byte[] clusterBytes = cluster.getBytes(); 236 int freeSpace = getRange(); 237 short startPointer = cluster.getStartPointerOfRecord(recordNumber); 238 boolean flag = recordNumber == cluster.actualRecordCount; 239 short startOfNext = 0; 240 short insertableAddress = CCzufDpowfsufs.getShortValue(clusterBytes, 0); 241 int oldRecordSize = (flag ? insertableAddress 242 : 243 (startOfNext = cluster.getStartPointerOfRecord( (short) ( 244 recordNumber + 245 1)))) - startPointer; 246 if (clusterBytes[startPointer] == versionHandler.DELETE) 247 throw new DException("DSE2003", new Object [] {new Integer (recordNumber)}); 248 if (clusterBytes[startPointer] == versionHandler.UPDATE) { 249 Object tk = getNewLocation(recordNumber, startPointer, clusterBytes); 250 throw new DException("DSE2005", new Object [] {tk}); 251 } 252 if (newBytes.length < 253 freeSpace + oldRecordSize - versionHandler.ACTIVE_DELETE - versionHandler.FULL_PARTIAL) { 254 byte[] bytes = flag ? null : 255 getClusterBytes( (short) (recordNumber + 1), clusterBytes); 256 short pointer = flag ? 0 : startOfNext; 257 short currentPointer = (short) (startPointer + 2); 258 cluster.updateBytes(currentPointer, newBytes); 259 currentPointer += newBytes.length; 260 short changeInStartPositions = (short) (currentPointer - pointer); 261 cluster.updateClusterInformation(pointer == 0 ? currentPointer : 262 (short) (currentPointer + bytes.length)); 263 if (!flag) { 264 cluster.updateBytes(currentPointer, bytes); 265 if (changeInStartPositions != 0) { 266 short s = recordNumber; 267 short recordSizePointer = (short) (databaseProperties.CLUSTERSIZE - 268 versionHandler.NEWADDRESSLENGTH - s * versionHandler.LENGTH - 269 versionHandler.LENGTH); 270 for (short len = (short) cluster.getColumnPositions().length; s < len; 271 s++) { 272 cluster.updateColumnPositions(s, 273 ( (short) (cluster. 274 getStartPointerOfRecord( (short) (s + 1)) + 275 changeInStartPositions))); 276 cluster.updateBytes(recordSizePointer, 277 CCzufDpowfsufs.getBytes(cluster. 278 getColumnPositions()[s])); 279 recordSizePointer -= versionHandler.LENGTH; 280 } 281 } 282 } 283 } 284 else{ 285 shiftClusterBytes(clusterBytes); 286 if (newBytes.length < getRange() + oldRecordSize - versionHandler.ACTIVE_DELETE - versionHandler.FULL_PARTIAL) { 287 update(recordNumber, newBytes); 288 } 289 throw DatabaseConstants.RECORD_CANNOT_UPDATED; 290 } 291 } 292 293 294 295 298 299 public int freeSpace() throws DException { 300 return databaseProperties.CLUSTERSIZE - CCzufDpowfsufs.getShortValue(cluster.getBytes(), 0) - versionHandler.NEWADDRESSLENGTH - 301 cluster.actualRecordCount * versionHandler.LENGTH - versionHandler.UPDATEBYTES; 302 } 303 304 319 320 public BufferRange retrieveBufferRange(short recordNumber) throws DException { 321 byte[] clusterBytes = cluster.getBytes(); 322 short startPointer = cluster.getStartPointerOfRecord(recordNumber); 323 if (clusterBytes[startPointer] == versionHandler.DELETE) { 324 throw StaticExceptions.RECORD_DELETED_EXCEPTION ; 325 } 326 327 if (clusterBytes[startPointer] == versionHandler.UPDATE) { 328 Object tk = getNewLocation(recordNumber, (short) (startPointer), 329 clusterBytes); 330 throw new DException("DSE2005", new Object [] {tk}); 331 } 332 startPointer += versionHandler.ACTIVE_DELETE + versionHandler.FULL_PARTIAL; 333 int size = (recordNumber == cluster.actualRecordCount) ? 334 (CCzufDpowfsufs.getShortValue(clusterBytes, 0) - startPointer) 335 : 336 (cluster.getStartPointerOfRecord( (short) (recordNumber + 1)) - 337 startPointer); 338 byte[] recordBytes = new byte[size]; 339 340 System.arraycopy(clusterBytes, startPointer, recordBytes, 0, size); 341 return new BufferRange(recordBytes, 0, size); 342 } 343 344 354 355 void updateNewAddress(short recordNumber, byte[] newBytes) throws DException { 356 byte[] clusterBytes = cluster.getBytes(); 357 short startPointer = cluster.getStartPointerOfRecord(recordNumber); 358 boolean flag = recordNumber == cluster.actualRecordCount; 359 short startOfNext = flag ? 0 : 360 cluster.getStartPointerOfRecord( (short) (recordNumber + 1)); 361 byte[] bytes = flag ? null : 362 getClusterBytes( (short) (recordNumber + 1), clusterBytes); 363 short pointer = flag ? 0 : startOfNext; 364 short currentPointer = (short) (startPointer + versionHandler.ACTIVE_DELETE + versionHandler.FULL_PARTIAL); 365 cluster.updateBytes(currentPointer, newBytes); 366 currentPointer += newBytes.length; 367 short changeInStartPositions = (short) (currentPointer - pointer); 368 cluster.updateClusterInformation(pointer == 0 ? currentPointer : 369 (short) (currentPointer + bytes.length)); 370 if (!flag) { 371 cluster.updateBytes(currentPointer, bytes); 372 short s = recordNumber; 373 short recordSizePointer = (short) (databaseProperties.CLUSTERSIZE - 374 versionHandler.NEWADDRESSLENGTH - s * versionHandler.LENGTH - versionHandler.LENGTH); 375 for (short len = (short) cluster.getColumnPositions().length; s < len; s++) { 376 cluster.updateColumnPositions(s, 377 (short) (cluster. 378 getStartPointerOfRecord( (short) ( 379 s + 380 1)) + changeInStartPositions)); 381 cluster.updateBytes(recordSizePointer, 382 CCzufDpowfsufs.getBytes(cluster.getColumnPositions()[ 383 s])); 384 recordSizePointer -= versionHandler.LENGTH; 385 } 386 } 387 cluster.updateByte(startPointer, versionHandler.UPDATE); 388 cluster.updateByte(startPointer + 1, versionHandler.FULL); 389 cluster.activeRecordCount++; 390 cluster.updateBytes(2 * versionHandler.LENGTH, 391 CCzufDpowfsufs.getBytes(cluster.activeRecordCount)); 392 } 393 394 399 400 public boolean isComplete(short recordNumber) throws DException { 401 return cluster.getBytes()[cluster.getStartPointerOfRecord(recordNumber) + 1] == 402 versionHandler.COMPLETE; 403 } 404 405 410 411 private void shiftClusterBytes(byte[] clusterBytes) throws DException{ 412 short recordNumber = 0; 413 short startPointer = 0; 414 do{ 415 if(recordNumber == cluster.actualRecordCount) 416 return; 417 startPointer = cluster.getStartPointerOfRecord(++recordNumber); 418 }while((clusterBytes[startPointer+1] != versionHandler.FULL && clusterBytes[startPointer]== versionHandler.ACTIVE || (clusterBytes[startPointer]== versionHandler.DELETE ))); 419 420 short dataPointer = startPointer; 421 int recordSizePointer = databaseProperties.CLUSTERSIZE - versionHandler.NEWADDRESSLENGTH - recordNumber * versionHandler.LENGTH; 422 for (int i = recordNumber; i <= cluster.actualRecordCount; i++) { 423 int recordSize = 0; 424 startPointer = cluster.getStartPointerOfRecord(recordNumber); 425 recordSize = clusterBytes[startPointer] == versionHandler.DELETE ? versionHandler.ACTIVE_DELETE :(clusterBytes[startPointer] == versionHandler.UPDATE ? versionHandler.ADDRESSLENGTH : (i == cluster.actualRecordCount ? (CCzufDpowfsufs.getShortValue(clusterBytes,0) - startPointer):cluster.getStartPointerOfRecord( (short) (recordNumber + 1)) - startPointer)); 426 cluster.updateBytes(clusterBytes,startPointer,dataPointer,recordSize); 427 cluster.updateColumnPositions(recordNumber - 1, dataPointer); 428 cluster.updateBytes(recordSizePointer,CCzufDpowfsufs.getBytes(dataPointer)); 429 dataPointer +=recordSize; 430 recordNumber++; 431 recordSizePointer -= versionHandler.LENGTH; 432 } 433 cluster.updateClusterInformation(dataPointer); 434 } 435 436 454 455 public ClusterStatus delete(short recordNumber, boolean checkKeyValidity) throws 456 DException { 457 if (recordNumber > cluster.actualRecordCount) 458 throw new DException("DSE2007", new Object [] {new Integer (recordNumber)}); 459 byte[] clusterBytes = cluster.getBytes(); 460 if (checkKeyValidity) 461 checkValidity1(recordNumber, clusterBytes); 462 short startPointer = cluster.getStartPointerOfRecord(recordNumber); 463 boolean curre = false; 464 Object tk = null; 465 if (clusterBytes[startPointer] == versionHandler.UPDATE) { 466 tk = getNewLocation(recordNumber, startPointer, clusterBytes); 467 curre = true; 468 } 469 470 cluster.activeRecordCount--; 471 472 cluster.updateByte(startPointer, versionHandler.DELETE); 473 boolean flag = recordNumber == cluster.actualRecordCount; 474 short insertableAddress = CCzufDpowfsufs.getShortValue(clusterBytes,0); 475 short oldRecordSize = (short) ( (flag ? insertableAddress :cluster.getStartPointerOfRecord( (short) (recordNumber + 1))) - startPointer); 476 477 if (!flag) { 478 byte[] bytes = getClusterBytes( (short) (recordNumber + 1), clusterBytes); 479 cluster.updateBytes(startPointer + 1, bytes); 480 int changeInStartPointer = (oldRecordSize - 1); 481 short s = (short) (recordNumber + 1); 482 int recordSizePointer = databaseProperties.CLUSTERSIZE - versionHandler.NEWADDRESSLENGTH - 483 s * versionHandler.LENGTH; 484 for (int len = cluster.getActualRecordCount(); s <= len; s++) { 485 int index = (s - 1); 486 short start = cluster.getStartPointerOfRecord(s); 487 short now = (short) (start - changeInStartPointer); 488 cluster.updateColumnPositions(index, now); 489 cluster.updateBytes(recordSizePointer, CCzufDpowfsufs.getBytes(now)); 490 recordSizePointer -= versionHandler.LENGTH; 491 } 492 } 493 cluster.updateClusterInformation( (short)(insertableAddress - oldRecordSize +1)); 494 if (curre) { 495 throw new DException("DSE2005", new Object [] {tk}); 496 } 497 return new ClusterStatus(cluster, cluster.activeRecordCount,cluster.actualRecordCount,false,false, curre); 498 } 499 500 506 public int getRange() throws DException { 507 return databaseProperties.CLUSTERSIZE - CCzufDpowfsufs.getShortValue(cluster.getBytes(),0) - versionHandler.LENGTH * cluster.actualRecordCount - versionHandler.NEWADDRESSLENGTH; 508 } 509 510 511 529 532 533 534 } 535 | Popular Tags |