use of org.apache.derby.iapi.util.ByteArray in project derby by apache.
the class ExpressionClassBuilder method getGeneratedClass.
// /////////////////////////////////////////////////////////////////////
//
// GENERATE BYTE CODE
//
// /////////////////////////////////////////////////////////////////////
/**
* Take the generated class, and turn it into an
* actual class.
* <p> This method assumes, does not check, that
* the class and its parts are all complete.
*
* @param savedBytes place to save generated bytes.
* if null, it is ignored
* @exception StandardException thrown when exception occurs
*/
GeneratedClass getGeneratedClass(ByteArray savedBytes) throws StandardException {
if (gc != null)
return gc;
if (savedBytes != null) {
ByteArray classBytecode = cb.getClassBytecode();
// note: be sure to set the length since
// the class builder allocates the byte array
// in big chunks
savedBytes.setBytes(classBytecode.getArray());
savedBytes.setLength(classBytecode.getLength());
}
gc = cb.getGeneratedClass();
// !! yippee !! here it is...
return gc;
}
use of org.apache.derby.iapi.util.ByteArray in project derby by apache.
the class StoredPage method logColumn.
/**
* Log column from input row to the given output stream.
* <p>
* Read data from row[arrayPosition], and write the column data in
* raw store page format to the given column. Along the way determine
* if the column will fit on the current page.
* <p>
* Action taken in this routine is determined by the kind of column as
* specified in the columnFlag:
* COLUMN_NONE - the column is insignificant
* COLUMN_FIRST - this is the first column in a logRow() call
* COLUMN_LONG - this is a known long column, therefore we will
* store part of the column on the current page and
* overflow the rest if necessary.
* <p>
* Upon entry to this routine logicalDataOut is tied to the
* DynamicByteArrayOutputStream out.
* <BR>
* If a column is a long column and it does not totally fit on the current
* page, then a LongColumnException is thrown. We package up info about
* the current long column in the partially filled in exception so that
* callers can take correct action. The column will now be set a as a
* stream.
*
* @return The spaceAvailable after accounting for space for this column.
*
* @param row array of column from which to read the column from.
* @param arrayPosition The array position of column to be reading from row.
* @param out The stream to write the raw store page format of the
* the column to.
* @param spaceAvailable The number of bytes available on the page for
* this column, this may differ from current page
* as it may include bytes used by previous
* columns.
* @param columnFlag one of: COLUMN_NONE, COLUMN_FIRST, or COLUMN_LONG.
*
* @exception StandardException Standard exception policy.
* @exception LongColumnException Thrown if column will not fit on a
* single page. See notes above
*/
private int logColumn(Object[] row, int arrayPosition, DynamicByteArrayOutputStream out, int spaceAvailable, int columnFlag, int overflowThreshold) throws StandardException, IOException {
// RESOLVE (mikem) - why will row be null?
Object column = (row != null ? row[arrayPosition] : null);
// header is already formatted.
if (column instanceof RawField) {
// field data is raw, no need to set up a field header etc.
byte[] data = ((RawField) column).getData();
if (data.length <= spaceAvailable) {
out.write(data);
spaceAvailable -= data.length;
}
return spaceAvailable;
}
// If this is a long column, it may fit in this page or it may not.
boolean longColumnDone = true;
// default field status.
int fieldStatus = StoredFieldHeader.setFixed(StoredFieldHeader.setInitial(), true);
int beginPosition = out.getPosition();
int columnBeginPosition = 0;
int headerLength;
int fieldDataLength = 0;
if (column instanceof StreamStorable) {
StreamStorable stream_storable_column = (StreamStorable) column;
if (stream_storable_column.returnStream() != null) {
column = (Object) stream_storable_column.returnStream();
}
}
if ((column == null) && (columnFlag != COLUMN_CREATE_NULL)) {
fieldStatus = StoredFieldHeader.setNonexistent(fieldStatus);
headerLength = StoredFieldHeader.write(logicalDataOut, fieldStatus, fieldDataLength, slotFieldSize);
} else if (column instanceof InputStream) {
RememberBytesInputStream bufferedIn = null;
int bufferLen = 0;
int estimatedMaxDataSize = getMaxDataLength(spaceAvailable, overflowThreshold);
// buffer.
if (column instanceof RememberBytesInputStream) {
// data is already RememberBytesInputStream
bufferedIn = (RememberBytesInputStream) column;
bufferLen = bufferedIn.numBytesSaved();
} else {
// data comes in as an inputstream
bufferedIn = new RememberBytesInputStream((InputStream) column, new MemByteHolder(maxFieldSize + 1));
// into the RememberBytesInputStream.
if (row[arrayPosition] instanceof StreamStorable)
((StreamStorable) row[arrayPosition]).setStream(bufferedIn);
// set column to the RememberBytesInputStream so that
// all future access to this column will be able to get
// at bytes that have been already read. This assignment
// is needed to ensure that if long column exception is
// thrown, the column is set correctly
column = bufferedIn;
}
// read the buffer by reading the max we can read.
if (bufferLen < (estimatedMaxDataSize + 1)) {
bufferLen += bufferedIn.fillBuf(estimatedMaxDataSize + 1 - bufferLen);
}
if ((bufferLen <= estimatedMaxDataSize)) {
// we will be able to fit this into the page
fieldDataLength = bufferLen;
fieldStatus = StoredFieldHeader.setFixed(fieldStatus, true);
headerLength = StoredFieldHeader.write(logicalDataOut, fieldStatus, fieldDataLength, slotFieldSize);
// if the field is extensible, then we write the serializable
// formatId. if the field is non-extensible, we don't need to
// write the formatId. but at this point, how do we know
// whether the field is extensible or not??? For Plato release,
// we do not support InputStream on extensible types,
// therefore, we ignore the formatId for now.
bufferedIn.putBuf(logicalDataOut, fieldDataLength);
} else {
if (columnFlag == COLUMN_LONG) {
// column is a long column and the remaining portion does
// not fit on the current page.
longColumnDone = false;
// it's a portion of a long column, and there is more to
// write reserve enough room for overflow pointer, then
// write as much data as we can leaving an extra 2 bytes
// for overflow field header.
fieldDataLength = estimatedMaxDataSize - OVERFLOW_POINTER_SIZE - 2;
fieldStatus = StoredFieldHeader.setFixed(fieldStatus, true);
headerLength = StoredFieldHeader.write(logicalDataOut, fieldStatus, fieldDataLength, slotFieldSize);
bufferedIn.putBuf(logicalDataOut, fieldDataLength);
// now, we need to adjust the buffer, move the unread
// bytes to the beginning position the cursor correctly,
// so, next time around, we can read more into the buffer.
int remainingBytes = bufferedIn.available();
// move the unread bytes to the beginning of the byteHolder.
int bytesShifted = bufferedIn.shiftToFront();
} else {
// column not a long column and does not fit on page.
int delta = maxFieldSize - bufferLen + 1;
if (delta > 0)
bufferLen += bufferedIn.fillBuf(delta);
fieldDataLength = bufferLen;
// the data will not fit on this page make sure the new
// input stream is passed back to the upper layer...
column = (Object) bufferedIn;
}
}
} else if (columnFlag == COLUMN_CREATE_NULL) {
//
// This block handles the case when a couple columns have been added
// recently and now one of the later columns is being updated. Newly added columns
// which appear in the row before the updated column don't actually have
// any values yet. We stuff NULLs into those newly added columns here.
// This fixes DERBY-5679.
//
fieldStatus = StoredFieldHeader.setNull(fieldStatus, true);
// header is written with 0 length here.
headerLength = StoredFieldHeader.write(logicalDataOut, fieldStatus, fieldDataLength, slotFieldSize);
} else if (column instanceof DataValueDescriptor) {
DataValueDescriptor sColumn = (DataValueDescriptor) column;
boolean isNull = (columnFlag == COLUMN_CREATE_NULL) || sColumn.isNull();
if (isNull) {
fieldStatus = StoredFieldHeader.setNull(fieldStatus, true);
}
// header is written with 0 length here.
headerLength = StoredFieldHeader.write(logicalDataOut, fieldStatus, fieldDataLength, slotFieldSize);
if (!isNull) {
// write the field data to the log
try {
columnBeginPosition = out.getPosition();
sColumn.writeExternal(logicalDataOut);
} catch (IOException ioe) {
// SQLData error reporting
if (logicalDataOut != null) {
Exception ne = logicalDataOut.getNestedException();
if (ne != null) {
if (ne instanceof StandardException) {
throw (StandardException) ne;
}
}
}
throw StandardException.newException(SQLState.DATA_STORABLE_WRITE_EXCEPTION, ioe);
}
fieldDataLength = (out.getPosition() - beginPosition) - headerLength;
}
} else if (column instanceof RecordHandle) {
// we are inserting an overflow pointer for a long column
// casted reference to column to avoid repeated casting.
RecordHandle overflowHandle = (RecordHandle) column;
fieldStatus = StoredFieldHeader.setOverflow(fieldStatus, true);
headerLength = StoredFieldHeader.write(logicalDataOut, fieldStatus, fieldDataLength, slotFieldSize);
fieldDataLength += CompressedNumber.writeLong(out, overflowHandle.getPageNumber());
fieldDataLength += CompressedNumber.writeInt(out, overflowHandle.getId());
} else {
// Serializable/Externalizable/Formattable
// all look the same at this point.
// header is written with 0 length here.
headerLength = StoredFieldHeader.write(logicalDataOut, fieldStatus, fieldDataLength, slotFieldSize);
logicalDataOut.writeObject(column);
fieldDataLength = (out.getPosition() - beginPosition) - headerLength;
}
// calculate the size of the field on page with compresed field header
fieldStatus = StoredFieldHeader.setFixed(fieldStatus, false);
int fieldSizeOnPage = StoredFieldHeader.size(fieldStatus, fieldDataLength, slotFieldSize) + fieldDataLength;
userRowSize += fieldDataLength;
boolean fieldIsLong = isLong(fieldSizeOnPage, overflowThreshold);
// Do we have enough space on the page for this field?
if (((spaceAvailable < fieldSizeOnPage) || (fieldIsLong)) && (columnFlag != COLUMN_LONG)) {
if (fieldIsLong) {
if (!(column instanceof InputStream)) {
// Convert already written object to an InputStream.
ByteArray fieldData = new ByteArray(((DynamicByteArrayOutputStream) out).getByteArray(), (columnBeginPosition), fieldDataLength);
ByteArrayInputStream columnIn = new ByteArrayInputStream(fieldData.getArray(), columnBeginPosition, fieldDataLength);
MemByteHolder byteHolder = new MemByteHolder(fieldDataLength + 1);
RememberBytesInputStream bufferedIn = new RememberBytesInputStream(columnIn, byteHolder);
// the data will not fit on this page make sure the new
// input stream is passed back to the upper layer...
column = bufferedIn;
}
out.setPosition(beginPosition);
// This exception carries the information for the client
// routine to continue inserting the long row on multiple
// pages.
LongColumnException lce = new LongColumnException();
lce.setColumn(column);
throw lce;
} else {
// Column does not fit on this page, but it isn't a long column.
out.setPosition(beginPosition);
return (spaceAvailable);
}
}
// Now we go back to update the fieldDataLength in the field header
out.setPosition(beginPosition);
// slotFieldSize is set based on the pageSize.
// We are borrowing this to set the size of our fieldDataLength.
fieldStatus = StoredFieldHeader.setFixed(fieldStatus, true);
headerLength = StoredFieldHeader.write(out, fieldStatus, fieldDataLength, slotFieldSize);
// set position to the end of the field
out.setPosition(beginPosition + fieldDataLength + headerLength);
spaceAvailable -= fieldSizeOnPage;
// YYZ: revisit
if (columnFlag == COLUMN_LONG) {
// BasePage.insertLongColumn to signal end of loop.
if (longColumnDone)
return -1;
else
return 1;
} else {
return (spaceAvailable);
}
}
use of org.apache.derby.iapi.util.ByteArray in project derby by apache.
the class DeleteOperation method writeOptionalDataToBuffer.
/**
* if logical undo, writes out the row that was deleted
*
* @exception IOException Can be thrown by any of the methods of ObjectOutput
* @exception StandardException Standard Derby policy.
*/
private void writeOptionalDataToBuffer(RawTransaction t) throws StandardException, IOException {
if (SanityManager.DEBUG) {
SanityManager.ASSERT(this.page != null);
}
DynamicByteArrayOutputStream logBuffer = t.getLogBuffer();
int optionalDataStart = logBuffer.getPosition();
if (SanityManager.DEBUG) {
SanityManager.ASSERT(optionalDataStart == 0, "Buffer for writing the optional data should start at position 0");
}
if (undo != null)
this.page.logRecord(doMeSlot, BasePage.LOG_RECORD_DEFAULT, recordId, (FormatableBitSet) null, logBuffer, (RecordHandle) null);
int optionalDataLength = logBuffer.getPosition() - optionalDataStart;
if (SanityManager.DEBUG) {
if (optionalDataLength != logBuffer.getUsed())
SanityManager.THROWASSERT("wrong optional data length, optionalDataLength = " + optionalDataLength + ", logBuffer.getUsed() = " + logBuffer.getUsed());
}
// set the position to the beginning of the buffer
logBuffer.setPosition(optionalDataStart);
this.preparedLog = new ByteArray(logBuffer.getByteArray(), optionalDataStart, optionalDataLength);
}
use of org.apache.derby.iapi.util.ByteArray in project derby by apache.
the class UpdateFieldOperation method writeOptionalDataToBuffer.
/**
* Write the old column value and and new column value as optional data.
* If logical undo, writes out the entire row's before image.
*
* @exception IOException Can be thrown by any of the methods of ObjectOutput.
* @exception StandardException Standard Derby policy.
*/
private void writeOptionalDataToBuffer(RawTransaction t, Object column) throws StandardException, IOException {
if (SanityManager.DEBUG) {
SanityManager.ASSERT(this.page != null);
}
DynamicByteArrayOutputStream logBuffer = t.getLogBuffer();
int optionalDataStart = logBuffer.getPosition();
if (SanityManager.DEBUG) {
SanityManager.ASSERT(optionalDataStart == 0, "Buffer for writing optional data should start at position 0");
}
// the after image of the column
this.page.logColumn(doMeSlot, fieldId, column, logBuffer, 100);
// the BI of the column
this.page.logField(doMeSlot, fieldId, logBuffer);
if (undo != null) {
// RESOLVE: we want the AFTER image of the row, not the BEFORE
// image. This works for now because only btree needs a logical
// undoable updateField and it always update only the pointer field
// to point to something else.
//
// But in the future, it needs to be changed.
this.page.logRecord(doMeSlot, BasePage.LOG_RECORD_DEFAULT, recordId, (FormatableBitSet) null, logBuffer, (RecordHandle) null);
// log the BI of the entire row
}
int optionalDataLength = logBuffer.getPosition() - optionalDataStart;
if (SanityManager.DEBUG) {
if (optionalDataLength != logBuffer.getUsed())
SanityManager.THROWASSERT("wrong optional data length, optionalDataLength = " + optionalDataLength + ", logBuffer.getUsed() = " + logBuffer.getUsed());
}
// set the position to the beginning of the buffer
logBuffer.setPosition(optionalDataStart);
this.preparedLog = new ByteArray(logBuffer.getByteArray(), optionalDataStart, optionalDataLength);
}
use of org.apache.derby.iapi.util.ByteArray in project derby by apache.
the class ContainerOperation method readExternal.
/**
* @exception IOException cannot read log record from log stream
* @exception ClassNotFoundException cannot read ByteArray object
*/
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
super.readExternal(in);
operation = in.readByte();
if (operation == CREATE && hasCreateByteArray) {
createByteArray = new ByteArray();
createByteArray.readExternal(in);
}
}
Aggregations