1 | /* |
2 | |
3 | Derby - Class org.apache.derby.impl.store.raw.log.ChecksumOperation |
4 | |
5 | Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable. |
6 | |
7 | Licensed under the Apache License, Version 2.0 (the "License"); |
8 | you may not use this file except in compliance with the License. |
9 | You may obtain a copy of the License at |
10 | |
11 | http://www.apache.org/licenses/LICENSE-2.0 |
12 | |
13 | Unless required by applicable law or agreed to in writing, software |
14 | distributed under the License is distributed on an "AS IS" BASIS, |
15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
16 | See the License for the specific language governing permissions and |
17 | limitations under the License. |
18 | |
19 | */ |
20 | |
21 | package org.apache.derby.impl.store.raw.log; |
22 | |
23 | import org.apache.derby.iapi.services.sanity.SanityManager; |
24 | import org.apache.derby.iapi.services.io.Formatable; |
25 | import org.apache.derby.iapi.services.io.FormatIdUtil; |
26 | import org.apache.derby.iapi.services.io.StoredFormatIds; |
27 | import org.apache.derby.catalog.UUID; |
28 | |
29 | import org.apache.derby.iapi.store.raw.Transaction; |
30 | import org.apache.derby.iapi.store.raw.Loggable; |
31 | import org.apache.derby.iapi.store.raw.log.LogInstant; |
32 | import org.apache.derby.iapi.store.raw.log.LogFactory; |
33 | import org.apache.derby.iapi.store.raw.xact.RawTransaction; |
34 | |
35 | import org.apache.derby.iapi.error.StandardException; |
36 | |
37 | import org.apache.derby.iapi.services.io.CompressedNumber; |
38 | import org.apache.derby.iapi.util.ByteArray; |
39 | |
40 | import java.io.Externalizable; |
41 | import java.io.OutputStream; |
42 | import java.io.InputStream; |
43 | import java.io.ObjectInput; |
44 | import java.io.ObjectOutput; |
45 | import java.io.IOException; |
46 | import org.apache.derby.iapi.services.io.LimitObjectInput; |
47 | |
48 | import java.util.zip.Checksum; |
49 | import java.util.zip.CRC32; |
50 | |
51 | |
52 | /** |
53 | A Log Operation that represents a checksum for a group of log records |
54 | that are written to the tranaction log file. |
55 | |
56 | <PRE> |
57 | @format_id LOGOP_CHECKSUM |
58 | the formatId is written by FormatIdOutputStream when this object is |
59 | written out by writeObject |
60 | @purpose checksum one or more log records while writing to disk |
61 | @upgrade |
62 | @disk_layout |
63 | checksumAlgo(byte) the checksum algorithm |
64 | checksumValue(long) the checksum value |
65 | dataLength(int) number of bytes that the checksum is calculated |
66 | @end_format |
67 | </PRE> |
68 | |
69 | @author Suresh Thalamati |
70 | @see Loggable |
71 | */ |
72 | |
73 | public class ChecksumOperation implements Loggable |
74 | { |
75 | |
76 | private byte checksumAlgo; |
77 | private long checksumValue; |
78 | private int dataLength; |
79 | private Checksum checksum; |
80 | |
81 | /* |
82 | * constant values for algorithm that are used to perform the checksum. |
83 | */ |
84 | public static final byte CRC32_ALGORITHM = (byte) 0x1; //java.util.zip.CRC32 |
85 | |
86 | private static final int formatLength = FormatIdUtil.getFormatIdByteLength(StoredFormatIds.LOGOP_CHECKSUM); |
87 | |
88 | public void init() |
89 | { |
90 | this.checksumAlgo = CRC32_ALGORITHM; |
91 | initializeChecksumAlgo(); |
92 | dataLength = 0; |
93 | } |
94 | |
95 | |
96 | // update the checksum |
97 | protected void update(byte[] buf, int off, int len) |
98 | { |
99 | checksum.update(buf, off , len); |
100 | dataLength += len; |
101 | } |
102 | |
103 | |
104 | // reset the checksum |
105 | protected void reset() |
106 | { |
107 | checksum.reset(); |
108 | dataLength = 0; |
109 | } |
110 | |
111 | |
112 | private void initializeChecksumAlgo() |
113 | { |
114 | if(checksumAlgo == CRC32_ALGORITHM) |
115 | this.checksum = new CRC32(); |
116 | } |
117 | |
118 | |
119 | /* |
120 | * Formatable methods |
121 | */ |
122 | |
123 | // no-arg constructor, required by Formatable |
124 | public ChecksumOperation() { super();} |
125 | |
126 | public void writeExternal(ObjectOutput out) throws IOException |
127 | { |
128 | checksumValue = checksum.getValue(); |
129 | out.writeByte(checksumAlgo); |
130 | out.writeInt(dataLength); |
131 | out.writeLong(checksumValue); |
132 | } |
133 | |
134 | public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException |
135 | { |
136 | checksumAlgo = (byte) in.readUnsignedByte(); |
137 | dataLength = in.readInt(); |
138 | checksumValue = in.readLong(); |
139 | initializeChecksumAlgo(); |
140 | } |
141 | |
142 | |
143 | public int getStoredSize() |
144 | { |
145 | return formatLength + 1 + 4 + 8; |
146 | } |
147 | |
148 | |
149 | |
150 | /** |
151 | Return my format identifier. |
152 | */ |
153 | public int getTypeFormatId() { |
154 | return StoredFormatIds.LOGOP_CHECKSUM; |
155 | } |
156 | |
157 | |
158 | |
159 | |
160 | |
161 | /** |
162 | Loggable methods |
163 | */ |
164 | |
165 | /** |
166 | * Nothing to do for the checksum log record because it does need to be |
167 | * applied during redo. |
168 | */ |
169 | public void doMe(Transaction xact, LogInstant instant, LimitObjectInput in) throws StandardException |
170 | { |
171 | } |
172 | |
173 | /** |
174 | the default for prepared log is always null for all the operations |
175 | that don't have optionalData. If an operation has optional data, |
176 | the operation need to prepare the optional data for this method. |
177 | |
178 | Checksum has no optional data to write out |
179 | |
180 | |
181 | */ |
182 | public ByteArray getPreparedLog() |
183 | { |
184 | return (ByteArray) null; |
185 | } |
186 | |
187 | /** |
188 | Checksum does not need to be redone, it is used to just verify that |
189 | log records are written completely. |
190 | */ |
191 | public boolean needsRedo(Transaction xact) |
192 | { |
193 | return false; |
194 | } |
195 | |
196 | |
197 | /** |
198 | Checksum has no resources to release |
199 | */ |
200 | public void releaseResource(Transaction xact) |
201 | {} |
202 | |
203 | /** |
204 | Checksum is a raw store operation |
205 | */ |
206 | public int group() |
207 | { |
208 | return Loggable.RAWSTORE | Loggable.CHECKSUM; |
209 | } |
210 | |
211 | |
212 | |
213 | |
214 | /** |
215 | * Access attributes of the checksum log record |
216 | */ |
217 | |
218 | protected int getDataLength() |
219 | { |
220 | return dataLength; |
221 | } |
222 | |
223 | |
224 | protected boolean isChecksumValid(byte[] data, int off , int length) |
225 | { |
226 | checksum.reset(); |
227 | checksum.update(data , off , length); |
228 | return checksum.getValue()== checksumValue; |
229 | |
230 | } |
231 | |
232 | |
233 | /** |
234 | DEBUG: Print self. |
235 | */ |
236 | public String toString() |
237 | { |
238 | if (SanityManager.DEBUG) |
239 | { |
240 | StringBuffer str = new StringBuffer(200) |
241 | .append("Checksum Operation ") |
242 | .append(" algorithm = ") |
243 | .append(checksumAlgo) |
244 | .append(" value = ") |
245 | .append(checksumValue) |
246 | .append(" data length= ").append(dataLength); |
247 | |
248 | return str.toString(); |
249 | } |
250 | else |
251 | return null; |
252 | } |
253 | } |
254 | |
255 | |
256 | |
257 | |
258 | |
259 | |
260 | |
261 | |
262 | |
263 | |
264 | |
265 | |