private void storeRecordForUpdate(int slot, ObjectInput in)
throws StandardException, IOException
{
// set up to read the in-memory record header back from the record
StoredRecordHeader recordHeader = getHeaderAtSlot(slot);
StoredRecordHeader newRecorderHeader = new StoredRecordHeader();
// recordHeader represents the new version of the record header.
newRecorderHeader.read(in);
int oldFieldCount = recordHeader.getNumberFields();
int newFieldCount = newRecorderHeader.getNumberFields();
int startField = recordHeader.getFirstField();
if (SanityManager.DEBUG) {
if (startField != newRecorderHeader.getFirstField())
SanityManager.THROWASSERT("First field changed from " + startField + " to " + newRecorderHeader.getFirstField());
}
// See if the number of fields shrunk, if so clear out the old data
// we do this first to stop shuffling about the fields that are going to
// be deleted during the update of the earlier fields. This case occurs
// on an update that changes the row to be overflowed.
if (newFieldCount < oldFieldCount) {
int oldDataStartingOffset = getFieldOffset(slot, startField + newFieldCount);
// calculate the length of the to be deleted fields
int deleteLength = getRecordOffset(slot) + getRecordPortionLength(slot) - oldDataStartingOffset;
// we are updateing to zero bytes!
updateRecordPortionLength(slot, -(deleteLength), deleteLength);
}
// write each field out to the page
int startingOffset = getRecordOffset(slot);
int newOffset = startingOffset;
int oldOffset = startingOffset;
// see which field we get to use the reserve space
int reservedSpaceFieldId = newFieldCount < oldFieldCount ?
newFieldCount - 1 : oldFieldCount - 1;
reservedSpaceFieldId += startField;
// the new data the needs to be written at newOffset but can't until
// unsedSpace >= newDataToWrite.length (allowing for the header)
DynamicByteArrayOutputStream newDataToWrite = null;
rawDataOut.setPosition(newOffset);
// write the record header, which may change in size
int oldLength = recordHeader.size();
int newLength = newRecorderHeader.size();
int unusedSpace = oldLength; // the unused space at newOffset
// no fields, so we can eat into the reserve space
if (reservedSpaceFieldId < startField) // no fields
unusedSpace += getReservedCount(slot);
if (unusedSpace >= newLength) {
newRecorderHeader.write(rawDataOut);
newOffset += newLength;
unusedSpace -= newLength;
} else {
newDataToWrite = new DynamicByteArrayOutputStream(getPageSize());
newRecorderHeader.write(newDataToWrite);
}
oldOffset += oldLength;
int recordDelta = (newLength - oldLength);
int oldFieldStatus = 0;