Return-Path: Delivered-To: apmail-db-derby-commits-archive@www.apache.org Received: (qmail 67141 invoked from network); 12 Jan 2006 10:10:43 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 12 Jan 2006 10:10:43 -0000 Received: (qmail 51311 invoked by uid 500); 12 Jan 2006 10:10:41 -0000 Delivered-To: apmail-db-derby-commits-archive@db.apache.org Received: (qmail 51241 invoked by uid 500); 12 Jan 2006 10:10:40 -0000 Mailing-List: contact derby-commits-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: "Derby Development" List-Id: Delivered-To: mailing list derby-commits@db.apache.org Received: (qmail 51004 invoked by uid 99); 12 Jan 2006 10:10:37 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 12 Jan 2006 02:10:37 -0800 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Thu, 12 Jan 2006 02:10:35 -0800 Received: (qmail 66894 invoked by uid 65534); 12 Jan 2006 10:10:15 -0000 Message-ID: <20060112101015.66892.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r368333 - in /db/derby/code/trunk/java/drda/org/apache/derby/impl/drda: ConsistencyToken.java DDMReader.java DDMWriter.java DRDAConnThread.java DRDAResultSet.java DRDAStatement.java DRDAString.java Database.java Pkgnamcsn.java Date: Thu, 12 Jan 2006 10:10:08 -0000 To: derby-commits@db.apache.org From: bernt@apache.org X-Mailer: svnmailer-1.0.5 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: bernt Date: Thu Jan 12 02:09:50 2006 New Revision: 368333 URL: http://svn.apache.org/viewcvs?rev=368333&view=rev Log: DERBY-212 Optimize some specific methods in Network Server to improve performance. Submitted by Knut Anders Hatlen Added: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/ConsistencyToken.java (with props) db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAString.java (with props) db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/Pkgnamcsn.java (with props) Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DDMReader.java db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DDMWriter.java db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAResultSet.java db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAStatement.java db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/Database.java Added: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/ConsistencyToken.java URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/ConsistencyToken.java?rev=368333&view=auto ============================================================================== --- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/ConsistencyToken.java (added) +++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/ConsistencyToken.java Thu Jan 12 02:09:50 2006 @@ -0,0 +1,92 @@ +/* + * Derby - class org.apache.derby.impl.drda.ConsistencyToken + * + * Copyright 2006 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You + * may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing + * permissions and limitations under the License. + * + */ + +package org.apache.derby.impl.drda; + +/** + * Class which represents an RDB Package Consistency Token. + */ +final class ConsistencyToken { + /** Byte array representation of the token. */ + private final byte[] bytes; + /** Cached hash code. */ + private int hash = 0; + + /** + * Create a new ConsistencyToken instance. + * + * @param bytes byte array representing the token + */ + public ConsistencyToken(byte[] bytes) { + this.bytes = bytes; + } + + /** + * Get the byte array representation of the consistency token. + * + * @return a byte[] value + */ + public byte[] getBytes() { + return bytes; + } + + /** + * Check whether this object is equal to another object. + * + * @param o another object + * @return true if the objects are equal + */ + public boolean equals(Object o) { + if (!(o instanceof ConsistencyToken)) return false; + ConsistencyToken ct = (ConsistencyToken) o; + int len = bytes.length; + if (len != ct.bytes.length) return false; + for (int i = 0; i < len; ++i) { + if (bytes[i] != ct.bytes[i]) return false; + } + return true; + } + + /** + * Calculate the hash code. + * + * @return hash code + */ + public int hashCode() { + if (hash == 0) { + int len = bytes.length; + for (int i = 0; i < len; ++i) { + hash ^= bytes[i]; + } + } + return hash; + } + + /** + * Return a string representation of the consistency token by + * converting it to a BigInteger value. (For + * debugging only.) + * + * @return a String value + */ + public String toString() { + return new java.math.BigInteger(bytes).toString(); + } +} Propchange: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/ConsistencyToken.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DDMReader.java URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DDMReader.java?rev=368333&r1=368332&r2=368333&view=diff ============================================================================== --- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DDMReader.java (original) +++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DDMReader.java Thu Jan 12 02:09:50 2006 @@ -1210,6 +1210,30 @@ } /** + * Read string value into a DRDAString object. + * + * @param dst destination for the read string + * @param size size (in bytes) of string to read + * @param unpad if true, remove padding (trailing spaces) + * + * @exception DRDAProtocolException + */ + protected void readString(DRDAString dst, int size, boolean unpad) + throws DRDAProtocolException + { + ensureBLayerDataInBuffer(size, ADJUST_LENGTHS); + int startPos = pos; + pos += size; + if (unpad) { + while ((size > 0) && + (buffer[startPos + size - 1] == ccsidManager.space)) { + --size; + } + } + dst.setBytes(buffer, startPos, size); + } + + /** * Read encoded string value * @param length - length of string to read * @return value Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DDMWriter.java URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DDMWriter.java?rev=368333&r1=368332&r2=368333&view=diff ============================================================================== --- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DDMWriter.java (original) +++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DDMWriter.java Thu Jan 12 02:09:50 2006 @@ -962,6 +962,24 @@ } /** + * Write padded scalar DRDAString object value. The + * string is converted into the appropriate codeset. + * + * @param drdaString string to be written + * @param paddedLength length to pad string to + */ + protected void writeScalarPaddedString (DRDAString drdaString, int paddedLength) + { + int stringLength = drdaString.length(); + int fillLength = paddedLength - stringLength; + ensureLength(paddedLength); + System.arraycopy(drdaString.getBytes(), 0, bytes, offset, stringLength); + offset += stringLength; + Arrays.fill(bytes, offset, offset + fillLength, ccsidManager.space); + offset += fillLength; + } + + /** * Write padded scalar byte array object includes length, codepoint and value * * @param codePoint - code point to write Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java?rev=368333&r1=368332&r2=368333&view=diff ============================================================================== --- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java (original) +++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java Thu Jan 12 02:09:50 2006 @@ -134,11 +134,19 @@ private SQLException databaseAccessException; // these fields are needed to feed back to jcc about a statement/procedure's PKGNAMCSN - private String rdbnam; - private String rdbcolid; - private String pkgid; - private String pkgcnstknStr; - private int secnumber; + /** The value returned by the previous call to + * parsePKGNAMCSN(). */ + private Pkgnamcsn prevPkgnamcsn = null; + /** Current RDB Package Name. */ + private DRDAString rdbnam = new DRDAString(ccsidManager); + /** Current RDB Collection Identifier. */ + private DRDAString rdbcolid = new DRDAString(ccsidManager); + /** Current RDB Package Identifier. */ + private DRDAString pkgid = new DRDAString(ccsidManager); + /** Current RDB Package Consistency Token. */ + private DRDAString pkgcnstkn = new DRDAString(ccsidManager); + /** Current RDB Package Section Number. */ + private int pkgsn; private final static String TIMEOUT_STATEMENT = "SET STATEMENT_TIMEOUT "; @@ -706,7 +714,7 @@ writeOPNQFLRM(null); break; } - String pkgnamcsn = parseOPNQRY(); + Pkgnamcsn pkgnamcsn = parseOPNQRY(); if (pkgnamcsn != null) { stmt = database.getDRDAStatement(pkgnamcsn); @@ -1649,12 +1657,12 @@ * QRYROWSET - Query Rowset Size - optional - level 7 * MONITOR - Monitor events - optional. * - * @return package name consistency token + * @return RDB Package Name, Consistency Token, and Section Number * @exception DRDAProtocolException */ - private String parseOPNQRY() throws DRDAProtocolException, SQLException + private Pkgnamcsn parseOPNQRY() throws DRDAProtocolException, SQLException { - String pkgnamcsn = null; + Pkgnamcsn pkgnamcsn = null; boolean gotQryblksz = false; int blksize = 0; int qryblkctl = CodePoint.QRYBLKCTL_DEFAULT; @@ -1965,34 +1973,42 @@ * * @throws DRDAProtocolException */ - private void writePKGNAMCSN(String pkgcnstknStr) throws DRDAProtocolException + private void writePKGNAMCSN(byte[] pkgcnstkn) throws DRDAProtocolException { writer.startDdm(CodePoint.PKGNAMCSN); - if (rdbcolid.length() == CodePoint.RDBCOLID_LEN && rdbnam.length() <= CodePoint.RDBNAM_LEN) - { //fixed format + if (rdbnam.length() <= CodePoint.RDBNAM_LEN && + rdbcolid.length() <= CodePoint.RDBCOLID_LEN && + pkgid.length() <= CodePoint.PKGID_LEN) + { // if none of RDBNAM, RDBCOLID and PKGID have a length of + // more than 18, use fixed format writer.writeScalarPaddedString(rdbnam, CodePoint.RDBNAM_LEN); writer.writeScalarPaddedString(rdbcolid, CodePoint.RDBCOLID_LEN); writer.writeScalarPaddedString(pkgid, CodePoint.PKGID_LEN); - writer.writeScalarPaddedString(pkgcnstknStr, CodePoint.PKGCNSTKN_LEN); - writer.writeShort(secnumber); + writer.writeScalarPaddedBytes(pkgcnstkn, + CodePoint.PKGCNSTKN_LEN, (byte) 0); + writer.writeShort(pkgsn); } else // extended format { - writer.writeShort(rdbnam.length()); - writer.writeScalarPaddedString(rdbnam, rdbnam.length()); - writer.writeShort(rdbcolid.length()); - writer.writeScalarPaddedString(rdbcolid, rdbcolid.length()); - writer.writeShort(pkgid.length()); - writer.writeScalarPaddedString(pkgid, pkgid.length()); - writer.writeScalarPaddedString(pkgcnstknStr, CodePoint.PKGCNSTKN_LEN); - writer.writeShort(secnumber); + int len = Math.max(CodePoint.RDBNAM_LEN, rdbnam.length()); + writer.writeShort(len); + writer.writeScalarPaddedString(rdbnam, len); + len = Math.max(CodePoint.RDBCOLID_LEN, rdbcolid.length()); + writer.writeShort(len); + writer.writeScalarPaddedString(rdbcolid, len); + len = Math.max(CodePoint.PKGID_LEN, pkgid.length()); + writer.writeShort(len); + writer.writeScalarPaddedString(pkgid, len); + writer.writeScalarPaddedBytes(pkgcnstkn, + CodePoint.PKGCNSTKN_LEN, (byte) 0); + writer.writeShort(pkgsn); } writer.endDdm(); } private void writePKGNAMCSN() throws DRDAProtocolException { - writePKGNAMCSN(pkgcnstknStr); + writePKGNAMCSN(pkgcnstkn.getBytes()); } /** @@ -2021,7 +2037,7 @@ private DRDAStatement parseCNTQRY() throws DRDAProtocolException, SQLException { byte val; - String pkgnamcsn = null; + Pkgnamcsn pkgnamcsn = null; boolean gotQryblksz = false; boolean qryrelscr = true; long qryrownbr = 1; @@ -3072,7 +3088,7 @@ * Parse PRPSQLSTT - Prepare SQL Statement * Instance Variables * RDBNAM - Relational Database Name - optional - * PKGNAMCAN - RDB Package Name, Consistency Token, and Section Number - required + * PKGNAMCSN - RDB Package Name, Consistency Token, and Section Number - required * RTNSQLDA - Return SQL Descriptor Area - optional * MONITOR - Monitor events - optional. * @@ -3087,7 +3103,7 @@ boolean rtnsqlda = false; boolean rtnOutput = true; // Return output SQLDA is default String typdefnam; - String pkgnamcsn = null; + Pkgnamcsn pkgnamcsn = null; DRDAStatement stmt = null; Database databaseToSet = null; @@ -3300,7 +3316,7 @@ { int codePoint; boolean rtnOutput = true; // default - String pkgnamcsn = null; + Pkgnamcsn pkgnamcsn = null; reader.markCollection(); codePoint = reader.getCodePoint(); @@ -3367,7 +3383,7 @@ codePoint = reader.getCodePoint(); boolean outputExpected = false; - String pkgnamcsn = null; + Pkgnamcsn pkgnamcsn = null; int numRows = 1; // default value int blkSize = 0; int maxrslcnt = 0; // default value @@ -3792,7 +3808,7 @@ writer.startDdm(CodePoint.PKGSNLST); for (int i = 0; i < numResults; i++) - writePKGNAMCSN(stmt.getResultSetPkgcnstknStr(i)); + writePKGNAMCSN(stmt.getResultSetPkgcnstkn(i).getBytes()); writer.endDdm(); writer.endDdmAndDss(); } @@ -4296,7 +4312,7 @@ { int codePoint; reader.markCollection(); - String pkgnamcsn = null; + Pkgnamcsn pkgnamcsn = null; codePoint = reader.getCodePoint(); while (codePoint != -1) { @@ -4385,7 +4401,7 @@ // NOTE: This codepoint is not in the DDM spec for 'EXCSQLSET', // but since it DOES get sent by jcc1.2, we have to have // a case for it... - String pkgnamcsn = parsePKGNAMCSN(); + Pkgnamcsn pkgnamcsn = parsePKGNAMCSN(); break; default: invalidCodePoint(codePoint); @@ -4612,72 +4628,91 @@ * PKGCNSTKN - RDB Package Consistency Token * PKGSN - RDB Package Section Number * + * @return Pkgnamcsn value * @throws DRDAProtocolException */ - private String parsePKGNAMCSN() throws DRDAProtocolException + private Pkgnamcsn parsePKGNAMCSN() throws DRDAProtocolException { - rdbnam = null; - rdbcolid = null; - pkgid = null; - secnumber = 0; - if (reader.getDdmLength() == CodePoint.PKGNAMCSN_LEN) { // This is a scalar object with the following fields - rdbnam = reader.readString(CodePoint.RDBNAM_LEN); + reader.readString(rdbnam, CodePoint.RDBNAM_LEN, true); if (SanityManager.DEBUG) trace("rdbnam = " + rdbnam); - rdbcolid = reader.readString(CodePoint.RDBCOLID_LEN); + reader.readString(rdbcolid, CodePoint.RDBCOLID_LEN, true); if (SanityManager.DEBUG) trace("rdbcolid = " + rdbcolid); - pkgid = reader.readString(CodePoint.PKGID_LEN); + reader.readString(pkgid, CodePoint.PKGID_LEN, true); if (SanityManager.DEBUG) trace("pkgid = " + pkgid); // we need to use the same UCS2 encoding, as this can be // bounced back to jcc (or keep the byte array) - pkgcnstknStr = reader.readString(CodePoint.PKGCNSTKN_LEN); + reader.readString(pkgcnstkn, CodePoint.PKGCNSTKN_LEN, false); if (SanityManager.DEBUG) - trace("pkgcnstkn = " + pkgcnstknStr); + trace("pkgcnstkn = " + pkgcnstkn); - secnumber = reader.readNetworkShort(); + pkgsn = reader.readNetworkShort(); if (SanityManager.DEBUG) - trace("secnumber = " + secnumber); + trace("pkgsn = " + pkgsn); } else // extended format { int length = reader.readNetworkShort(); if (length < CodePoint.RDBNAM_LEN || length > CodePoint.MAX_NAME) badObjectLength(CodePoint.RDBNAM); - rdbnam = reader.readString(length); + reader.readString(rdbnam, length, true); if (SanityManager.DEBUG) trace("rdbnam = " + rdbnam); //RDBCOLID can be variable length in this format length = reader.readNetworkShort(); - rdbcolid = reader.readString(length); + reader.readString(rdbcolid, length, true); if (SanityManager.DEBUG) trace("rdbcolid = " + rdbcolid); length = reader.readNetworkShort(); if (length != CodePoint.PKGID_LEN) badObjectLength(CodePoint.PKGID); - pkgid = reader.readString(CodePoint.PKGID_LEN); + reader.readString(pkgid, CodePoint.PKGID_LEN, true); if (SanityManager.DEBUG) trace("pkgid = " + pkgid); - pkgcnstknStr = reader.readString(CodePoint.PKGCNSTKN_LEN); + reader.readString(pkgcnstkn, CodePoint.PKGCNSTKN_LEN, false); if (SanityManager.DEBUG) - trace("pkgcnstkn = " + pkgcnstknStr); + trace("pkgcnstkn = " + pkgcnstkn); - secnumber = reader.readNetworkShort(); + pkgsn = reader.readNetworkShort(); if (SanityManager.DEBUG) - trace("secnumber = " + secnumber); + trace("pkgsn = " + pkgsn); } - // Note: This string is parsed by DRDAStatement.buildDB2CursorName() - return rdbnam + " " + rdbcolid + " " + pkgid + " " + secnumber + " " + pkgcnstknStr; + + // In most cases, the pkgnamcsn object is equal to the + // previously returned object. To avoid allocation of a new + // object in these cases, we first check to see if the old + // object can be reused. + if ((prevPkgnamcsn == null) || + rdbnam.wasModified() || + rdbcolid.wasModified() || + pkgid.wasModified() || + pkgcnstkn.wasModified() || + (prevPkgnamcsn.getPkgsn() != pkgsn)) + { + // The byte array returned by pkgcnstkn.getBytes() might + // be modified by DDMReader.readString() later, so we have + // to create a copy of the array. + byte[] token = new byte[pkgcnstkn.length()]; + System.arraycopy(pkgcnstkn.getBytes(), 0, token, 0, token.length); + + prevPkgnamcsn = + new Pkgnamcsn(rdbnam.toString(), rdbcolid.toString(), + pkgid.toString(), pkgsn, + new ConsistencyToken(token)); + } + + return prevPkgnamcsn; } /** @@ -4852,7 +4887,7 @@ */ private DRDAStatement parseCLSQRY() throws DRDAProtocolException, SQLException { - String pkgnamcsn = null; + Pkgnamcsn pkgnamcsn = null; reader.markCollection(); long qryinsid = 0; boolean gotQryinsid = false; Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAResultSet.java URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAResultSet.java?rev=368333&r1=368332&r2=368333&view=diff ============================================================================== --- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAResultSet.java (original) +++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAResultSet.java Thu Jan 12 02:09:50 2006 @@ -80,7 +80,7 @@ private ArrayList rsExtPositions; - protected String pkgcnstknStr; // Unique consistency token for ResultSet 0 + protected ConsistencyToken pkgcnstkn; // Unique consistency token for ResultSet 0 // splitQRYDTA is normally null. If it is non-null, it means that // the last QRYDTA response which was sent for this statement was @@ -119,9 +119,9 @@ * set consistency token for this resultSet * */ - protected void setPkgcnstknStr(String pkgcnstknStr) + protected void setPkgcnstkn(ConsistencyToken pkgcnstkn) { - this.pkgcnstknStr = pkgcnstknStr; + this.pkgcnstkn = pkgcnstkn; } @@ -460,7 +460,7 @@ { String s = indent + "***** DRDASResultSet toDebugString ******\n"; s += indent + "State:" + getStateString(state)+ "\n"; - s += indent + "pkgcnstknStr: {" +pkgcnstknStr + "}\n"; + s += indent + "pkgcnstkn: {" + pkgcnstkn + "}\n"; s += indent + "cursor Name: "; String cursorName = null; try { Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAStatement.java URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAStatement.java?rev=368333&r1=368332&r2=368333&view=diff ============================================================================== --- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAStatement.java (original) +++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAStatement.java Thu Jan 12 02:09:50 2006 @@ -61,10 +61,10 @@ protected String ccsidMBCEncoding; //Java encoding for CCSIDMBC protected Database database; // Database this statement is created for - private String pkgnamcsn; // Package name/section # and consistency token - protected String pkgcnstknStr; // Consistency token for the first result set + private Pkgnamcsn pkgnamcsn; // Package name/section # and consistency token + protected ConsistencyToken pkgcnstkn; // Consistency token for the first result set protected String pkgid; // package id - protected String sectionNumber; // section number + protected int pkgsn; // section number protected int withHoldCursor = -1; // hold cursor after commit attribute. protected int isolationLevel; //JCC isolation level for Statement protected String cursorName; @@ -628,16 +628,13 @@ * (see getStaticPackageIsolation) * @param pkgnamcsn package id section number and token from the client */ - protected void setPkgnamcsn(String pkgnamcsn) + protected void setPkgnamcsn(Pkgnamcsn pkgnamcsn) { this.pkgnamcsn = pkgnamcsn; // Store the consistency string for the first ResultSet. // this will be used to calculate consistency strings for the // other result sets. - StringTokenizer st = new StringTokenizer(pkgnamcsn); - st.nextToken(); // rdbnam (disregard) - st.nextToken(); // rdbcolid (disregard) - pkgid = st.nextToken(); // pkgid + pkgid = pkgnamcsn.getPkgid(); if (isDynamicPkgid(pkgid)) { @@ -661,15 +658,15 @@ // cursor name // trim the SYS off the pkgid so it wont' be in the cursor name String shortPkgid = pkgid.substring(pkgid.length() -5 , pkgid.length()); - sectionNumber = st.nextToken() ; - this.cursorName = "SQL_CUR" + shortPkgid + "C" + sectionNumber ; + pkgsn = pkgnamcsn.getPkgsn(); + this.cursorName = "SQL_CUR" + shortPkgid + "C" + pkgsn ; } else // static package { isolationLevel = getStaticPackageIsolation(pkgid); } - this.pkgcnstknStr = st.nextToken(); + this.pkgcnstkn = pkgnamcsn.getPkgcnstkn(); } @@ -695,7 +692,7 @@ * * @return pkgnamcsn */ - protected String getPkgnamcsn() + protected Pkgnamcsn getPkgnamcsn() { return pkgnamcsn; @@ -726,7 +723,7 @@ return currentDrdaRs.getResultSet(); else { - String key = (String) resultSetKeyList.get(rsNum); + ConsistencyToken key = (ConsistencyToken) resultSetKeyList.get(rsNum); return ((DRDAResultSet) (resultSetTable.get( key))).getResultSet(); } } @@ -762,8 +759,8 @@ */ protected void setCurrentDrdaResultSet(int rsNum) { - String consistToken = getResultSetPkgcnstknStr(rsNum); - if (currentDrdaRs.pkgcnstknStr == consistToken) + ConsistencyToken consistToken = getResultSetPkgcnstkn(rsNum); + if (currentDrdaRs.pkgcnstkn == consistToken) return; currentDrdaRs = getDrdaResultSet(consistToken); @@ -776,9 +773,11 @@ * consistency token * */ - protected void setCurrentDrdaResultSet(String pkgnamcsn) + protected void setCurrentDrdaResultSet(Pkgnamcsn pkgnamcsn) { - String consistToken = extractPkgcnstknStr(pkgnamcsn); + pkgid = pkgnamcsn.getPkgid(); + pkgsn = pkgnamcsn.getPkgsn(); + ConsistencyToken consistToken = pkgnamcsn.getPkgcnstkn(); DRDAResultSet newDrdaRs = getDrdaResultSet(consistToken); if (newDrdaRs != null) currentDrdaRs = newDrdaRs; @@ -789,11 +788,11 @@ * get DRDAResultSet by consistency token * */ - private DRDAResultSet getDrdaResultSet(String consistToken) + private DRDAResultSet getDrdaResultSet(ConsistencyToken consistToken) { if ( resultSetTable == null || (currentDrdaRs != null && - currentDrdaRs.pkgcnstknStr == consistToken )) + currentDrdaRs.pkgcnstkn == consistToken )) { return currentDrdaRs; } @@ -809,24 +808,10 @@ */ private DRDAResultSet getDrdaResultSet(int rsNum) { - String consistToken = getResultSetPkgcnstknStr(rsNum); + ConsistencyToken consistToken = getResultSetPkgcnstkn(rsNum); return getDrdaResultSet(consistToken); } - - /* - * get consistency token from pkgnamcsn - */ - private String extractPkgcnstknStr(String pkgnamcsn) - { - StringTokenizer st = new StringTokenizer(pkgnamcsn); - st.nextToken(); // rdbnam (disregard) - st.nextToken(); // rdbcolid (disregard) - pkgid = st.nextToken(); // pkgid - sectionNumber = st.nextToken() ; // secno - return st.nextToken(); - } - /** Add a new resultSet to this statement. * Set as the current result set if there is not an * existing current resultset. @@ -836,13 +821,13 @@ * For a single resultSet that is the same as the statement's * For multiple resultSets just the consistency token is changed */ - protected String addResultSet(ResultSet value, int holdValue) throws SQLException + protected ConsistencyToken addResultSet(ResultSet value, int holdValue) throws SQLException { DRDAResultSet newDrdaRs = null; int rsNum = numResultSets; - String newRsPkgcnstknStr = calculateResultSetPkgcnstknStr(rsNum); + ConsistencyToken newRsPkgcnstkn = calculateResultSetPkgcnstkn(rsNum); if (rsNum == 0) newDrdaRs = currentDrdaRs; @@ -858,22 +843,22 @@ // before we store our new resultSet. // For just a single resultSet we don't ever create the Hashtable. resultSetTable = new Hashtable(); - resultSetTable.put(pkgcnstknStr,currentDrdaRs); + resultSetTable.put(pkgcnstkn, currentDrdaRs); resultSetKeyList = new ArrayList(); - resultSetKeyList.add(0,pkgcnstknStr); + resultSetKeyList.add(0, pkgcnstkn); } - resultSetTable.put(newRsPkgcnstknStr,newDrdaRs); - resultSetKeyList.add(rsNum, newRsPkgcnstknStr); + resultSetTable.put(newRsPkgcnstkn, newDrdaRs); + resultSetKeyList.add(rsNum, newRsPkgcnstkn); } newDrdaRs.setResultSet(value); - newDrdaRs.setPkgcnstknStr(newRsPkgcnstknStr); + newDrdaRs.setPkgcnstkn(newRsPkgcnstkn); newDrdaRs.withHoldCursor = holdValue; setRsDefaultOptions(newDrdaRs); newDrdaRs.suspend(); numResultSets++; - return newRsPkgcnstknStr; + return newRsPkgcnstkn; } /** @@ -890,12 +875,12 @@ * @param rsNum result set starting with 0 * @return consistency token (key) for the result set */ - protected String getResultSetPkgcnstknStr(int rsNum) + protected ConsistencyToken getResultSetPkgcnstkn(int rsNum) { if (rsNum == 0) - return pkgcnstknStr; + return pkgcnstkn; else - return (String) resultSetKeyList.get(rsNum); + return (ConsistencyToken) resultSetKeyList.get(rsNum); } @@ -1243,7 +1228,7 @@ s += indent + ps; else { - s += indent + pkgid + sectionNumber ; + s += indent + pkgid + pkgsn ; s += "\t" + getSQLText(); } return s; @@ -1258,24 +1243,19 @@ * @return Consistency token for result set */ - protected String calculateResultSetPkgcnstknStr(int rsNum) + protected ConsistencyToken calculateResultSetPkgcnstkn(int rsNum) { - String consistToken = pkgcnstknStr; + ConsistencyToken consistToken = pkgcnstkn; - if (rsNum == 0 || pkgcnstknStr == null) + if (rsNum == 0 || pkgcnstkn == null) return consistToken; else { - try { - BigInteger consistTokenBi = - new BigInteger(consistToken.getBytes(NetworkServerControlImpl.DEFAULT_ENCODING)); - BigInteger rsNumBi = BigInteger.valueOf(rsNum); - consistTokenBi = consistTokenBi.subtract(rsNumBi); - consistToken = new String(consistTokenBi.toByteArray(),NetworkServerControlImpl.DEFAULT_ENCODING); - } - catch (UnsupportedEncodingException e) - {// Default encoding always supported - } + BigInteger consistTokenBi = + new BigInteger(consistToken.getBytes()); + BigInteger rsNumBi = BigInteger.valueOf(rsNum); + consistTokenBi = consistTokenBi.subtract(rsNumBi); + consistToken = new ConsistencyToken(consistTokenBi.toByteArray()); } return consistToken; } Added: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAString.java URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAString.java?rev=368333&view=auto ============================================================================== --- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAString.java (added) +++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAString.java Thu Jan 12 02:09:50 2006 @@ -0,0 +1,142 @@ +/* + * Derby - class org.apache.derby.impl.drda.DRDAString + * + * Copyright 2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You + * may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing + * permissions and limitations under the License. + * + */ + +package org.apache.derby.impl.drda; + +/** + * This class provides functionality for reusing buffers and strings + * when parsing DRDA packets. A byte array representing a string is + * stored internally. When the string is requested as a + * String object, the byte array is converted to a + * string, and the string is cached to avoid unnecessary conversion + * later. + */ +final class DRDAString { + /** Buffer representing the string. */ + private byte[] buffer; + /** Object used to convert byte buffer to string. */ + private final CcsidManager ccsidManager; + + /** True if the contents were modified in the previous call to + * setBytes. */ + private boolean modified; + + /** The previously generated string. */ + private String cachedString; + + /** + * Create a new DRDAString instance. + * + * @param m a CcsidManager value specifying + * which encoding is used + */ + public DRDAString(CcsidManager m) { + this.buffer = new byte[0]; + this.ccsidManager = m; + this.cachedString = null; + } + + /** + * Check whether the internal buffer contains the same data as + * another byte buffer. + * + * @param buf a byte array + * @param offset start position in the byte array + * @param size how many bytes to read from the byte array + * @return true if the internal buffer contains the + * same data as the specified byte array + */ + private boolean equalTo(byte[] buf, int offset, int size) { + int len = buffer.length; + if (len != size) return false; + for (int i = 0; i < len; ++i) { + if (buffer[i] != buf[i+offset]) return false; + } + return true; + } + + /** + * Modify the internal byte buffer. If the new data is equal to + * the old data, the cached values are not cleared. + * + * @param src the new bytes + * @param offset start offset + * @param size number of bytes to use + */ + public void setBytes(byte[] src, int offset, int size) { + if (equalTo(src, offset, size)) { + modified = false; + return; + } + if (buffer.length != size) { + buffer = new byte[size]; + } + System.arraycopy(src, offset, buffer, 0, size); + modified = true; + cachedString = null; + } + + /** + * Check whether the contents of the DRDAString were + * modified in the previous call to setBytes(). + * + * @return true if the contents were modified + */ + public boolean wasModified() { + return modified; + } + + /** + * Convert the internal byte array to a string. The string value + * is cached. + * + * @return a String value + */ + public String toString() { + if (cachedString == null) { + cachedString = + ccsidManager.convertToUCS2(buffer); + } + return cachedString; + } + + /** + * Return the length in bytes of the internal string + * representation. + * + * @return length of internal representation + */ + public int length() { + return buffer.length; + } + + /** + * Return the internal byte array. The returned array should not + * be modified, as it is used internally in + * DRDAString. The value of the array might be + * modified by subsequent calls to + * DRDAString.setBytes(). + * + * @return internal buffer + */ + public byte[] getBytes() { + return buffer; + } +} Propchange: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAString.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/Database.java URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/Database.java?rev=368333&r1=368332&r2=368333&view=diff ============================================================================== --- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/Database.java (original) +++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/Database.java Thu Jan 12 02:09:50 2006 @@ -71,7 +71,7 @@ DRDAStatement defaultStatement; // default statement used // for execute imm private DRDAStatement currentStatement; // current statement we are working on - Hashtable stmtTable; // Hash table for storing statements + private Hashtable stmtTable; // Hash table for storing statements boolean forXA = false; @@ -156,7 +156,7 @@ * @param pkgnamcsn package/ section # for statement * @return DRDAStatement */ - protected DRDAStatement getDefaultStatement(String pkgnamcsn) + protected DRDAStatement getDefaultStatement(Pkgnamcsn pkgnamcsn) { currentStatement = defaultStatement; currentStatement.setPkgnamcsn(pkgnamcsn); @@ -171,7 +171,7 @@ * @param pkgnamcsn Package name and section * @return DRDAStatement */ - protected DRDAStatement newDRDAStatement(String pkgnamcsn) + protected DRDAStatement newDRDAStatement(Pkgnamcsn pkgnamcsn) throws SQLException { DRDAStatement stmt = getDRDAStatement(pkgnamcsn); @@ -192,30 +192,14 @@ * @param pkgnamcsn - key to access statement * @return DRDAStatement */ - protected DRDAStatement getDRDAStatement(String pkgnamcsn) - throws SQLException - { - // Need to get the short version because resultSets have different - // corelation ids. - String key = getStmtKey(pkgnamcsn); - DRDAStatement newStmt = null; - - // If our current statement doesn't match,retrieve the statement - // and make it current if not null. - if (currentStatement == null || - !key.equals(getStmtKey(currentStatement.getPkgnamcsn()))); - { - newStmt = (DRDAStatement) stmtTable.get(key); - } - - if (newStmt != null) // don't blow away currentStatement if we can't find this one - currentStatement = newStmt; - else - return null; - - // Set the correct result set. - currentStatement.setCurrentDrdaResultSet(pkgnamcsn); - return currentStatement; + protected DRDAStatement getDRDAStatement(Pkgnamcsn pkgnamcsn) { + DRDAStatement newStmt = + (DRDAStatement) stmtTable.get(pkgnamcsn.getStatementKey()); + if (newStmt != null) { + currentStatement = newStmt; + currentStatement.setCurrentDrdaResultSet(pkgnamcsn); + } + return newStmt; } /** @@ -262,12 +246,12 @@ */ protected void storeStatement(DRDAStatement stmt) throws SQLException { - stmtTable.put(getStmtKey(stmt.getPkgnamcsn()), stmt); + stmtTable.put(stmt.getPkgnamcsn().getStatementKey(), stmt); } protected void removeStatement(DRDAStatement stmt) throws SQLException { - stmtTable.remove(stmt.getPkgnamcsn()); + stmtTable.remove(stmt.getPkgnamcsn().getStatementKey()); stmt.close(); } @@ -373,14 +357,6 @@ +"\t") +"\n"; } return s; - } - - - private String getStmtKey(String pkgnamcsn) - { - if (pkgnamcsn == null) - return null; - return pkgnamcsn.substring(0,pkgnamcsn.length() - CodePoint.PKGCNSTKN_LEN); } } Added: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/Pkgnamcsn.java URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/Pkgnamcsn.java?rev=368333&view=auto ============================================================================== --- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/Pkgnamcsn.java (added) +++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/Pkgnamcsn.java Thu Jan 12 02:09:50 2006 @@ -0,0 +1,198 @@ +/* + * Derby - class org.apache.derby.impl.drda.Pkgnamcsn + * + * Copyright 2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You + * may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing + * permissions and limitations under the License. + * + */ + +package org.apache.derby.impl.drda; + +/** + * Class representing a PKGNAMCSN object (RDB Package Name, + * Consistency Token, and Section Number). + */ +final class Pkgnamcsn { + /** Database name. */ + private final String rdbnam; + /** RDB Package Collection Identifier. */ + private final String rdbcolid; + /** RDB Package Identifier. */ + private final String pkgid; + /** RDB Package Section Number. */ + private final int pkgsn; + /** RDB Package Consistency Token. */ + private final ConsistencyToken pkgcnstkn; + + /** Object which can be used for hashing when the consistency + * token can be ignored. */ + private Object statementKey = null; + + /** + * Create a new Pkgnamcsn instance. + * + * @param rdbnam database name + * @param rdbcolid RDB Package Collection Identifier + * @param pkgid RDB Package Identifier + * @param pkgsn RDB Package Section Number + * @param pkgcnstkn RDB Package Consistency Token + */ + public Pkgnamcsn(String rdbnam, String rdbcolid, String pkgid, + int pkgsn, ConsistencyToken pkgcnstkn) { + this.rdbnam = rdbnam; + this.rdbcolid = rdbcolid; + this.pkgid = pkgid; + this.pkgsn = pkgsn; + this.pkgcnstkn = pkgcnstkn; + } + + /** + * Get RDBNAM. + * + * @return database name + */ + public String getRdbnam() { + return rdbnam; + } + + /** + * Get RDBCOLID. + * + * @return RDB Package Collection Identifier + */ + public String getRdbcolid() { + return rdbcolid; + } + + /** + * Get PKGID. + * + * @return RDB Package Identifier + */ + public String getPkgid() { + return pkgid; + } + + /** + * Get PKGSN. + * + * @return RDB Package Section Number + */ + public int getPkgsn() { + return pkgsn; + } + + /** + * Get PKGCNSTKN. + * + * @return RDB Package Consistency Token + */ + public ConsistencyToken getPkgcnstkn() { + return pkgcnstkn; + } + + /** + * Return string representation. + * + * @return a String value + */ + public String toString() { + return super.toString() + "(\"" + rdbnam + "\", \"" + + rdbcolid + "\", \"" + pkgid + "\", " + pkgsn + + ", " + pkgcnstkn + ")"; + } + + /** + * Return an object which can be used as a key in a hash table + * when the value of the consistency token can be ignored. The + * object has equals() and hashCode() + * methods which consider other objects returned from + * getStatementKey() equal if RDBNAM, RDBCOLID, PKGID + * and PKGSN are equal. + * + * @return an Object value + * @see Database#getDRDAStatement(Pkgnamcsn) + * @see Database#storeStatement(DRDAStatement) + * @see Database#removeStatement(DRDAStatement) + */ + public Object getStatementKey() { + if (statementKey == null) { + statementKey = new StatementKey(); + } + return statementKey; + } + + /** + * Class for objects used as keys in the hash table + * stmtTable found in the Database + * class. The equals() and hashCode() + * methods consider other StatementKey objects equal + * to this object if they are associated with a + * Pkgnamcsn object with the same values for RDBNAM, + * RDBCOLID, PKGID and PKGSN. + * + * @see Database + */ + private final class StatementKey { + /** Cached hash code. */ + private int hash = 0; + /** + * Check whether RDBNAM, RDBCOLID, PKGID and PKGSN of another + * StatementKey object matches this object. + * + * @param obj another object + * @return true if the objects are equal + */ + public boolean equals(Object obj) { + if (StatementKey.this == obj) { + return true; + } else if (obj instanceof StatementKey) { + return ((StatementKey) obj).isKeyFor(Pkgnamcsn.this); + } else { + return false; + } + } + /** + * Calculate hash code. + * + * @return hash code + */ + public int hashCode() { + if (hash == 0) { + hash = + rdbnam.hashCode() ^ + rdbcolid.hashCode() ^ + pkgid.hashCode() ^ + pkgsn; + } + return hash; + } + /** + * Check whether this object can be used as a key for a + * Pkgnamcsn object. + * + * @param p a Pkgnamcsn value + * @return true if this object can be key for the + * Pkgnamcsn object + */ + private boolean isKeyFor(Pkgnamcsn p) { + return + rdbnam.equals(p.rdbnam) && + rdbcolid.equals(p.rdbcolid) && + pkgid.equals(p.pkgid) && + pkgsn == p.pkgsn; + } + } +} Propchange: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/Pkgnamcsn.java ------------------------------------------------------------------------------ svn:eol-style = native