KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > store > access > btree > D_BTreeController


1 /*
2
3    Derby - Class org.apache.derby.impl.store.access.btree.D_BTreeController
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.impl.store.access.btree;
23
24 import org.apache.derby.iapi.reference.Property;
25
26 import org.apache.derby.iapi.services.context.ContextManager;
27 import org.apache.derby.iapi.services.diag.Diagnosticable;
28 import org.apache.derby.iapi.services.diag.DiagnosticableGeneric;
29 import org.apache.derby.iapi.services.diag.DiagnosticUtil;
30 import org.apache.derby.iapi.services.monitor.Monitor;
31 import org.apache.derby.iapi.services.sanity.SanityManager;
32 import org.apache.derby.iapi.db.Database;
33 import org.apache.derby.iapi.error.StandardException;
34 import org.apache.derby.iapi.store.access.AccessFactory;
35 import org.apache.derby.iapi.store.access.ConglomerateController;
36 import org.apache.derby.iapi.store.access.TransactionController;
37 import org.apache.derby.iapi.store.raw.ContainerHandle;
38 import org.apache.derby.iapi.store.raw.Page;
39
40 import java.util.Properties JavaDoc;
41
42 /**
43
44   A BTreeDiag class is a "helper" class for the rest of the btree generic
45   code. It is separated into a separate class so that it can be compiled
46   out if necessary (or loaded at runtime if necessary).
47
48   <p>
49   more info.
50 **/

