1 21 package org.apache.derby.impl.store.raw.data; 22 23 import org.apache.derby.iapi.services.sanity.SanityManager; 24 25 import org.apache.derby.iapi.store.raw.PageKey; 26 import org.apache.derby.iapi.store.raw.RecordHandle; 27 28 import java.io.IOException ; 29 import java.io.EOFException ; 30 31 import java.io.InputStream ; 32 import java.io.OutputStream ; 33 34 import org.apache.derby.iapi.services.io.CompressedNumber; 35 36 57 58 public final class StoredRecordHeader 59 { 60 61 65 66 85 public static final int RECORD_INITIAL = 0x00; 86 public static final int RECORD_DELETED = 0x01; 87 public static final int RECORD_OVERFLOW = 0x02; 88 public static final int RECORD_HAS_FIRST_FIELD = 0x04; 89 public static final int RECORD_VALID_MASK = 0x0f; 90 91 92 96 97 102 protected int id; 103 104 116 protected int status; 117 118 121 protected int numberFields; 122 123 126 protected RecordHandle handle; 127 128 129 136 protected int overflowId; 137 138 139 144 protected long overflowPage; 145 146 157 protected int firstField; 158 159 160 164 public StoredRecordHeader() 165 { 166 } 167 168 public StoredRecordHeader(int id, int numberFields) 169 { 170 setId(id); 171 setNumberFields(numberFields); 172 } 173 174 public StoredRecordHeader( 175 byte data[], 176 int offset) 177 { 178 read(data, offset); 179 } 180 181 public StoredRecordHeader(StoredRecordHeader loadTargetFrom) 182 { 183 this.status = loadTargetFrom.status; 184 this.id = loadTargetFrom.id; 185 this.numberFields = loadTargetFrom.numberFields; 186 handle = null; 187 188 overflowId = loadTargetFrom.overflowId; 189 overflowPage = loadTargetFrom.overflowPage; 190 firstField = loadTargetFrom.firstField; 191 } 192 193 197 198 204 protected RecordHandle getHandle( 205 PageKey pageId, 206 int current_slot) 207 { 208 if (handle == null) 209 handle = new RecordId(pageId, id, current_slot); 210 211 return handle; 212 } 213 214 219 public final int getId() 220 { 221 return id; 222 } 223 224 public int getNumberFields() 225 { 226 return numberFields; 227 } 228 229 public long getOverflowPage() 230 { 231 return overflowPage; 232 } 233 234 public int getOverflowId() 235 { 236 return overflowId; 237 } 238 239 public int getFirstField() 240 { 241 return firstField; 242 } 243 244 public final boolean hasOverflow() 245 { 246 return ((status & RECORD_OVERFLOW) == RECORD_OVERFLOW); 247 } 248 249 protected final boolean hasFirstField() 250 { 251 return ((status & RECORD_HAS_FIRST_FIELD) == RECORD_HAS_FIRST_FIELD); 252 } 253 254 260 public final boolean isDeleted() 261 { 262 return ((status & RECORD_DELETED) == RECORD_DELETED); 263 } 264 265 266 280 public int size() 281 { 282 int len = 287 (id <= CompressedNumber.MAX_COMPRESSED_INT_ONE_BYTE) ? 288 2 : 289 (id <= CompressedNumber.MAX_COMPRESSED_INT_TWO_BYTES) ? 290 3 : 5; 291 292 if ((status & (RECORD_OVERFLOW | RECORD_HAS_FIRST_FIELD)) == 0) 293 { 294 len += 296 (numberFields <= CompressedNumber.MAX_COMPRESSED_INT_ONE_BYTE) ? 297 1 : 298 (numberFields <= CompressedNumber.MAX_COMPRESSED_INT_TWO_BYTES) ? 299 2 : 4; 300 } 301 else if ((status & RECORD_OVERFLOW) == 0) 302 { 303 305 len += 312 ((numberFields <= CompressedNumber.MAX_COMPRESSED_INT_ONE_BYTE) ? 313 1 : 314 (numberFields <= CompressedNumber.MAX_COMPRESSED_INT_TWO_BYTES) ? 315 2 : 4) + 316 317 ((firstField <= CompressedNumber.MAX_COMPRESSED_INT_ONE_BYTE) ? 318 1 : 319 (firstField <= CompressedNumber.MAX_COMPRESSED_INT_TWO_BYTES) ? 320 2 : 4); 321 } 322 else 323 { 324 326 len += CompressedNumber.sizeLong(overflowPage); 327 len += CompressedNumber.sizeInt(overflowId); 328 329 if (hasFirstField()) 330 { 331 len += CompressedNumber.sizeInt(firstField); 332 len += CompressedNumber.sizeInt(numberFields); 333 } 334 } 335 336 return len; 337 } 338 339 343 344 353 public int setDeleted(boolean deleteTrue) 354 { 355 356 int retCode = 0; 357 358 if (deleteTrue) 359 { 360 if (!isDeleted()) 361 { 362 retCode = 1; 364 status |= RECORD_DELETED; 365 } 366 } 367 else 368 { 369 if (isDeleted()) 370 { 371 retCode = -1; 373 status &= ~RECORD_DELETED; 374 } 375 } 376 377 return(retCode); 378 } 379 380 public void setFirstField(int firstField) 381 { 382 this.firstField = firstField; 383 status |= RECORD_HAS_FIRST_FIELD; 384 } 385 386 public final void setId(int id) 387 { 388 this.id = id; 389 } 390 391 public void setOverflowDetails(RecordHandle overflowHandle) 392 { 393 this.overflowPage = overflowHandle.getPageNumber(); 394 this.overflowId = overflowHandle.getId(); 395 } 396 397 public void setOverflowFields(StoredRecordHeader loadFromTarget) 398 { 399 this.status = (loadFromTarget.status | RECORD_OVERFLOW); 400 this.id = loadFromTarget.id; 401 this.numberFields = loadFromTarget.numberFields; 402 this.firstField = loadFromTarget.firstField; 403 handle = null; 404 } 405 406 407 public final void setNumberFields(int numberFields) 408 { 409 this.numberFields = numberFields; 410 } 411 412 416 public int write(OutputStream out) 417 throws IOException 418 { 419 if (SanityManager.DEBUG) 422 { 423 if ((status & ~RECORD_VALID_MASK) != 0) 424 SanityManager.THROWASSERT( 425 "Invalid status in StoredRecordHeaader = " + status); 426 } 427 428 int len = 1; 430 out.write(status); 431 432 len += CompressedNumber.writeInt(out, id); 434 435 436 if (hasOverflow()) 438 { 439 len += CompressedNumber.writeLong(out, overflowPage); 441 len += CompressedNumber.writeInt(out, overflowId); 442 } 443 444 if (hasFirstField()) 446 { 447 len += CompressedNumber.writeInt(out, firstField); 448 } 449 450 if (!hasOverflow() || hasFirstField()) 455 len += CompressedNumber.writeInt(out, numberFields); 456 457 return len; 458 } 459 460 public void read(java.io.ObjectInput in) 461 throws IOException 462 { 463 464 status = in.read(); 466 if (status < 0) 467 throw new EOFException (); 468 469 if (SanityManager.DEBUG) 472 { 473 if ((status & ~RECORD_VALID_MASK) != 0) 474 SanityManager.THROWASSERT( 475 "Invalid status in StoredRecordHeader = " + status); 476 } 477 478 id = CompressedNumber.readInt(in); 480 481 if (hasOverflow()) 483 { 484 overflowPage = CompressedNumber.readLong(in); 485 overflowId = CompressedNumber.readInt(in); 486 487 } 488 else 489 { 490 overflowPage = 0; 491 overflowId = 0; 492 } 493 494 if (hasFirstField()) 496 { 497 firstField = CompressedNumber.readInt(in); 498 } 499 else 500 { 501 firstField = 0; 502 } 503 504 if (!hasOverflow() || hasFirstField()) 511 numberFields = CompressedNumber.readInt(in); 512 else 513 numberFields = 0; 514 515 handle = null; 516 } 517 518 private int readId( 519 byte[] data, 520 int offset) 521 { 522 int value = data[offset++]; 523 524 if ((value & ~0x3f) == 0) 525 { 526 id = value; 528 529 return(1); 530 } 531 else if ((value & 0x80) == 0) 532 { 533 535 id = (((value & 0x3f) << 8) | (data[offset] & 0xff)); 536 537 return(2); 538 } 539 else 540 { 541 id = 543 ((value & 0x7f) << 24) | 544 ((data[offset++] & 0xff) << 16) | 545 ((data[offset++] & 0xff) << 8) | 546 ((data[offset] & 0xff) ); 547 548 return(4); 549 } 550 } 551 private int readOverFlowPage( 552 byte[] data, 553 int offset) 554 { 555 int int_value = data[offset++]; 556 557 if ((int_value & ~0x3f) == 0) 558 { 559 562 overflowPage = ((int_value << 8) | (data[offset] & 0xff)); 563 564 return(2); 565 } 566 else if ((int_value & 0x80) == 0) 567 { 568 570 overflowPage = 571 ((int_value & 0x3f) << 24) | 572 ((data[offset++] & 0xff) << 16) | 573 ((data[offset++] & 0xff) << 8) | 574 ((data[offset] & 0xff) ); 575 576 return(4); 577 578 } 579 else 580 { 581 overflowPage = 583 (((long) (int_value & 0x7f)) << 56) | 584 (((long) (data[offset++] & 0xff)) << 48) | 585 (((long) (data[offset++] & 0xff)) << 40) | 586 (((long) (data[offset++] & 0xff)) << 32) | 587 (((long) (data[offset++] & 0xff)) << 24) | 588 (((long) (data[offset++] & 0xff)) << 16) | 589 (((long) (data[offset++] & 0xff)) << 8) | 590 (((long) (data[offset] & 0xff)) ); 591 592 return(8); 593 } 594 } 595 private int readOverFlowId( 596 byte[] data, 597 int offset) 598 { 599 int value = data[offset++]; 600 601 if ((value & ~0x3f) == 0) 602 { 603 overflowId = value; 605 606 return(1); 607 } 608 else if ((value & 0x80) == 0) 609 { 610 612 overflowId = (((value & 0x3f) << 8) | (data[offset] & 0xff)); 613 614 return(2); 615 } 616 else 617 { 618 overflowId = 620 ((value & 0x7f) << 24) | 621 ((data[offset++] & 0xff) << 16) | 622 ((data[offset++] & 0xff) << 8) | 623 ((data[offset] & 0xff) ); 624 625 return(4); 626 } 627 } 628 private int readFirstField( 629 byte[] data, 630 int offset) 631 { 632 int value = data[offset++]; 633 634 if ((value & ~0x3f) == 0) 635 { 636 firstField = value; 638 639 return(1); 640 } 641 else if ((value & 0x80) == 0) 642 { 643 645 firstField = (((value & 0x3f) << 8) | (data[offset] & 0xff)); 646 647 return(2); 648 } 649 else 650 { 651 firstField = 653 ((value & 0x7f) << 24) | 654 ((data[offset++] & 0xff) << 16) | 655 ((data[offset++] & 0xff) << 8) | 656 ((data[offset] & 0xff) ); 657 658 return(4); 659 } 660 } 661 private void readNumberFields( 662 byte[] data, 663 int offset) 664 { 665 int value = data[offset++]; 666 667 if ((value & ~0x3f) == 0) 668 { 669 numberFields = value; 671 } 672 else if ((value & 0x80) == 0) 673 { 674 676 numberFields = (((value & 0x3f) << 8) | (data[offset] & 0xff)); 677 } 678 else 679 { 680 numberFields = 682 ((value & 0x7f) << 24) | 683 ((data[offset++] & 0xff) << 16) | 684 ((data[offset++] & 0xff) << 8) | 685 ((data[offset] & 0xff) ); 686 } 687 } 688 689 690 private void read( 691 byte[] data, 692 int offset) 693 { 694 status = data[offset++]; 695 696 int value = data[offset++]; 697 698 if ((value & ~0x3f) == 0) 699 { 700 id = value; 702 } 703 else if ((value & 0x80) == 0) 704 { 705 707 id = (((value & 0x3f) << 8) | (data[offset++] & 0xff)); 708 } 709 else 710 { 711 id = 713 ((value & 0x7f) << 24) | 714 ((data[offset++] & 0xff) << 16) | 715 ((data[offset++] & 0xff) << 8) | 716 ((data[offset++] & 0xff) ); 717 } 718 719 if ((status & (RECORD_OVERFLOW | RECORD_HAS_FIRST_FIELD)) == 0) 720 { 721 overflowPage = 0; 723 overflowId = 0; 724 firstField = 0; 725 726 readNumberFields(data, offset); 727 } 728 else if ((status & RECORD_OVERFLOW) == 0) 729 { 730 overflowPage = 0; 732 overflowId = 0; 733 734 offset += readFirstField(data, offset); 735 736 readNumberFields(data, offset); 737 } 738 else 739 { 740 742 offset += readOverFlowPage(data, offset); 743 offset += readOverFlowId(data, offset); 744 745 if (hasFirstField()) 746 { 747 offset += readFirstField(data, offset); 748 readNumberFields(data, offset); 749 } 750 else 751 { 752 firstField = 0; 753 numberFields = 0; 754 } 755 } 756 757 handle = null; 758 759 return; 760 } 761 762 763 public String toString() 764 { 765 if (SanityManager.DEBUG) 766 { 767 String str = "recordHeader: Id=" + getId(); 768 769 str += "\n isDeleted = " + isDeleted(); 770 str += "\n hasOverflow = " + hasOverflow(); 771 str += "\n hasFirstField = " + hasFirstField(); 772 str += "\n numberFields = " + getNumberFields(); 773 str += "\n firstField = " + getFirstField(); 774 str += "\n overflowPage = " + getOverflowPage(); 775 str += "\n overflowId = " + getOverflowId(); 776 777 return str; 778 } 779 else 780 { 781 return null; 782 } 783 } 784 } 785 | Popular Tags |