001: /*
002:
003: Derby - Class org.apache.derby.iapi.store.raw.FetchDescriptor
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.iapi.store.raw;
023:
024: import org.apache.derby.iapi.services.sanity.SanityManager;
025:
026: import org.apache.derby.iapi.store.access.Qualifier;
027:
028: import org.apache.derby.iapi.services.io.FormatableBitSet;
029:
030: /**
031:
032: FetchDescriptor is used to package up all the arguments necessary to
033: describe what rows and what row parts should be returned from the store
034: back to language as part of a fetch.
035: <p>
036: The FetchDescriptor may also contain scratch space used to process the
037: qualifiers passed in the scan. This scratch space will be used to cache
038: information about the qualifiers, valid column list, row size so that
039: calculations need only be done once per scan rather than every iteration.
040: **/
041:
042: public final class FetchDescriptor {
043:
044: /**************************************************************************
045: * Fields of the class
046: **************************************************************************
047: */
048: private int row_length;
049: private FormatableBitSet validColumns;
050: private Qualifier[][] qualifier_list;
051: private int[] materialized_cols;
052: private int maxFetchColumnId;
053:
054: private static final int ZERO_FILL_LENGTH = 100;
055: private static final int[] zero_fill_array = new int[ZERO_FILL_LENGTH];
056:
057: // use int arrays rather than FormatableBitSet's to get most efficient processing
058: // in performance critical loop which reads columns from page.
059: private int[] validColumnsArray;
060:
061: /**************************************************************************
062: * Constructors for This class:
063: **************************************************************************
064: */
065: FetchDescriptor() {
066: }
067:
068: public FetchDescriptor(int input_row_length) {
069: row_length = input_row_length;
070: }
071:
072: public FetchDescriptor(int input_row_length,
073: int single_valid_column_number) {
074: row_length = input_row_length;
075: maxFetchColumnId = single_valid_column_number;
076: validColumnsArray = new int[maxFetchColumnId + 1];
077: validColumnsArray[single_valid_column_number] = 1;
078: }
079:
080: public FetchDescriptor(int input_row_length,
081: FormatableBitSet input_validColumns,
082: Qualifier[][] input_qualifier_list) {
083: row_length = input_row_length;
084: qualifier_list = input_qualifier_list;
085:
086: if (qualifier_list != null) {
087: materialized_cols = new int[row_length];
088: }
089:
090: setValidColumns(input_validColumns);
091: }
092:
093: /**************************************************************************
094: * Public Methods of This class:
095: **************************************************************************
096: */
097:
098: /**
099: * Return the column list bit map.
100: * <p>
101: * A description of which columns to return from every fetch in the scan.
102: * A row array and a valid column bit map work together to describe the row
103: * to be returned by the scan - see RowUtil for description of how these two
104: * parameters work together to describe a "row".
105: *
106: * @return The column list bit map.
107: *
108: * @exception StandardException Standard exception policy.
109: **/
110: public final FormatableBitSet getValidColumns() {
111: return (validColumns);
112: }
113:
114: public final int[] getValidColumnsArray() {
115: return (validColumnsArray);
116: }
117:
118: public final void setValidColumns(
119: FormatableBitSet input_validColumns) {
120: validColumns = input_validColumns;
121:
122: setMaxFetchColumnId();
123:
124: if (validColumns != null) {
125: validColumnsArray = new int[maxFetchColumnId + 1];
126: for (int i = maxFetchColumnId; i >= 0; i--) {
127: validColumnsArray[i] = ((validColumns.isSet(i)) ? 1 : 0);
128: }
129: }
130: }
131:
132: /**
133: * Return the qualifier array.
134: * <p>
135: * Return the array of qualifiers in this FetchDescriptor. The array of
136: * qualifiers which, applied to each key, restricts the rows returned by
137: * the scan. Rows for which any one of the qualifiers returns false are
138: * not returned by the scan. If null, all rows are returned. Qualifiers
139: * can only reference columns which are included in the scanColumnList.
140: * The column id that a qualifier returns in the column id the table, not
141: * the column id in the partial row being returned.
142: * <p>
143: * A null qualifier array means there are no qualifiers.
144: *
145: * @return The qualifier array, it may be null.
146: *
147: * @exception StandardException Standard exception policy.
148: **/
149: public final Qualifier[][] getQualifierList() {
150: return (qualifier_list);
151: }
152:
153: /**
154: * Internal to store.
155: **/
156: public final int[] getMaterializedColumns() {
157: return (materialized_cols);
158: }
159:
160: /**
161: * Internal to store.
162: **/
163: public final int getMaxFetchColumnId() {
164: return (maxFetchColumnId);
165: }
166:
167: private final void setMaxFetchColumnId() {
168: maxFetchColumnId = row_length - 1;
169:
170: if (validColumns != null) {
171: int vCol_length = validColumns.getLength();
172:
173: if (vCol_length < maxFetchColumnId + 1)
174: maxFetchColumnId = vCol_length - 1;
175:
176: for (; maxFetchColumnId >= 0; maxFetchColumnId--) {
177: if (validColumns.isSet(maxFetchColumnId))
178: break;
179: }
180: }
181: }
182:
183: /**
184: * Internal to store.
185: **/
186: public final void reset() {
187: int[] cols = materialized_cols;
188:
189: if (cols != null) {
190: // New row, clear the array map.
191:
192: /*
193: * this was too slow.
194: for (int i = cols.length - 1; i >= 0;)
195: {
196:
197: cols[i--] = 0;
198: }
199: */
200:
201: if (cols.length <= ZERO_FILL_LENGTH) {
202: // fast path the usual case.
203: System.arraycopy(zero_fill_array, 0, cols, 0,
204: cols.length);
205: } else {
206: int offset = 0;
207: int howMany = cols.length;
208:
209: while (howMany > 0) {
210: int count = howMany > zero_fill_array.length ? zero_fill_array.length
211: : howMany;
212:
213: System.arraycopy(zero_fill_array, 0, cols, offset,
214: count);
215: howMany -= count;
216: offset += count;
217: }
218: }
219: }
220: }
221: }
|