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 / OverflowInputStream.java
diff --git a/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/store/raw/data/OverflowInputStream.java b/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/store/raw/data/OverflowInputStream.java
new file mode 100644 (file)
index 0000000..a2e3a84
--- /dev/null
@@ -0,0 +1,194 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.store.raw.data.OverflowInputStream\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.error.StandardException;\r
+import org.apache.derby.iapi.reference.SQLState;\r
+\r
+import org.apache.derby.iapi.store.raw.RecordHandle;\r
+\r
+import org.apache.derby.iapi.types.Resetable;\r
+import org.apache.derby.iapi.store.raw.LockingPolicy;\r
+import org.apache.derby.iapi.store.access.TransactionController;\r
+\r
+import java.io.IOException;\r
+\r
+/**\r
+       A OverflowInputStream is used by store to turn a long column\r
+       into an InputStream.\r
+*/\r
+public class OverflowInputStream\r
+extends BufferedByteHolderInputStream\r
+implements Resetable\r
+{\r
+       protected BaseContainerHandle owner;\r
+       protected long overflowPage;\r
+       protected int overflowId;\r
+    // remember first page and id for reset\r
+       protected long firstOverflowPage;\r
+       protected int firstOverflowId;\r
+    // the row to lock for Blobs/Clobs\r
+    protected RecordHandle recordToLock;\r
+    \r
+    // Make sure record is only locked once.\r
+    private boolean initialized = false;\r
+\r
+       public OverflowInputStream(ByteHolder bh, BaseContainerHandle owner,\r
+                   long overflowPage, int overflowId, RecordHandle recordToLock)\r
+        throws IOException, StandardException\r
+       {\r
+               super(bh);\r
+               this.owner = owner;\r
+               this.overflowPage = overflowPage;\r
+               this.overflowId = overflowId;\r
+               this.firstOverflowPage = overflowPage;\r
+               this.firstOverflowId = overflowId;\r
+        this.recordToLock = recordToLock;\r
+               fillByteHolder();\r
+       }\r
+\r
+\r
+       public void fillByteHolder() throws IOException\r
+       {\r
+               if ((this.bh.available() == 0) && (this.overflowPage != -1))\r
+        {\r
+                       this.bh.clear();\r
+\r
+                       try\r
+            {\r
+                               // fill the byte holder with data from the page.\r
+                               BasePage columnOverflowPage = \r
+                    ((BasePage) this.owner.getPage(overflowPage));\r
+\r
+                               if (columnOverflowPage != null)\r
+                {\r
+                                       columnOverflowPage.restorePortionLongColumn(this);\r
+                                       columnOverflowPage.unlatch();\r
+                                       columnOverflowPage = null;\r
+                               }\r
+                       }\r
+            catch (StandardException se)\r
+            {\r
+                               throw new IOException( se.toString() );\r
+                       }\r
+                       this.bh.startReading();\r
+               }\r
+       }\r
+\r
+\r
+       public long getOverflowPage() {\r
+               return this.overflowPage;\r
+       }\r
+\r
+       public int getOverflowId() {\r
+               return this.overflowId;\r
+       }\r
+\r
+       public void setOverflowPage(long overflowPage) {\r
+               this.overflowPage = overflowPage;\r
+       }\r
+\r
+       public void setOverflowId(int overflowId) {\r
+               this.overflowId = overflowId;\r
+       }\r
+\r
+\r
+    /*\r
+     Methods of Resetable interface.\r
+    */\r
+\r
+    /*\r
+     Resets the stream to the beginning.\r
+     */\r
+    public void resetStream() throws IOException, StandardException\r
+    {\r
+        // check the container is open, this is needed to make sure the\r
+        // container closed exception is thrown as a StandardException and not\r
+        // as an IOException\r
+        owner.checkOpen();\r
+        // return to the original overflow page and id\r
+               this.overflowPage = firstOverflowPage;\r
+               this.overflowId = firstOverflowId;\r
+        // completely clear the byte holder\r
+        this.bh.clear();\r
+        this.bh.startReading();\r
+        // fill the byte holder\r
+               fillByteHolder();\r
+    }\r
+\r
+    /**\r
+     * Initialize.  Reopen the container. This will have the effect of\r
+     * getting an intent shared lock on the table, which will stay around until\r
+     * the enclosing blob/clob object is closed, or until the end of the \r
+     * transaction. Also get a read lock on the appropriate row.\r
+     * \r
+     * @throws org.apache.derby.iapi.error.StandardException\r
+     */\r
+    public void initStream() throws StandardException\r
+    {\r
+        if (initialized) return;\r
+        \r
+        // it is possible that the transaction in which the stream was\r
+        // created is committed and no longer valid\r
+        // dont want to get NPE but instead throw error that\r
+        // container was not opened\r
+        if (owner.getTransaction() == null)\r
+            throw StandardException.newException(SQLState.DATA_CONTAINER_CLOSED);\r
+                \r
+        /*\r
+        We use isolation level READ_COMMITTED and reopen the container to \r
+        get a new container handle to use for locking.  This way, the lock will\r
+        be freed when we the container handle is closed. This will happen in\r
+        closeStream() or when the transaction commits. \r
+        Hence, locks will be released before the end of transaction if \r
+        blobs/clobs are explicitly released.\r
+        */\r
+        LockingPolicy lp = \r
+            owner.getTransaction().newLockingPolicy(\r
+                LockingPolicy.MODE_RECORD, \r
+                TransactionController.ISOLATION_READ_COMMITTED, true);\r
+\r
+        // reopen the container\r
+        owner = (BaseContainerHandle) owner.getTransaction().openContainer(\r
+            owner.getId(), lp, owner.getMode());\r
+\r
+        // get a read lock on the appropriate row\r
+        // this will wait until either the lock is granted or an exception is\r
+        // thrown\r
+        owner.getLockingPolicy().lockRecordForRead(\r
+            owner.getTransaction(), owner, recordToLock, true, false);\r
+        \r
+        initialized = true;\r
+    }\r
+\r
+\r
+    /*\r
+      Close the container associated with this stream. (This will also free the \r
+      associated IS table lock and the associated S row lock.)\r
+    */\r
+    public void closeStream()\r
+    {\r
+        owner.close();\r
+        initialized = false;\r
+    }\r
+\r
+}\r