--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.impl.store.access.heap.D_HeapController\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to you under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.impl.store.access.heap;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.store.raw.ContainerHandle;\r
+import org.apache.derby.iapi.store.raw.Page;\r
+import org.apache.derby.iapi.services.diag.DiagnosticableGeneric;\r
+import org.apache.derby.iapi.services.diag.DiagnosticUtil;\r
+\r
+import java.util.Properties;\r
+\r
+\r
+/**\r
+\r
+ The HeapController_D class implements the Diagnostics protocol for the\r
+ HeapController class.\r
+\r
+**/\r
+\r
+class TableStats\r
+{\r
+ public int num_pages = 0; // number of pages in heap.\r
+ public int num_overflow_pgs = 0; // number of overflow pages heap.\r
+ public int num_entries = 0; // number recs on page\r
+ public int num_deleted = 0; // number of recs on page marked deleted.\r
+ public long max_pageno = 0; // biggest page number allocated\r
+ public long num_free_bytes = 0; // number of free bytes on the pages.\r
+ public long num_res_bytes = 0; // number of reserved bytes on the pages.\r
+ public long num_overflow_rows = 0; // number of over flow rows on page.\r
+ public long num_rowsize_bytes = 0; // number of bytes in rows.\r
+ public long min_rowsize_bytes = Long.MAX_VALUE; // length of shortest row.\r
+ public long max_rowsize_bytes = Long.MIN_VALUE; // length of longest row.\r
+}\r
+\r
+public class D_HeapController extends DiagnosticableGeneric\r
+{\r
+ /* Private/Protected methods of This class: */\r
+ private static void diag_page(\r
+ Page page,\r
+ Properties prop,\r
+ TableStats stat)\r
+ throws StandardException\r
+ {\r
+ stat.num_pages++;\r
+ stat.num_entries += page.recordCount();\r
+ stat.num_deleted += \r
+ (page.recordCount() - page.nonDeletedRecordCount());\r
+ stat.max_pageno = Math.max(stat.max_pageno, page.getPageNumber());\r
+\r
+ DiagnosticUtil.findDiagnostic(page).diag_detail(prop);\r
+\r
+ // number of free bytes on page.\r
+ int free_bytes = \r
+ Integer.parseInt(prop.getProperty(Page.DIAG_BYTES_FREE));\r
+\r
+ stat.num_free_bytes += free_bytes;\r
+\r
+ // number of bytes reserved on page.\r
+ int res_bytes = \r
+ Integer.parseInt(prop.getProperty(Page.DIAG_BYTES_RESERVED));\r
+\r
+ stat.num_res_bytes += res_bytes;\r
+\r
+ // overflow rows.\r
+ int overflow = \r
+ Integer.parseInt(prop.getProperty(Page.DIAG_NUMOVERFLOWED));\r
+\r
+ stat.num_overflow_rows += overflow;\r
+\r
+ // size of rows.\r
+ int rowsize = \r
+ Integer.parseInt(prop.getProperty(Page.DIAG_ROWSIZE));\r
+\r
+ stat.num_rowsize_bytes += rowsize;\r
+\r
+ // minimum row size.\r
+ int min_rowsize = \r
+ Integer.parseInt(prop.getProperty(Page.DIAG_MINROWSIZE));\r
+\r
+ if (min_rowsize != 0)\r
+ stat.min_rowsize_bytes = \r
+ Math.min(stat.min_rowsize_bytes, min_rowsize);\r
+\r
+ // maximum row size.\r
+ int max_rowsize = \r
+ Integer.parseInt(prop.getProperty(Page.DIAG_MAXROWSIZE));\r
+\r
+ stat.max_rowsize_bytes = Math.max(stat.max_rowsize_bytes, max_rowsize);\r
+ }\r
+\r
+ private static String out_summary(\r
+ String hdr,\r
+ long value,\r
+ double ratio,\r
+ String ratio_desc)\r
+ {\r
+ String double_str = "" + ratio;\r
+ String short_str;\r
+\r
+ if (ratio > 0.001)\r
+ {\r
+ short_str = double_str.substring(\r
+ 0, \r
+ Math.min(double_str.lastIndexOf(".") + 3, double_str.length()));\r
+ }\r
+ else \r
+ {\r
+ short_str = "NA";\r
+ }\r
+\r
+ return(\r
+ "\t" + hdr + value + ".\t(" + short_str + \r
+ " " + ratio_desc + ").\n");\r
+ }\r
+ \r
+\r
+ private static String diag_tabulate(\r
+ Properties prop,\r
+ TableStats stat)\r
+ {\r
+ String ret_string = new String();\r
+\r
+ // Totals:\r
+ ret_string += \r
+ "Heap conglom has:\n" + \r
+ "\t" + prop.getProperty(Page.DIAG_PAGE_SIZE) + " bytes per page\n" +\r
+ "\t" + stat.num_pages + " total used pages (" +\r
+ (Integer.parseInt(prop.getProperty(Page.DIAG_PAGE_SIZE)) * \r
+ stat.num_pages) + \r
+ " bytes)\n" +\r
+ "\tmaximum page number = " + stat.max_pageno + ".\n" +\r
+ "\treserved space % = " + prop.getProperty(Page.DIAG_RESERVED_SPACE) + "%.\n" +\r
+ "\tminimum record size = " + prop.getProperty(Page.DIAG_MINIMUM_REC_SIZE) + ".\n" +\r
+ "\tminimum record length = " + stat.min_rowsize_bytes + ".\n" +\r
+ "\tmaximum record length = " + stat.max_rowsize_bytes + ".\n" +\r
+ "\t# of bytes in rows = " + stat.num_rowsize_bytes + "." +\r
+ "\t(" + \r
+ (stat.num_entries == 0 ? \r
+ 0 : (stat.num_rowsize_bytes / stat.num_entries)) + \r
+ " bytes/row).\n" +\r
+ out_summary(\r
+ "# of reserved bytes = ", \r
+ stat.num_res_bytes,\r
+ (stat.num_res_bytes / stat.num_pages),\r
+ "reserved bytes/page") +\r
+ out_summary(\r
+ "# of free bytes = ",\r
+ stat.num_free_bytes,\r
+ (stat.num_free_bytes / stat.num_pages),\r
+ "free bytes/page") +\r
+ out_summary(\r
+ "# of total records = ",\r
+ stat.num_entries,\r
+ (((double) stat.num_entries) / stat.num_pages),\r
+ "records/page") +\r
+ out_summary(\r
+ "# of overflow records = ",\r
+ stat.num_overflow_rows,\r
+ (((double) stat.num_overflow_rows) / stat.num_pages),\r
+ "overflow records/page") +\r
+ out_summary(\r
+ "# of deleted records = ",\r
+ stat.num_deleted,\r
+ (((double) stat.num_deleted) / stat.num_pages),\r
+ "deleted records/page"); \r
+\r
+ return(ret_string);\r
+ }\r
+\r
+ /*\r
+ ** Methods of Diagnosticable\r
+ */\r
+ public void init(Object obj)\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ SanityManager.ASSERT(obj instanceof HeapController);\r
+\r
+ super.init(obj);\r
+ }\r
+\r
+\r
+ /**\r
+ * Default implementation of diagnostic on the object.\r
+ * <p>\r
+ * This routine returns a string with whatever diagnostic information\r
+ * you would like to provide about this object.\r
+ * <p>\r
+ * This routine should be overriden by a real implementation of the\r
+ * diagnostic information you would like to provide.\r
+ * <p>\r
+ *\r
+ * @return A string with diagnostic information about the object.\r
+ *\r
+ * @exception StandardException Standard Derby exception policy\r
+ **/\r
+ public String diag()\r
+ throws StandardException\r
+ {\r
+ long pageid;\r
+ ContainerHandle container = \r
+ ((HeapController) this.diag_object).getOpenConglom().getContainer();\r
+\r
+ TableStats stat = new TableStats();\r
+\r
+ // ask page to provide diag info:\r
+ Properties prop = new Properties();\r
+ prop.put(Page.DIAG_PAGE_SIZE, "");\r
+ prop.put(Page.DIAG_BYTES_FREE, "");\r
+ prop.put(Page.DIAG_BYTES_RESERVED, "");\r
+ prop.put(Page.DIAG_RESERVED_SPACE, "");\r
+ prop.put(Page.DIAG_MINIMUM_REC_SIZE, "");\r
+ prop.put(Page.DIAG_NUMOVERFLOWED, "");\r
+ prop.put(Page.DIAG_ROWSIZE, "");\r
+ prop.put(Page.DIAG_MINROWSIZE, "");\r
+ prop.put(Page.DIAG_MAXROWSIZE, "");\r
+\r
+ // scan all pages in the heap gathering summary stats in stat\r
+ Page page = container.getFirstPage();\r
+\r
+ while (page != null)\r
+ {\r
+ this.diag_page(page, prop, stat);\r
+ pageid = page.getPageNumber();\r
+ page.unlatch();\r
+ page = container.getNextPage(pageid);\r
+ }\r
+\r
+ return(this.diag_tabulate(prop, stat));\r
+ }\r
+}\r