001: /*
002:
003: Derby - Class org.apache.derby.impl.store.raw.data.DirectActions
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.store.raw.data;
023:
024: import org.apache.derby.iapi.reference.SQLState;
025:
026: import org.apache.derby.iapi.services.io.ArrayInputStream;
027: import org.apache.derby.iapi.services.io.FormatableBitSet;
028: import org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream;
029: import org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream;
030:
031: import org.apache.derby.iapi.services.sanity.SanityManager;
032:
033: import org.apache.derby.iapi.error.StandardException;
034:
035: import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo;
036:
037: import org.apache.derby.iapi.store.raw.Page;
038: import org.apache.derby.iapi.store.raw.RecordHandle;
039: import org.apache.derby.iapi.store.raw.xact.RawTransaction;
040: import org.apache.derby.iapi.store.raw.log.LogInstant;
041:
042: import org.apache.derby.iapi.types.DataValueDescriptor;
043:
044: import java.io.ByteArrayOutputStream;
045: import java.io.IOException;
046:
047: public class DirectActions implements PageActions {
048:
049: protected DynamicByteArrayOutputStream outBytes;
050: protected ArrayInputStream limitIn;
051:
052: public DirectActions() {
053: outBytes = new DynamicByteArrayOutputStream();
054: limitIn = new ArrayInputStream();
055: }
056:
057: public void actionDelete(RawTransaction t, BasePage page, int slot,
058: int recordId, boolean delete, LogicalUndo undo)
059: throws StandardException {
060: try {
061:
062: page.setDeleteStatus((LogInstant) null, slot, delete);
063:
064: } catch (IOException ioe) {
065:
066: throw StandardException.newException(
067: SQLState.DATA_UNEXPECTED_EXCEPTION, ioe);
068: }
069:
070: }
071:
072: public int actionUpdate(RawTransaction t, BasePage page, int slot,
073: int recordId, Object[] row, FormatableBitSet validColumns,
074: int realStartColumn,
075: DynamicByteArrayOutputStream logBuffer,
076: int realSpaceOnPage, RecordHandle headRowHandle)
077: throws StandardException {
078: if (logBuffer == null)
079: outBytes.reset();
080: else
081: outBytes = (DynamicByteArrayOutputStream) logBuffer;
082:
083: try {
084:
085: // manufactures the new row into outBytes
086: int nextColumn = page.logRow(slot, false, recordId, row,
087: validColumns, outBytes, 0, Page.INSERT_OVERFLOW,
088: realStartColumn, realSpaceOnPage, 100);
089:
090: limitIn.setData(outBytes.getByteArray());
091: limitIn.setPosition(outBytes.getBeginPosition());
092: limitIn.setLimit(outBytes.getPosition()
093: - outBytes.getBeginPosition());
094:
095: // copy the new row from outBytes into the page
096: page.storeRecord((LogInstant) null, slot, false, limitIn);
097:
098: return nextColumn;
099:
100: } catch (IOException ioe) {
101:
102: throw StandardException.newException(
103: SQLState.DATA_UNEXPECTED_EXCEPTION, ioe);
104: }
105:
106: }
107:
108: public void actionPurge(RawTransaction t, BasePage page, int slot,
109: int num_rows, int[] recordIds, boolean needDataLogged)
110: throws StandardException {
111: // purge the records in the stored version
112: // we need to remove from high to low because the slots will be moved down
113: // as soon as one is removed.
114:
115: // we could get the slot with the recordId but that will be a waste
116: // since the page was never unlatch and the slot number is good
117:
118: try {
119: for (int i = num_rows - 1; i >= 0; i--) {
120: page.purgeRecord((LogInstant) null, slot + i,
121: recordIds[i]);
122: }
123: } catch (IOException ioe) {
124:
125: throw StandardException.newException(
126: SQLState.DATA_UNEXPECTED_EXCEPTION, ioe);
127: }
128:
129: }
130:
131: public void actionUpdateField(RawTransaction t, BasePage page,
132: int slot, int recordId, int fieldId, Object newValue,
133: LogicalUndo undo) throws StandardException {
134: outBytes.reset();
135:
136: try {
137:
138: page.logColumn(slot, fieldId, newValue,
139: (DynamicByteArrayOutputStream) outBytes, 100);
140:
141: limitIn.setData(outBytes.getByteArray());
142: limitIn.setPosition(outBytes.getBeginPosition());
143: limitIn.setLimit(outBytes.getPosition()
144: - outBytes.getBeginPosition());
145:
146: page.storeField((LogInstant) null, slot, fieldId, limitIn);
147:
148: } catch (IOException ioe) {
149:
150: throw StandardException.newException(
151: SQLState.DATA_UNEXPECTED_EXCEPTION, ioe);
152: }
153:
154: }
155:
156: public int actionInsert(RawTransaction t, BasePage page, int slot,
157: int recordId, Object[] row, FormatableBitSet validColumns,
158: LogicalUndo undo, byte insertFlag, int startColumn,
159: boolean isLongColumn, int realStartColumn,
160: DynamicByteArrayOutputStream logBuffer,
161: int realSpaceOnPage, int overflowThreshold)
162: throws StandardException {
163: if (logBuffer == null)
164: outBytes.reset();
165: else
166: outBytes = (DynamicByteArrayOutputStream) logBuffer;
167:
168: try {
169: if (isLongColumn) {
170: startColumn = page
171: .logLongColumn(slot, recordId, row[0],
172: (DynamicByteArrayOutputStream) outBytes);
173: } else {
174: startColumn = page.logRow(slot, true, recordId, row,
175: validColumns,
176: (DynamicByteArrayOutputStream) outBytes,
177: startColumn, insertFlag, realStartColumn,
178: realSpaceOnPage, overflowThreshold);
179: }
180:
181: limitIn.setData(outBytes.getByteArray());
182: limitIn.setPosition(outBytes.getBeginPosition());
183: limitIn.setLimit(outBytes.getPosition()
184: - outBytes.getBeginPosition());
185:
186: page.storeRecord((LogInstant) null, slot, true, limitIn);
187: return (startColumn);
188:
189: } catch (IOException ioe) {
190:
191: throw StandardException.newException(
192: SQLState.DATA_UNEXPECTED_EXCEPTION, ioe);
193: }
194:
195: }
196:
197: public void actionCopyRows(RawTransaction t, BasePage destPage,
198: BasePage srcPage, int destSlot, int numRows, int srcSlot,
199: int[] recordIds) throws StandardException {
200: try {
201:
202: // check to make sure the destination page have the necessary space to
203: // take the rows - count the bytes once for checking, then once for
204: // real
205:
206: // this one is for checking
207: int[] spaceNeeded = new int[numRows];
208: for (int i = 0; i < numRows; i++) {
209: outBytes.reset();
210: srcPage.logRecord(srcSlot + i,
211: BasePage.LOG_RECORD_DEFAULT, recordIds[i],
212: (FormatableBitSet) null, outBytes,
213: (RecordHandle) null);
214: spaceNeeded[i] = outBytes.getUsed();
215:
216: // do not worry about reserve space since we cannot rollback
217: }
218:
219: if (!destPage.spaceForCopy(numRows, spaceNeeded)) {
220: throw StandardException
221: .newException(SQLState.DATA_NO_SPACE_FOR_RECORD);
222: }
223:
224: // this one is for real
225: for (int i = 0; i < numRows; i++) {
226: // the recordId passed in is the record Id this row will have at
227: // the destination page, not the record Id this row has on the
228: // srcPage.
229: outBytes.reset();
230: srcPage.logRecord(srcSlot + i,
231: BasePage.LOG_RECORD_DEFAULT, recordIds[i],
232: (FormatableBitSet) null, outBytes,
233: (RecordHandle) null);
234:
235: limitIn.setData(outBytes.getByteArray());
236: limitIn.setPosition(outBytes.getBeginPosition());
237: limitIn.setLimit(outBytes.getPosition()
238: - outBytes.getBeginPosition());
239:
240: destPage.storeRecord((LogInstant) null, destSlot + i,
241: true, limitIn);
242: }
243: } catch (IOException ioe) {
244:
245: throw StandardException.newException(
246: SQLState.DATA_UNEXPECTED_EXCEPTION, ioe);
247: }
248:
249: }
250:
251: public void actionInvalidatePage(RawTransaction t, BasePage page)
252: throws StandardException {
253: page.setPageStatus((LogInstant) null, BasePage.INVALID_PAGE);
254: }
255:
256: public void actionInitPage(RawTransaction t, BasePage page,
257: int initFlag, int pageFormatId, long pageOffset)
258: throws StandardException {
259: boolean overflowPage = ((initFlag & BasePage.INIT_PAGE_OVERFLOW) != 0);
260: boolean reuse = ((initFlag & BasePage.INIT_PAGE_REUSE) != 0);
261:
262: int nextRecordId = ((initFlag & BasePage.INIT_PAGE_REUSE_RECORDID) == 0) ? page
263: .newRecordId()
264: : RecordHandle.FIRST_RECORD_ID;
265:
266: if (SanityManager.DEBUG)
267: SanityManager
268: .ASSERT(page.getTypeFormatId() == pageFormatId,
269: "Direct initPage somehow got the wrong page formatId");
270:
271: page.initPage((LogInstant) null, BasePage.VALID_PAGE,
272: nextRecordId, overflowPage, reuse);
273: }
274:
275: public void actionShrinkReservedSpace(RawTransaction t,
276: BasePage page, int slot, int recordId, int newValue,
277: int oldValue) throws StandardException {
278: try {
279: page.setReservedSpace((LogInstant) null, slot, newValue);
280: } catch (IOException ioe) {
281: throw StandardException.newException(
282: SQLState.DATA_UNEXPECTED_EXCEPTION, ioe);
283: }
284: }
285:
286: }
|