1 21 22 package org.apache.derby.impl.store.raw.data; 23 24 import org.apache.derby.iapi.reference.SQLState; 25 26 import org.apache.derby.iapi.services.io.FormatableBitSet; 27 import org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream; 28 import org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream; 29 30 import org.apache.derby.iapi.services.locks.C_LockFactory; 31 import org.apache.derby.iapi.services.locks.Lockable; 32 import org.apache.derby.iapi.services.locks.Latch; 33 import org.apache.derby.iapi.services.locks.VirtualLockTable; 34 35 import org.apache.derby.iapi.services.sanity.SanityManager; 36 37 import org.apache.derby.iapi.services.io.LimitObjectInput; 38 import org.apache.derby.iapi.services.io.TypedFormat; 39 40 import org.apache.derby.iapi.error.StandardException; 41 42 import org.apache.derby.iapi.store.raw.AuxObject; 43 import org.apache.derby.iapi.store.raw.ContainerHandle; 44 import org.apache.derby.iapi.store.raw.ContainerKey; 45 import org.apache.derby.iapi.store.raw.FetchDescriptor; 46 import org.apache.derby.iapi.store.raw.Page; 47 import org.apache.derby.iapi.store.raw.PageKey; 48 import org.apache.derby.iapi.store.raw.RecordHandle; 49 import org.apache.derby.iapi.store.raw.RawStoreFactory; 50 import org.apache.derby.iapi.store.raw.xact.RawTransaction; 51 import org.apache.derby.iapi.store.raw.log.LogInstant; 52 53 import org.apache.derby.iapi.store.access.Qualifier; 54 import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo; 55 56 import org.apache.derby.iapi.types.DataValueDescriptor; 57 58 import java.io.IOException ; 59 import java.io.OutputStream ; 60 import java.io.ObjectInput ; 61 62 import java.util.Hashtable ; 63 import java.util.Observer ; 64 import java.util.Observable ; 65 66 67 86 87 88 public abstract class BasePage implements Page, Lockable, Observer , TypedFormat 89 { 90 91 101 private AuxObject auxObj; 102 103 108 protected PageKey identity; 109 110 115 private StoredRecordHeader[] headers; 117 private int recordCount; 118 119 124 protected BaseContainerHandle owner; 125 126 129 private int nestedLatch; 130 131 135 private Latch myLatch; 136 137 protected boolean inClean; 139 157 protected boolean preLatch; 158 159 164 private LogInstant lastLog; 165 166 172 private long pageVersion = 0; 174 177 private byte pageStatus; 178 179 190 public static final byte VALID_PAGE = 1; 191 public static final byte INVALID_PAGE = 2; 192 193 202 public static final int INIT_PAGE_REUSE = 0x1; 203 public static final int INIT_PAGE_OVERFLOW = 0x2; 204 public static final int INIT_PAGE_REUSE_RECORDID = 0x4; 205 206 216 public static final int LOG_RECORD_DEFAULT = 0x0; 217 public static final int LOG_RECORD_FOR_UPDATE = 0x1; 218 public static final int LOG_RECORD_FOR_PURGE = 0x2; 219 220 223 224 protected BasePage() 225 { 226 227 } 228 229 235 protected void initialize() 236 { 237 setAuxObject(null); 238 identity = null; 239 recordCount = 0; 240 clearLastLogInstant(); 241 242 if (SanityManager.DEBUG) 243 { 244 if (nestedLatch != 0) 245 SanityManager.THROWASSERT("nestedLatch is non-zero in initialize - value = " + nestedLatch); 246 if (inClean) 247 SanityManager.THROWASSERT("inClean is true in initialize"); 248 if (preLatch) 249 SanityManager.THROWASSERT("preLatch is true in initialize"); 250 } 251 252 } 253 254 258 protected void initializeHeaders(int numRecords) 259 { 260 261 if (SanityManager.DEBUG) 262 { 263 if (recordCount != 0) 264 SanityManager.THROWASSERT( 265 "record count = " + recordCount + 266 " before initSlotTable is called"); 267 } 268 269 headers = new StoredRecordHeader[numRecords]; 270 } 271 272 273 276 277 protected void fillInIdentity(PageKey key) { 278 if (SanityManager.DEBUG) { 279 SanityManager.ASSERT(identity == null); 280 } 281 282 identity = key; 283 } 284 285 public void clearIdentity() { 286 287 if (SanityManager.DEBUG) { 288 SanityManager.ASSERT(!isLatched()); 289 } 290 291 identity = null; 292 293 cleanPageForReuse(); 294 } 295 296 297 300 protected void cleanPageForReuse() 301 { 302 setAuxObject(null); 303 recordCount = 0; 304 } 305 306 307 310 public Object getIdentity() { 311 return identity; 312 } 313 314 317 318 private static final RecordHandle InvalidRecordHandle = 319 new RecordId( 320 new PageKey( 321 new ContainerKey(0,0), ContainerHandle.INVALID_PAGE_NUMBER), 322 RecordHandle.INVALID_RECORD_HANDLE); 323 324 public final RecordHandle getInvalidRecordHandle() 325 { 326 return InvalidRecordHandle; 328 } 329 330 public static final RecordHandle MakeRecordHandle(PageKey pkey, int recordHandleConstant) 331 throws StandardException 332 { 333 if (recordHandleConstant >= RecordHandle.FIRST_RECORD_ID) 334 { 335 throw StandardException.newException( 336 SQLState.DATA_CANNOT_MAKE_RECORD_HANDLE, 337 new Long (recordHandleConstant)); 338 } 339 340 return new RecordId(pkey, recordHandleConstant); 341 } 342 343 public final RecordHandle makeRecordHandle(int recordHandleConstant) 344 throws StandardException 345 { 346 return MakeRecordHandle(getPageId(), recordHandleConstant); 347 } 348 349 350 public final long getPageNumber() { 351 if (SanityManager.DEBUG) { 352 SanityManager.ASSERT(isLatched(), "page is not latched."); 353 SanityManager.ASSERT(identity != null, "identity is null."); 354 } 355 356 return identity.getPageNumber(); 357 } 358 359 public final RecordHandle getRecordHandle(int recordId) { 360 if (SanityManager.DEBUG) { 361 SanityManager.ASSERT(isLatched()); 362 } 363 364 int slot = findRecordById(recordId, FIRST_SLOT_NUMBER); 365 if (slot < 0) 366 return null; 367 368 return getRecordHandleAtSlot(slot); 369 } 370 371 public final RecordHandle getRecordHandleAtSlot(int slot) { 372 return getHeaderAtSlot(slot).getHandle(getPageId(), slot); 373 } 374 375 379 public final boolean recordExists(RecordHandle handle, boolean ignoreDelete) 380 throws StandardException 381 { 382 if (SanityManager.DEBUG) { 383 SanityManager.ASSERT(isLatched()); 384 } 385 386 if (handle.getId() < RecordHandle.FIRST_RECORD_ID) 387 { 388 throw StandardException.newException( 389 SQLState.DATA_INVALID_RECORD_HANDLE, handle); 390 } 391 392 if (handle.getPageNumber() != getPageNumber()) 393 return false; 394 395 int slot = findRecordById(handle.getId(), handle.getSlotNumberHint()); 396 return (slot >= FIRST_SLOT_NUMBER && 397 (ignoreDelete || !isDeletedAtSlot(slot))); 398 } 399 400 418 419 public RecordHandle fetch( 420 RecordHandle handle, 421 Object [] row, 422 FormatableBitSet validColumns, 423 boolean forUpdate) 424 throws StandardException { 425 426 if (SanityManager.DEBUG) { 427 SanityManager.ASSERT(isLatched()); 428 } 429 430 owner.getLockingPolicy().lockRecordForRead(myLatch, handle, forUpdate); 431 432 int slot = getSlotNumber(handle); 434 435 StoredRecordHeader recordHeader = getHeaderAtSlot(slot); 436 437 if (recordHeader.isDeleted()) 438 return null; 439 440 FetchDescriptor hack_fetch = 441 new FetchDescriptor( 442 row.length, validColumns, (Qualifier[][]) null); 443 444 restoreRecordFromSlot( 446 slot, row, hack_fetch, handle, recordHeader, true); 447 448 owner.getLockingPolicy().unlockRecordAfterRead( 449 owner.getTransaction(), owner, handle, forUpdate, true); 450 451 return handle; 452 } 453 454 455 public RecordHandle fetchFromSlot( 456 RecordHandle rh, 457 int slot, 458 Object [] row, 459 FetchDescriptor fetchDesc, 460 boolean ignoreDelete) 461 throws StandardException 462 { 463 if (SanityManager.DEBUG) { 464 SanityManager.ASSERT(isLatched()); 465 466 if (rh != null) 467 SanityManager.ASSERT(getSlotNumber(rh) == slot); 468 } 469 470 checkSlotOnPage(slot); 471 472 StoredRecordHeader recordHeader = getHeaderAtSlot(slot); 473 474 if (rh == null) 475 rh = recordHeader.getHandle(getPageId(), slot); 476 477 if (!ignoreDelete && recordHeader.isDeleted()) 478 return null; 479 480 497 498 return( 499 restoreRecordFromSlot( 500 slot, row, fetchDesc, rh, recordHeader, true) ? rh : null); 501 } 502 503 504 508 public final RecordHandle fetchFieldFromSlot( 509 int slot, 510 int fieldId, 511 Object column) 512 throws StandardException 513 { 514 Object [] row = new Object [fieldId + 1]; 517 row[fieldId] = column; 518 FormatableBitSet singleColumn = new FormatableBitSet(fieldId + 1); 519 520 singleColumn.set(fieldId); 521 522 FetchDescriptor fetchDesc = 523 new FetchDescriptor(fieldId + 1, singleColumn,(Qualifier[][]) null); 524 525 return(fetchFromSlot(null, slot, row, fetchDesc, true)); 526 } 527 528 533 public final int getSlotNumber(RecordHandle handle) 534 throws StandardException 535 { 536 if (SanityManager.DEBUG) { 537 SanityManager.ASSERT(isLatched()); 538 } 539 540 int slot = findRecordById(handle.getId(), handle.getSlotNumberHint()); 541 542 if (slot < 0) 543 { 544 throw StandardException.newException( 545 SQLState.RAWSTORE_RECORD_VANISHED, handle); 546 } 547 548 return slot; 549 } 550 551 556 public final int getNextSlotNumber(RecordHandle handle) 557 throws StandardException 558 { 559 if (SanityManager.DEBUG) { 560 SanityManager.ASSERT(isLatched()); 561 } 562 563 int slot = findNextRecordById(handle.getId()); 564 565 return slot; 566 } 567 568 571 public RecordHandle insertAtSlot( 572 int slot, 573 Object [] row, 574 FormatableBitSet validColumns, 575 LogicalUndo undo, 576 byte insertFlag, 577 int overflowThreshold) 578 throws StandardException 579 { 580 if (SanityManager.DEBUG) { 581 if (overflowThreshold == 0) 582 SanityManager.THROWASSERT("overflowThreshold cannot be 0"); 583 } 584 585 if ((insertFlag & Page.INSERT_DEFAULT) == Page.INSERT_DEFAULT) { 586 return (insertNoOverflow(slot, row, validColumns, undo, insertFlag, overflowThreshold)); 587 } else { 588 if (SanityManager.DEBUG) { 589 if (undo != null) 590 SanityManager.THROWASSERT("logical undo with overflow allowed on insert " + undo.toString()); 591 } 592 return (insertAllowOverflow(slot, 593 row, validColumns, 0, insertFlag, overflowThreshold, (RecordHandle) null)); 594 } 595 } 596 597 protected RecordHandle insertNoOverflow( 598 int slot, 599 Object [] row, 600 FormatableBitSet validColumns, 601 LogicalUndo undo, 602 byte insertFlag, 603 int overflowThreshold) 604 throws StandardException 605 { 606 607 if (SanityManager.DEBUG) { 608 SanityManager.ASSERT(isLatched()); 609 } 610 611 if (!owner.updateOK()) 612 { 613 throw StandardException.newException( 614 SQLState.DATA_CONTAINER_READ_ONLY); 615 } 616 617 if (slot < FIRST_SLOT_NUMBER || slot > recordCount) 618 { 619 throw StandardException.newException( 620 SQLState.DATA_SLOT_NOT_ON_PAGE); 621 } 622 623 if (!allowInsert()) 624 return null; 625 626 RawTransaction t = owner.getTransaction(); 627 628 if (undo != null) { 630 t.checkLogicalOperationOk(); 631 } 632 633 int recordId; 634 RecordHandle handle; 635 636 do { 637 638 640 656 recordId = newRecordIdAndBump(); 657 handle = new RecordId(getPageId(), recordId, slot); 658 659 } while(!owner.getLockingPolicy().lockRecordForWrite( 660 t, handle, 661 true , 662 false )); 663 664 665 owner.getActionSet().actionInsert(t, this, slot, recordId, row, validColumns, 666 undo, insertFlag, 0, false, -1, (DynamicByteArrayOutputStream) null, -1, overflowThreshold); 667 668 672 return handle; 673 } 674 675 678 public final RecordHandle insert( 679 Object [] row, 680 FormatableBitSet validColumns, 681 byte insertFlag, 682 int overflowThreshold) 683 throws StandardException 684 { 685 686 if (SanityManager.DEBUG) { 687 if (overflowThreshold == 0) 688 SanityManager.THROWASSERT("overflowThreshold much be greater than 0"); 689 } 690 691 if (((insertFlag & Page.INSERT_DEFAULT) == Page.INSERT_DEFAULT)) { 692 return (insertAtSlot(recordCount, row, validColumns, 693 (LogicalUndo) null, insertFlag, overflowThreshold)); 694 } else { 695 return (insertAllowOverflow(recordCount, row, validColumns, 0, 696 insertFlag, overflowThreshold, (RecordHandle) null)); 697 } 698 } 699 700 708 public RecordHandle insertAllowOverflow( 709 int slot, 710 Object [] row, 711 FormatableBitSet validColumns, 712 int startColumn, 713 byte insertFlag, 714 int overflowThreshold, 715 RecordHandle nextPortionHandle) 716 throws StandardException 717 { 718 719 BasePage curPage = this; 720 721 if (!curPage.owner.updateOK()) 722 { 723 throw StandardException.newException( 724 SQLState.DATA_CONTAINER_READ_ONLY); 725 } 726 727 728 RecordHandle headHandle = null; 730 RecordHandle handleToUpdate = null; 731 732 RawTransaction t = curPage.owner.getTransaction(); 733 734 for (;;) { 735 736 if (SanityManager.DEBUG) { 737 SanityManager.ASSERT(curPage.isLatched()); 738 } 739 740 if (!curPage.allowInsert()) 741 return null; 742 743 if (curPage != this) 745 slot = curPage.recordCount; 746 747 boolean isLongColumns = false; 748 int realStartColumn = -1; 749 int realSpaceOnPage = -1; 750 751 DynamicByteArrayOutputStream logBuffer = null; 752 753 int recordId = curPage.newRecordIdAndBump(); 755 RecordHandle handle = 756 new RecordId(curPage.getPageId(), recordId, slot); 757 758 if (curPage == this) { 759 760 761 if (handleToUpdate == null) { 763 764 while (!owner.getLockingPolicy().lockRecordForWrite( 765 t, handle, 766 true , 767 false )) { 768 769 789 recordId = curPage.newRecordIdAndBump(); 791 handle = 792 new RecordId(curPage.getPageId(), recordId, slot); 793 } 794 } 795 796 headHandle = handle; 797 } 798 799 do { 800 801 try { 804 805 startColumn = 806 owner.getActionSet().actionInsert( 807 t, curPage, slot, recordId, 808 row, validColumns, (LogicalUndo) null, 809 insertFlag, startColumn, false, 810 realStartColumn, logBuffer, realSpaceOnPage, 811 overflowThreshold); 812 isLongColumns = false; 813 814 } catch (LongColumnException lce) { 815 816 817 logBuffer = new DynamicByteArrayOutputStream(lce.getLogBuffer()); 823 824 RecordHandle longColumnHandle = 827 insertLongColumn(curPage, lce, insertFlag); 828 829 int overflowFieldLen = 0; 831 try { 832 overflowFieldLen += 833 appendOverflowFieldHeader((DynamicByteArrayOutputStream)logBuffer, longColumnHandle); 834 } catch (IOException ioe) { 835 return null; 837 } 838 839 realStartColumn = lce.getNextColumn() + 1; 842 realSpaceOnPage = lce.getRealSpaceOnPage() - overflowFieldLen; 843 844 isLongColumns = true; 845 } 846 } while (isLongColumns); 847 848 if (handleToUpdate != null) { 849 updateOverflowDetails(handleToUpdate, handle); 851 } 852 853 if (startColumn == -1) { 855 856 if (curPage != this) 857 curPage.unlatch(); 858 859 if (nextPortionHandle != null) { 860 updateOverflowDetails(handle, nextPortionHandle); 863 } 864 865 return headHandle; 866 } 867 868 handleToUpdate = handle; 869 870 BasePage nextPage = 871 curPage.getOverflowPageForInsert( 872 slot, row, validColumns,startColumn); 873 874 if (curPage != this) 875 curPage.unlatch(); 876 curPage = nextPage; 877 } 878 879 } 880 881 888 protected RecordHandle insertLongColumn(BasePage mainChainPage, 889 LongColumnException lce, byte insertFlag) 890 throws StandardException 891 { 892 893 Object [] row = new Object [1]; 896 row[0] = lce.getColumn(); 897 898 RecordHandle firstHandle = null; 899 RecordHandle handle = null; 900 RecordHandle prevHandle = null; 901 BasePage curPage = mainChainPage; 902 BasePage prevPage = null; 903 boolean isFirstPage = true; 904 905 int startColumn = 0; 909 RawTransaction t = curPage.owner.getTransaction(); 910 911 do { 912 917 if (!isFirstPage) { 918 prevPage = curPage; 919 prevHandle = handle; 920 } 921 922 curPage = (BasePage) getNewOverflowPage(); 924 925 if (SanityManager.DEBUG) { 926 SanityManager.ASSERT(curPage.isLatched()); 927 SanityManager.ASSERT(curPage.allowInsert()); 928 } 929 930 int slot = curPage.recordCount; 931 932 int recordId = curPage.newRecordId(); 933 handle = new RecordId(curPage.getPageId(), recordId, slot); 934 935 if (isFirstPage) 936 firstHandle = handle; 937 938 startColumn = owner.getActionSet().actionInsert(t, curPage, slot, recordId, 940 row, (FormatableBitSet)null, (LogicalUndo) null, insertFlag, 941 startColumn, true, -1, (DynamicByteArrayOutputStream) null, -1, 100); 942 943 if (!isFirstPage) { 946 prevPage.updateFieldOverflowDetails(prevHandle, handle); 949 prevPage.unlatch(); 950 prevPage = null; 951 } else 952 isFirstPage = false; 953 954 } while (startColumn != (-1)) ; 955 956 if (curPage != null) { 957 curPage.unlatch(); 958 curPage = null; 959 } 960 961 return (firstHandle); 962 } 963 964 965 971 public abstract void preDirty(); 972 973 983 public abstract void updateOverflowDetails(RecordHandle handle, RecordHandle overflowHandle) 984 throws StandardException; 985 986 996 public abstract void updateFieldOverflowDetails(RecordHandle handle, RecordHandle overflowHandle) 997 throws StandardException; 998 999 1011 public abstract int appendOverflowFieldHeader(DynamicByteArrayOutputStream logBuffer, RecordHandle overflowHandle) 1012 throws StandardException, IOException ; 1013 1014 public abstract BasePage getOverflowPageForInsert( 1015 int slot, 1016 Object [] row, 1017 FormatableBitSet validColumns, 1018 int startColumn) 1019 throws StandardException; 1020 1021 protected abstract BasePage getNewOverflowPage() 1022 throws StandardException; 1023 1024 public final boolean update( 1025 RecordHandle handle, 1026 Object [] row, 1027 FormatableBitSet validColumns) 1028 throws StandardException 1029 { 1030 if (SanityManager.DEBUG) { 1031 SanityManager.ASSERT(isLatched()); 1032 } 1033 1034 if (!owner.updateOK()) 1035 { 1036 throw StandardException.newException( 1037 SQLState.DATA_CONTAINER_READ_ONLY); 1038 } 1039 1040 RawTransaction t = owner.getTransaction(); 1041 1042 owner.getLockingPolicy().lockRecordForWrite(myLatch, handle); 1043 1044 int slot = getSlotNumber(handle); 1045 1046 if (isDeletedAtSlot(slot)) 1047 return false; 1048 1049 doUpdateAtSlot(t, slot, handle.getId(), row, validColumns); 1050 1051 return true; 1052 } 1053 1054 1055 1059 public boolean delete(RecordHandle handle, LogicalUndo undo) 1060 throws StandardException 1061 { 1062 if (SanityManager.DEBUG) { 1063 SanityManager.ASSERT(isLatched()); 1064 } 1065 1066 owner.getLockingPolicy().lockRecordForWrite(myLatch, handle); 1067 1068 int slot = getSlotNumber(handle); 1069 1070 if (isDeletedAtSlot(slot)) 1071 return false; 1072 1073 deleteAtSlot(slot, true, undo); 1074 return true; 1075 } 1076 1077 1084 public final RecordHandle updateAtSlot( 1085 int slot, 1086 Object [] row, 1087 FormatableBitSet validColumns) 1088 throws StandardException 1089 { 1090 if (SanityManager.DEBUG) { 1091 SanityManager.ASSERT(isLatched()); 1092 } 1093 1094 if (!owner.updateOK()) 1095 { 1096 throw StandardException.newException( 1097 SQLState.DATA_CONTAINER_READ_ONLY); 1098 } 1099 1100 if (isDeletedAtSlot(slot)) 1101 { 1102 throw StandardException.newException( 1103 SQLState.DATA_UPDATE_DELETED_RECORD); 1104 } 1105 1106 1107 RecordHandle handle = getRecordHandleAtSlot(slot); 1108 1109 RawTransaction t = owner.getTransaction(); 1110 1111 doUpdateAtSlot(t, slot, handle.getId(), row, validColumns); 1112 1113 return handle; 1114 } 1115 1116 public abstract void doUpdateAtSlot( 1117 RawTransaction t, 1118 int slot, 1119 int id, 1120 Object [] row, 1121 FormatableBitSet validColumns) 1122 throws StandardException; 1123 1124 1131 public RecordHandle updateFieldAtSlot( 1132 int slot, 1133 int fieldId, 1134 Object newValue, 1135 LogicalUndo undo) 1136 throws StandardException 1137 { 1138 if (SanityManager.DEBUG) { 1139 SanityManager.ASSERT(isLatched()); 1140 SanityManager.ASSERT(newValue != null); 1141 } 1142 1143 if (!owner.updateOK()) 1144 { 1145 throw StandardException.newException( 1146 SQLState.DATA_CONTAINER_READ_ONLY); 1147 } 1148 1149 if (isDeletedAtSlot(slot)) 1150 { 1151 throw StandardException.newException( 1152 SQLState.DATA_UPDATE_DELETED_RECORD); 1153 } 1154 1155 RawTransaction t = owner.getTransaction(); 1156 RecordHandle handle = getRecordHandleAtSlot(slot); 1157 1158 owner.getActionSet().actionUpdateField(t, this, slot, 1159 handle.getId(), fieldId, newValue, undo); 1160 1161 return handle; 1162 } 1163 1164 1167 public final int fetchNumFields(RecordHandle handle) 1168 throws StandardException 1169 { 1170 if (SanityManager.DEBUG) { 1171 SanityManager.ASSERT(isLatched()); 1172 } 1173 1174 return fetchNumFieldsAtSlot(getSlotNumber(handle)); 1175 } 1176 1177 1180 public int fetchNumFieldsAtSlot(int slot) 1181 throws StandardException 1182 { 1183 if (SanityManager.DEBUG) { 1184 SanityManager.ASSERT(isLatched()); 1185 } 1186 1187 return getHeaderAtSlot(slot).getNumberFields(); 1188 } 1189 1190 1204 public RecordHandle deleteAtSlot(int slot, boolean delete, LogicalUndo undo) 1205 throws StandardException 1206 { 1207 if (SanityManager.DEBUG) { 1208 SanityManager.ASSERT(isLatched()); 1209 } 1210 1211 if (!owner.updateOK()) 1212 { 1213 throw StandardException.newException( 1214 SQLState.DATA_CONTAINER_READ_ONLY); 1215 } 1216 1217 if (delete) 1218 { 1219 if (isDeletedAtSlot(slot)) 1220 { 1221 throw StandardException.newException( 1222 SQLState.DATA_UPDATE_DELETED_RECORD); 1223 } 1224 1225 } 1226 else { 1228 if (!isDeletedAtSlot(slot)) 1229 { 1230 throw StandardException.newException( 1231 SQLState.DATA_UNDELETE_RECORD); 1232 } 1233 } 1234 1235 RawTransaction t = owner.getTransaction(); 1236 1237 if (undo != null) { 1239 t.checkLogicalOperationOk(); 1240 } 1241 1242 RecordHandle handle = getRecordHandleAtSlot(slot); 1243 1244 owner.getActionSet().actionDelete(t, this, slot, handle.getId(), delete, undo); 1245 1246 1249 return handle; 1250 } 1251 1252 1253 1259 public void purgeAtSlot(int slot, int numpurges, boolean needDataLogged) 1260 throws StandardException 1261 { 1262 if (SanityManager.DEBUG) 1263 { 1264 SanityManager.ASSERT(isLatched()); 1265 1266 if (isOverflowPage()) 1267 SanityManager.THROWASSERT( 1268 "purge committed deletes on an overflow page. Page = " + 1269 this); 1270 } 1271 1272 1273 if (numpurges <= 0) 1274 return; 1275 1276 if (!owner.updateOK()) 1277 { 1278 throw StandardException.newException( 1279 SQLState.DATA_CONTAINER_READ_ONLY); 1280 } 1281 1282 if ((slot < 0) || ((slot+numpurges) > recordCount)) 1283 { 1284 1285 throw StandardException.newException( 1286 SQLState.DATA_SLOT_NOT_ON_PAGE); 1287 } 1288 1289 RawTransaction t = owner.getTransaction(); 1290 1291 int[] recordIds = new int[numpurges]; 1293 1294 PageKey pageId = getPageId(); 1296 for (int i = 0; i < numpurges; i++) 1297 { 1298 recordIds[i] = getHeaderAtSlot(slot + i).getId(); 1299 1300 RecordHandle handle = getRecordHandleAtSlot(slot); 1302 owner.getLockingPolicy().lockRecordForWrite(t, handle, false, true); 1303 1304 1309 if (owner.isTemporaryContainer() || entireRecordOnPage(slot+i)) 1310 continue; 1311 1312 RecordHandle headRowHandle = 1315 getHeaderAtSlot(slot+i).getHandle(pageId, slot+i); 1316 purgeRowPieces(t, slot+i, headRowHandle, needDataLogged); 1317 } 1318 1319 owner.getActionSet().actionPurge(t, this, slot, numpurges, recordIds, needDataLogged); 1320 1321 } 1322 1323 1327 protected abstract void purgeRowPieces(RawTransaction t, int slot, 1328 RecordHandle headRowHandle, 1329 boolean needDataLogged) 1330 throws StandardException; 1331 1332 1333 1336 public void copyAndPurge(Page destPage, int src_slot, int num_rows, int dest_slot) 1337 throws StandardException 1338 { 1339 if (SanityManager.DEBUG) { 1340 SanityManager.ASSERT(isLatched()); 1341 } 1342 1343 if (num_rows <= 0) 1344 { 1345 throw StandardException.newException(SQLState.DATA_NO_ROW_COPIED); 1346 } 1347 1348 if (!owner.updateOK()) 1349 { 1350 throw StandardException.newException( 1351 SQLState.DATA_CONTAINER_READ_ONLY); 1352 } 1353 1354 if ((src_slot < 0) || ((src_slot + num_rows) > recordCount)) 1355 { 1356 throw StandardException.newException( 1357 SQLState.DATA_SLOT_NOT_ON_PAGE); 1358 } 1359 1360 if (SanityManager.DEBUG) { 1361 SanityManager.ASSERT((destPage instanceof BasePage), "must copy from BasePage to BasePage"); 1364 } 1365 1366 BasePage dpage = (BasePage)destPage; 1367 1368 1371 PageKey pageId = getPageId(); 1373 if (!pageId.getContainerId().equals(dpage.getPageId().getContainerId())) 1374 { 1375 throw StandardException.newException( 1376 SQLState.DATA_DIFFERENT_CONTAINER, 1377 pageId.getContainerId(), 1378 dpage.getPageId().getContainerId()); 1379 } 1380 1381 int[] recordIds = new int[num_rows]; 1382 1383 RawTransaction t = owner.getTransaction(); 1384 1385 for (int i = 0; i < num_rows; i++) 1387 { 1388 RecordHandle handle = getRecordHandleAtSlot(src_slot+i); 1389 owner.getLockingPolicy().lockRecordForWrite(t, handle, false, true); 1390 1391 recordIds[i] = getHeaderAtSlot(src_slot + i).getId(); 1392 } 1393 1394 dpage.copyInto(this, src_slot, num_rows, dest_slot); 1396 1397 1403 owner.getActionSet().actionPurge( 1404 t, this, src_slot, num_rows, recordIds, true); 1405 } 1406 1407 1408 1412 public void unlatch() { 1413 if (SanityManager.DEBUG) { 1414 SanityManager.ASSERT(isLatched()); 1415 } 1416 1417 releaseExclusive(); 1418 } 1419 1420 1421 public boolean isLatched() { 1422 if (SanityManager.DEBUG) { 1423 1424 synchronized(this) 1425 { 1426 SanityManager.ASSERT(identity != null); 1427 if (owner != null) { 1428 if (owner != myLatch.getQualifier()) 1429 SanityManager.THROWASSERT("Page incorrectly latched - " + owner + " " + myLatch.getQualifier()); 1430 } 1431 } 1432 } 1433 1434 return owner != null; 1435 } 1436 1437 1438 public final int recordCount() { 1439 if (SanityManager.DEBUG) { 1440 SanityManager.ASSERT(isLatched()); 1441 } 1442 1443 return recordCount; 1444 } 1445 1446 1449 protected abstract int internalDeletedRecordCount(); 1450 1451 1454 protected int internalNonDeletedRecordCount() 1455 { 1456 if (pageStatus != VALID_PAGE) 1458 return 0; 1459 1460 int deletedCount = internalDeletedRecordCount(); 1461 1462 if (deletedCount == -1) { 1463 int count = 0; 1464 int maxSlot = recordCount; 1465 for (int slot = FIRST_SLOT_NUMBER ; slot < maxSlot; slot++) { 1466 if (!isDeletedOnPage(slot)) 1467 count++; 1468 } 1469 return count; 1470 1471 } else { 1472 1473 if (SanityManager.DEBUG) { 1474 int delCount = 0; 1475 int maxSlot = recordCount; 1476 for (int slot = FIRST_SLOT_NUMBER ; slot < maxSlot; slot++) { 1477 if (recordHeaderOnDemand(slot).isDeleted()) 1478 delCount++; 1479 } 1480 if (delCount != deletedCount) 1481 SanityManager.THROWASSERT("incorrect deleted row count. Should be: " 1482 + delCount + ", instead got: " + deletedCount 1483 + ", maxSlot = " + maxSlot + ", recordCount = " + recordCount); 1484 } 1485 1486 return (recordCount - deletedCount); 1487 } 1488 } 1489 1490 1491 public int nonDeletedRecordCount() { 1492 if (SanityManager.DEBUG) { 1493 SanityManager.ASSERT(isLatched()); 1494 } 1495 1496 return internalNonDeletedRecordCount(); 1497 1498 } 1499 1500 1529 public boolean shouldReclaimSpace( 1530 int num_non_deleted_rows, 1531 int slot_just_deleted) 1532 throws StandardException 1533 { 1534 if (SanityManager.DEBUG) 1535 { 1536 SanityManager.ASSERT(isLatched()); 1537 } 1538 1539 boolean ret_val = false; 1540 1541 if (internalNonDeletedRecordCount() <= num_non_deleted_rows) 1542 { 1543 ret_val = true; 1544 } 1545 else 1546 { 1547 if (!entireRecordOnPage(slot_just_deleted)) 1548 { 1549 ret_val = true; 1550 } 1551 } 1552 1553 return(ret_val); 1554 } 1555 1556 protected final boolean isDeletedOnPage(int slot) 1558 { 1559 return getHeaderAtSlot(slot).isDeleted(); 1560 } 1561 1562 1563 1566 public boolean isDeletedAtSlot(int slot) 1567 throws StandardException 1568 { 1569 if (SanityManager.DEBUG) { 1570 SanityManager.ASSERT(isLatched()); 1571 } 1572 1573 checkSlotOnPage(slot); 1574 1575 return isDeletedOnPage(slot); 1576 } 1577 1578 1587 public void setAuxObject(AuxObject obj) 1588 { 1589 if (SanityManager.DEBUG) { 1590 SanityManager.ASSERT((identity == null) || isLatched()); 1591 } 1592 1593 if (auxObj != null) { 1594 auxObj.auxObjectInvalidated(); 1595 } 1596 1597 auxObj = obj; 1598 } 1599 1600 1607 public AuxObject getAuxObject() 1608 { 1609 if (SanityManager.DEBUG) { 1610 SanityManager.ASSERT(isLatched()); 1611 } 1612 1613 return auxObj; 1614 } 1615 1616 1619 1620 1626 public void lockEvent(Latch lockInfo) { 1627 if (SanityManager.DEBUG) { 1628 SanityManager.ASSERT(owner == null, "Should only be called when not locked"); 1629 } 1630 1631 synchronized (this) { 1632 1633 myLatch = lockInfo; 1634 1635 (owner = (BaseContainerHandle) lockInfo.getQualifier()).addObserver(this); 1641 preLatch = true; 1642 } 1643 } 1644 1645 1650 public boolean requestCompatible(Object requestedQualifier, Object grantedQualifier) { 1651 if (SanityManager.DEBUG) { 1652 SanityManager.ASSERT(owner != null, "Should only be called when locked"); 1653 } 1654 1655 return false; 1656 } 1657 1658 1663 public boolean lockerAlwaysCompatible() { 1664 if (SanityManager.DEBUG) { 1665 SanityManager.ASSERT(owner != null, "Should only be called when locked"); 1666 } 1667 1668 return false; 1669 } 1670 1671 1677 public void unlockEvent(Latch lockInfo) { 1678 if (SanityManager.DEBUG) { 1679 SanityManager.ASSERT(owner != null, "Should only be called when locked"); 1680 } 1681 1682 synchronized (this) { 1683 1684 if (SanityManager.DEBUG) { 1685 if (nestedLatch != 0) 1686 SanityManager.THROWASSERT("nestedLatch is non-zero on unlockEvent - value = " + nestedLatch); 1687 } 1688 1689 owner.deleteObserver(this); 1690 owner = null; 1691 myLatch = null; 1692 if (inClean) 1693 notifyAll(); 1694 } 1695 } 1696 1697 1698 1701 1702 1712 1713 public void update(Observable obj, Object arg) { 1714 1715 if (SanityManager.DEBUG) { 1716 SanityManager.ASSERT(isLatched()); 1717 SanityManager.ASSERT(obj == owner); 1718 } 1719 1720 releaseExclusive(); 1721 } 1722 1723 1726 1727 1732 public PageKey getPageId() { 1733 if (SanityManager.DEBUG) { 1734 SanityManager.ASSERT(identity != null); 1735 } 1736 1737 return identity; 1738 } 1739 1740 1746 public void setExclusive(BaseContainerHandle requester) 1747 throws StandardException { 1748 1749 RawTransaction t = requester.getTransaction(); 1750 1751 synchronized (this) 1764 { 1765 if ((owner != null) && (t == owner.getTransaction())) { 1769 1770 if (t.inAbort()) { 1771 nestedLatch++; 1773 return; 1774 } 1775 } 1776 } 1778 1779 1780 t.getLockFactory().latchObject( 1782 t, this, requester, C_LockFactory.WAIT_FOREVER); 1783 1784 1786 if (SanityManager.DEBUG) { 1787 SanityManager.ASSERT(isLatched(), "page not latched"); 1788 } 1789 1790 synchronized (this) 1791 { 1792 1800 while (inClean) 1801 { 1802 try 1803 { 1804 wait(); 1806 } 1807 catch (InterruptedException ie) 1808 { 1809 } 1810 } 1811 1812 preLatch = false; 1814 } 1815 1816 } 1817 1818 1823 boolean setExclusiveNoWait(BaseContainerHandle requester) throws StandardException { 1824 1825 RawTransaction t = requester.getTransaction(); 1826 1827 synchronized (this) 1829 { 1830 if ((owner != null) && (t == owner.getTransaction())) { 1831 1832 if (t.inAbort()) { 1833 nestedLatch++; 1835 return true; 1836 } 1837 } 1838 } 1840 1841 boolean gotLatch = t.getLockFactory().latchObject(t, this, requester, C_LockFactory.NO_WAIT); 1843 if (!gotLatch) 1844 return false; 1845 1846 synchronized (this) 1847 { 1848 1856 while (inClean) 1857 { 1858 1861 try 1862 { 1863 wait(); 1865 } 1866 catch (InterruptedException ie) 1867 { 1868 } 1869 } 1870 1871 preLatch = false; 1873 } 1874 1875 if (SanityManager.DEBUG) { 1876 SanityManager.ASSERT(isLatched(), "page not latched"); 1877 } 1878 1879 return true; 1880 } 1881 1882 1887 protected void releaseExclusive() { 1888 1889 if (SanityManager.DEBUG) { 1890 if (!isLatched()) 1891 { 1892 SanityManager.THROWASSERT( 1893 "releaseExclusive failed, nestedLatch = " + nestedLatch); 1894 } 1895 } 1896 1897 if (nestedLatch > 0) { 1898 nestedLatch--; 1899 return; 1900 } 1901 1902 RawTransaction t = owner.getTransaction(); 1903 t.getLockFactory().unlatch(myLatch); 1904 } 1905 1906 1909 1910 1914 1915 protected final void setHeaderAtSlot(int slot, StoredRecordHeader rh) { 1916 1917 if (slot < headers.length) 1918 { 1919 if (rh != null) 1921 { 1922 headers[slot] = rh; 1923 } 1924 } 1925 else 1926 { 1927 StoredRecordHeader[] new_headers = new StoredRecordHeader[slot + 1]; 1929 1930 System.arraycopy(headers, 0, new_headers, 0, headers.length); 1931 1932 headers = new_headers; 1933 1934 headers[slot] = rh; 1935 } 1936 } 1937 1938 protected final void bumpRecordCount(int number) { 1939 recordCount += number; 1940 } 1941 1942 public final StoredRecordHeader getHeaderAtSlot(int slot) { 1943 1944 if (slot < headers.length) 1945 { 1946 StoredRecordHeader rh = headers[slot]; 1947 1948 return((rh != null) ? rh : recordHeaderOnDemand(slot)); 1949 } 1950 else 1951 { 1952 return recordHeaderOnDemand(slot); 1953 } 1954 } 1955 1956 1966 public abstract boolean entireRecordOnPage(int slot) 1967 throws StandardException; 1968 1969 1970 public abstract StoredRecordHeader recordHeaderOnDemand(int slot); 1971 1972 1978 private final void checkSlotOnPage(int slot) 1979 throws StandardException { 1980 1981 if (SanityManager.DEBUG) { 1982 SanityManager.ASSERT(isLatched()); 1983 } 1984 1985 if (slot >= FIRST_SLOT_NUMBER && slot < recordCount) 1986 { 1987 return; 1988 } 1989 1990 throw StandardException.newException(SQLState.DATA_SLOT_NOT_ON_PAGE); 1991 } 1992 1993 2009 public int setDeleteStatus(int slot, boolean delete) throws StandardException, IOException { 2010 2011 if (SanityManager.DEBUG) { 2012 checkSlotOnPage(slot);; 2014 } 2015 2016 return (getHeaderAtSlot(slot).setDeleted(delete)); 2017 } 2018 2019 2024 public void deallocatePage() throws StandardException 2025 { 2026 if (SanityManager.DEBUG) { 2027 SanityManager.ASSERT(isLatched()); 2028 } 2029 2030 if (!owner.updateOK()) 2031 { 2032 throw StandardException.newException( 2033 SQLState.DATA_CONTAINER_READ_ONLY); 2034 } 2035 2036 RawTransaction t = owner.getTransaction(); 2037 2038 owner.getActionSet().actionInvalidatePage(t, this); 2039 } 2040 2041 2045 public void initPage(int initFlag, long pageOffset) 2046 throws StandardException 2047 { 2048 if (SanityManager.DEBUG) { 2049 SanityManager.ASSERT(isLatched()); 2050 } 2051 2052 if (!owner.updateOK()) 2053 { 2054 throw StandardException.newException( 2055 SQLState.DATA_CONTAINER_READ_ONLY); 2056 } 2057 2058 RawTransaction t = owner.getTransaction(); 2059 2060 owner.getActionSet().actionInitPage( 2061 t, this, initFlag, getTypeFormatId(), pageOffset); 2062 } 2063 2064 2084 public int findRecordById(int recordId, int slotHint) { 2085 2086 if (SanityManager.DEBUG) { 2087 SanityManager.ASSERT(isLatched()); 2088 } 2089 2090 if (slotHint == FIRST_SLOT_NUMBER) 2091 slotHint = recordId - RecordHandle.FIRST_RECORD_ID; 2092 2093 int maxSlot = recordCount(); 2094 2095 if ((slotHint > FIRST_SLOT_NUMBER) && 2096 (slotHint < maxSlot) && 2097 (recordId == getHeaderAtSlot(slotHint).getId())) { 2098 return(slotHint); 2099 } else { 2100 for (int slot = FIRST_SLOT_NUMBER; slot < maxSlot; slot++) { 2101 if (recordId == getHeaderAtSlot(slot).getId()) { 2102 return slot; 2103 } 2104 } 2105 } 2106 2107 return -1; 2108 } 2109 2110 2138 private int findNextRecordById(int recordId) 2139 { 2140 if (SanityManager.DEBUG) 2141 { 2142 SanityManager.ASSERT(isLatched()); 2143 } 2144 2145 int maxSlot = recordCount(); 2146 2147 for (int slot = FIRST_SLOT_NUMBER; slot < maxSlot; slot++) 2148 { 2149 if (getHeaderAtSlot(slot).getId() > recordId) 2150 { 2151 return(slot); 2152 } 2153 } 2154 2155 return -1; 2156 } 2157 2158 2164 private void copyInto(BasePage srcPage, int src_slot, int num_rows, 2165 int dest_slot) 2166 throws StandardException 2167 { 2168 if ((dest_slot < 0) || dest_slot > recordCount) 2169 { 2170 throw StandardException.newException( 2171 SQLState.DATA_SLOT_NOT_ON_PAGE); 2172 } 2173 2174 RawTransaction t = owner.getTransaction(); 2175 2176 2178 int[] recordIds = new int[num_rows]; 2179 2180 PageKey pageId = getPageId(); 2182 2185 for (int i = 0; i < num_rows; i++) 2186 { 2187 if (i == 0) 2188 recordIds[i] = newRecordId(); 2189 else 2190 recordIds[i] = newRecordId(recordIds[i-1]); 2191 2192 RecordHandle handle = new RecordId(pageId, recordIds[i], i); 2193 owner.getLockingPolicy().lockRecordForWrite(t, handle, false, true); 2194 } 2195 2196 owner.getActionSet().actionCopyRows(t, this, srcPage, 2198 dest_slot, num_rows, src_slot, 2199 recordIds); 2200 } 2201 2202 2213 protected void removeAndShiftDown(int slot) 2214 { 2215 if (SanityManager.DEBUG) { 2216 SanityManager.ASSERT(isLatched()); 2217 2218 SanityManager.ASSERT(slot >= 0 && slot < recordCount); 2219 } 2220 2221 System.arraycopy( 2229 headers, slot + 1, headers, slot, headers.length - (slot + 1)); 2230 headers[headers.length - 1] = null; 2231 2232 recordCount--; 2233 } 2234 2235 2236 2244 protected StoredRecordHeader shiftUp(int low) 2245 { 2246 2247 if (SanityManager.DEBUG) 2248 { 2249 SanityManager.ASSERT(isLatched()); 2250 2251 if ((low < 0) || (low > recordCount)) 2252 { 2253 SanityManager.THROWASSERT( 2254 "shiftUp failed, low must be between 0 and recordCount." + 2255 " low = " + low + ", recordCount = " + recordCount + 2256 "\n page = " + this); 2257 } 2258 } 2259 2260 if (low < headers.length) 2261 { 2262 2276 2277 System.arraycopy( 2279 headers, low, headers, low + 1, headers.length - (low + 1)); 2280 2281 headers[low] = null; 2282 } 2283 2284 return(null); 2285 } 2286 2287 2288 2289 2318 public void compactRecord(RecordHandle handle) throws StandardException 2319 { 2320 if (SanityManager.DEBUG) { 2321 SanityManager.ASSERT(isLatched()); 2322 } 2323 2324 if (!owner.updateOK()) 2325 { 2326 throw StandardException.newException( 2327 SQLState.DATA_CONTAINER_READ_ONLY); 2328 } 2329 2330 if (handle.getId() < RecordHandle.FIRST_RECORD_ID) 2331 { 2332 throw StandardException.newException( 2333 SQLState.DATA_INVALID_RECORD_HANDLE, handle); 2334 } 2335 2336 if (handle.getPageNumber() != getPageNumber()) 2337 { 2338 throw StandardException.newException( 2339 SQLState.DATA_WRONG_PAGE_FOR_HANDLE, handle); 2340 } 2341 2342 if (isOverflowPage()) 2343 { 2344 throw StandardException.newException( 2345 SQLState.DATA_UNEXPECTED_OVERFLOW_PAGE, handle); 2346 } 2347 2348 int slot = findRecordById(handle.getId(), handle.getSlotNumberHint()); 2349 2350 if (slot >= 0) 2351 { 2352 compactRecord(owner.getTransaction(), slot, handle.getId()); 2353 } 2354 } 2356 2357 2358 2362 2363 2366 2367 public final LogInstant getLastLogInstant() 2368 { 2369 return lastLog; 2370 } 2371 2372 protected final void clearLastLogInstant() { 2373 lastLog = null; 2374 } 2375 2376 protected final void updateLastLogInstant(LogInstant instant) 2377 { 2378 if (SanityManager.DEBUG) { 2379 SanityManager.ASSERT(isLatched()); 2380 } 2381 2382 if (instant != null) 2386 lastLog = instant; 2387 } 2388 2389 2392 2393 2396 public final long getPageVersion() 2397 { 2398 return pageVersion; 2399 } 2400 2401 2404 protected final long bumpPageVersion() 2405 { 2406 if (SanityManager.DEBUG) { 2407 SanityManager.ASSERT(isLatched()); 2408 } 2409 return ++pageVersion; 2410 } 2411 2412 2418 public final void setPageVersion(long v) 2419 { 2420 pageVersion = v; 2421 } 2422 2423 2424 2427 protected void setPageStatus(byte status) 2428 { 2429 pageStatus = status; 2430 } 2431 2432 2433 2436 public byte getPageStatus() 2437 { 2438 return pageStatus; 2439 } 2440 2441 2442 2447 2448 2487 protected abstract boolean restoreRecordFromSlot( 2488 int slot, 2489 Object [] row, 2490 FetchDescriptor fetchDesc, 2491 RecordHandle rh, 2492 StoredRecordHeader recordHeader, 2493 boolean isHeadRow) 2494 throws StandardException; 2495 2496 2497 2505 protected abstract void restorePortionLongColumn(OverflowInputStream fetchStream) 2506 throws StandardException, IOException ; 2507 2508 2515 public abstract int newRecordId() throws StandardException; 2516 2517 2524 public abstract int newRecordIdAndBump() throws StandardException; 2525 2526 2536 protected abstract int newRecordId(int recordId) throws StandardException; 2537 2538 2546 public abstract boolean spaceForCopy(int num_rows, int[] spaceNeeded) 2547 throws StandardException; 2548 2549 2557 public abstract int getTotalSpace(int slot) throws StandardException; 2558 2559 2567 public abstract int getReservedCount(int slot) throws IOException ; 2568 2569 2580 2581 2582 2585 2586 2592 2593 public abstract int getRecordLength(int slot) throws IOException ; 2594 2595 2605 public abstract void restoreRecordFromStream( 2606 LimitObjectInput in, 2607 Object [] row) 2608 throws StandardException, IOException ; 2609 2610 2627 public abstract void logRecord(int slot, int flag, int recordId, 2628 FormatableBitSet validColumns, OutputStream out, 2629 RecordHandle headRowHandle) 2630 throws StandardException, IOException ; 2631 2632 2633 2662 public abstract int logRow( 2663 int slot, 2664 boolean forInsert, 2665 int recordId, 2666 Object [] row, 2667 FormatableBitSet validColumns, 2668 DynamicByteArrayOutputStream out, 2669 int startColumn, 2670 byte insertFlag, 2671 int realStartColumn, 2672 int realSpaceOnPage, 2673 int overflowThreshold) 2674 throws StandardException, IOException ; 2675 2676 2688 public abstract void logField(int slot, int fieldNumber, OutputStream out) 2689 throws StandardException, IOException ; 2690 2702 public abstract void logColumn( 2703 int slot, 2704 int fieldId, 2705 Object column, 2706 DynamicByteArrayOutputStream out, 2707 int overflowThreshold) 2708 throws StandardException, IOException ; 2709 2710 2722 public abstract int logLongColumn( 2723 int slot, 2724 int recordId, 2725 Object column, 2726 DynamicByteArrayOutputStream out) 2727 throws StandardException, IOException ; 2728 2729 2741 public abstract void storeRecord(LogInstant instant, int slot, boolean forInsert, ObjectInput in) 2742 throws StandardException, IOException ; 2743 2744 2755 public abstract void storeField(LogInstant instant, int slot, 2756 int fieldId, 2757 ObjectInput in) 2758 throws StandardException, IOException ; 2759 2760 2769 public abstract void reserveSpaceForSlot(LogInstant instant, int slot, int spaceToReserve) 2770 throws StandardException, IOException ; 2771 2772 2773 2782 public abstract void skipField(ObjectInput in) 2783 throws StandardException, IOException ; 2784 2785 public abstract void skipRecord(ObjectInput in) throws StandardException, IOException ; 2786 2787 2798 public abstract void setDeleteStatus(LogInstant instant, int slot, boolean delete) 2799 throws StandardException, IOException ; 2800 2801 2813 public abstract void purgeRecord(LogInstant instant, int slot, 2814 int recordId) 2815 throws StandardException, IOException ; 2816 2817 2822 protected abstract void compactRecord(RawTransaction t, int slot, int recordId) 2823 throws StandardException; 2824 2825 2835 public abstract void setPageStatus(LogInstant instant, byte status) 2836 throws StandardException; 2837 2838 2839 2846 public abstract void initPage(LogInstant instant, byte status, 2847 int recordId, boolean overflow, boolean reuse) 2848 throws StandardException; 2849 2850 2854 public abstract void setReservedSpace(LogInstant instant, int slot, int value) 2855 throws StandardException, IOException ; 2856 2857 2861 public abstract boolean isOverflowPage(); 2862 2863 2866 public abstract boolean allowInsert(); 2867 2868 2873 public abstract boolean unfilled(); 2874 2875 2880 public abstract void setContainerRowCount(long count); 2881 2882 2885 protected abstract byte[] getPageArray() throws StandardException; 2886 2887 2890 2891 2892 protected String slotTableToString() 2893 { 2894 String str = null; 2895 2896 if (SanityManager.DEBUG) 2897 { 2898 StoredRecordHeader rh; 2899 str = new String (); 2900 2901 for (int slot = FIRST_SLOT_NUMBER; slot < recordCount; slot++) { 2902 rh = getHeaderAtSlot(slot); 2903 if (rh != null) 2904 str += "Slot " + slot + " recordId " + rh.getId(); 2905 else 2906 str += "Slot " + slot + " null record"; 2907 str += "\n"; 2908 } 2909 } 2910 return str; 2911 } 2912 2913 2916 public boolean lockAttributes(int flag, Hashtable attributes) 2917 { 2918 if (SanityManager.DEBUG) 2919 { 2920 SanityManager.ASSERT(attributes != null, 2921 "cannot call lockProperties with null attribute list"); 2922 } 2923 2924 if ((flag & VirtualLockTable.LATCH) == 0) 2925 return false; 2926 2927 PageKey pageId = identity; 2929 2930 if (pageId == null) 2932 return false; 2933 2934 attributes.put(VirtualLockTable.CONTAINERID, 2935 new Long (pageId.getContainerId().getContainerId())); 2936 attributes.put(VirtualLockTable.LOCKNAME, pageId.toString()); 2937 attributes.put(VirtualLockTable.LOCKTYPE, "LATCH"); 2938 2939 2943 return true; 2944 } 2945 2946 2947} 2948 | Popular Tags |