KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > store > access > btree > index > B2IUndo


1 /*
2
3    Derby - Class org.apache.derby.impl.store.access.btree.index.B2IUndo
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.access.btree.index;
23
24 import org.apache.derby.iapi.reference.SQLState;
25
26 import org.apache.derby.iapi.services.io.ArrayInputStream;
27
28 import org.apache.derby.iapi.services.sanity.SanityManager;
29
30 import org.apache.derby.iapi.services.io.Formatable;
31 import org.apache.derby.iapi.services.io.FormatIdUtil;
32 import org.apache.derby.iapi.services.io.StoredFormatIds;
33 import org.apache.derby.iapi.error.StandardException;
34
35 import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo;
36 import org.apache.derby.iapi.store.access.conglomerate.TransactionManager;
37
38 import org.apache.derby.iapi.store.access.RowUtil;
39 import org.apache.derby.iapi.store.access.DynamicCompiledOpenConglomInfo;
40 import org.apache.derby.iapi.store.access.Qualifier;
41 import org.apache.derby.iapi.store.access.ScanController;
42 import org.apache.derby.iapi.store.access.TransactionController;
43
44 import org.apache.derby.iapi.store.raw.ContainerHandle;
45 import org.apache.derby.iapi.store.raw.FetchDescriptor;
46 import org.apache.derby.iapi.store.raw.LockingPolicy;
47 import org.apache.derby.iapi.store.raw.LogicalUndoable;
48 import org.apache.derby.iapi.store.raw.Page;
49 import org.apache.derby.iapi.store.raw.RecordHandle;
50 import org.apache.derby.iapi.store.raw.Transaction;
51
52 import org.apache.derby.iapi.types.DataValueDescriptor;
53
54 // imports of inherited impl's
55
import org.apache.derby.impl.store.access.btree.BTree;
56 import org.apache.derby.impl.store.access.btree.BTreeLockingPolicy;
57 import org.apache.derby.impl.store.access.btree.ControlRow;
58 import org.apache.derby.impl.store.access.btree.OpenBTree;
59 import org.apache.derby.impl.store.access.btree.SearchParameters;
60
61 import java.io.ObjectInput JavaDoc;
62 import java.io.IOException JavaDoc;
63 import java.io.ObjectOutput JavaDoc;
64 import org.apache.derby.iapi.services.io.LimitObjectInput;
65
66 import org.apache.derby.iapi.services.io.FormatableBitSet;
67
68 /**
69  * @format_id ACCESS_B2IUNDO_V1_ID
70  *
71  * @purpose Implements the LogicalUndo and Formatable interfaces, basically
72  * providing a way for raw store recovery to "call back" access code
73  * to provide logical undo ability.
74  *
75  * @upgrade RESOLVE.
76  *
77  * @disk_layout
78  * No state associated with this format.
79  *
80  **/

81
82 /**
83
84 The B2IUndo interface packages up the routines which the rawstore needs
85 to call to perform logical undo of a record in a B2i. The rawstore will
86 determine that a page has changed since the record was written, and if it
87 has it will call the findUndo() interface, to find the page where the record
88 exists (as it may have moved).
89 <p>
90 This class must not contain any persistent state, as this class is stored
91 in the log record of the insert/delete.
92
93 @see org.apache.derby.iapi.store.raw.LogicalUndoable
94 @see org.apache.derby.iapi.store.raw.Undoable#generateUndo
95 **/

