KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > store > raw > data > InsertOperation


1 /*
2
3    Derby - Class org.apache.derby.impl.store.raw.data.InsertOperation
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.store.raw.data;
23
24 import org.apache.derby.iapi.reference.SQLState;
25 import org.apache.derby.impl.store.raw.data.BasePage;
26 import org.apache.derby.impl.store.raw.data.ReclaimSpace;
27
28 import org.apache.derby.iapi.services.sanity.SanityManager;
29 import org.apache.derby.iapi.services.io.FormatIdUtil;
30 import org.apache.derby.iapi.services.io.StoredFormatIds;
31
32 import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo;
33
34 import org.apache.derby.iapi.store.raw.PageKey;
35 import org.apache.derby.iapi.store.raw.Compensation;
36 import org.apache.derby.iapi.store.raw.Page;
37 import org.apache.derby.iapi.store.raw.RecordHandle;
38 import org.apache.derby.iapi.store.raw.Transaction;
39
40 import org.apache.derby.iapi.store.raw.log.LogInstant;
41 import org.apache.derby.iapi.store.raw.xact.RawTransaction;
42
43 import org.apache.derby.iapi.error.StandardException;
44
45 import org.apache.derby.iapi.types.DataValueDescriptor;
46
47 import org.apache.derby.iapi.services.io.CompressedNumber;
48 import org.apache.derby.iapi.services.io.FormatableBitSet;
49 import org.apache.derby.iapi.util.ByteArray;
50 import org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream;
51 import org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream;
52
53 import java.io.OutputStream JavaDoc;
54 import java.io.ObjectOutput JavaDoc;
55 import java.io.ObjectInput JavaDoc;
56 import java.io.IOException JavaDoc;
57 import org.apache.derby.iapi.services.io.LimitObjectInput;
58
59
60 /**
61     Represents an insert of a record onto a page.
62
63     <PRE>
64     @format_id LOGOP_INSERT
65         the formatId is written by FormatIdOutputStream when this object is
66         written out by writeObject
67     @purpose insert a row onto a page
68     @upgrade
69     @disk_layout
70         LogicalPageOperation the superclass
71         doMeSlot(CompressedInt) which slot to operate on
72         insertFlat(byte) to undo with purge or with delete
73
74         OptionalData The after image of the row to be inserted.
75     @end_format
76     </PRE>
77     @see Page#insertAtSlot
78 */

