Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / derby-10.3.2.1 / java / engine / org / apache / derby / impl / store / raw / data / UpdateFieldOperation.java
diff --git a/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/store/raw/data/UpdateFieldOperation.java b/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/store/raw/data/UpdateFieldOperation.java
new file mode 100644 (file)
index 0000000..2a1f6d6
--- /dev/null
@@ -0,0 +1,371 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.store.raw.data.UpdateFieldOperation\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.data;\r
+\r
+import org.apache.derby.iapi.reference.SQLState;\r
+\r
+import org.apache.derby.impl.store.raw.data.BasePage;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import org.apache.derby.iapi.services.io.FormatIdUtil;\r
+import org.apache.derby.iapi.services.io.StoredFormatIds;\r
+\r
+import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo;\r
+\r
+import org.apache.derby.iapi.store.raw.Page;\r
+import org.apache.derby.iapi.store.raw.RecordHandle;\r
+import org.apache.derby.iapi.store.raw.Transaction;\r
+import org.apache.derby.iapi.store.raw.xact.RawTransaction; \r
+\r
+import org.apache.derby.iapi.store.raw.log.LogInstant;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+import org.apache.derby.iapi.types.DataValueDescriptor;\r
+\r
+import org.apache.derby.iapi.services.io.FormatableBitSet;\r
+import org.apache.derby.iapi.services.io.CompressedNumber;\r
+import org.apache.derby.iapi.util.ByteArray;\r
+import org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream;\r
+\r
+import java.io.OutputStream;\r
+import java.io.ObjectOutput;\r
+import java.io.ObjectInput;\r
+import java.io.IOException;\r
+import org.apache.derby.iapi.services.io.LimitObjectInput;\r
+\r
+\r
+/**\r
+       Represents the update of a particular field of a row on a page.\r
+\r
+       <PRE>\r
+       @format_id      LOGOP_UPDATE_FIELD\r
+               the formatId is written by FormatIdOutputStream when this object is\r
+               written out by writeObject\r
+       @purpose        update a field of a record on the page\r
+       @upgrade\r
+       @disk_layout\r
+               LogicalPageOperation    the super class\r
+               doMeSlot(CompressedInt) the slot of the record being updated\r
+               fieldId(CompressedInt)  the recordId of the record being updated\r
+\r
+               OptionalData    The after image of the column (length included),\r
+                                               follow by the old image of the record (length\r
+                                               included).  If this is logically undoable, then the\r
+                                               before image of the entire row is logged\r
+       @end_format\r
+       </PRE>\r
+*/\r
+public final class UpdateFieldOperation extends LogicalPageOperation \r
+{\r
+\r
+       protected int                   doMeSlot;       // insert slot - only valid during a doMe() operation\r
+       protected int                   fieldId;\r
+\r
+       transient protected ByteArray preparedLog;\r
+\r
+       public UpdateFieldOperation(\r
+    RawTransaction      t, \r
+    BasePage            page, \r
+    int                 slot, \r
+    int                 recordId, \r
+    int                 fieldId, \r
+    Object column, \r
+    LogicalUndo         undo) \r
+               throws StandardException\r
+       {\r
+               super(page, undo, recordId);\r
+\r
+               this.doMeSlot = slot;\r
+               this.fieldId = fieldId;\r
+\r
+               try {\r
+                       writeOptionalDataToBuffer(t, column);\r
+               } catch (IOException ioe) {\r
+                       throw StandardException.newException(\r
+                    SQLState.DATA_UNEXPECTED_EXCEPTION, ioe);\r
+               }\r
+       }\r
+\r
+       /*\r
+        * Formatable methods\r
+        */\r
+\r
+       // no-arg constructor, required by Formatable \r
+       public UpdateFieldOperation() { super(); }\r
+\r
+       public void writeExternal(ObjectOutput out) throws IOException \r
+       {\r
+               super.writeExternal(out);\r
+               CompressedNumber.writeInt(out, doMeSlot);\r
+               CompressedNumber.writeInt(out, fieldId);\r
+       }\r
+\r
+       /**\r
+               Read this in\r
+               @exception IOException error reading from log stream\r
+               @exception ClassNotFoundException log stream corrupted\r
+       */\r
+       public void readExternal(ObjectInput in) \r
+                throws IOException, ClassNotFoundException\r
+       {\r
+               super.readExternal(in);\r
+               doMeSlot = CompressedNumber.readInt(in);\r
+               fieldId = CompressedNumber.readInt(in);\r
+       }\r
+\r
+       /**\r
+               Return my format identifier.\r
+       */\r
+       public int getTypeFormatId() {\r
+               return StoredFormatIds.LOGOP_UPDATE_FIELD;\r
+       }\r
+\r
+       /*\r
+        * Loggable methods\r
+        */\r
+       /**\r
+               Change the value of a field.\r
+\r
+               @exception IOException Can be thrown by any of the methods of ObjectInput.\r
+               @exception StandardException Standard Derby policy.\r
+\r
+               @see org.apache.derby.iapi.store.raw.Loggable#doMe\r
+       */\r
+       public void doMe(Transaction xact, LogInstant instant, LimitObjectInput in)\r
+                throws StandardException, IOException \r
+       {\r
+               this.page.storeField(instant, doMeSlot, fieldId, in);\r
+       }\r
+       \r
+       /*\r
+        * Undoable methods\r
+        */\r
+\r
+       /**\r
+               Restore field to its old value.\r
+\r
+               @exception IOException Can be thrown by any of the methods of ObjectInput.\r
+               @exception StandardException Standard Derby policy.\r
+\r
+               @see LogicalPageOperation#undoMe\r
+       */\r
+       public void undoMe(Transaction xact, BasePage undoPage, int undoRecordId,\r
+                                          LogInstant CLRInstant, LimitObjectInput in)\r
+                throws StandardException, IOException\r
+       {\r
+               int slot = \r
+            undoPage.findRecordById(undoRecordId, Page.FIRST_SLOT_NUMBER);\r
+               \r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       // if the record Id has changed, the page had better changed\r
+                       // this can only happen during recovery since in run time undo,\r
+                       // this resetRecordHandle gets called and this object have the new\r
+                       // page number and recordId\r
+                       if (undoRecordId != this.recordId)\r
+                               if (undoPage.getPageNumber() == getPageId().getPageNumber())\r
+                                       SanityManager.THROWASSERT(\r
+                                                                        "recordId changed from " + this.recordId +\r
+                                                                        " to " + undoRecordId +\r
+                                                                        " but page number did not change " +\r
+                                                                        undoPage.getPageNumber());\r
+\r
+                       if (slot == -1)\r
+                               SanityManager.THROWASSERT(\r
+                                       "recordId " +\r
+                                       undoRecordId +\r
+                                       " not found on page " +\r
+                                       undoPage.getPageNumber());\r
+               }\r
+\r
+               undoPage.skipField((java.io.ObjectInput) in);   // skip the after image of the column\r
+               undoPage.storeField(CLRInstant, slot, fieldId, in);\r
+               undoPage.setAuxObject(null);\r
+       }\r
+\r
+       /*\r
+        * LogicalUndoable methods\r
+        */\r
+\r
+\r
+       /**\r
+               Restore the row stored in the optional data of the log record.\r
+\r
+               @exception IOException error reading from log stream\r
+               @exception StandardException Standard Derby error policy\r
+       */\r
+       public void restoreLoggedRow(Object[] row, LimitObjectInput in)\r
+               throws StandardException, IOException\r
+       {\r
+               BasePage p = null;\r
+\r
+               try {\r
+                       // the optional data is written by the page in the same format it\r
+                       // stores record on the page, \r
+                       // only a page knows how to restore a logged row back to a storable row\r
+                       // first get the page where the insert went even though the row may no\r
+                       // longer be there\r
+                       p = (BasePage)(getContainer().getPage(getPageId().getPageNumber()));\r
+\r
+                       // skip over the before and after image of the column, position the\r
+                       // input stream at the entire row\r
+                       p.skipField(in);        // AI of the column\r
+                       p.skipField(in);        // BI of the column\r
+\r
+                       p.restoreRecordFromStream(in, row);\r
+\r
+                       // RESOLVE: this returns the BI of the row, what we need is the AI\r
+                       // of the row.  We need to someone splice in the AI of the column\r
+                       // into the storable row.\r
+\r
+               } finally {\r
+\r
+                       if (p != null) {\r
+                               p.unlatch();\r
+                               p = null;\r
+                       }\r
+               }\r
+       }\r
+\r
+       /*\r
+        * method to support BeforeImageLogging\r
+        */\r
+\r
+       /**\r
+        * restore the before image of the page\r
+        *\r
+        * @exception StandardException Standard Derby Error Policy\r
+        * @exception IOException problem reading the complete log record from the\r
+        * input stream\r
+        */\r
+       public void restoreMe(Transaction xact, BasePage undoPage, LogInstant CLRInstant, LimitObjectInput in)\r
+                throws StandardException, IOException\r
+       {\r
+               int slot = undoPage.findRecordById(recordId, Page.FIRST_SLOT_NUMBER);\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       if ( ! getPageId().equals(undoPage.getPageId()))\r
+                               SanityManager.THROWASSERT(\r
+                                                               "restoreMe cannot restore to a different page. "\r
+                                                                + "doMe page:" + getPageId() + " undoPage:" + \r
+                                                                undoPage.getPageId());\r
+                       if (slot != doMeSlot)\r
+                               SanityManager.THROWASSERT(\r
+                                                               "restoreMe cannot restore to a different slot. "\r
+                                                                + "doMe slot:" + doMeSlot + " undoMe slot: " +\r
+                                                                slot + " recordId:" + recordId);\r
+               }\r
+\r
+               undoPage.skipField(in); // skip the after image of the column\r
+               undoPage.storeField(CLRInstant, slot, fieldId, in);\r
+               undoPage.setAuxObject(null);\r
+       }\r
+\r
+       /*\r
+               methods to support prepared log\r
+               \r
+               the following two methods should not be called during recover\r
+       */\r
+\r
+       public ByteArray getPreparedLog()\r
+       {\r
+               return (this.preparedLog);\r
+       }\r
+\r
+       /**\r
+         Write the old column value and and new column value as optional data.\r
+         If logical undo, writes out the entire row's before image.\r
+\r
+               @exception IOException Can be thrown by any of the methods of ObjectOutput.\r
+               @exception StandardException Standard Derby policy.\r
+       */\r
+       private void writeOptionalDataToBuffer(\r
+    RawTransaction      t, \r
+    Object column)\r
+               throws StandardException, IOException\r
+       {\r
+\r
+               if (SanityManager.DEBUG) {\r
+                       SanityManager.ASSERT(this.page != null);\r
+               }\r
+\r
+               DynamicByteArrayOutputStream logBuffer = t.getLogBuffer();\r
+               int optionalDataStart = logBuffer.getPosition();\r
+\r
+               if (SanityManager.DEBUG) {\r
+                       SanityManager.ASSERT(optionalDataStart == 0,\r
+                               "Buffer for writing optional data should start at position 0");\r
+               }\r
+                               \r
+               this.page.logColumn(doMeSlot, fieldId, column, logBuffer, 100); // the after image of the column\r
+               this.page.logField(doMeSlot, fieldId, logBuffer); // the BI of the column\r
+               if (undo != null)\r
+               {\r
+                       // RESOLVE: we want the AFTER image of the row, not the BEFORE\r
+                       // image.   This works for now because only btree needs a logical\r
+                       // undoable updateField and it always update only the pointer field\r
+                       // to point to something else.\r
+                       //\r
+                       // But in the future, it needs to be changed. \r
+\r
+                       this.page.logRecord(doMeSlot, BasePage.LOG_RECORD_DEFAULT,\r
+                                                               recordId, (FormatableBitSet) null, logBuffer,\r
+                                                               (RecordHandle)null); \r
+                       // log the BI of the entire row\r
+\r
+               }\r
+\r
+               int optionalDataLength = logBuffer.getPosition() - optionalDataStart;\r
+\r
+               if (SanityManager.DEBUG) {\r
+                       if (optionalDataLength != logBuffer.getUsed())\r
+                               SanityManager.THROWASSERT("wrong optional data length, optionalDataLength = "\r
+                                       + optionalDataLength + ", logBuffer.getUsed() = " + logBuffer.getUsed());\r
+               }\r
+\r
+               // set the position to the beginning of the buffer\r
+               logBuffer.setPosition(optionalDataStart);\r
+\r
+               this.preparedLog = new ByteArray(logBuffer.getByteArray(), optionalDataStart,\r
+                       optionalDataLength);\r
+       }\r
+\r
+       /**\r
+         DEBUG: Print self.\r
+       */\r
+       public String toString()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       return super.toString() + \r
+                               "UpdateField : " + \r
+                               " Slot=" + doMeSlot +\r
+                               " recordId=" + recordId +\r
+                               " fieldId=" + fieldId;\r
+               }\r
+               else\r
+                       return null;\r
+       }\r
+\r
+}\r