KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > store > raw > log > LogRecord


1 /*
2
3    Derby - Class org.apache.derby.impl.store.raw.log.LogRecord
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.log;
23
24 import org.apache.derby.iapi.reference.SQLState;
25
26 import org.apache.derby.iapi.services.sanity.SanityManager;
27 import org.apache.derby.iapi.services.io.FormatIdUtil;
28 import org.apache.derby.iapi.services.io.StoredFormatIds;
29 import org.apache.derby.iapi.services.io.Formatable;
30
31 import org.apache.derby.iapi.error.StandardException;
32
33 import org.apache.derby.iapi.store.raw.Loggable;
34 import org.apache.derby.iapi.store.raw.Compensation;
35 import org.apache.derby.iapi.store.raw.RePreparable;
36 import org.apache.derby.iapi.store.raw.Undoable;
37
38 import org.apache.derby.iapi.store.raw.xact.TransactionId;
39
40 import org.apache.derby.iapi.services.io.CompressedNumber;
41
42 import java.io.ObjectOutput JavaDoc;
43 import java.io.ObjectInput JavaDoc;
44 import java.io.IOException JavaDoc;
45
46
47 /**
48     The log record written out to disk. This log record includes:
49     <P>
50     The is a holder object that may be setup using the setValue() and re-used
51     rather than creating a new object for each actual log record.
52
53     <P> <PRE>
54     The format of a log record is
55
56     @format_id LOG_RECORD
57         the formatId is written by FormatIdOutputStream when this object is
58         written out by writeObject
59     @purpose The log record described every change to the persistent store
60     @upgrade
61     @disk_layout
62         loggable group(CompressedInt) the loggable's group value
63         xactId(TransactionId) The Transaction this log belongs to
64         op(Loggable) the log operation
65     @end_format
66     </PRE>
67
68 */