79 public final class InsertOperation extends LogicalPageOperation
80 {
81
82     protected int doMeSlot; // insert slot - only valid during doMe()
83
protected byte insertFlag; // see page insertFlag
84

85     /** next column that need to be inserted. */
86     transient protected int startColumn;
87
88     transient protected ByteArray preparedLog;
89
90     // yyz: revisit later, whether we need preparedLog, maybe everything will be prepared...
91
public InsertOperation(
92     RawTransaction t,
93     BasePage page,
94     int slot,
95     int recordId,
96     Object JavaDoc[] row,
97     FormatableBitSet validColumns,
98     LogicalUndo undo,
99     byte insertFlag,
100     int startColumn,
101     boolean isLongColumn,
102     int realStartColumn,
103     DynamicByteArrayOutputStream logBuffer,
104     int realSpaceOnPage,
105     int overflowThreshold)
106         throws StandardException
107     {
108         super(page, undo, recordId);
109
110         this.doMeSlot = slot;
111         this.insertFlag = insertFlag;
112         this.startColumn = startColumn;
113
114         try {
115             writeOptionalDataToBuffer(t, logBuffer, row, validColumns,
116                 isLongColumn, realStartColumn, realSpaceOnPage, overflowThreshold);
117         } catch (IOException JavaDoc ioe) {
118             throw StandardException.newException(
119                     SQLState.DATA_UNEXPECTED_EXCEPTION, ioe);
120         }
121     }
122
123     /*
124      * Formatable methods
125      */

126
127     // no-arg constructor, required by Formatable
128
public InsertOperation() { super(); }
129
130     /**
131         Write this out.
132         @exception IOException error writing to log stream
133     */

134     public void writeExternal(ObjectOutput JavaDoc out) throws IOException JavaDoc
135     {
136         super.writeExternal(out);
137         CompressedNumber.writeInt(out, doMeSlot);
138         out.writeByte(insertFlag);
139
140     }
141
142     /**
143         Read this in
144         @exception IOException error reading from log stream
145         @exception ClassNotFoundException log stream corrupted
146     */

147     public void readExternal(ObjectInput JavaDoc in)
148          throws IOException JavaDoc, ClassNotFoundException JavaDoc
149     {
150         super.readExternal(in);
151         doMeSlot = CompressedNumber.readInt(in);
152         insertFlag = in.readByte();
153     }
154
155     /**
156         Return my format identifier.
157     */

158     public int getTypeFormatId() {
159         return StoredFormatIds.LOGOP_INSERT;
160     }
161
162     /*
163      * Loggable methods
164      */

165     /**
166         @exception IOException Can be thrown by any of the methods of ObjectInput.
167         @exception StandardException Standard Cloudscape policy.
168       
169         @see org.apache.derby.iapi.store.raw.Loggable#doMe
170     */

171     public void doMe(Transaction xact, LogInstant instant, LimitObjectInput in)
172          throws StandardException, IOException JavaDoc
173     {
174         this.page.storeRecord(instant, doMeSlot, true, in);
175     }
176
177     /*
178      * PageOperation methods
179      */

180
181     /**
182         Undo the insert by simply marking the just inserted record as deleted.
183         All logical undo logic has already been taken care of by generateUndo.
184
185         @exception IOException Can be thrown by any of the methods of ObjectInput.
186         @exception StandardException Standard Cloudscape policy.
187
188         @see LogicalPageOperation#undoMe
189     */

190     public void undoMe(Transaction xact, BasePage undoPage, int undoRecordId,
191                        LogInstant CLRInstant, LimitObjectInput in)
192          throws StandardException, IOException JavaDoc
193     {
194         int slot =
195             undoPage.findRecordById(undoRecordId, Page.FIRST_SLOT_NUMBER);
196
197         if (SanityManager.DEBUG)
198         {
199             // if the record Id has changed, the page had better changed
200
// this can only happen during recovery since in run time undo,
201
// this resetRecordHandle gets called and this object have the new
202
// page number and recordId
203
if (undoRecordId != this.recordId)
204                 if (undoPage.getPageNumber() == getPageId().getPageNumber())
205                     SanityManager.THROWASSERT(
206                         "recordId changed from " + this.recordId +
207                         " to " + undoRecordId +
208                         " but page number did not change " +
209                         undoPage.getPageNumber());
210
211             if (slot == -1)
212                 SanityManager.THROWASSERT(
213                     "recordId " +
214                     undoRecordId +
215                     " not found on page " +
216                     undoPage.getPageNumber());
217         }
218
219         if ((insertFlag & Page.INSERT_UNDO_WITH_PURGE) != 0)
220         {
221             undoPage.purgeRecord(CLRInstant, slot, undoRecordId);
222
223             RawTransaction rxact = (RawTransaction)xact;
224
225             // If we purged the last row off an overflow page, reclaim that
226
// page - we have to do this post transaction termination because we
227
// are underneath the log right now and cannot interrupt the log
228
// stream.
229
if (rxact.handlesPostTerminationWork() &&
230                 undoPage.isOverflowPage() && undoPage.recordCount() == 0)
231             {
232                 ReclaimSpace work =
233                     new ReclaimSpace(ReclaimSpace.PAGE, (PageKey)undoPage.getIdentity(),
234                                      rxact.getDataFactory(), true /* service ASAP */);
235                 rxact.addPostTerminationWork(work);
236             }
237         }
238         else
239         {
240             undoPage.setDeleteStatus(CLRInstant, slot, true);
241         }
242
243         undoPage.setAuxObject(null);
244     }
245
246     /*
247      * LogicalUndoable methods
248      */

249
250
251     /**
252         Restore the row stored in the optional data of the log record.
253
254         @exception IOException error reading from log stream
255         @exception StandardException Standard Cloudscape error policy
256     */

257     public void restoreLoggedRow(Object JavaDoc[] row, LimitObjectInput in)
258         throws StandardException, IOException JavaDoc
259
260     {
261         Page p = null;
262
263         try {
264             // the optional data is written by the page in the same format it
265
// stores record on the page,
266
// only a page knows how to restore a logged row back to a storable row
267
// first get the page where the insert went even though the row may no
268
// longer be there
269
p = getContainer().getPage(getPageId().getPageNumber());
270
271             ((BasePage)p).restoreRecordFromStream(in, row);
272
273         } finally {
274
275             if (p != null) {
276                 p.unlatch();
277                 p = null;
278             }
279         }
280     }
281
282     /*
283      * method to support BeforeImageLogging
284      */

285
286     /**
287      * restore the before image of the page
288      *
289      * @exception StandardException Standard Cloudscape Error Policy
290      * @exception IOException problem reading the complete log record from the
291      * input stream
292      */

293
294     public void restoreMe(Transaction xact, BasePage undoPage, LogInstant CLRinstant, LimitObjectInput in)
295          throws StandardException, IOException JavaDoc
296     {
297         if (SanityManager.DEBUG)
298         {
299             int slot = undoPage.findRecordById(recordId,Page.FIRST_SLOT_NUMBER);
300
301             if ( ! getPageId().equals(undoPage.getPageId()))
302                 SanityManager.THROWASSERT(
303                                 "restoreMe cannot restore to a different page. "
304                                  + "doMe page:" + getPageId() + " undoPage:" +
305                                  undoPage.getPageId());
306             if (slot != doMeSlot)
307                 SanityManager.THROWASSERT(
308                                 "restoreMe cannot restore to a different slot. "
309                                  + "doMe slot:" + doMeSlot + " undoMe slot: " +
310                                  slot + " recordId:" + recordId);
311         }
312         insertFlag |= Page.INSERT_UNDO_WITH_PURGE;
313
314         // undo the insert with purge.
315
undoMe(xact, undoPage, recordId, CLRinstant, in);
316     }
317
318     /*
319         methods to support prepared log
320         
321         the following two methods should not be called during recover
322     */

323
324     public ByteArray getPreparedLog()
325     {
326         return (this.preparedLog);
327     }
328
329
330     public int getNextStartColumn()
331     {
332         return (this.startColumn);
333     }
334     
335     /**
336         Writes out the row that is to be inserted as the optional data.
337
338         @exception IOException Can be thrown by any of the methods of ObjectOutput
339         @exception StandardException Standard Cloudscape policy.
340     */

341     private void writeOptionalDataToBuffer(
342     RawTransaction t,
343     DynamicByteArrayOutputStream logBuffer,
344     Object JavaDoc[] row,
345     FormatableBitSet validColumns,
346     boolean isLongColumn,
347     int realStartColumn,
348     int realSpaceOnPage,
349     int overflowThreshold)
350         throws StandardException, IOException JavaDoc
351     {
352
353         if (SanityManager.DEBUG) {
354             SanityManager.ASSERT(this.page != null);
355         }
356
357         DynamicByteArrayOutputStream localLogBuffer = null;
358         if (logBuffer != null) {
359             localLogBuffer = (DynamicByteArrayOutputStream) logBuffer;
360         } else {
361             realStartColumn = -1;
362             realSpaceOnPage = -1;
363             localLogBuffer = t.getLogBuffer();
364         }
365         
366         if (isLongColumn) {
367             this.startColumn = this.page.logLongColumn(doMeSlot, recordId,
368                 row[0], localLogBuffer);
369         } else {
370             this.startColumn = this.page.logRow(doMeSlot, true, recordId,
371                 row, validColumns, localLogBuffer, this.startColumn, insertFlag,
372                 realStartColumn, realSpaceOnPage, overflowThreshold);
373         }
374
375         int optionalDataStart = localLogBuffer.getBeginPosition();
376         int optionalDataLength = localLogBuffer.getPosition() - optionalDataStart;
377
378         this.preparedLog = new ByteArray (localLogBuffer.getByteArray(), optionalDataStart,
379             optionalDataLength);
380     }
381
382     /**
383       DEBUG: Print self.
384     */

385     public String JavaDoc toString()
386     {
387         if (SanityManager.DEBUG)
388         {
389             return super.toString() +
390             "Insert : " +
391             " Slot=" + doMeSlot +
392             " recordId=" + recordId;
393         }
394         else
395             return null;
396     }
397
398 }
399
Popular Tags