001: /*
002:
003: Derby - Class org.apache.derby.impl.store.raw.log.ChecksumOperation
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.store.raw.log;
023:
024: import org.apache.derby.iapi.services.sanity.SanityManager;
025: import org.apache.derby.iapi.services.io.Formatable;
026: import org.apache.derby.iapi.services.io.FormatIdUtil;
027: import org.apache.derby.iapi.services.io.StoredFormatIds;
028: import org.apache.derby.catalog.UUID;
029:
030: import org.apache.derby.iapi.store.raw.Transaction;
031: import org.apache.derby.iapi.store.raw.Loggable;
032: import org.apache.derby.iapi.store.raw.log.LogInstant;
033: import org.apache.derby.iapi.store.raw.log.LogFactory;
034: import org.apache.derby.iapi.store.raw.xact.RawTransaction;
035:
036: import org.apache.derby.iapi.error.StandardException;
037:
038: import org.apache.derby.iapi.services.io.CompressedNumber;
039: import org.apache.derby.iapi.util.ByteArray;
040:
041: import java.io.Externalizable;
042: import java.io.OutputStream;
043: import java.io.InputStream;
044: import java.io.ObjectInput;
045: import java.io.ObjectOutput;
046: import java.io.IOException;
047: import org.apache.derby.iapi.services.io.LimitObjectInput;
048:
049: import java.util.zip.Checksum;
050: import java.util.zip.CRC32;
051:
052: /**
053: A Log Operation that represents a checksum for a group of log records
054: that are written to the tranaction log file.
055:
056: <PRE>
057: @format_id LOGOP_CHECKSUM
058: the formatId is written by FormatIdOutputStream when this object is
059: written out by writeObject
060: @purpose checksum one or more log records while writing to disk
061: @upgrade
062: @disk_layout
063: checksumAlgo(byte) the checksum algorithm
064: checksumValue(long) the checksum value
065: dataLength(int) number of bytes that the checksum is calculated
066: @end_format
067: </PRE>
068:
069: @author Suresh Thalamati
070: @see Loggable
071: */
072:
073: public class ChecksumOperation implements Loggable {
074:
075: private byte checksumAlgo;
076: private long checksumValue;
077: private int dataLength;
078: private Checksum checksum;
079:
080: /*
081: * constant values for algorithm that are used to perform the checksum.
082: */
083: public static final byte CRC32_ALGORITHM = (byte) 0x1; //java.util.zip.CRC32
084:
085: private static final int formatLength = FormatIdUtil
086: .getFormatIdByteLength(StoredFormatIds.LOGOP_CHECKSUM);
087:
088: public void init() {
089: this .checksumAlgo = CRC32_ALGORITHM;
090: initializeChecksumAlgo();
091: dataLength = 0;
092: }
093:
094: // update the checksum
095: protected void update(byte[] buf, int off, int len) {
096: checksum.update(buf, off, len);
097: dataLength += len;
098: }
099:
100: // reset the checksum
101: protected void reset() {
102: checksum.reset();
103: dataLength = 0;
104: }
105:
106: private void initializeChecksumAlgo() {
107: if (checksumAlgo == CRC32_ALGORITHM)
108: this .checksum = new CRC32();
109: }
110:
111: /*
112: * Formatable methods
113: */
114:
115: // no-arg constructor, required by Formatable
116: public ChecksumOperation() {
117: super ();
118: }
119:
120: public void writeExternal(ObjectOutput out) throws IOException {
121: checksumValue = checksum.getValue();
122: out.writeByte(checksumAlgo);
123: out.writeInt(dataLength);
124: out.writeLong(checksumValue);
125: }
126:
127: public void readExternal(ObjectInput in) throws IOException,
128: ClassNotFoundException {
129: checksumAlgo = (byte) in.readUnsignedByte();
130: dataLength = in.readInt();
131: checksumValue = in.readLong();
132: initializeChecksumAlgo();
133: }
134:
135: public int getStoredSize() {
136: return formatLength + 1 + 4 + 8;
137: }
138:
139: /**
140: Return my format identifier.
141: */
142: public int getTypeFormatId() {
143: return StoredFormatIds.LOGOP_CHECKSUM;
144: }
145:
146: /**
147: Loggable methods
148: */
149:
150: /**
151: * Nothing to do for the checksum log record because it does need to be
152: * applied during redo.
153: */
154: public void doMe(Transaction xact, LogInstant instant,
155: LimitObjectInput in) throws StandardException {
156: }
157:
158: /**
159: the default for prepared log is always null for all the operations
160: that don't have optionalData. If an operation has optional data,
161: the operation need to prepare the optional data for this method.
162:
163: Checksum has no optional data to write out
164:
165:
166: */
167: public ByteArray getPreparedLog() {
168: return (ByteArray) null;
169: }
170:
171: /**
172: Checksum does not need to be redone, it is used to just verify that
173: log records are written completely.
174: */
175: public boolean needsRedo(Transaction xact) {
176: return false;
177: }
178:
179: /**
180: Checksum has no resources to release
181: */
182: public void releaseResource(Transaction xact) {
183: }
184:
185: /**
186: Checksum is a raw store operation
187: */
188: public int group() {
189: return Loggable.RAWSTORE | Loggable.CHECKSUM;
190: }
191:
192: /**
193: * Access attributes of the checksum log record
194: */
195:
196: protected int getDataLength() {
197: return dataLength;
198: }
199:
200: protected boolean isChecksumValid(byte[] data, int off, int length) {
201: checksum.reset();
202: checksum.update(data, off, length);
203: return checksum.getValue() == checksumValue;
204:
205: }
206:
207: /**
208: DEBUG: Print self.
209: */
210: public String toString() {
211: if (SanityManager.DEBUG) {
212: StringBuffer str = new StringBuffer(200).append(
213: "Checksum Operation ").append(" algorithm = ")
214: .append(checksumAlgo).append(" value = ").append(
215: checksumValue).append(" data length= ")
216: .append(dataLength);
217:
218: return str.toString();
219: } else
220: return null;
221: }
222: }
|