51 class LevelInfo
52 {
53     public int num_pages = 0; // number of pages in heap.
54
public int num_overflow_pgs = 0; // number of overflow pages heap.
55
public int num_entries = 0; // number recs on page
56
public int num_deleted = 0; // number of recs on page marked deleted.
57
public long max_pageno = 0; // biggest page number allocated
58
public long num_free_bytes = 0; // number of free bytes on the pages.
59
public long num_res_bytes = 0; // number of reserved bytes on the pages.
60
public long num_overflow_rows = 0; // number of over flow rows on page.
61
public long num_rowsize_bytes = 0; // number of bytes in rows.
62
public long num_slottab_bytes = 0; // number of bytes in slot table.
63
public long min_rowsize_bytes = Long.MAX_VALUE; // length of shortest row.
64
public long max_rowsize_bytes = Long.MIN_VALUE; // length of longest row.
65
}
66
67 public class D_BTreeController extends DiagnosticableGeneric
68 {
69     /* Private/Protected methods of This class: */
70     private static void diag_page(
71     OpenBTree open_btree,
72     ControlRow control_row,
73     Properties JavaDoc prop,
74     LevelInfo level_info[])
75         throws StandardException
76     {
77         LevelInfo li = level_info[control_row.getLevel()];
78         Page page = control_row.page;
79
80
81
82         li.num_pages++;
83         li.num_entries += (page.recordCount() - 1);
84         li.num_deleted += (page.recordCount() - page.nonDeletedRecordCount());
85         li.max_pageno = Math.max(li.max_pageno, page.getPageNumber());
86
87         DiagnosticUtil.findDiagnostic(page).diag_detail(prop);
88
89
90         DiagnosticUtil.findDiagnostic(page).diag_detail(prop);
91
92         // number of free bytes on page.
93
int free_bytes =
94             Integer.parseInt(prop.getProperty(Page.DIAG_BYTES_FREE));
95
96         li.num_free_bytes += free_bytes;
97
98         // number of bytes reserved on page.
99
int res_bytes =
100             Integer.parseInt(prop.getProperty(Page.DIAG_BYTES_RESERVED));
101
102         li.num_res_bytes += res_bytes;
103
104         // overflow rows.
105
int overflow =
106             Integer.parseInt(prop.getProperty(Page.DIAG_NUMOVERFLOWED));
107
108         li.num_overflow_rows += overflow;
109
110         // size of rows.
111
int rowsize =
112             Integer.parseInt(prop.getProperty(Page.DIAG_ROWSIZE));
113
114         li.num_rowsize_bytes += rowsize;
115
116         // size of slot table.
117
int slottable_size =
118             Integer.parseInt(prop.getProperty(Page.DIAG_SLOTTABLE_SIZE));
119
120         li.num_slottab_bytes += slottable_size;
121
122         // minimum row size.
123
int min_rowsize =
124             Integer.parseInt(prop.getProperty(Page.DIAG_MINROWSIZE));
125
126         li.min_rowsize_bytes = Math.min(li.min_rowsize_bytes, min_rowsize);
127
128         // maximum row size.
129
int max_rowsize =
130             Integer.parseInt(prop.getProperty(Page.DIAG_MAXROWSIZE));
131
132         li.max_rowsize_bytes = Math.max(li.max_rowsize_bytes, max_rowsize);
133     }
134
135     private static void diag_level(
136     OpenBTree open_btree,
137     ControlRow control_row,
138     Properties JavaDoc prop,
139     LevelInfo level_info[])
140         throws StandardException
141     {
142         ControlRow child = null;
143
144         diag_page(open_btree, control_row, prop, level_info);
145
146         try
147         {
148             child = control_row.getLeftChild(open_btree);
149
150             if (child != null)
151             {
152                 // this is a branch page.
153
if (SanityManager.DEBUG)
154                     SanityManager.ASSERT(
155                         control_row instanceof BranchControlRow);
156
157                 BranchControlRow branch = (BranchControlRow) control_row;
158
159                 diag_level(open_btree, child, prop, level_info);
160                 child.release();
161                 child = null;
162
163                 int numslots = branch.page.recordCount();
164                 for (int slot = 1; slot < numslots; slot++)
165                 {
166                     child = branch.getChildPageAtSlot(open_btree, slot);
167                     diag_level(open_btree, child, prop, level_info);
168                     child.release();
169                     child = null;
170                 }
171             }
172         }
173         finally
174         {
175             if (child != null)
176                 child.release();
177         }
178
179         return;
180     }
181
182     private static String JavaDoc out_summary(
183     String JavaDoc hdr,
184     long value,
185     double ratio,
186     String JavaDoc ratio_desc)
187     {
188         String JavaDoc double_str = "" + ratio;
189
190         String JavaDoc short_str = double_str.substring(
191             0, Math.min(double_str.lastIndexOf(".") + 3, double_str.length()));
192
193         return(
194             "\t" + hdr + value + ".\t(" + short_str +
195             " " + ratio_desc + ").\n");
196     }
197
198     private static String JavaDoc diag_onelevel(
199     Properties JavaDoc prop,
200     LevelInfo li)
201     {
202         String JavaDoc ret_string = new String JavaDoc();
203
204         ret_string +=
205             "Btree conglom has:\n" +
206             "\t" + prop.getProperty(Page.DIAG_PAGE_SIZE) + " bytes per page\n" +
207             "\t" + li.num_pages + " total used pages (" +
208                 (Integer.parseInt(prop.getProperty(Page.DIAG_PAGE_SIZE)) *
209                      li.num_pages) +
210                 " bytes)\n" +
211             "\tmaximum page number = " + li.max_pageno + ".\n" +
212             "\treserved space % = " + prop.getProperty(Page.DIAG_RESERVED_SPACE) + "%.\n" +
213             "\tminimum record size = " + prop.getProperty(Page.DIAG_MINIMUM_REC_SIZE) + ".\n" +
214             "\tpage overhead bytes = " + prop.getProperty(Page.DIAG_PAGEOVERHEAD) + " bytes per page.\n" +
215             "\tminimum record length = " + li.min_rowsize_bytes + ".\n" +
216             "\tmaximum record length = " + li.max_rowsize_bytes + ".\n" +
217             "\t# of bytes in rows = " + li.num_rowsize_bytes + "." +
218                 "\t(" +
219                 (li.num_entries == 0 ?
220                      0 : (li.num_rowsize_bytes / li.num_entries)) +
221                 " bytes/row).\n" +
222             out_summary(
223                 "# of reserved bytes = ",
224                 li.num_res_bytes,
225                 (li.num_res_bytes / li.num_pages),
226                 "reserved bytes/page") +
227             out_summary(
228                 "# of free bytes = ",
229                 li.num_free_bytes,
230                 (li.num_free_bytes / li.num_pages),
231                 "free bytes/page") +
232             out_summary(
233                 "# of slot table bytes = ",
234                 li.num_slottab_bytes,
235                 (li.num_slottab_bytes / li.num_pages),
236                 "slot table bytes/page") +
237             out_summary(
238                 "# of reserved+free+row+slot bytes = ",
239                 (li.num_rowsize_bytes +
240                  li.num_res_bytes +
241                  li.num_free_bytes +
242                  li.num_slottab_bytes),
243                 ((li.num_rowsize_bytes +
244                   li.num_res_bytes +
245                   li.num_free_bytes +
246                   li.num_slottab_bytes) / li.num_pages),
247                 "summed bytes/page") +
248             out_summary(
249                 "# of total records = ",
250                 li.num_entries,
251                 (((double) li.num_entries) / li.num_pages),
252                 "records/page") +
253             out_summary(
254                 "# of overflow records = ",
255                 li.num_overflow_rows,
256                 (((double) li.num_overflow_rows) / li.num_pages),
257                 "overflow records/page") +
258             out_summary(
259                 "# of deleted records = ",
260                 li.num_deleted,
261                 (((double) li.num_deleted) / li.num_pages),
262                 "deleted records/page");
263
264         return(ret_string);
265     }
266             
267
268     private static String JavaDoc diag_tabulate(
269     Properties JavaDoc prop,
270     LevelInfo level_info[])
271     {
272         String JavaDoc ret_string = new String JavaDoc();
273         LevelInfo total = new LevelInfo();
274
275         // first tabulate totals for all levels
276

277         for (int level = 0; level < level_info.length; level++)
278         {
279             LevelInfo li = level_info[level];
280
281             total.num_pages += li.num_pages;
282             total.num_overflow_pgs += li.num_overflow_pgs;
283             total.num_entries += li.num_entries;
284             total.num_deleted += li.num_deleted;
285             total.max_pageno = Math.max(total.max_pageno, li.max_pageno);
286             total.num_free_bytes += li.num_free_bytes;
287             total.num_res_bytes += li.num_res_bytes;
288             total.num_overflow_rows += li.num_overflow_rows;
289             total.num_rowsize_bytes += li.num_rowsize_bytes;
290             total.num_slottab_bytes += li.num_slottab_bytes;
291             total.min_rowsize_bytes =
292                 Math.min(total.min_rowsize_bytes, li.min_rowsize_bytes);
293             total.max_rowsize_bytes =
294                 Math.max(total.max_rowsize_bytes, li.max_rowsize_bytes);
295         }
296
297         ret_string +=
298             "Btree conglom has:\n" +
299             "\t" + prop.getProperty(Page.DIAG_PAGE_SIZE) + " bytes per page\n" +
300             "\t" + total.num_pages + " total used pages (" +
301                 (Integer.parseInt(prop.getProperty(Page.DIAG_PAGE_SIZE)) *
302                      total.num_pages) +
303                 " bytes)\n" +
304             "\tmaximum page number = " + total.max_pageno + ".\n" +
305             "\treserved space % = " + prop.getProperty(Page.DIAG_RESERVED_SPACE) + "%.\n" +
306             "\tminimum record size = " + prop.getProperty(Page.DIAG_MINIMUM_REC_SIZE) + ".\n" +
307             "\tpage overhead bytes = " + prop.getProperty(Page.DIAG_PAGEOVERHEAD) + " bytes per page.\n";
308
309         // Format Totals:
310
ret_string += diag_onelevel(prop, total);
311
312         // Format Totals by level:
313

314         // Totals by level:
315
for (int level = 0; level < level_info.length; level++)
316         {
317             LevelInfo li = level_info[level];
318
319             ret_string += "level[" + level + "] stats:\n";
320
321             ret_string += diag_onelevel(prop, li);
322         }
323
324         return(ret_string);
325     }
326
327     private static String JavaDoc olddiag_tabulate(
328     Properties JavaDoc prop,
329     LevelInfo level_info[])
330     {
331         String JavaDoc ret_string = new String JavaDoc();
332         long total_pages = 0;
333         long total_res = 0;
334
335         for (int level = 0; level < level_info.length; level++)
336         {
337             total_pages += level_info[level].num_pages;
338         }
339
340
341         // Totals:
342
ret_string +=
343             "Btree conglom has:\n" +
344             "\t" + prop.getProperty(Page.DIAG_PAGE_SIZE) + " bytes per page\n" +
345             "\t" + total_pages + " total pages (" +
346                 (Integer.parseInt(prop.getProperty(Page.DIAG_PAGE_SIZE)) *
347                      total_pages) + " bytes)\n" +
348             "\t" + level_info.length + " total levels\n" +
349             "\t" + level_info[0].num_entries + " total user records\n";
350
351         // Totals by level:
352
for (int level = 0; level < level_info.length; level++)
353         {
354             LevelInfo li = level_info[level];
355
356             ret_string += "level[" + level + "] stats:\n";
357
358             ret_string +=
359                 "\t# of pages = " + li.num_pages + ".\n" +
360                 "\t# of entries = " + li.num_entries + ". " +
361                 "(" + (li.num_entries / li.num_pages) + " entries/page).\n" +
362                 "\t# of deleted entries = " + li.num_deleted + ". " +
363                 "(" + (li.num_deleted / li.num_pages) + " deleted/page).\n" +
364                 "\t# of free bytes = " + li.num_res_bytes + ". " +
365                 "(" + (li.num_res_bytes / li.num_pages) + " reserved bytes/page).\n" +
366                 "\t# of free bytes = " + li.num_free_bytes + ". " +
367                 "(" + (li.num_free_bytes / li.num_pages) + " free bytes/page).\n" +
368                 "\t# of slot table bytes= " + li.num_slottab_bytes + ". " +
369                 "(" + (li.num_slottab_bytes / li.num_pages) + " slot table bytes/page).\n";
370         }
371
372         return(ret_string);
373     }
374
375     /*
376     ** Methods of Diagnosticable
377     */

378     public void init(Object JavaDoc obj)
379     {
380         if (SanityManager.DEBUG)
381             SanityManager.ASSERT(obj instanceof BTreeController);
382
383         super.init(obj);
384     }
385
386     /**
387      * Default implementation of diagnostic on the object.
388      * <p>
389      * This routine returns a string with whatever diagnostic information
390      * you would like to provide about this object.
391      * <p>
392      * This routine returns a summary table of information about pages in
393      * each level of the btree. It tells the height of the tree, the
394      * average free and reserved bytes per level, and the page size.
395      * <p>
396      *
397      * @return A string with diagnostic information about the object.
398      *
399      * @exception StandardException Standard cloudscape exception policy
400      **/

401     public String JavaDoc diag()
402         throws StandardException
403     {
404         OpenBTree open_btree = (BTreeController) this.diag_object;
405         ControlRow root = null;
406         int tree_height;
407         LevelInfo level_info[] = null;
408         String JavaDoc diag_info = new String JavaDoc();
409
410         
411         try
412         {
413             tree_height = open_btree.getHeight();
414             root = ControlRow.Get(open_btree, BTree.ROOTPAGEID);
415
416             // Allocate a LevelInfo array with one entry per level of the tree.
417
level_info = new LevelInfo[tree_height];
418             for (int level = 0; level < level_info.length; level++)
419                 level_info[level] = new LevelInfo();
420
421             // ask page to provide diag info:
422
Properties JavaDoc prop = new Properties JavaDoc();
423             prop.put(Page.DIAG_PAGE_SIZE, "");
424             prop.put(Page.DIAG_BYTES_FREE, "");
425             prop.put(Page.DIAG_BYTES_RESERVED, "");
426             prop.put(Page.DIAG_RESERVED_SPACE, "");
427             prop.put(Page.DIAG_MINIMUM_REC_SIZE, "");
428             prop.put(Page.DIAG_NUMOVERFLOWED, "");
429             prop.put(Page.DIAG_ROWSIZE, "");
430             prop.put(Page.DIAG_MINROWSIZE, "");
431             prop.put(Page.DIAG_MAXROWSIZE, "");
432             prop.put(Page.DIAG_PAGEOVERHEAD, "");
433             prop.put(Page.DIAG_SLOTTABLE_SIZE, "");
434
435             diag_level(open_btree, root, prop, level_info);
436
437
438             diag_info = diag_tabulate(prop, level_info);
439         }
440         finally
441         {
442             if (root != null)
443                 root.release();
444         }
445
446         return(diag_info);
447     }
448 }
449
Popular Tags