KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derby.impl.store.raw.data.ContainerOperation
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.services.io.FormatIdUtil;
25 import org.apache.derby.iapi.services.io.StoredFormatIds;
26 import org.apache.derby.iapi.services.sanity.SanityManager;
27
28 import org.apache.derby.iapi.store.raw.Compensation;
29 import org.apache.derby.iapi.store.raw.ContainerHandle;
30 import org.apache.derby.iapi.store.raw.LockingPolicy;
31 import org.apache.derby.iapi.store.raw.Transaction;
32 import org.apache.derby.iapi.store.raw.Undoable;
33
34 import org.apache.derby.iapi.store.raw.xact.RawTransaction;
35 import org.apache.derby.iapi.store.raw.data.RawContainerHandle;
36 import org.apache.derby.iapi.store.raw.log.LogInstant;
37
38 import org.apache.derby.iapi.error.StandardException;
39
40 import org.apache.derby.iapi.util.ByteArray;
41
42 import java.io.ObjectOutput JavaDoc;
43 import java.io.InputStream JavaDoc;
44 import java.io.ObjectInput JavaDoc;
45 import java.io.IOException JavaDoc;
46 import org.apache.derby.iapi.services.io.LimitObjectInput;
47
48 /**
49     Log operation to create, drop or remove a container.
50
51     Both the doMe or the undoMe of a create actually caused the container
52     header to be modified and flushed before the log record is flushed. This
53     is necessary for 2 reasons, one is that of ensuring enough disk space, and
54     the other is because unlike any other operation, the log record create
55     container is in the log stream before the container is in the container
56     cache. What this mean is that if a checkpoint started after the container
57     operation but before the container is kept or is dirtied in the container
58     cache, then checkpoint will not know to wait for the container to be kept
59     or cleaned. The checkpoint will erroneous assume that the operation does
60     not need to be redone since its log instant is before the checkpoint but in
61     fact the change has not been flushed to disk.
62
63     A drop or remove container does not have this problem. The container exist
64     and is in kept state when the operation is logged so the checkpoint will
65     not overlook it and it doesn't need to flush the container header. In the
66     case of remove, the stub is flushed for a different reason - that of
67     ensuring disk space.
68
69 */

