001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.execute.rts.RealHashScanStatistics
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.sql.execute.rts;
023:
024: import org.apache.derby.iapi.services.io.StoredFormatIds;
025: import org.apache.derby.iapi.util.PropertyUtil;
026:
027: import org.apache.derby.iapi.services.i18n.MessageService;
028: import org.apache.derby.iapi.reference.SQLState;
029:
030: import org.apache.derby.iapi.services.io.FormatableHashtable;
031: import org.apache.derby.iapi.services.io.FormatableProperties;
032:
033: import java.io.ObjectOutput;
034: import java.io.ObjectInput;
035: import java.io.IOException;
036:
037: import java.util.Enumeration;
038: import java.util.Hashtable;
039: import java.util.Properties;
040:
041: /**
042: ResultSetStatistics implemenation for HashScanResultSet.
043:
044: @author jerry
045:
046: */
047: public class RealHashScanStatistics extends
048: RealNoPutResultSetStatistics {
049:
050: /* Leave these fields public for object inspectors */
051: public boolean isConstraint;
052: public int hashtableSize;
053: public int[] hashKeyColumns;
054: public String isolationLevel;
055: public String lockString;
056: public String tableName;
057: public String indexName;
058: public String nextQualifiers;
059: public String scanQualifiers;
060: public String startPosition = null;
061: public String stopPosition = null;
062: public FormatableProperties scanProperties;
063:
064: // CONSTRUCTORS
065:
066: /**
067: *
068: *
069: */
070: public RealHashScanStatistics(int numOpens, int rowsSeen,
071: int rowsFiltered, long constructorTime, long openTime,
072: long nextTime, long closeTime, int resultSetNumber,
073: String tableName, String indexName, boolean isConstraint,
074: int hashtableSize, int[] hashKeyColumns,
075: String scanQualifiers, String nextQualifiers,
076: Properties scanProperties, String startPosition,
077: String stopPosition, String isolationLevel,
078: String lockString, double optimizerEstimatedRowCount,
079: double optimizerEstimatedCost) {
080: super (numOpens, rowsSeen, rowsFiltered, constructorTime,
081: openTime, nextTime, closeTime, resultSetNumber,
082: optimizerEstimatedRowCount, optimizerEstimatedCost);
083: this .tableName = tableName;
084: this .indexName = indexName;
085: this .isConstraint = isConstraint;
086: this .hashtableSize = hashtableSize;
087: this .hashKeyColumns = hashKeyColumns;
088: this .scanQualifiers = scanQualifiers;
089: this .nextQualifiers = nextQualifiers;
090: this .scanProperties = new FormatableProperties();
091: if (scanProperties != null) {
092: for (Enumeration e = scanProperties.keys(); e
093: .hasMoreElements();) {
094: String key = (String) e.nextElement();
095: this .scanProperties.put(key, scanProperties.get(key));
096: }
097: }
098: this .startPosition = startPosition;
099: this .stopPosition = stopPosition;
100: this .isolationLevel = isolationLevel;
101: this .lockString = lockString;
102: }
103:
104: // ResultSetStatistics methods
105:
106: /**
107: * Return the statement execution plan as a String.
108: *
109: * @param depth Indentation level.
110: *
111: * @return String The statement executio plan as a String.
112: */
113: public String getStatementExecutionPlanText(int depth) {
114: String header;
115: String isolationString = null;
116:
117: initFormatInfo(depth);
118:
119: if (indexName != null) {
120: header = indent
121: + MessageService
122: .getTextMessage(
123: SQLState.RTS_HASH_SCAN_RS_USING,
124: tableName,
125: MessageService
126: .getTextMessage(isConstraint ? SQLState.RTS_CONSTRAINT
127: : SQLState.RTS_INDEX),
128: indexName);
129: } else {
130: header = indent
131: + MessageService.getTextMessage(
132: SQLState.RTS_HASH_SCAN_RS, tableName);
133: }
134:
135: header = header
136: + " "
137: + MessageService.getTextMessage(SQLState.RTS_LOCKING,
138: isolationLevel, lockString) + ": \n";
139:
140: String scanInfo = indent
141: + MessageService.getTextMessage(SQLState.RTS_SCAN_INFO)
142: + ": \n"
143: + PropertyUtil
144: .sortProperties(scanProperties, subIndent);
145:
146: String hashKeyColumnString;
147: if (hashKeyColumns.length == 1) {
148: hashKeyColumnString = MessageService
149: .getTextMessage(SQLState.RTS_HASH_KEY)
150: + " " + hashKeyColumns[0];
151: } else {
152: hashKeyColumnString = MessageService
153: .getTextMessage(SQLState.RTS_HASH_KEYS)
154: + " (" + hashKeyColumns[0];
155: for (int index = 1; index < hashKeyColumns.length; index++) {
156: hashKeyColumnString = hashKeyColumnString + ","
157: + hashKeyColumns[index];
158: }
159: hashKeyColumnString = hashKeyColumnString + ")";
160: }
161:
162: return header
163: + indent
164: + MessageService.getTextMessage(SQLState.RTS_NUM_OPENS)
165: + " = "
166: + numOpens
167: + "\n"
168: + indent
169: + MessageService
170: .getTextMessage(SQLState.RTS_HASH_TABLE_SIZE)
171: + " = "
172: + hashtableSize
173: + "\n"
174: + indent
175: + hashKeyColumnString
176: + "\n"
177: + indent
178: + MessageService.getTextMessage(SQLState.RTS_ROWS_SEEN)
179: + " = "
180: + rowsSeen
181: + "\n"
182: + indent
183: + MessageService
184: .getTextMessage(SQLState.RTS_ROWS_FILTERED)
185: + " = "
186: + rowsFiltered
187: + "\n"
188: + dumpTimeStats(indent, subIndent)
189: + "\n"
190: + ((rowsSeen > 0) ? subIndent
191: + MessageService
192: .getTextMessage(SQLState.RTS_NEXT_TIME)
193: + " = " + (nextTime / rowsSeen) + "\n" : "")
194: + "\n"
195: + scanInfo
196: + subIndent
197: + MessageService
198: .getTextMessage(SQLState.RTS_START_POSITION)
199: + ": \n"
200: + startPosition
201: + subIndent
202: + MessageService
203: .getTextMessage(SQLState.RTS_STOP_POSITION)
204: + ": \n"
205: + stopPosition
206: + subIndent
207: + MessageService
208: .getTextMessage(SQLState.RTS_SCAN_QUALS)
209: + ":\n"
210: + scanQualifiers
211: + "\n"
212: + subIndent
213: + MessageService
214: .getTextMessage(SQLState.RTS_NEXT_QUALS)
215: + ":\n" + nextQualifiers + "\n" +
216: // RESOLVE - estimated row count and cost will eventually
217: // be displayed for all nodes
218: dumpEstimatedCosts(subIndent);
219: }
220:
221: /**
222: * Return information on the scan nodes from the statement execution
223: * plan as a String.
224: *
225: * @param depth Indentation level.
226: * @param tableName if not NULL then print information for this table only
227: *
228: * @return String The information on the scan nodes from the
229: * statement execution plan as a String.
230: */
231: public String getScanStatisticsText(String tableName, int depth) {
232: if ((tableName == null) || (tableName.equals(this .tableName)))
233: return getStatementExecutionPlanText(depth);
234: else
235: return (String) "";
236: }
237:
238: // Class implementation
239:
240: public String toString() {
241: return getStatementExecutionPlanText(0);
242: }
243:
244: /**
245: * If this node is on a database item (like a table or an index), then provide a
246: * string that describes the on item.
247: *
248: */
249: public String getNodeOn() {
250: return MessageService.getTextMessage(SQLState.RTS_ON_USING,
251: tableName, indexName);
252: }
253:
254: /**
255: * Format for display, a name for this node.
256: *
257: */
258: public String getNodeName() {
259: return MessageService.getTextMessage(SQLState.RTS_HASH_SCAN);
260: }
261: }
|