KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > iapi > store > access > StoreCostController


1 /*
2
3    Derby - Class org.apache.derby.iapi.store.access.StoreCostController
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.iapi.store.access;
23
24 import org.apache.derby.iapi.types.DataValueDescriptor;
25
26 import org.apache.derby.iapi.types.RowLocation;
27
28 import org.apache.derby.iapi.error.StandardException;
29 import org.apache.derby.iapi.services.io.FormatableBitSet;
30
31 /**
32
33 The StoreCostController interface provides methods that an access client
34 (most likely the system optimizer) can use to get store's estimated cost of
35 various operations on the conglomerate the StoreCostController was opened
36 for.
37 <p>
38 It is likely that the implementation of StoreCostController will open
39 the conglomerate and will leave the conglomerate open until the
40 StoreCostController is closed. This represents a significant amount of
41 work, so the caller if possible should attempt to open the StoreCostController
42 once per unit of work and rather than close and reopen the controller. For
43 instance if the optimizer needs to cost 2 different scans against a single
44 conglomerate, it should use one instance of the StoreCostController.
45 <p>
46 The locking behavior of the implementation of a StoreCostController is
47 undefined, it may or may not get locks on the underlying conglomerate. It
48 may or may not hold locks until end of transaction.
49 An optimal implementation will not get any locks on the underlying
50 conglomerate, thus allowing concurrent access to the table by a executing
51 query while another query is optimizing.
52 <p>
53 @see TransactionController#openStoreCost
54 @see RowCountable
55
56 **/

