KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derby.impl.store.raw.data.CopyRowsOperation
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
26 import org.apache.derby.impl.store.raw.data.BasePage;
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.raw.Page;
33 import org.apache.derby.iapi.store.raw.RecordHandle;
34 import org.apache.derby.iapi.store.raw.Transaction;
35 import org.apache.derby.iapi.store.raw.log.LogInstant;
36 import org.apache.derby.iapi.store.raw.xact.RawTransaction;
37
38 import org.apache.derby.iapi.error.StandardException;
39
40 import org.apache.derby.iapi.services.io.CompressedNumber;
41 import org.apache.derby.iapi.services.io.FormatableBitSet;
42 import org.apache.derby.iapi.util.ByteArray;
43 import org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream;
44
45
46 import java.io.OutputStream JavaDoc;
47 import java.io.ObjectOutput JavaDoc;
48 import java.io.ObjectInput JavaDoc;
49 import java.io.IOException JavaDoc;
50 import org.apache.derby.iapi.services.io.LimitObjectInput;
51
52 /**
53     Represents copying num_rows from one page to another page.
54
55     <PRE>
56     @format_id LOGOP_COPY_ROWS
57         the formatId is written by FormatIdOutputStream when this object is
58         written out by writeObject
59     @purpose copy some rows from one page to another
60     @upgrade
61     @disk_layout
62         PhysicalPageOperation the superclass
63         num_rows(CompressedInt) number of rows to copy
64         destSlot(CompressedInt) the first slot number at the destination page
65         recordIds(CompressedInt[num_rows]) the recordIds at the destination page
66
67         OptionalData the after image of the rows to be inserted into the
68                         destination page
69     @end_format
70     </PRE>
71 */

