--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.impl.store.raw.data.DirectActions\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to you under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.impl.store.raw.data;\r
+\r
+import org.apache.derby.iapi.reference.SQLState;\r
+\r
+import org.apache.derby.iapi.services.io.ArrayInputStream;\r
+import org.apache.derby.iapi.services.io.FormatableBitSet;\r
+import org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream;\r
+import org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo;\r
+\r
+import org.apache.derby.iapi.store.raw.Page;\r
+import org.apache.derby.iapi.store.raw.RecordHandle;\r
+import org.apache.derby.iapi.store.raw.xact.RawTransaction;\r
+import org.apache.derby.iapi.store.raw.log.LogInstant;\r
+\r
+import org.apache.derby.iapi.types.DataValueDescriptor;\r
+\r
+\r
+import java.io.ByteArrayOutputStream;\r
+import java.io.IOException;\r
+\r
+\r
+public class DirectActions implements PageActions {\r
+\r
+ protected DynamicByteArrayOutputStream outBytes; \r
+ protected ArrayInputStream limitIn;\r
+ \r
+ public DirectActions() {\r
+ outBytes = new DynamicByteArrayOutputStream();\r
+ limitIn = new ArrayInputStream();\r
+ }\r
+\r
+ public void actionDelete(\r
+ RawTransaction t, \r
+ BasePage page, \r
+ int slot, \r
+ int recordId, \r
+ boolean delete, \r
+ LogicalUndo undo)\r
+ throws StandardException\r
+ {\r
+ try {\r
+\r
+ page.setDeleteStatus((LogInstant)null, slot, delete);\r
+\r
+ } catch (IOException ioe) {\r
+\r
+ throw StandardException.newException(\r
+ SQLState.DATA_UNEXPECTED_EXCEPTION, ioe);\r
+ }\r
+ \r
+ }\r
+\r
+ public int actionUpdate(\r
+ RawTransaction t, \r
+ BasePage page, \r
+ int slot, \r
+ int recordId,\r
+ Object[] row, \r
+ FormatableBitSet validColumns,\r
+ int realStartColumn, \r
+ DynamicByteArrayOutputStream logBuffer, \r
+ int realSpaceOnPage, \r
+ RecordHandle headRowHandle)\r
+ throws StandardException\r
+ {\r
+ if (logBuffer == null)\r
+ outBytes.reset();\r
+ else\r
+ outBytes = (DynamicByteArrayOutputStream) logBuffer;\r
+\r
+ try {\r
+\r
+ // manufactures the new row into outBytes\r
+ int nextColumn = \r
+ page.logRow(\r
+ slot, false, recordId, row, validColumns, outBytes, 0,\r
+ Page.INSERT_OVERFLOW, realStartColumn, \r
+ realSpaceOnPage, 100);\r
+\r
+ limitIn.setData(outBytes.getByteArray());\r
+ limitIn.setPosition(outBytes.getBeginPosition());\r
+ limitIn.setLimit(outBytes.getPosition() - outBytes.getBeginPosition());\r
+\r
+ // copy the new row from outBytes into the page\r
+ page.storeRecord((LogInstant) null, slot, false, limitIn);\r
+\r
+ return nextColumn;\r
+\r
+ } catch (IOException ioe) {\r
+\r
+ throw StandardException.newException(\r
+ SQLState.DATA_UNEXPECTED_EXCEPTION, ioe);\r
+ }\r
+\r
+ }\r
+\r
+ public void actionPurge(RawTransaction t, BasePage page, int slot, int\r
+ num_rows, int[] recordIds, boolean needDataLogged)\r
+ throws StandardException\r
+ {\r
+ // purge the records in the stored version\r
+ // we need to remove from high to low because the slots will be moved down\r
+ // as soon as one is removed.\r
+\r
+ // we could get the slot with the recordId but that will be a waste\r
+ // since the page was never unlatch and the slot number is good\r
+\r
+ try {\r
+ for (int i = num_rows-1; i >= 0; i--)\r
+ {\r
+ page.purgeRecord((LogInstant) null, slot+i, recordIds[i]);\r
+ }\r
+ } catch (IOException ioe) {\r
+\r
+ throw StandardException.newException(\r
+ SQLState.DATA_UNEXPECTED_EXCEPTION, ioe);\r
+ }\r
+\r
+ }\r
+\r
+ public void actionUpdateField(\r
+ RawTransaction t, \r
+ BasePage page, \r
+ int slot, \r
+ int recordId, \r
+ int fieldId, \r
+ Object newValue, \r
+ LogicalUndo undo)\r
+ throws StandardException\r
+ {\r
+ outBytes.reset();\r
+\r
+ try {\r
+\r
+ page.logColumn(slot, fieldId, newValue, (DynamicByteArrayOutputStream) outBytes, 100);\r
+\r
+ limitIn.setData(outBytes.getByteArray());\r
+ limitIn.setPosition(outBytes.getBeginPosition());\r
+ limitIn.setLimit(outBytes.getPosition() - outBytes.getBeginPosition());\r
+\r
+ page.storeField((LogInstant) null, slot, fieldId, limitIn);\r
+\r
+ } catch (IOException ioe) {\r
+\r
+ throw StandardException.newException(\r
+ SQLState.DATA_UNEXPECTED_EXCEPTION, ioe);\r
+ }\r
+\r
+ }\r
+\r
+ public int actionInsert(\r
+ RawTransaction t, \r
+ BasePage page, \r
+ int slot, \r
+ int recordId,\r
+ Object[] row, \r
+ FormatableBitSet validColumns, \r
+ LogicalUndo undo, \r
+ byte insertFlag, \r
+ int startColumn,\r
+ boolean isLongColumn, \r
+ int realStartColumn, \r
+ DynamicByteArrayOutputStream logBuffer, \r
+ int realSpaceOnPage,\r
+ int overflowThreshold)\r
+ throws StandardException\r
+ {\r
+ if (logBuffer == null)\r
+ outBytes.reset();\r
+ else\r
+ outBytes = (DynamicByteArrayOutputStream) logBuffer;\r
+\r
+ try {\r
+ if (isLongColumn) {\r
+ startColumn = page.logLongColumn(slot, recordId,\r
+ row[0], (DynamicByteArrayOutputStream) outBytes);\r
+ } else {\r
+ startColumn = page.logRow(slot, true, recordId, row, validColumns,\r
+ (DynamicByteArrayOutputStream) outBytes, startColumn, insertFlag, realStartColumn, realSpaceOnPage,\r
+ overflowThreshold);\r
+ }\r
+ \r
+ limitIn.setData(outBytes.getByteArray());\r
+ limitIn.setPosition(outBytes.getBeginPosition());\r
+ limitIn.setLimit(outBytes.getPosition() - outBytes.getBeginPosition());\r
+\r
+ page.storeRecord((LogInstant) null, slot, true, limitIn);\r
+ return (startColumn);\r
+\r
+ } catch (IOException ioe) {\r
+\r
+ throw StandardException.newException(\r
+ SQLState.DATA_UNEXPECTED_EXCEPTION, ioe);\r
+ }\r
+\r
+ }\r
+\r
+ public void actionCopyRows(RawTransaction t, BasePage destPage, BasePage srcPage, int destSlot, int numRows, int srcSlot, int[] recordIds)\r
+ throws StandardException\r
+ {\r
+ try {\r
+\r
+ // check to make sure the destination page have the necessary space to\r
+ // take the rows - count the bytes once for checking, then once for\r
+ // real\r
+\r
+ // this one is for checking\r
+ int[] spaceNeeded = new int[numRows];\r
+ for (int i = 0; i < numRows; i++)\r
+ {\r
+ outBytes.reset();\r
+ srcPage.logRecord(srcSlot + i, BasePage.LOG_RECORD_DEFAULT, \r
+ recordIds[i], (FormatableBitSet) null,\r
+ outBytes, (RecordHandle)null);\r
+ spaceNeeded[i] = outBytes.getUsed();\r
+\r
+ // do not worry about reserve space since we cannot rollback\r
+ }\r
+\r
+ if (!destPage.spaceForCopy(numRows, spaceNeeded))\r
+ {\r
+ throw StandardException.newException(\r
+ SQLState.DATA_NO_SPACE_FOR_RECORD);\r
+ }\r
+\r
+ // this one is for real\r
+ for (int i = 0; i < numRows; i++)\r
+ {\r
+ // the recordId passed in is the record Id this row will have at\r
+ // the destination page, not the record Id this row has on the\r
+ // srcPage.\r
+ outBytes.reset();\r
+ srcPage.logRecord(srcSlot + i, BasePage.LOG_RECORD_DEFAULT, \r
+ recordIds[i], (FormatableBitSet) null,\r
+ outBytes, (RecordHandle)null);\r
+\r
+ limitIn.setData(outBytes.getByteArray());\r
+ limitIn.setPosition(outBytes.getBeginPosition());\r
+ limitIn.setLimit(outBytes.getPosition() - outBytes.getBeginPosition());\r
+\r
+ destPage.storeRecord((LogInstant) null, destSlot+i, true, limitIn);\r
+ }\r
+ } catch (IOException ioe) {\r
+\r
+ throw StandardException.newException(\r
+ SQLState.DATA_UNEXPECTED_EXCEPTION, ioe);\r
+ }\r
+\r
+ }\r
+\r
+ public void actionInvalidatePage(RawTransaction t, BasePage page)\r
+ throws StandardException\r
+ {\r
+ page.setPageStatus((LogInstant)null, BasePage.INVALID_PAGE);\r
+ }\r
+\r
+ public void actionInitPage(RawTransaction t, BasePage page, int initFlag,\r
+ int pageFormatId, long pageOffset)\r
+ throws StandardException\r
+ {\r
+ boolean overflowPage = ((initFlag & BasePage.INIT_PAGE_OVERFLOW) != 0);\r
+ boolean reuse = ((initFlag & BasePage.INIT_PAGE_REUSE) != 0);\r
+\r
+ int nextRecordId = ((initFlag & BasePage.INIT_PAGE_REUSE_RECORDID) == 0) ?\r
+ page.newRecordId() : RecordHandle.FIRST_RECORD_ID;\r
+\r
+ if (SanityManager.DEBUG)\r
+ SanityManager.ASSERT(page.getTypeFormatId() == pageFormatId, \r
+ "Direct initPage somehow got the wrong page formatId"); \r
+\r
+ page.initPage((LogInstant)null, BasePage.VALID_PAGE,\r
+ nextRecordId, overflowPage, reuse);\r
+ }\r
+\r
+ public void actionShrinkReservedSpace(RawTransaction t, BasePage page, \r
+ int slot, int recordId, int newValue, int oldValue)\r
+ throws StandardException\r
+ {\r
+ try\r
+ {\r
+ page.setReservedSpace((LogInstant)null, slot, newValue);\r
+ }\r
+ catch (IOException ioe) \r
+ {\r
+ throw StandardException.newException(\r
+ SQLState.DATA_UNEXPECTED_EXCEPTION, ioe);\r
+ }\r
+ }\r
+\r
+}\r