57
58 public interface StoreCostController extends RowCountable
59 {
60     // The folllowing constants should only be used by StoreCostController
61
// implementors.
62

63     // The base cost to fetch a cached page, and select a single
64
// heap row by RowLocation, fetching 0 columns.
65
public static final double BASE_CACHED_ROW_FETCH_COST = 0.17;
66
67     // The base cost to page in a page from disk to cache, and select a single
68
// heap row by RowLocation, fetching 0 columns.
69
public static final double BASE_UNCACHED_ROW_FETCH_COST = 1.5;
70
71     // The base cost to fetch a single row as part of group fetch scan with
72
// 16 rows per group, fetching 0 columns.
73
public static final double BASE_GROUPSCAN_ROW_COST = 0.12;
74
75     // The base cost to fetch a single row as part of a nongroup fetch scan
76
// fetching 0 columns.
77
public static final double BASE_NONGROUPSCAN_ROW_FETCH_COST = 0.25;
78
79     // The base cost to fetch a single row as part of a nongroup fetch scan
80
// fetching 1 columns.
81
public static final double BASE_HASHSCAN_ROW_FETCH_COST = 0.14;
82
83
84     // This is an estimate of the per byte cost associated with fetching the
85
// row from the table, it just assumes the cost scales per byte which is
86
// probably not true, but a good first guess. It is meant to be added
87
// to the above costs - for instance the cost of fetching a 100 byte
88
// row from a page assumed to be in the cache is:
89
// BASE_CACHED_ROW_FETCH_COST + (100 * BASE_ROW_PER_BYTECOST)
90
//
91
// The estimate for this number is the cost of retrieving all cost from
92
// a cached 100 byte row - the cost of getting 0 colums from cached row.
93
public static final double BASE_ROW_PER_BYTECOST = (0.56 - 0.16) / 100;
94
95     /**
96      * Indicates that access to the page necessary to fulfill the fetch
97      * request is likely to be a page "recently" used. See
98      * getFetchFromFullKeyCost() and getScanCost().
99      **/

100     public static final int STORECOST_CLUSTERED = 0x01;
101
102     /**
103      * Used for the scan_type parameter to the getScanCost() routine.
104      * STORECOST_SCAN_NORMAL indicates that the scan will use the standard
105      * next/fetch, where each fetch can retrieve 1 or many rows (if
106      * fetchNextGroup() interface is used).
107      **/

108     public static final int STORECOST_SCAN_SET = 0x01;
109
110
111     /**
112      * Used for the scan_type parameter to the getScanCost() routine.
113      * STORECOST_SCAN_SET - The entire result set will be retrieved using the
114      * the fetchSet() interface.
115      **/

116     public static final int STORECOST_SCAN_NORMAL = 0x02;
117
118     /**
119      * Close the controller.
120      * <p>
121      * Close the open controller. This method always succeeds, and never
122      * throws any exceptions. Callers must not use the StoreCostController
123      * Cost controller after closing it; they are strongly advised to clear
124      * out the scan controller reference after closing.
125      * <p>
126      *
127      * @exception StandardException Standard exception policy.
128      **/

129     void close()
130         throws StandardException;
131
132     /**
133      * Return the cost of calling ConglomerateController.fetch().
134      * <p>
135      * Return the estimated cost of calling ConglomerateController.fetch()
136      * on the current conglomerate. This gives the cost of finding a record
137      * in the conglomerate given the exact RowLocation of the record in
138      * question.
139      * <p>
140      * The validColumns parameter describe what kind of row
141      * is being fetched, ie. it may be cheaper to fetch a partial row than a
142      * complete row.
143      * <p>
144      *
145      *
146      * @param validColumns A description of which columns to return from
147      * row on the page into "templateRow." templateRow,
148      * and validColumns work together to
149      * describe the row to be returned by the fetch -
150      * see RowUtil for description of how these three
151      * parameters work together to describe a fetched
152      * "row".
153      *
154      * @param access_type Describe the type of access the query will be
155      * performing to the ConglomerateController.
156      *
157      * STORECOST_CLUSTERED - The location of one fetch
158      * is likely clustered "close" to the next
159      * fetch. For instance if the query plan were
160      * to sort the RowLocations of a heap and then
161      * use those RowLocations sequentially to
162      * probe into the heap, then this flag should
163      * be specified. If this flag is not set then
164      * access to the table is assumed to be
165      * random - ie. the type of access one gets
166      * if you scan an index and probe each row
167      * in turn into the base table is "random".
168      *
169      *
170      * @return The cost of the fetch.
171      *
172      * @exception StandardException Standard exception policy.
173      *
174      * @see RowUtil
175      **/

176     public double getFetchFromRowLocationCost(
177     FormatableBitSet validColumns,
178     int access_type)
179         throws StandardException;
180
181     /**
182      * Return the cost of exact key lookup.
183      * <p>
184      * Return the estimated cost of calling ScanController.fetch()
185      * on the current conglomerate, with start and stop positions set such
186      * that an exact match is expected.
187      * <p>
188      * This call returns the cost of a fetchNext() performed on a scan which
189      * has been positioned with a start position which specifies exact match
190      * on all keys in the row.
191      * <p>
192      * Example:
193      * <p>
194      * In the case of a btree this call can be used to determine the cost of
195      * doing an exact probe into btree, giving all key columns. This cost
196      * can be used if the client knows it will be doing an exact key probe
197      * but does not have the key's at optimize time to use to make a call to
198      * getScanCost()
199      * <p>
200      *
201      *
202      * @param validColumns A description of which columns to return from
203      * row on the page into "templateRow." templateRow,
204      * and validColumns work together to
205      * describe the row to be returned by the fetch -
206      * see RowUtil for description of how these three
207      * parameters work together to describe a fetched
208      * "row".
209      *
210      * @param access_type Describe the type of access the query will be
211      * performing to the ScanController.
212      *
213      * STORECOST_CLUSTERED - The location of one scan
214      * is likely clustered "close" to the previous
215      * scan. For instance if the query plan were
216      * to used repeated "reopenScan()'s" to probe
217      * for the next key in an index, then this flag
218      * should be be specified. If this flag is not
219      * set then each scan will be costed independant
220      * of any other predicted scan access.
221      *
222      * @return The cost of the fetch.
223      *
224      * @exception StandardException Standard exception policy.
225      *
226      * @see RowUtil
227      **/

228     public double getFetchFromFullKeyCost(
229     FormatableBitSet validColumns,
230     int access_type)
231         throws StandardException;
232
233     /**
234      * Calculate the cost of a scan.
235      * <p>
236      * Cause this object to calculate the cost of performing the described
237      * scan. The interface is setup such that first a call is made to
238      * calcualteScanCost(), and then subsequent calls to accessor routines
239      * are made to get various pieces of information about the cost of
240      * the scan.
241      * <p>
242      * For the purposes of costing this routine is going to assume that
243      * a page will remain in cache between the time one next()/fetchNext()
244      * call and a subsequent next()/fetchNext() call is made within a scan.
245      * <p>
246      * The result of costing the scan is placed in the "cost_result".
247      * The cost of the scan is stored by calling
248      * cost_result.setEstimatedCost(cost).
249      * The estimated row count is stored by calling
250      * cost_result.setEstimatedRowCount(row_count).
251      * <p>
252      * The estimated cost of the scan assumes the caller will
253      * execute a fetchNext() loop for every row that qualifies between
254      * start and stop position. Note that this cost is different than
255      * execution a next(),fetch() loop; or if the scan is going to be
256      * terminated by client prior to reaching the stop condition.
257      * <p>
258      * The estimated number of rows returned from the scan
259      * assumes the caller will execute a fetchNext() loop for every
260      * row that qualifies between start and stop position.
261      * <p>
262      *
263      *
264      * @param scan_type The type of scan that will be executed. There
265      * are currently 2 types:
266      * STORECOST_SCAN_NORMAL - scans will be executed
267      * using the standard next/fetch, where each fetch
268      * can retrieve 1 or many rows (if fetchNextGroup()
269      * interface is used).
270      *
271      * STORECOST_SCAN_SET - The entire result set will
272      * be retrieved using the the fetchSet() interface.
273      *
274      * @param row_count Estimated total row count of the table. The
275      * current system tracks row counts in heaps better
276      * than btree's (btree's have "rows" which are not
277      * user rows - branch rows, control rows), so
278      * if available the client should
279      * pass in the base table's row count into this
280      * routine to be used as the index's row count.
281      * If the caller has no idea, pass in -1.
282      *
283      * @param group_size The number of rows to be returned by a single
284      * fetch call for STORECOST_SCAN_NORMAL scans.
285      *
286      * @param forUpdate Should be true if the caller intends to update
287      * through the scan.
288      *
289      * @param scanColumnList A description of which columns to return from
290      * every fetch in the scan. template,
291      * and scanColumnList work together
292      * to describe the row to be returned by the scan -
293      * see RowUtil for description of how these three
294      * parameters work together to describe a "row".
295      *
296      * @param template A prototypical row which the scan may use to
297      * maintain its position in the conglomerate. Not
298      * all access method scan types will require this,
299      * if they don't it's ok to pass in null.
300      * In order to scan a conglomerate one must
301      * allocate 2 separate "row" templates. The "row"
302      * template passed into openScan is for the private
303      * use of the scan itself, and no access to it
304      * should be made by the caller while the scan is
305      * still open. Because of this the scanner must
306      * allocate another "row" template to hold the
307      * values returned from fetch(). Note that this
308      * template must be for the full row, whether a
309      * partial row scan is being executed or not.
310      *
311      * @param startKeyValue An indexable row which holds a (partial) key
312      * value which, in combination with the
313      * startSearchOperator, defines the starting
314      * position of the scan. If null, the starting
315      * position of the scan is the first row of the
316      * conglomerate. The startKeyValue must only
317      * reference columns included in the scanColumnList.
318      *
319      * @param startSearchOperator
320      * an operator which defines how the startKeyValue
321      * is to be searched for. If startSearchOperation
322      * is ScanController.GE, the scan starts on the
323      * first row which is greater than or equal to the
324      * startKeyValue. If startSearchOperation is
325      * ScanController.GT, the scan starts on the first
326      * row whose key is greater than startKeyValue. The
327      * startSearchOperation parameter is ignored if the
328      * startKeyValue parameter is null.
329      *
330      * @param stopKeyValue An indexable row which holds a (partial) key
331      * value which, in combination with the
332      * stopSearchOperator, defines the ending position
333      * of the scan. If null, the ending position of the
334      * scan is the last row of the conglomerate. The
335      * stopKeyValue must only reference columns included
336      * in the scanColumnList.
337      *
338      * @param stopSearchOperator
339      * an operator which defines how the stopKeyValue
340      * is used to determine the scan stopping position.
341      * If stopSearchOperation is ScanController.GE, the
342      * scan stops just before the first row which is
343      * greater than or equal to the stopKeyValue. If
344      * stopSearchOperation is ScanController.GT, the
345      * scan stops just before the first row whose key
346      * is greater than startKeyValue. The
347      * stopSearchOperation parameter is ignored if the
348      * stopKeyValue parameter is null.
349      *
350      *
351      * @param access_type Describe the type of access the query will be
352      * performing to the ScanController.
353      *
354      * STORECOST_CLUSTERED - The location of one scan
355      * is likely clustered "close" to the previous
356      * scan. For instance if the query plan were
357      * to used repeated "reopenScan()'s" to probe
358      * for the next key in an index, then this flag
359      * should be be specified. If this flag is not
360      * set then each scan will be costed independant
361      * of any other predicted scan access.
362      *
363      *
364      * @exception StandardException Standard exception policy.
365      *
366      * @see RowUtil
367      **/

368     public void getScanCost(
369         int scan_type,
370         long row_count,
371         int group_size,
372         boolean forUpdate,
373         FormatableBitSet scanColumnList,
374         DataValueDescriptor[] template,
375         DataValueDescriptor[] startKeyValue,
376         int startSearchOperator,
377         DataValueDescriptor[] stopKeyValue,
378         int stopSearchOperator,
379         boolean reopen_scan,
380         int access_type,
381         StoreCostResult cost_result)
382             throws StandardException;
383
384     /**
385      * Return an "empty" row location object of the correct type.
386      * <p>
387      *
388      * @return The empty Rowlocation.
389      *
390      * @exception StandardException Standard exception policy.
391      **/

392     RowLocation newRowLocationTemplate()
393         throws StandardException;
394 }
395
Popular Tags