69 public class LogRecord implements Formatable {
70
71     private TransactionId xactId; // the transaction Id
72
private Loggable op; // the loggable
73
private int group; // the loggable's group value
74

75     // the objectInput stream that contains the loggable object. The
76
// objectification of the transaction Id and the the loggable object is
77
// delayed from readExternal time to getTransactionId and getLoggable time
78
// to give the log scan an opportunity to discard the loggable based on
79
// group value and xactId.
80
transient ObjectInput JavaDoc input;
81
82     private static final int formatLength = FormatIdUtil.getFormatIdByteLength(StoredFormatIds.LOG_RECORD);
83
84     public LogRecord() {
85     }
86
87     /*
88      * Formatable methods
89      */

90
91     /**
92         Write this out.
93         @exception IOException error writing to log stream
94     */

95     public void writeExternal(ObjectOutput JavaDoc out) throws IOException JavaDoc
96     {
97         CompressedNumber.writeInt(out, group);
98         out.writeObject(xactId);
99         out.writeObject(op);
100     }
101
102     /**
103         Read this in
104         @exception IOException error reading from log stream
105         @exception ClassNotFoundException corrupted log stream
106     */

107     public void readExternal(ObjectInput JavaDoc in) throws IOException JavaDoc, ClassNotFoundException JavaDoc
108     {
109         group = CompressedNumber.readInt(in);
110         input = in; // tie the input to this logRecord
111

112         xactId = null; // delay reading these until later
113
op = null;
114     }
115
116     /**
117         Return my format identifier.
118     */

119     public int getTypeFormatId() {
120         return StoredFormatIds.LOG_RECORD;
121     }
122
123     /*
124      * class specific methods
125      */

126     public void setValue(TransactionId xactId, Loggable op)
127     {
128         this.xactId = xactId;
129         this.op = op;
130
131         this.group = op.group();
132     }
133
134     public static int formatOverhead()
135     {
136         return formatLength;
137     }
138
139     public static int maxGroupStoredSize()
140     {
141         return CompressedNumber.MAX_INT_STORED_SIZE;
142     }
143
144     public static int maxTransactionIdStoredSize(TransactionId tranId)
145     {
146         return tranId.getMaxStoredSize();
147     }
148
149     
150     public static int getStoredSize(int group, TransactionId xactId)
151     {
152         
153         if (SanityManager.DEBUG)
154         {
155             SanityManager.ASSERT(xactId == null,
156                                  "size calculation are based on xactId being null");
157         }
158
159         return formatLength + CompressedNumber.sizeInt(group) +
160             FormatIdUtil.getFormatIdByteLength(StoredFormatIds.NULL_FORMAT_ID);
161     }
162
163
164     public TransactionId getTransactionId()
165          throws IOException JavaDoc, ClassNotFoundException JavaDoc
166     {
167         if (xactId != null)
168             return xactId;
169
170         if (SanityManager.DEBUG)
171             SanityManager.ASSERT(input != null,
172                      "xactId not objectified but object input is not set");
173
174         Object JavaDoc obj = input.readObject();
175         if (SanityManager.DEBUG)
176         {
177             SanityManager.ASSERT(obj instanceof TransactionId,
178                          "log record not getting expected TransactionId");
179         }
180         xactId = (TransactionId)obj;
181
182         return xactId;
183     }
184
185     public Loggable getLoggable() throws IOException JavaDoc, ClassNotFoundException JavaDoc {
186
187         if (op != null) // If log operation is already objectified,
188
return op; // then just return it.
189

190         if (SanityManager.DEBUG)
191             SanityManager.ASSERT(input != null,
192                      "logop not objectified but object input is not set");
193
194         if (xactId == null) // xactId is not read off yet
195
{
196             xactId = (TransactionId)input.readObject();
197         }
198
199         Object JavaDoc obj = input.readObject();
200
201         if (SanityManager.DEBUG) {
202             if ( ! (obj instanceof Loggable))
203                 SanityManager.THROWASSERT(
204                     "log record not getting expected Loggable: got : " +
205                     obj.getClass().getName());
206         }
207         op = (Loggable)obj;
208
209         input = null;
210
211         return op;
212     }
213
214     public RePreparable getRePreparable()
215         throws IOException JavaDoc, ClassNotFoundException JavaDoc
216     {
217         return((RePreparable) getLoggable());
218     }
219
220     /**
221         Skip over the loggable. Set the input stream to point ot after the
222         loggable as if the entire log record has been sucked in by the log
223         record
224
225         @exception StandardException if the loggable is not found, log is corrupt
226     */

227     public void skipLoggable() throws StandardException
228     {
229         if (op != null) // loggable already read off
230
return;
231
232         try
233         {
234             if (xactId == null)
235                 xactId = (TransactionId)input.readObject(); // get rid of the transactionId
236

237             if (op == null)
238                 op = (Loggable)input.readObject(); // get rid of the loggable
239
}
240         catch(ClassNotFoundException JavaDoc cnfe)
241         {
242             throw StandardException.newException(SQLState.LOG_CORRUPTED, cnfe);
243         }
244         catch(IOException JavaDoc ioe)
245         {
246             throw StandardException.newException(SQLState.LOG_CORRUPTED, ioe);
247         }
248     }
249
250     public Undoable getUndoable() throws IOException JavaDoc, ClassNotFoundException JavaDoc
251     {
252         if (op == null)
253             getLoggable(); // objectify it
254

255         if (op instanceof Undoable)
256             return (Undoable) op;
257         else
258             return null;
259     }
260
261     public boolean isCLR() {
262         return ((group & Loggable.COMPENSATION) != 0);
263     }
264
265     public boolean isFirst() {
266         return ((group & Loggable.FIRST) != 0);
267     }
268
269     public boolean isComplete() {
270         return ((group & Loggable.LAST) != 0);
271     }
272
273     public boolean isPrepare() {
274         return ((group & Loggable.PREPARE) != 0);
275     }
276
277     public boolean requiresPrepareLocks() {
278         return ((group & Loggable.XA_NEEDLOCK) != 0);
279     }
280
281     public boolean isCommit()
282     {
283         if (SanityManager.DEBUG)
284         {
285             SanityManager.ASSERT((group & Loggable.LAST) == Loggable.LAST,
286                  "calling isCommit on log record that is not last");
287             SanityManager.ASSERT((group & (Loggable.COMMIT | Loggable.ABORT)) != 0,
288                  "calling isCommit on log record before commit status is recorded");
289         }
290         return ((group & Loggable.COMMIT) != 0);
291     }
292
293     public boolean isAbort()
294     {
295         if (SanityManager.DEBUG)
296         {
297             SanityManager.ASSERT((group & Loggable.LAST) == Loggable.LAST,
298                  "calling isAbort on log record that is not last");
299             SanityManager.ASSERT((group & (Loggable.COMMIT | Loggable.ABORT)) != 0,
300                  "calling isAbort on log record before abort status is recorded");
301         }
302         return ((group & Loggable.ABORT) != 0);
303     }
304
305     public int group()
306     {
307         return group;
308     }
309
310
311     public boolean isChecksum() {
312         return ((group & Loggable.CHECKSUM) != 0);
313     }
314 }
315
Popular Tags