96 public class B2IUndo implements LogicalUndo, Formatable
97 {
98     /**
99      * Find the page and record to undo. If no logical undo is necessary,
100      * i.e., row has not moved, then just return the latched page where undo
101      * should go. If the record has moved, it has a new recordId on the new
102      * page, this routine needs to call pageOp.resetRecord with the new
103      * RecordHandle so that the logging system can update the compensation
104      * Operation with the new location.
105      *
106      * @param rawtran the transaction doing the rollback
107      * @param pageOp the page operation that supports logical undo. This
108      * LogicalUndo function pointer is a field of that
109      * pageOperation
110      * @param in data stored in the log stream that contains the record
111      * data necessary to restore the row.
112      *
113      * @exception StandardException Standard Cloudscape error policy
114      * @exception IOException Method may read from InputStream
115      *
116      */

117     public Page findUndo(
118     Transaction rawtran,
119     LogicalUndoable pageOp,
120     LimitObjectInput in)
121         throws StandardException, IOException JavaDoc
122     {
123         ControlRow root = null;
124         ControlRow control_row = null;
125         DataValueDescriptor[] logged_index_row_template = null;
126         DataValueDescriptor[] template = null;
127         Page ret_page = null;
128         ContainerHandle container = pageOp.getContainer();
129         RecordHandle rechandle = pageOp.getRecordHandle();
130         boolean ok_exit = false;
131         int compare_result = 1;
132         B2I btree = null;
133
134         // Open the btree to associate the open contain handle, thus the
135
// current xact with all subsequent operations during undo.
136

137
138         try
139         {
140
141             // Need Conglomerate to create templates - get from the root page.
142
root = ControlRow.Get(container, BTree.ROOTPAGEID);
143
144             if (SanityManager.DEBUG)
145                 SanityManager.ASSERT(root.getPage().isLatched());
146
147             btree = (B2I) root.getConglom(B2I.FORMAT_NUMBER);
148
149             if (SanityManager.DEBUG)
150                 SanityManager.ASSERT(btree instanceof B2I);
151
152             // create a template for the logged index row from the conglomerate.
153
logged_index_row_template = btree.createTemplate();
154
155             // create a template for the page index row from the conglomerate.
156
template = btree.createTemplate();
157         }
158         finally
159         {
160             if (root != null)
161                 root.release();
162         }
163
164         // Get logged row from record.
165
pageOp.restoreLoggedRow(logged_index_row_template, in);
166
167         // RESOLVE (mikem) - currently restoreLoggedRow() may latch and unlatch
168
// a page in the container (see ST059).
169
// Now get the page where the record used to be.
170

171         ok_exit = false;
172         try
173         {
174             // "open" the btree, using recovery's already opened container
175
OpenBTree open_btree = new OpenBTree();
176
177             open_btree.init(
178                 (TransactionManager) null, // current user xact - not needed
179
(TransactionManager) null, // current xact - not needed
180
pageOp.getContainer(), // recovery already opened container
181
rawtran,
182                 false,
183                 ContainerHandle.MODE_FORUPDATE,
184                                             // open_mode not used - container is
185
// already opened.
186
TransactionManager.MODE_NONE,
187                 (BTreeLockingPolicy) null, // don't get locks during undo
188
btree,
189                 (LogicalUndo) null, // no logical undo necessary, as
190
// this code only does read.
191
(DynamicCompiledOpenConglomInfo) null);
192
193             // System.out.println(
194
// "calling logical undo, recordhandle = " + rechandle);
195
// System.out.println("calling logical undo, record= " +
196
// logged_index_row_template);
197

198             // Get the page where the record was originally, before splits
199
// could have possibly moved it.
200
control_row = ControlRow.Get(open_btree, rechandle.getPageNumber());
201
202             // init compare_result, if record doesn't exist do the search
203
compare_result = 1;
204
205             if (control_row.getPage().recordExists(rechandle, true))
206             {
207
208                 if (SanityManager.DEBUG)
209                 {
210                     SanityManager.ASSERT(
211                         control_row.getPage().fetchNumFields(rechandle) ==
212                         logged_index_row_template.length);
213                 }
214
215                 // create template for the page index row from the conglomerate.
216
RecordHandle ret_rechandle =
217                     control_row.getPage().fetchFromSlot(
218                         (RecordHandle) null,
219                         control_row.getPage().getSlotNumber(rechandle),
220                         template,
221                         (FetchDescriptor) null,
222                         true);
223
224                 // compare the 2 rows, and if they are the same then the raw
225
// store has the right page and record and there is no work to
226
// be done (this is usual case).
227
compare_result = ControlRow.CompareIndexRowToKey(
228                     template, logged_index_row_template,
229                     logged_index_row_template.length, 1,
230                     open_btree.getColumnSortOrderInfo());
231             }
232
233             if (compare_result == 0)
234             {
235                 ret_page = control_row.getPage();
236             }
237             else
238             {
239                 // if the 2 don't compare equal, search the btree from the root
240
// for the logged row, find the leaf, reset the row for the raw
241
// store, and return the new page latched.
242

243                 // Create the objects needed for the insert.
244
SearchParameters sp = new SearchParameters(
245                         logged_index_row_template, ScanController.GE,
246                         template, open_btree, false);
247
248                 control_row.release();
249                 control_row = null;
250                 control_row =
251                     ControlRow.Get(open_btree, BTree.ROOTPAGEID).search(sp);
252
253                 if (!sp.resultExact)
254                 {
255                     if (SanityManager.DEBUG)
256                     {
257                         SanityManager.THROWASSERT(
258                             "B2IUndo - could not find key being searched for:" +
259                             ";key = " +
260                                 RowUtil.toString(logged_index_row_template) +
261                             ";sp = " + sp +
262                             "control_row = " + control_row +
263                             "control_row.debugPage() = " +
264                                 control_row.debugPage(open_btree) +
265                             "control_row.getPage() = " +
266                                 control_row.getPage());
267                     }
268
269                     throw StandardException.newException(
270                             SQLState.BTREE_ROW_NOT_FOUND_DURING_UNDO);
271                 }
272                 else
273                 {
274                     RecordHandle rh =
275                         control_row.getPage().fetchFromSlot(
276                             (RecordHandle) null,
277                             sp.resultSlot, new DataValueDescriptor[0],
278                             (FetchDescriptor) null,
279                             true);
280
281                     pageOp.resetRecordHandle(rh);
282
283                     ret_page = control_row.getPage();
284                 }
285             }
286             ok_exit = true;
287         }
288         finally
289         {
290             //System.out.println("B2iUndo returning with rec handle: " +
291
// pageOp.getRecordHandle());
292
if ((!ok_exit) && (control_row != null))
293                 control_row.release();
294         }
295
296         return(ret_page);
297     }
298
299     /**
300         Return my format identifier.
301
302         @see org.apache.derby.iapi.services.io.TypedFormat#getTypeFormatId
303     */

304     public int getTypeFormatId()
305     {
306         return StoredFormatIds.ACCESS_B2IUNDO_V1_ID;
307     }
308
309     /**
310     This object has no state, so nothing to write.*/

311
312     public void writeExternal(ObjectOutput JavaDoc out) throws IOException JavaDoc
313     {
314         return;
315     }
316
317     /**
318     Restore the in-memory representation from the stream.
319
320     This object has no state, so nothing to restore.
321     @exception ClassNotFoundException Thrown if the stored representation is
322     serialized and a class named in the stream could not be found.
323
324     @see java.io.Externalizable#readExternal
325     */

326     public void readExternal(ObjectInput JavaDoc in)
327         throws IOException JavaDoc, ClassNotFoundException JavaDoc
328     {
329         return;
330     }
331     public void readExternal(ArrayInputStream in)
332         throws IOException JavaDoc, ClassNotFoundException JavaDoc
333     {
334         return;
335     }
336 }
337
Popular Tags