--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.impl.store.raw.log.ChecksumOperation\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to you under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.impl.store.raw.log;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+import org.apache.derby.iapi.services.io.Formatable;\r
+import org.apache.derby.iapi.services.io.FormatIdUtil;\r
+import org.apache.derby.iapi.services.io.StoredFormatIds;\r
+import org.apache.derby.catalog.UUID;\r
+\r
+import org.apache.derby.iapi.store.raw.Transaction;\r
+import org.apache.derby.iapi.store.raw.Loggable;\r
+import org.apache.derby.iapi.store.raw.log.LogInstant;\r
+import org.apache.derby.iapi.store.raw.log.LogFactory;\r
+import org.apache.derby.iapi.store.raw.xact.RawTransaction;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+import org.apache.derby.iapi.services.io.CompressedNumber;\r
+import org.apache.derby.iapi.util.ByteArray;\r
+\r
+import java.io.Externalizable;\r
+import java.io.OutputStream;\r
+import java.io.InputStream;\r
+import java.io.ObjectInput;\r
+import java.io.ObjectOutput;\r
+import java.io.IOException;\r
+import org.apache.derby.iapi.services.io.LimitObjectInput;\r
+\r
+import java.util.zip.Checksum;\r
+import java.util.zip.CRC32;\r
+\r
+\r
+/**\r
+ A Log Operation that represents a checksum for a group of log records\r
+ that are written to the tranaction log file.\r
+\r
+ <PRE>\r
+ @format_id LOGOP_CHECKSUM\r
+ the formatId is written by FormatIdOutputStream when this object is\r
+ written out by writeObject\r
+ @purpose checksum one or more log records while writing to disk\r
+ @upgrade\r
+ @disk_layout\r
+ checksumAlgo(byte) the checksum algorithm \r
+ checksumValue(long) the checksum value \r
+ dataLength(int) number of bytes that the checksum is calculated\r
+ @end_format\r
+ </PRE>\r
+\r
+ @see Loggable\r
+*/\r
+\r
+public class ChecksumOperation implements Loggable \r
+{\r
+\r
+ private byte checksumAlgo;\r
+ private long checksumValue; \r
+ private int dataLength; \r
+ private Checksum checksum; \r
+\r
+ /*\r
+ * constant values for algorithm that are used to perform the checksum.\r
+ */\r
+ public static final byte CRC32_ALGORITHM = (byte) 0x1; //java.util.zip.CRC32\r
+ \r
+ private static final int formatLength = FormatIdUtil.getFormatIdByteLength(StoredFormatIds.LOGOP_CHECKSUM);\r
+ \r
+ public void init()\r
+ {\r
+ this.checksumAlgo = CRC32_ALGORITHM;\r
+ initializeChecksumAlgo();\r
+ dataLength = 0;\r
+ }\r
+\r
+ \r
+ // update the checksum\r
+ protected void update(byte[] buf, int off, int len)\r
+ {\r
+ checksum.update(buf, off , len);\r
+ dataLength += len;\r
+ }\r
+\r
+ \r
+ // reset the checksum \r
+ protected void reset()\r
+ {\r
+ checksum.reset();\r
+ dataLength = 0;\r
+ }\r
+\r
+\r
+ private void initializeChecksumAlgo()\r
+ {\r
+ if(checksumAlgo == CRC32_ALGORITHM)\r
+ this.checksum = new CRC32();\r
+ }\r
+\r
+\r
+ /*\r
+ * Formatable methods\r
+ */\r
+\r
+ // no-arg constructor, required by Formatable \r
+ public ChecksumOperation() { super();}\r
+\r
+ public void writeExternal(ObjectOutput out) throws IOException \r
+ { \r
+ checksumValue = checksum.getValue();\r
+ out.writeByte(checksumAlgo);\r
+ out.writeInt(dataLength);\r
+ out.writeLong(checksumValue);\r
+ }\r
+\r
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException\r
+ {\r
+ checksumAlgo = (byte) in.readUnsignedByte();\r
+ dataLength = in.readInt();\r
+ checksumValue = in.readLong();\r
+ initializeChecksumAlgo();\r
+ }\r
+\r
+\r
+ public int getStoredSize()\r
+ {\r
+ return formatLength + 1 + 4 + 8;\r
+ } \r
+\r
+\r
+\r
+ /**\r
+ Return my format identifier.\r
+ */\r
+ public int getTypeFormatId() {\r
+ return StoredFormatIds.LOGOP_CHECKSUM;\r
+ }\r
+\r
+\r
+\r
+\r
+\r
+ /**\r
+ Loggable methods\r
+ */\r
+\r
+ /**\r
+ * Nothing to do for the checksum log record because it does need to be\r
+ * applied during redo. \r
+ */\r
+ public void doMe(Transaction xact, LogInstant instant, LimitObjectInput in) throws StandardException\r
+ {\r
+ }\r
+\r
+ /**\r
+ the default for prepared log is always null for all the operations\r
+ that don't have optionalData. If an operation has optional data,\r
+ the operation need to prepare the optional data for this method.\r
+\r
+ Checksum has no optional data to write out\r
+\r
+ \r
+ */\r
+ public ByteArray getPreparedLog()\r
+ {\r
+ return (ByteArray) null;\r
+ }\r
+\r
+ /**\r
+ Checksum does not need to be redone, it is used to just verify that\r
+ log records are written completely.\r
+ */\r
+ public boolean needsRedo(Transaction xact)\r
+ {\r
+ return false;\r
+ }\r
+\r
+\r
+ /**\r
+ Checksum has no resources to release\r
+ */\r
+ public void releaseResource(Transaction xact)\r
+ {}\r
+\r
+ /**\r
+ Checksum is a raw store operation\r
+ */\r
+ public int group()\r
+ {\r
+ return Loggable.RAWSTORE | Loggable.CHECKSUM;\r
+ }\r
+\r
+ \r
+\r
+\r
+ /**\r
+ * Access attributes of the checksum log record\r
+ */\r
+\r
+ protected int getDataLength() \r
+ {\r
+ return dataLength;\r
+ }\r
+\r
+\r
+ protected boolean isChecksumValid(byte[] data, int off , int length)\r
+ {\r
+ checksum.reset();\r
+ checksum.update(data , off , length);\r
+ return checksum.getValue()== checksumValue;\r
+\r
+ }\r
+\r
+\r
+ /**\r
+ DEBUG: Print self.\r
+ */\r
+ public String toString()\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ {\r
+ StringBuffer str = new StringBuffer(200)\r
+ .append("Checksum Operation ")\r
+ .append(" algorithm = ")\r
+ .append(checksumAlgo)\r
+ .append(" value = ")\r
+ .append(checksumValue)\r
+ .append(" data length= ").append(dataLength);\r
+\r
+ return str.toString();\r
+ }\r
+ else\r
+ return null;\r
+ }\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r