001: /*
002:
003: Derby - Class org.apache.derby.impl.store.access.btree.SearchParameters
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.store.access.btree;
023:
024: import java.io.PrintStream;
025:
026: import org.apache.derby.iapi.services.sanity.SanityManager;
027:
028: import org.apache.derby.iapi.error.StandardException;
029:
030: import org.apache.derby.iapi.store.access.ScanController;
031: import org.apache.derby.iapi.store.access.RowUtil;
032:
033: import org.apache.derby.iapi.types.DataValueDescriptor;
034:
035: /**
036:
037: Parameters that are passed down during a recursive b-tree search.
038: This class is intended to be used as a struct, primarily to make
039: it easier to pass a number of search parameters around, and also
040: to make it easy to re-use objects and not re-allocate.
041:
042: **/
043:
044: public class SearchParameters {
045:
046: /**
047: * Position on key just left of a sequence of partial key matches.
048: * Used by scan which will then start scan on next key.
049: **/
050: public static final int POSITION_LEFT_OF_PARTIAL_KEY_MATCH = 1;
051:
052: /**
053: * Position on last key in a sequence of partial key matches.
054: * Used by scan which will then start scan on next key.
055: **/
056: public static final int POSITION_RIGHT_OF_PARTIAL_KEY_MATCH = -1;
057:
058: /**
059: The key being searched for. Never intended to be modified
060: for the lifetime of the object.
061: **/
062: public DataValueDescriptor[] searchKey;
063:
064: /**
065: Value to return in comparisons where partial key matches exactly
066: the partial key of a row. Use this parameter to control where
067: in a duplicate partial key list to position the search.
068:
069: Here are some examples:
070:
071: Assume: dataset of {1,0}, {5,1}, {5,2}, {6,4}; and partial key of {5}.
072:
073:
074: If the scan is GE , then the scan intially wants to position
075: on {1,0} (one before first qualifying row) - In this case when a partial
076: match is found we want to return 1 when we hit {5,1}; but if the
077: searchOperator is GT, then we want to return -1 on {5,1}, {5,2}, and then
078: return 1 on {6,4}.
079:
080:
081: partial_key_match_op = POSITION_LEFT_OF_PARTIAL_KEY_MATCH:
082: Scan is looking for GE the partial key, so position the scan to the
083: left of any partial key that exactly matches the partial key.
084: If the scan is GE , then the scan intially wants to position
085: on {1,0} (one before first qualifying row) - In this case when a partial
086: match is found we want to return 1 when we hit {5,1}.
087:
088: partial_key_match_op = POSITION_RIGHT_OF_PARTIAL_KEY_MATCH:
089: Scan is looking for GT the partial key, so position the scan to the
090: right of any partial key that exactly matches the partial key.
091: If the scan is GT, then the scan intially wants to position
092: on {5,2} (one before first qualifying row) - In this case when a partial
093: match is found we want to return -1 when we hit on {5,1}, {5,2}, and then
094: return 1 on {6,4}.
095:
096: partial_key_match_op = 0:
097: Scan does not care where in a set of duplicate partial keys to position
098: to (not used currently).
099: **/
100: int partial_key_match_op;
101:
102: /**
103: An index row with the correct types for the index,
104: into which rows are read during the search.
105: Rows are read into the template during a page search, but
106: they will be overwritten; there is only one template per
107: search.
108: **/
109: public DataValueDescriptor[] template;
110:
111: /**
112: The b-tree this search is for. Effectively read-only for the
113: lifetime of this object.
114: **/
115: public OpenBTree btree;
116:
117: /**
118: The resulting slot from the search. Updated when the search completes.
119: **/
120: public int resultSlot;
121:
122: /**
123: Whether the row found exactly matched the searchKey. Updated
124: when the search completes.
125: **/
126: public boolean resultExact;
127:
128: /**
129: Whether the search is for the optimizer, to determine range of scan.
130: **/
131: public boolean searchForOptimizer;
132:
133: /**
134: If this is an optimizer search, the fraction of rows that are left of
135: the current search. When the search completes this number multiplied by
136: the number of leaf rows in the table is the number of rows left of
137: the result slot in the search.
138: **/
139: public float left_fraction;
140:
141: /**
142: If this is an optimizer search, the fraction of rows that are "in" the
143: the current search. This number is used as we descend down the tree to
144: track the percentage of rows that we think are in the current subtree
145: defined by all leaf's that can be reached from the current branch.
146: **/
147: public float current_fraction;
148:
149: /**
150: Construct search parameters.
151:
152: @exception StandardException Standard exception policy.
153: **/
154: public SearchParameters(DataValueDescriptor[] searchKey,
155: int partial_key_match_op, DataValueDescriptor[] template,
156: OpenBTree btree, boolean searchForOptimizer)
157: throws StandardException {
158: this .searchKey = searchKey;
159: this .partial_key_match_op = partial_key_match_op;
160: this .template = template;
161: this .btree = btree;
162: this .resultSlot = 0;
163: this .resultExact = false;
164: this .searchForOptimizer = searchForOptimizer;
165:
166: if (this .searchForOptimizer) {
167: this .left_fraction = 0;
168: this .current_fraction = 1;
169: }
170:
171: if (SanityManager.DEBUG) {
172: // RESOLVE - this is ugly but has caught some problems.
173: SanityManager.ASSERT(partial_key_match_op == -1
174: || partial_key_match_op == 1);
175: }
176: }
177:
178: public String toString() {
179: if (SanityManager.DEBUG) {
180: String string = "key = "
181: + RowUtil.toString(searchKey)
182: + ";"
183: + "op = "
184: + (partial_key_match_op == 1 ? "GE"
185: : (partial_key_match_op == -1 ? "GT"
186: : "BAD OP:" + partial_key_match_op))
187: + ";" + "template = "
188: + RowUtil.toString(template)
189: + ";"
190: +
191: // RESOLVE (mikem) - do we want to print out btree?
192: // "btree = " + btree + ";" +
193: "Slot = " + resultSlot + ";" + "Exact = "
194: + resultExact + ";";
195:
196: return (string);
197: } else {
198: return (null);
199: }
200: }
201: }
|