70 public class ContainerOperation extends ContainerBasicOperation implements Undoable
71 {
72     protected byte operation; // create, drop, or remove
73

74     // in previous version of contianerOperation, there may not
75
// be a createByteArray
76
transient protected boolean hasCreateByteArray = true;
77
78     protected ByteArray createByteArray; // information necessary to
79
// recreate the container
80

81     protected static final byte CREATE = (byte)1;
82     protected static final byte DROP = (byte)2;
83     protected static final byte REMOVE = (byte)4;
84
85     protected ContainerOperation(RawContainerHandle hdl, byte operation)
86          throws StandardException
87     {
88         super(hdl);
89         this.operation = operation;
90     }
91
92     /*
93      * Formatable methods
94      */

95
96     // no-arg constructor, required by Formatable
97
public ContainerOperation() { super(); }
98
99     public void writeExternal(ObjectOutput JavaDoc out) throws IOException JavaDoc
100     {
101         super.writeExternal(out);
102         out.writeByte(operation);
103
104         if (operation == CREATE)
105         {
106             try
107             {
108                 createByteArray = containerHdl.logCreateContainerInfo();
109             }
110             catch (StandardException se)
111             {
112                 throw new IOException JavaDoc(se.toString());
113             }
114                     
115             createByteArray.writeExternal(out);
116         }
117     }
118
119     /**
120         @exception IOException cannot read log record from log stream
121         @exception ClassNotFoundException cannot read ByteArray object
122      */

123     public void readExternal(ObjectInput JavaDoc in)
124          throws IOException JavaDoc, ClassNotFoundException JavaDoc
125     {
126         super.readExternal(in);
127         operation = in.readByte();
128
129         if (operation == CREATE && hasCreateByteArray)
130         {
131             createByteArray = new ByteArray();
132             createByteArray.readExternal(in);
133         }
134     }
135
136     /**
137         Return my format identifier.
138     */

139     public int getTypeFormatId() {
140         return StoredFormatIds.LOGOP_CONTAINER;
141     }
142
143
144     /*
145      * override ContainerBasicOperation's findContainerForRedoRecovery
146      */

147     /**
148         Find container for load tran.
149         <p>
150         If we are in load tran, and the operation is a create, the container
151         may not (should not?) exist yet. We need to recreate it.
152
153         @exception StandardException Standard Cloudscape policy.
154      */

155     protected RawContainerHandle findContainerForRedoRecovery(
156     RawTransaction xact)
157          throws StandardException
158     {
159         if (SanityManager.DEBUG)
160             SanityManager.ASSERT(createByteArray != null,
161             "cannot reCreate container in load tran, createByteArray is null");
162
163         long sid = containerId.getSegmentId();
164         long cid = containerId.getContainerId();
165
166         xact.reCreateContainerForRedoRecovery(sid, cid, createByteArray);
167
168         // now we should be able to open this container
169
return xact.openDroppedContainer(containerId, (LockingPolicy)null);
170     }
171
172     /**
173         @exception StandardException Standard Cloudscape error policy
174     */

175     public final void doMe(Transaction tran, LogInstant instant,
176                            LimitObjectInput in)
177          throws StandardException
178     {
179
180         switch (operation)
181         {
182         case DROP:
183             containerHdl.dropContainer(instant, true);
184             //
185
// RESOLVE: if it hasn't been stubbified, even at redo time, we will
186
// want to earmark this as a post commit work because we know it will
187
// not be wasted effort.
188
//
189
break;
190
191         case REMOVE:
192             containerHdl.removeContainer(instant);
193             break;
194
195         case CREATE:
196             break;
197             // nothing to do with create container, it has already been synced to
198
// disk. If the container is subsequently dropped or even removed,
199
// that's fine too. Don't bother to find it.
200
}
201
202         releaseResource(tran);
203     }
204
205
206     /**
207         Undo of create, drop or remove
208
209         @param tran the transaction that is undoing this operation
210         @param hdl the container handle. This is found here during runtime
211         undo - in which case we made the CLR and passed in the containerHdl
212         found in generateUndo and it is passed back to this; or it is found in
213         the CLR's needsRedo and is passed in and this operation never found the
214         container. Either case, release resource at the end is safe
215         @param CLRInstant the log instant of the CLR
216         @param in optional data
217
218         @exception StandardException Standard Cloudscape error policy
219     */

220     public void undoMe(Transaction tran, RawContainerHandle hdl,
221                        LogInstant CLRInstant, LimitObjectInput in)
222          throws StandardException
223     {
224         switch(operation)
225         {
226         case DROP:
227             if (SanityManager.DEBUG) {
228                 SanityManager.ASSERT(hdl != null, "container handle is null");
229                 SanityManager.ASSERT(hdl.getContainerStatus() != RawContainerHandle.COMMITTED_DROP,
230                                      "Undoing a drop but the container status is not dropped");
231             }
232             hdl.dropContainer(CLRInstant, false); // not dropped
233
break;
234
235         case CREATE:
236             // remove the container
237
hdl.removeContainer(CLRInstant);
238             break;
239
240         case REMOVE:
241             if (SanityManager.DEBUG) {
242                 SanityManager.THROWASSERT("cannot undo REMOVE, should not have generated a CLR in the first place");
243             }
244             break;
245         }
246         releaseResource(tran);
247
248     }
249
250     /**
251         @see org.apache.derby.iapi.store.raw.Undoable
252         @exception StandardException Standard Cloudscape error policy
253     */

254     public Compensation generateUndo(Transaction tran, LimitObjectInput in)
255          throws StandardException
256     {
257         if (operation == REMOVE)
258             return null; // cannot undo REMOVE
259
else
260         {
261             RawContainerHandle undoContainerHandle = findContainer(tran);
262             
263             // mark the container as pre-dirtied so that if a checkpoint
264
// happens after the log record is sent to the log stream, the
265
// cache cleaning will wait for this change.
266
//
267
// RESOLVE: don't do this now because if undo failed, this
268
// container will be "stuck" in the preDirty state and checkpoint
269
// will be stuck
270
// undoContainerHandle.preDirty(true);
271
//
272

273             return new ContainerUndoOperation(undoContainerHandle, this);
274         }
275     }
276
277     /** debug */
278     public String JavaDoc toString()
279     {
280         if (SanityManager.DEBUG)
281         {
282             String JavaDoc str = super.toString();
283             switch(operation)
284             {
285             case CREATE: str += " CREATE container " + containerId;
286                 break;
287             case DROP: str += " DROP container " + containerId;
288                 break;
289             case REMOVE: str += " REMOVE container " + containerId;
290                 break;
291             }
292             return str;
293         }
294         else
295             return null;
296     }
297
298
299 }
300
Popular Tags