72 public class CopyRowsOperation extends PhysicalPageOperation {
73
74     protected int num_rows;
75     protected int destSlot; // copy into this page starting from destSlot
76
protected int[] recordIds; // num_rows of recordIds (use these for undo)
77
protected int[] reservedSpace; // number of bytes to reserve for each row.
78

79     transient protected ByteArray preparedLog;
80
81     public CopyRowsOperation(RawTransaction t, BasePage destPage, BasePage srcPage,
82                              int destSlot, int num_rows,
83                              int srcSlot, int[] recordIds)
84         throws StandardException
85     {
86         super(destPage);
87
88         this.num_rows = num_rows;
89         this.destSlot = destSlot;
90         this.recordIds = recordIds;
91
92         try {
93             reservedSpace = new int[num_rows];
94             for (int i = 0; i < num_rows; i++) {
95                 reservedSpace[i] = srcPage.getReservedCount(i + srcSlot);
96             }
97
98             writeOptionalDataToBuffer(t, srcPage, srcSlot);
99         } catch (IOException JavaDoc ioe) {
100             throw StandardException.newException(
101                     SQLState.DATA_UNEXPECTED_EXCEPTION, ioe);
102         }
103     }
104
105     /*
106      * Formatable methods
107      */

108
109     // no-arg constructor, required by Formatable
110
public CopyRowsOperation() { super(); }
111 /*
112     public CopyRowsOperation(BasePage destPage) { super(destPage); }
113 */

114     public void writeExternal(ObjectOutput JavaDoc out) throws IOException JavaDoc
115     {
116         super.writeExternal(out);
117
118         CompressedNumber.writeInt(out, num_rows);
119         CompressedNumber.writeInt(out, destSlot);
120         
121         for (int i = 0; i < num_rows; i++) {
122             CompressedNumber.writeInt(out, recordIds[i]);
123             CompressedNumber.writeInt(out, reservedSpace[i]);
124         }
125     }
126
127     /**
128         Read this in
129         @exception IOException error reading from log stream
130         @exception ClassNotFoundException log stream corrupted
131     */

132     public void readExternal(ObjectInput JavaDoc in)
133          throws IOException JavaDoc, ClassNotFoundException JavaDoc
134     {
135         super.readExternal(in);
136
137         num_rows = CompressedNumber.readInt(in);
138         destSlot = CompressedNumber.readInt(in);
139
140         recordIds = new int[num_rows];
141         reservedSpace = new int[num_rows];
142         for (int i = 0; i < num_rows; i++) {
143             recordIds[i] = CompressedNumber.readInt(in);
144             reservedSpace[i] = CompressedNumber.readInt(in);
145         }
146     }
147
148     /**
149         Return my format identifier.
150     */

151     public int getTypeFormatId() {
152         return StoredFormatIds.LOGOP_COPY_ROWS;
153     }
154
155     /*
156      * Loggable methods
157      */

158     /**
159         @exception IOException Can be thrown by any of the methods of ObjectInput.
160         @exception StandardException Standard Cloudscape policy.
161       
162         @see org.apache.derby.iapi.store.raw.Loggable#doMe
163     */

164     public void doMe(Transaction xact, LogInstant instant, LimitObjectInput in)
165          throws StandardException, IOException JavaDoc
166     {
167         /*
168          * this operation's do me will bump the page version by more than 1
169          */

170         for (int i = 0; i < num_rows; i++)
171         {
172             page.storeRecord(instant, destSlot+i, true, in);
173
174             if (reservedSpace[i] > 0)
175                 page.reserveSpaceForSlot(instant, destSlot + i, reservedSpace[i]);
176         }
177     }
178
179     /*
180      * PhysicalPageOperation method
181      */

182
183     /**
184         to undo this operation, purge all records that were copied over.
185
186         @exception IOException Can be thrown by any of the methods of ObjectInput.
187         @exception StandardException Standard Cloudscape error policy
188         @see PhysicalPageOperation#undoMe
189      */

190     public void undoMe(Transaction xact, BasePage undoPage,
191                        LogInstant CLRInstant, LimitObjectInput in)
192          throws StandardException, IOException JavaDoc
193     {
194         // purge the records in the stored version
195
// since we search for each recordId, it doesn't matter whether we
196
// purge from high to low. In most cases, it will be in order so do it
197
// from high to low to save some work.
198

199         int slot;
200
201         for (int i = num_rows-1; i >= 0; i--)
202         {
203             slot = undoPage.findRecordById(recordIds[i], i);
204             undoPage.purgeRecord(CLRInstant, slot, recordIds[i]);
205         }
206
207         undoPage.setAuxObject(null);
208     }
209
210     /*
211      * PageBasicOperation method to support BeforeImageLogging
212      */

213
214     /**
215      * restore the before image of the page
216      *
217      * @exception IOException problem reading the complete log record from the input stream
218      * @exception StandardException Standard Cloudscape Error Policy
219      */

220     public void restoreMe(Transaction xact, BasePage undoPage,
221                        LogInstant CLRInstant, LimitObjectInput in)
222          throws StandardException, IOException JavaDoc
223     {
224         undoMe(xact, undoPage, CLRInstant, in);
225     }
226
227     /*
228         methods to support prepared log
229         
230         the following two methods should not be called during recover
231     */

232
233     public ByteArray getPreparedLog()
234     {
235         return (this.preparedLog);
236     }
237
238     /**
239         Write the rows that are to be copied into this page
240
241         @exception IOException Can be thrown by any of the methods of ObjectOutput.
242         @exception StandardException Standard Cloudscape policy.
243
244     */

245     private void writeOptionalDataToBuffer(RawTransaction t, BasePage srcPage, int srcSlot)
246         throws StandardException, IOException JavaDoc
247     {
248         if (SanityManager.DEBUG) {
249             SanityManager.ASSERT(this.page != null);
250             SanityManager.ASSERT(srcPage != null);
251         }
252
253         DynamicByteArrayOutputStream logBuffer = t.getLogBuffer();
254         int optionalDataStart = logBuffer.getPosition();
255
256         if (SanityManager.DEBUG) {
257             SanityManager.ASSERT(optionalDataStart == 0,
258                 "Buffer for writing the optional data should start at position 0");
259         }
260
261         // check to make sure the destination page have the necessary space to
262
// take the rows
263
int[] spaceNeeded = new int[num_rows];
264         int startPosition = logBuffer.getPosition();
265
266         for (int i = 0; i < num_rows; i++)
267         {
268             // the recordId passed in is the record Id this row will have at
269
// the destination page, not the record Id this row has on the
270
// srcPage.
271
srcPage.logRecord(i + srcSlot, BasePage.LOG_RECORD_DEFAULT,
272                               recordIds[i], (FormatableBitSet) null, logBuffer,
273                               (RecordHandle)null);
274             spaceNeeded[i] = logBuffer.getPosition() - startPosition;
275             startPosition = logBuffer.getPosition();
276
277             // now spaceNeeded[i] has the actual record size. However, the src
278
// page may actually leave more space for the record due to
279
// reserved space. Because we want to copy the reserve space as well,
280
// we need to take into account that amount.
281
spaceNeeded[i] += reservedSpace[i];
282         }
283
284         // page is the destination page.
285
if (!page.spaceForCopy(num_rows, spaceNeeded))
286         {
287             throw StandardException.newException(
288                     SQLState.DATA_NO_SPACE_FOR_RECORD);
289         }
290
291         int optionalDataLength = logBuffer.getPosition() - optionalDataStart;
292         
293         if (SanityManager.DEBUG) {
294             if (optionalDataLength != logBuffer.getUsed())
295                 SanityManager.THROWASSERT("wrong optional data length, optionalDataLength = "
296                     + optionalDataLength + ", logBuffer.getUsed() = " + logBuffer.getUsed());
297         }
298
299         // set the position to the beginning of the buffer
300
logBuffer.setPosition(optionalDataStart);
301
302         this.preparedLog = new ByteArray(logBuffer.getByteArray(), optionalDataStart,
303             optionalDataLength);
304     }
305
306     /**
307       DEBUG: Print self.
308      */

309     public String JavaDoc toString()
310     {
311         if (SanityManager.DEBUG)
312         {
313             String JavaDoc str = super.toString() +
314                 "CopyRows : " + num_rows + " to slots starting at " + destSlot;
315
316             for (int i = 0; i < num_rows; i++)
317             {
318                 str += " (recordId=" + recordIds[i] + ")";
319             }
320             return str;
321         }
322         else
323             return null;
324     }
325 }
326
Popular Tags